Skip to main content

data_split

Challenge

Imported from local notes.md.

Solution

Original Notes

data_split

Challenge Summary

  • Given: A single hostname, data-needs-splitting.umbccd.net, with the hint that the real program had to be found first.
  • Goal: Recover the hidden reverse-engineering target, analyze it, and determine the correct flag.
  • Constraints: No starting files were provided locally; the only entry point was the domain name.

Initial Recon / Triage

  • Observations:
    • A records for data-needs-splitting.umbccd.net did not resolve.
    • A TXT query on that hostname returned multiple numbered strings.
    • The TXT chunks began with PK, which is the ZIP/JAR magic once base64-decoded.
  • File identification:
    • The numbered TXT records were ordered base64 fragments of a Java archive.
    • Reconstructed archive contents: Main.class, Loader.class, and assets/file.dat.
    • assets/file.dat was itself a Java class file loaded reflectively.
  • Entry points:
    • DNS TXT records on data-needs-splitting.umbccd.net
    • Java entry class Main

Hypotheses & Approach

  • Hypothesis 1: The challenge data was intentionally split across DNS TXT records and needed to be reassembled.
  • Hypothesis 2: The visible JAR was only a loader, and the actual validation logic lived in the embedded assets/file.dat class.

Execution Steps (Reproducible)

Stage 1

Commands:

cd /root/dawg2026CTF/data_split
dig TXT data-needs-splitting.umbccd.net +short | tr -d '"' | sort | sed 's/^[0-9][0-9]//' | tr -d '\n' > artifacts/payload.b64
base64 -d artifacts/payload.b64 > artifacts/payload.jar
file artifacts/payload.jar
unzip -l artifacts/payload.jar

Results:

  • The TXT records reconstructed into artifacts/payload.jar.
  • The JAR contained Main.class, Loader.class, and assets/file.dat.

Stage 2

Commands:

cd /root/dawg2026CTF/data_split
javap -classpath artifacts/payload.jar -c -p Main
javap -classpath artifacts/payload.jar -c -p Loader
unzip -p artifacts/payload.jar assets/file.dat > artifacts/hidden.class
javap -c -p artifacts/hidden.class

Results:

  • Main instantiated Loader, which loaded /assets/file.dat as a class and invoked validate().
  • The hidden class was Validator.
  • Validator.validate() read stdin, XORed each character with two repeating 16-bit masks, appended the resulting integers as decimal text, and compared that against a hard-coded numeric string.

Stage 3

Commands:

cd /root/dawg2026CTF/data_split
python3 - <<'PY'
target = '145511939249997195145441944550467175145531942549987228145401943650017203145451934650207244145651934650127169'
key1 = 2194307438957234483
key2 = 148527584754938272
mask = [((key1 >> (16 * i)) & 0xffff) ^ ((key2 >> (16 * i)) & 0xffff) for i in range(4)]
lengths = [5, 5, 4, 4]

out = []
pos = 0
idx = 0
while pos < len(target):
chunk = int(target[pos:pos + lengths[idx % 4]])
out.append(chr(chunk ^ mask[idx % 4]))
pos += lengths[idx % 4]
idx += 1

print(''.join(out))
PY

printf 'DawgCTF{J@v@_My_B3l0v3d}\n' | java -jar artifacts/payload.jar

Results:

  • The decoded candidate flag was DawgCTF{J@v@_My_B3l0v3d}.
  • Running the JAR with that input printed Correct!, confirming the solution.

Artifacts Produced

  • artifacts/payload.b64 - concatenated base64 recovered from DNS TXT records.
  • artifacts/payload.jar - reconstructed Java archive.
  • artifacts/hidden.class - extracted validator class from assets/file.dat.

Flag

DawgCTF{J@v@_My_B3l0v3d}