Updated: Nov 1
In this CTF we finished in 26th place.
Here are two writeups of challenges I have solved.
I didn't put many screenshots since the CTF was down not long after it was ended.
Shuffle - Forensics
I was provided with a binary file.
I tried to identify what this file is using the 'file' command but it could not identify it.
'File' command usually checks Magic Numbers and the Magic File to determine the file type.
"Magic bytes" are a sequence of bytes that appear at the beginning of a file and are used to identify the type of the file. This sequence of bytes is sometimes called a "magic number" or "file signature".
For example, these are the magic bytes of a PNG file (left: Hex, right: ASCII)
(Here's a large list of different magic bytes: https://www.garykessler.net/library/file_sigs.html)
I opened it in Notepad++:
It looks like a PNG file. We can understand it from the beginning of the file, which looks like the Magic Bytes of a PNG file type (as shown before), but something is broken. From my experience, I know that the "PNG" ASCII characters should be on the same line.
After trying to change it manually without success I opened the file in '010 Editor' (a great hex editor):
Let's examine the hexadecimal sequence for the beginning of a PNG file and identify any discrepancies.
The sequence of a PNG file type should always start with the following hexadecimal sequence:
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52.
This sequence is the magic bytes and the beginning of the IHDR chunk.
Wait, what is IHDR chunk? What are chunks?
"Chunks" are the building blocks of the file format. A PNG file is made up of multiple chunks, each of which conveys certain information about the image or the data it contains.
For example, some of the chunks for PNG file are IHDR, PLTE, IDAT, sRGB and many more.
This is the chunks structure for PNG file:
Length: A 4-byte integer that specifies the length of the data field of the chunk (number of bytes dedicated to it.
Type: A 4-byte chunk type code. For example, "IHDR".
Data: The actual data bytes of the chunk.
CRC: A 4-byte code to check if chunk data has changed.
For example, these are the length and type section of the IHDR chunk which always stay the same (0x08-0x0B, 0x0C-0x0F respectively):
So... back to the challenge, the initial sequence (first 16 bytes - file type signature and some sections of the IHDR chunk) always remains the same.
However, in this case, it appears to be shuffled:
Initially, I attempted to manually correct the sequence, but the image remained corrupted.
I realized I might have to correct the entire hexadecimal sequence. But I can't determine the original sequence unless there's a pattern. Maybe some of the hexadecimal values were swapped with each other. Let's manually fix the sequences that I already know (those that are always the same), and see if there's a clear pattern in the shuffling:
The orange text marks the hex that I manually fixed.
It seems that the shuffle goes in this pattern:
Keep the first 2 bytes as they are.
Replace the 3rd byte with the 5th.
Replace the 4th byte with the 6th.
Continue this pattern for the entire file.
I asked ChatGPT to create a script for me to reshuffle the bytes using the pattern I provided:
I opened the new file, and I got the original file:
Extracttheflag! - Web
I've got the source code of a PHP page. Here are the interesting parts:
A session is started, and the admin session variable is set to false.
I checked what the extract() function is.
Note that it's insecure to use untrusted data for this function from user input.
In PHP, the extract($_POST) function is used to convert POST request data into corresponding internal variables.
When PHP runs the extract() function on the $_POST array, it creates variables that mirror the array's contents. This can pose a security risk if extract() ends up overwriting pre-existing variables, which, in our scenario, is exactly what happens.
According to this code part, my session's admin variable should be true in order to see the flag.
Sending a POST request with _SESSION['admin'] set as 'true', would cause the session admin variable to be rewritten and the flag would be exposed:
curl 'https://extracttheflag.ctf.cert.unlp.edu.ar' -X POST -d _SESSION['admin']=true