Nullcon HackIM CTF 2025
Last updated
Last updated
Hey, fellow hackers! 🏴☠️
In this writeup 📝, I’ll break down some of the exciting challenges solved by myself and my squad P4rad0x in the Nullcon HackIM CTF 2025.
In this challenge, I was given a Python script (main.py) that encrypts a flag using XOR and shuffling. A scrambled hex output containing the encrypted flag.
Our goal❓ Recover the original flag!.
Looking at main.py
, we can break down the encryption process:
XOR Encoding:
Each character of the flag is XORed with a single-byte key.
This converts the flag into a scrambled list of integers.
Chunking and Shuffling:
The encrypted data is split into chunks of 4 bytes.
A random seed (0-10) is used to shuffle the chunks.
The shuffled bytes are then converted to hex and printed as the output.
I was given this scrambled hex output:
To undo the encryption, I needed to reverse each step:
Convert Hex to Bytes
The scrambled hex string is converted back into a list of numbers.
Brute-force the Shuffling Seed
Since the seed used for shuffling is between 0 and 10, I can try all possible seeds to reverse the shuffle order.
I reconstruct the original order by checking all possible shuffled indices.
Recover the XOR Key
Since flags typically follow a format like "ENO{", I can use known plaintext attack to determine the XOR key.
Compare "ENO{" with the first 4 decrypted characters to derive the key.
Apply XOR Decryption
Once the key is found, XOR it with all the scrambled bytes to reveal the flag.
When executing dec.py
, it successfully reverses the shuffle, finds the XOR key, and decrypts the flag! 🎉
ENO{5CR4M83L3D_3GG5_4R3_1ND33D_T45TY!!!}
This challenge gave me a binary file—a simple program that asks for input and checks if it’s the correct flag. But instead of guessing, I need to dig into the code and find the flag myself. Let’s go! 🚀
First, I ran the file
command to see what I was dealing with:
So, it’s a 64-bit ELF binary and stripped (which means no function names—just raw assembly).
Time to crack it open! 🔥
I loaded the binary into Ghidra—a software reverse engineering (SRE) framework and found the main function. Here's what it does:
Prompts for user input.
Passes the input to a flag-checking function.
This function encrypts the user input and then compares it to a stored encrypted flag in the .rodata
section.
And there it was—the encrypted flag hidden in memory. Here's the encryption logic :
Each byte of the input gets modified:
It adds the byte’s index to itself.
Then it XORs the result with 0x5A
.
Bitwise shifts happen next:
The encrypted byte is shifted left by 3.
OR’ed with the same byte shifted right by 5.
Now, I just needed to decrypt it!. I just had to reverse the process to get back the original flag!
Here's my Python script to decrypt the flag:
I ran the script, and… BOOM!💥
ENO{R3V3R53_3NG1N33R1NG_M45T3R!!!}
In this challenge, I had to use SQL injection techniques to uncover the hidden flag. Let’s dive in!
Clicking on the provided link took me to a paginated web application—a site that loads data in chunks instead of displaying everything at once.
I also noticed a "Source" button that led me to: http://52.59.124.14:5012/?source
Here, I found the source code of the backend, which was a crucial clue.
Reading through the code, I discovered an important detail:
🚨 The flag (id = 1) was restricted! 🚨
The site’s database had an "id" field where each entry had a unique number.
Direct access to id = 1 (the flag) was blocked—so I couldn’t just go to ?id=1
.
However, there was a vulnerability in how the pagination feature handled input.
The pagination feature worked with two parameters:
But here’s the catch: the "max_items" value wasn’t properly validated.
I crafted a simple SQL injection payload:
2,10
→ Normal pagination parameters.
OR id=1
→ A condition to forcefully retrieve the entry where id=1
(which contains the flag).
By entering this into the URL: http://52.59.124.14:5012/?p=2,10%20OR%20id=1
Boom! 💥 After decoding got the flag!
ENO{SQL1_W1th_0uT_C0mm4_W0rks_SomeHow!}
This challenge gave me a PNG image file, there was something hidden inside. But where? How?
First things first, I ran the usual checks:
🛠 exiftool
– Nothing suspicious in the metadata.
🛠 file
command – Just a regular JPG file.
No hidden comments, no strange data, just a plain old image. Since metadata didn’t give me anything, I turned to a more powerful tool: zsteg.
Zsteg is also a tool used to detect LSB steganography only in the case of PNG and BMP images.
I ran:
And BOOM! 💥 A flag appeared!
ENO{57394n09r4phy_15_w4y_c00l3r_7h4n_p0rn06r4phy}
This one started with a pcapng file (a packet capture file) containing USB traffic. First step?
Wireshark—the go-to tool for network forensics!
Opening the file in Wireshark, I spotted several packets with NCMA and NCM0 identifiers. Looking deeper, I found the USB device that used for this capture was a Gigabit Ethernet adapter (AX88179) from ASIX Electronics Corp. Cool
While scrolling through the packet list, I noticed something cool—a PNG file signature inside the hex data. That meant an image was hidden in the traffic!
I grabbed the hex data of the packet containing the PNG signature and ran it through CyberChef.
💥 Boom! A QR code appeared!
ENO{USB_ETHERNET_ADAPTER_ARE_COOL_N!C3}