# Level 3 - Rotary Precision (Misc)

<figure><img src="https://243380073-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBIa0PcXGYuP6chd3J1Ry%2Fuploads%2FzVjVi7lzUzL6nqS7irq4%2Fimage.png?alt=media&#x26;token=b098d5a5-4d98-4194-a4d5-1945fcadc65c" alt=""><figcaption></figcaption></figure>

{% file src="<https://243380073-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBIa0PcXGYuP6chd3J1Ry%2Fuploads%2F9eNzmiPJWi2w6UaBG23b%2Frotary-precision.txt?alt=media&token=99427237-70d5-4f25-b18a-fe88bdbd47ed>" %}

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:

```python
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:

```python
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:

```python
# 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}
```
