TCS Hackquest Season 10 — Round 1
By Kishan Jai Soorya a.k.a L0n3_W0lf
TCS HackQuest Season 10: Round 1
By Kishan Jai Soorya a.k.a L0n3_W0lf

Introduction
On 13th December 2025, I participated in HackQuest 10 — Round 1, a Capture the Flag competition with multiple domains including Steganography, Binary Exploitation, Cryptography, Forensics, Web Exploitation, and Reverse Engineering.
In this writeup, I will walk through my approach for each challenge, step by step.
Challenge 1: Noise
Category: Miscellaneous / Forensics
We were given a file named 0Ae703d1E7.opt. The file extension was unfamiliar, so my first instinct was to extract any readable strings from it.
I used the *strings command piped with grep* to search for the flag format directly:
strings 0Ae703d1E7.opt | grep -aE 'HQX\{[^}]+\}'

This immediately revealed the flag hidden among the noise in the file.
Flag: HQX{543c40987fbca1c89974603649428016}
Challenge 2: Hidden Layers
Category: Steganography
We were given a PNG image file named image_FFf6c9Ae7b.png. Since it was a steganography challenge, I decided to run zsteg, a tool that detects hidden data in PNG and BMP files through various bit-level techniques.
zsteg -a image_FFf6c9Ae7b.png
The -a flag tells zsteg to try all known methods. Among the output, the flag was clearly visible.

Flag: HQX{24c0ce09e06382ad3f9312439d1d48f0}
Challenge 3: StackFall
Category: Binary Exploitation / Pwn
From the portal, we were given an ELF binary file. I opened it in Binary Ninja to analyze the binary.

After decompiling, I found the main() function which calls a healthCheck() function. However, there was another function called win() — this was the actual flag printer, but it was never called directly.

Looking closely at the healthCheck() function, I noticed a vulnerability:

The program reads up to 128 characters using scanf(“%128s”, var_88), but the buffer was not large enough to safely hold that input — leading to a buffer overflow.
By entering 128 → A’s, the overflow overwrites the return address and redirects execution into the win() function:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
“A” repeated 128 times → skips all checks → triggers win() → prints the flag.

Flag: HQX{8d0b49450b73d5778ba31927f2b8e19b}
Challenge 4: Address Abyss
Category: Forensics / Scripting
We were given a log file containing a large number of IP addresses. After opening the file, I noticed that only two specific IP formats contained useful data:
- IPv4 format: “92.7.A.B”
- IPv6 format: “2510:a1:A::B”

In both formats, A represents the index (position in the flag) and B represents the character. All other lines were noise.
I wrote a Python script using regular expressions to extract and reconstruct the flag:
import re
ipv4 = re.compile(r'⁹²\.7\.(\d+)\.(\d)$')
ipv6 = re.compile(r'²⁵¹⁰:a1:([0–9a-fA-F]+)::([0–9a-fA-F])$')
flag_parts = {}
with open("ip_logs_A4152c7Ec8.txt", "r") as f:
for line in f:
line = line.strip()
m4 = ipv4.match(line)
if m4:
index = int(m4.group(1))
flag_parts[index] = m4.group(2)
continue
m6 = ipv6.match(line)
if m6:
index = int(m6.group(1), 16) # hex to decimal
flag_parts[index] = m6.group(2)
flag = "".join(flag_parts[i] for i in sorted(flag_parts))
print(flag)

Flag: HQX{e1f63411d09f9abfd9786dbb0860d9f4}
Challenge 5: Seeds of Time
Category: Cryptography
We were given a file containing a ciphertext along with the Python source code showing how the encryption was performed.

The encryption logic was straightforward, it XORs the flag with a keystream generated by Python’s random.random() function. The seed used was int(time.time()), which means the random number generator was seeded with a Unix timestamp.
Since Python’s random module is not cryptographically secure and the seed is predictable, I wrote a brute-force script that tries timestamps going backward from the current time:
import time
import random
import string
cipher_hex = "f60d1ef6307bc56ed4f3f8fe41ea9b99d6ee77fe888e998649e0083b601303b923ebba81ca"
cipher = bytes.fromhex(cipher_hex)
def is_likely_flag(text):
if "flag{" in text.lower() or "ctf{" in text.lower():
return True
printable_count = sum(1 for c in text if c in string.printable)
return printable_count == len(text) and len(text) > 0
print("Brute-forcing seeds based on time…")
current_time = int(time.time())
seconds_to_check = 3000000
found = False
for i in range(seconds_to_check):
seed_candidate = current_time - i
random.seed(seed_candidate)
keystream = bytearray(int(random.random() * 256) for _ in range(len(cipher)))
decrypted_bytes = bytes([c ^ k for c, k in zip(cipher, keystream)])
try:
decrypted_text = decrypted_bytes.decode('utf-8')
if is_likely_flag(decrypted_text):
print(f"Success!")
print(f"Seed: {seed_candidate}")
print(f"Offset: -{i} seconds from now")
print(f"Flag: {decrypted_text}")
found = True
break
except UnicodeDecodeError:
continue
if not found:
print("Flag not found in the search range.")
After running the script, it successfully found the correct seed and decrypted the flag.

Flag: HQX{c126bb454b4dfcec6eec51f0729fbd08}
Challenge 6: Dot-Trace
Category: Steganography
We were given a text file containing a pattern of dots, spaces, and tabs. The challenge description also included a flag snippet encoded in Base64.
After analyzing the file structure, I figured out the encoding scheme:

