{"slug": "security-through-obfuscation-is-dead", "title": "Security Through Obfuscation Is Dead", "summary": "GPT-6 Astra reverse engineered the custom challenge-code format of the country guessing game Guessterra purely from example tokens, without access to source code, according to a first-person account by the developer's brother. The model identified a 24-byte Base64URL-decoded structure of a 20-byte payload plus a 4-byte checksum equal to SHA256(bytes[0:20])[0:4], then recovered country codes by XORing bytes 17-19 with bytes 1-3, yielding \"kr\" for South Korea and \"de\" for Germany. The finding shows that obfuscation-based security for shareable game links fails against AI pattern analysis.", "body_md": "My brother vibe coded a country guessing game called [**Guessterra**](https://guessterra.stiuvou.ch/).\n\nOne of its features lets you challenge another player. You finish a game, generate a link, send it to someone else, and they get the same country to guess.\n\nAs his brother, naturally, my first thought was not:\n\n*“What a nice feature.”*\n\nIt was:\n\n**“I wonder if I can break it.”**\n\nA challenge link looked something like this:\n\n```\nhttps://guessterra.stiuvou.ch/challenge?code=AX9AoA1piAyDX33slpK8vGAUJaAeUpyn\n```\n\nThe interesting part was the value after `code=`.\n\nIt looked random, but somewhere inside that string, the game clearly had to store the information to reproduce the challenge. My first thought was it’s probably base64 encoded.\n\nMy second thought was that I wanted to see whether GPT-6 Astra could figure out how the format worked.\n\nI didn’t give it any source code. I didn’t explain how the sharing feature had been implemented. I just gave it a handful of challenge codes and told it which countries they represented.\n\nThe question was simple:\n\n**Can GPT-6 reverse engineer a custom challenge-code format purely from examples?**\n\nIt turns out the answer is yes.\n\n## Starting with a random-looking token\n\nThe first example was a challenge for South Korea:\n\n```\nAa8dX2-WJ2ymvflxyDaOJELEb19QK6oq\n```\n\nAstra recognised that the token looked like Base64URL and decoded it into 24 raw bytes:\n\n```\n01 af 1d 5f 6f 96 27 6c\na6 bd f9 71 c8 36 8e 24\n42 c4 6f 5f 50 2b aa 2a\n```\n\nThere was no obvious `KR`, `KOR`, country ID, or other readable value inside it.\n\nAt first there were plenty of possibilities. Maybe the country was encrypted. Maybe the token was just a random database ID. Maybe it contained a hash, nonce, or some other cryptographic structure.\n\nOne example wasn’t enough to tell.\n\nSo I played the game again to get another challenge for the same country:\n\n```\nAR5AGuxf-9bY7Ky04MVgPHh1MhqBTJvY\n```\n\nThe two tokens were completely different apart from the first byte.\n\nThat ruled out the simplest possibility: this wasn’t just the country encoded in some deterministic way.\n\nI then supplied more examples, including Germany and the United Kingdom by playing the game again.\n\nFor a while, they still looked mostly like random binary data.\n\n## “Keep trying out things”\n\nGPT-6 Astra had explored a few plausible explanations, but none of them had worked yet and it had already given up.\n\nMy extremely sophisticated contribution to the reverse-engineering process was:\n\n**“keep trying out things”**\n\nAnd surprisingly, that turned out to be useful advice.\n\nInstead of concluding that the value was encrypted or otherwise inaccessible, Astra kept looking for relationships between different parts of the token.\n\nThat produced the first real breakthrough.\n\n## The checksum\n\nThe final four bytes weren’t random.\n\nThey matched the first four bytes of the SHA-256 hash of the preceding 20 bytes:\n\n```\nchecksum = SHA256(bytes[0:20])[0:4]\n```\n\nSo the token had a definite internal structure:\n\n```\n[ 20-byte payload ][ 4-byte checksum ]\n```\n\nThat didn’t reveal the country yet, but it was an important clue.\n\nThe challenge code wasn’t just an opaque blob anymore. It was a small custom binary format.\n\nThe next discovery by Astra was the most interesting one.\n\nBytes 1 through 16 appeared to contain random data. Astra started checking whether the remaining bytes were somehow related to that random section.\n\nFor the first South Korea token, it XORed bytes 17 through 19 with bytes 1 through 3:\n\n```\nc4 6f 5f\nXOR\naf 1d 5f\n=\n6b 72 00\n```\n\nIn ASCII:\n\n```\n6b = k\n72 = r\n```\n\nSo the result was:\n\n```\nkr 00\n```\n\nInteresting.\n\nBut one match could still be coincidence.\n\nSo Astra tried the completely different second South Korea challenge:\n\n```\n75 32 1a\nXOR\n1e 40 1a\n=\n6b 72 00\n```\n\nAgain:\n\n```\nkr 00\n```\n\nThat was the point where the scheme effectively fell apart.\n\n## Checking other countries\n\nGermany produced:\n\n```\ne3 1a d1\nXOR\n87 7f d1\n=\n64 65 00\n```\n\n`64 65` is ASCII for:\n\n```\nde\n```\n\nThe United Kingdom produced:\n\n```\n19 68 c1\nXOR\n7e 0a c1\n=\n67 62 00\n```\n\nWhich gives:\n\n```\ngb\n```\n\nThat was an especially nice confirmation because ISO 3166-1 uses **GB**, not **UK**.\n\nAt this point the structure was pretty clear:\n\n```\nbyte 0      version\nbytes 1–16  16 bytes of random data\nbytes 17–19 XOR-masked values\nbytes 20–23 checksum\n```\n\nThe first two masked values could be recovered with:\n\n```\ncountry_letter_1 = byte[17] XOR byte[1]\ncountry_letter_2 = byte[18] XOR byte[2]\n```\n\nThose two bytes form the lowercase ISO country code.\n\n## The real test: unknown challenges\n\nFinding a pattern in examples where you already know the answer is one thing.\n\nThe real test was whether the same method could decode completely new challenges without knowing the countries beforehand.\n\nSo I started sending fresh links.\n\nOne decoded to:\n\n```\nKE\n```\n\n**Kenya.**\n\nAnother:\n\n```\nBR\n```\n\n**Brazil.**\n\nAnd another:\n\n```\nID\n```\n\n**Indonesia.**\n\nAll of them also passed the SHA-256 checksum test and it was the right answer inside the game.\n\nAt that point, it wasn’t just a theory. Astra had built a working decoder.\n\n## Why the obfuscation doesn’t protect the answer\n\nThe country is XORed with random-looking bytes.\n\nThat sounds vaguely cryptographic until you realise that the bytes needed to reverse the XOR are included in the exact same token.\n\nConceptually, the format does this:\n\n```\nhidden_country = country XOR mask\n```\n\nBut then sends both:\n\n```\nhidden_country\nmask\n```\n\nWhich means anyone who understands the format can simply calculate:\n\n```\ncountry = hidden_country XOR mask\n```\n\nThe SHA-256 checksum makes it possible to detect whether the token has been modified, but it doesn’t make the contents secret.\n\nThere is no secret key involved.\n\nIt’s obfuscation, not encryption.\n\n## The part I found most interesting\n\nThe XOR itself isn’t particularly exotic.\n\nWhat surprised me was how little information Astra needed to work all of this out.\n\nIt had:\n\n- a handful of opaque challenge strings;\n- the countries corresponding to some of them;\n- no source code;\n- no documentation;\n- and repeated encouragement to keep experimenting.\n\nFrom that, it identified the transport encoding, found structure in the binary data, discovered the checksum, tested different hypotheses, found the XOR relationship, and successfully decoded previously unseen examples.\n\nSmall custom formats used to have a certain amount of protection simply because understanding them was annoying and time-consuming.\n\nThat barrier is getting much smaller.\n\n## Conclusion\n\nWhat started as me trying to cheat at my brother’s country guessing game turned into a surprisingly fun reverse-engineering experiment.\n\nThe challenge link looked like a random string:\n\n```\ncode=AX9AoA1piAyDX33slpK8vGAUJaAeUpyn\n```\n\nBut underneath it was a small binary format containing random data, an XOR-masked ISO country code, another masked byte, and a truncated SHA-256 checksum.\n\nThe country wasn’t really encrypted. It was just hidden well enough that a human looking at the URL wouldn’t immediately recognise it.\n\nAnd apparently, in 2026, getting past that can require little more than a few examples and the instruction:\n\n**“keep trying out things.”**\n\n**Security through obfuscation is dead, killed by AI.**", "url": "https://wpnews.pro/news/security-through-obfuscation-is-dead", "canonical_source": "https://www.robinglauser.ch/blog/2026/09/11/security-through-obfuscation-is-dead/", "published_at": "2026-09-18 09:28:51+00:00", "updated_at": "2026-09-18 09:55:27.107631+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-tools"], "entities": ["GPT-6 Astra", "Guessterra", "South Korea", "Germany", "United Kingdom"], "alternates": {"html": "https://wpnews.pro/news/security-through-obfuscation-is-dead", "markdown": "https://wpnews.pro/news/security-through-obfuscation-is-dead.md", "text": "https://wpnews.pro/news/security-through-obfuscation-is-dead.txt", "jsonld": "https://wpnews.pro/news/security-through-obfuscation-is-dead.jsonld"}}