Level 3 - Rotary Precision (Misc)

When we look at the file we see a bunch of things like:
G90
M82
M106 S0
M140 S60
M190 S60
M104 S210 T0
M109 S210 T0
G28 ; home all axes
G1 X0 Y0 Z0.2 F1500 E15 ; purging
G1 X5 Y10 Z0.2 F3000 ; get ready to prime
G92 E0 ; reset extrusion distance
; process Process1
; layer 1, Z = 0.240
T0
G92 E0.0000
G1 E-4.0000 F2400
; feature outer perimeter
; tool H0.240 W0.480
G1 Z0.240 F1000
G1 X116.825 Y82.987 F4000
G1 E0.0000 F2400
G92 E0.0000
G1 X118.091 Y83.080 E0.0547 F750
G1 X119.695 Y83.283 E0.1244
G1 X120.353 Y83.398 E0.1532
G1 X121.461 Y83.631 E0.2020
...
Upon further research, this turns out to be gcode, which essentially tells a 3D printer how to move, extrude filament, and control temperatures to build a 3D object layer by layer. I used various online and downloadable tools to visualise the image, but I couldn't see anything that resembled a flag (it was just a 3D image of a dragon).
Then we notice these suspicious lines:
G0 X7.989824091696275e-39 Y9.275539254788188e-39
G0 X7.989832499487061e-39 Y9.642842003063152e-39
G0 X5.14285644847226e-39 Y1.0928530541484243e-38
G0 X8.081637167078837e-39 Y8.081677804734302e-39
G0 X1.1020403872700771e-38 Y6.336807581627862e-39
G0 X1.1479535110641404e-38 Y9.918370912312555e-39
GPT eventually recognised these lines as IEEE-754 steganography hiding the flag text in X/Y coordinates. It gave me this decoder:
import re
FLT_TRUE_MIN = 1.401298464e-45 # IEEE-754 float32 smallest subnormal
out = []
with open("rotary-precision.gcode", "r", encoding="utf-8", errors="ignore") as f:
for line in f:
# look for scientific-notation coords like X1.23e-39 or Y9.64E-39
for axis in ("X","Y"):
m = re.search(rf"{axis}([+-]?\d+(?:\.\d+)?[eE][+-]?\d+)", line)
if not m:
continue
v = float(m.group(1))
if v <= 0.0: # skip zeros
continue
n = int(round(v / FLT_TRUE_MIN)) # 24-bit mantissa
# turn into 3 bytes, drop 0x00 padding, collect ASCII
out.extend(b for b in n.to_bytes(3, "big") if b != 0x00)
decoded = bytes(out).decode("ascii", errors="ignore")
print(decoded)
This is the script's output:
WaenWgiR81wLXQXnxgEq}FlbshG6c2UVh_zOB3ME{2jfbTB44IEVvo8vIkWSkc4sd
fer tor_top(alni ,ek)y
: hcraes t =A"CBEDGFIHKJMLONQPSRUTWVYXaZcbedgfihkjmlonqpsrutwvyx0z21436587{9_}
" hsfi t =ek
y ichpre= "
" of rhcrai nlpia:n
i dnxe= c ahsrtei.dnxec(ah)r
c pieh r=+( hcraes[ti(dnxe+ s ihtf ) %el(nhcraes)t)]
s ihtf= ( hsfi t +ek)y% l nec(ahsrte
)
r teru nichpre
After scrutinising this for some time, it turns out to be an obfuscated python snippet wherein every two adjacent letters (including the newline character) are swapped. The first line is the ciphertext which also got swapped.
It's actually doing something like this:
def rot_cipher(plain, key):
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}_"
shift = key
cipher = ""
for char in plain:
index = charset.index(char)
cipher += charset[(index + shift) % len(charset)]
shift = (shift + key) % len(charset)
return cipher
Now we can simply write a script that brutes all likely keys from 0 to 31, and prints the flag if found:
# Corresponding decryption function:
def rot_decipher(cipher, key):
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}_"
shift = key
plain = ""
for char in cipher:
index = charset.index(char)
plain += charset[(index - shift) % len(charset)]
shift = (shift + key) % len(charset)
return plain
for i in range(32):
key = i
# Encrypt
# encrypted = rot_cipher(original_text, key)
# encrypted = "WaenWgiR81wLXQXnxgEq}FlbshG6c2UVh_zOB3ME{2jfbTB44IEVvo8vIkWSkc4s"
encrypted = 'aWnegWRi18LwQXnXgxqEF}blhs6G2cVU_hOz3BEM2{fjTb4BI4VEovv8kISWcks4'
# print(f"Original: {original_text}")
# print(f"Encrypted: {encrypted}")
# Decrypt
decrypted = rot_decipher(encrypted, key)
if decrypted[:4] == "TISC":
print(f"flag: {decrypted}")
# Verify they match
# print(f"Match: {original_text == decrypted}")
# TISC{thr33_d33_pr1n71n9_15_FuN_4c3d74845bc30de033f2e7706b585456}
Last updated