**.**(dot + space) = 0**.\t**(dot + tab) = 1**. . . . . .**was padding/separator**.\n.\t.\n**was a block delimiter**. . .**marked the end of data
Each block of bits formed a binary representation of a character. I wrote a Python decoder:
path = r"3bfFb2A0EAenc.txt"
with open(path, "r", newline="") as f:
data = f.read()
blocks = data.split(".\n.\t.\n")
flag = ""
for block in blocks:
if block.strip() == ". . .":
break
block = block.replace(". . . . . .", "")
bits = ""
i = 0
while i < len(block) - 1:
if block[i:i+2] == ". ":
bits += "0"
i += 2
elif block[i:i+2] == ".\t":
bits += "1"
i += 2
else:
i += 1
if bits:
flag += chr(int(bits, 2))
print("FLAG =", flag)

Flag: HQX{ba44805fbe0f2e33ce4c0cacb2af175e}
Challenge 7: Synthetic Stacks
Category: Forensics / Steganography
We were given what appeared to be an image file. However, upon closer inspection, the actual file format was 7z (7-Zip archive) — and it was password protected.
Step 1: Cracking the Archive Password
I used John the Ripper to crack the 7z password. First, I extracted the hash:
7z2john archive_file > hash.txt

After cleaning the hash, I fed it to John:
john hash.txt

John cracked the password: angela
Step 2: Extracting the Contents
After extracting the archive with the password, I found a text file containing Base64 encoded strings.

Step 3: Decoding
I decoded the Base64 text and found an image containing a QR code. Scanning the QR code revealed the flag.


Flag: HQX{df30cb178eda45116b87893e6551c8de}
Challenge 8: Know Meh Better
Category: Reverse Engineering
We were given a Windows .EXE file. Since it was a Python-compiled executable, I used pyinstxtractor to decompile it:
python3 pyinstxtractor.py know_meh_better.exe

This extracted the .pyc files from the executable. Next, I decompiled the .pyc file back to readable Python using uncompyle6:
uncompyle6 -o . know_meh_better.pyc

After reading the decompiled source code, I understood the encryption logic. The program used len.doc as the XOR key and applied it cyclically to the cipher bytes.
I wrote a Python script to reverse the encryption:
slt = len.__doc__
cipher = bytes.fromhex("0123322c1714694427216d173a393b543f5a22576d132e0d23094759234a345a3a5d3f412c033f543c6a131d2e31115e4625")
print("".join(
chr(cipher[i] ^ ord(slt[i % len(slt)]))
for i in range(len(cipher))
))
The output was a Base64 encoded string.

After decoding it, I got the flag.

Flag: HQX{2483296533536a784253cd9245401d74}
Challenge 9: Fast and Rebound
Category: Web Exploitation / SSRF
After many attempts, I identified this as a DNS Rebinding challenge designed to exploit a Time-of-Check to Time-of-Use (TOCTOU) vulnerability in a Server-Side Request Forgery (SSRF) scenario.
Understanding the Vulnerability
The server validates the domain at check time (resolves to an external IP), but by the time it actually fetches the resource, the DNS has “rebounded” to 127.0.0.1 — the localhost.
Crafting the Payload
I used the rbndr.us service, which alternates DNS responses between two IPs. The service works by converting IPs to hexadecimal:
- 127.0.0.1 → 7f000001
- 8.8.8.8 → 08080808 (decoy external IP)
The format is: <IP1_Hex>.<IP2_Hex>.rbndr.us
http://7f000001.08080808.rbndr.us:8080

Getting the Flag
After several attempts (since DNS rebinding is probabilistic), the server fetched from 127.0.0.1 instead of the external IP. I found the flag at the /flag endpoint.

Flag: HQX{f37052426c34c286f35f1781c7aebf3b}
Challenge 10: Unfair Flip
Category: Web Exploitation / Client-Side
This was a browser-based challenge involving a coin flip game. By reading the JavaScript source code of the webpage, I understood that the game logic was entirely client-side.
The Exploit
The goal was to set all coins to Heads. Since the game state was controlled by a JavaScript variable, I simply opened the browser console and ran:
window.coins = ["H", "H", "H"];
Then, I called the hidden flag function:
window._hiddenFlag();
Flag: HQX{5c4e92253474f5d9f5e4800950e86a41}
Challenge 11: Mission No-Possible
Category: Web Exploitation / NoSQL Injection
This challenge presented an admin login page. After trying various payloads, I identified that the backend was vulnerable to NoSQL Injection.
The Exploit
I used the username eve and injected a NoSQL payload in the password field:
{“$ne”: “”}

This payload bypasses the authentication check because $ne (not equal) to an empty string matches any non-empty password in the database.

This gave me a token. Using that token, I accessed the admin panel and retrieved the flag.
Flag: HQX{a6bbcca13404fdb5e4856f4c81c8f95d}
I managed to rank in the Top 25 → check here
Thank you for reading! 😊
메타데이터
- post_id
- e4f405fe05b4
- slug
- tcs-hackquest-season-10-round-1-e4f405fe05b4
- url
- https://medium.com/@kishanjaisoorya16/tcs-hackquest-season-10-round-1-e4f405fe05b4
- canonical_url
- https://medium.com/@kishanjaisoorya16/tcs-hackquest-season-10-round-1-e4f405fe05b4
- author_url
- https://medium.com/@kishanjaisoorya16
- status
- ok
- fetched_at
- 2026-06-25 12:15:08