Forensicsmedium
Meshage In A Bottle
by Pavel Knespl (capyplivl)
A 3D asset portal exposes a "deprecated" versioned directory with live directory indexing. A backup file named .sys is actually certutil -encode armored base64 of a binary STL model. The flag is spelled out by the model's extruded geometry, not present as a string in the bytes.
Solve
- Map the app. The landing page hints that
/assets_production_system_v2/is deprecated in favor of a v3 pipeline. Indexing is claimed "disabled" but is live on v3. Start the instance, then:
The v3 listing containscurl -s https://<target>/assets_production_system_v3/ curl -s https://<target>/assets_production_system_v3/bak/bak/, which holdsfile_backup.sys. - Download the backup. Its header is
-----BEGIN CERTIFICATE-----followed by base64, i.e.certutil -encodeoutput, not a real cert:curl -s https://<target>/assets_production_system_v3/bak/file_backup.sys -o file_backup.sys head -c 60 file_backup.sys - Strip the PEM lines and base64-decode to recover a binary STL (
OpenSCAD Modelheader, 5952 triangles).stringsshows no flag; it is pure geometry. Bounding box X 0-160, Y 0-25, Z 0-3 (flat extruded text):import base64, re body = re.sub(r'-----[^-]+-----', '', open('file_backup.sys').read()) open('decoded.stl','wb').write(base64.b64decode(''.join(body.split()))) - Render the model. Project only the vertical wall faces (triangles with |normal.z| < 0.3) onto the XY plane to reveal the extruded text:
The rendered text reads the flag.import struct, matplotlib; matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.collections import LineCollection raw = open('decoded.stl','rb').read(); n = struct.unpack('<I', raw[80:84])[0] off, segs = 84, [] for _ in range(n): rec = raw[off:off+50]; off += 50 nx,ny,nz = struct.unpack('<3f', rec[:12]); v = struct.unpack('<9f', rec[12:48]) if abs(nz) < 0.3: p = [v[0:2], v[3:5], v[6:8]] segs += [(p[0],p[1]),(p[1],p[2]),(p[2],p[0])] ax = plt.subplots(figsize=(32,6))[1] ax.add_collection(LineCollection(segs, colors='black', linewidths=0.6)) ax.set_xlim(-2,162); ax.set_ylim(-2,27); ax.set_aspect('equal'); ax.axis('off') plt.savefig('render_outline.png', dpi=150, bbox_inches='tight', facecolor='white')
Flag: SVIBGR{n3v3r_d1sm1ss_th3_f1n3_4rts}