Categorymisc
PublishedAugust 31, 2025
CompetitionNNS CTF 2025
Points488 pts (9 solves)
AuthorBlorptopia
Rank

[NNS CTF 2025] Misc - tobe Writeup

[NNS CTF 2025] Misc - tobe Writeup

Cool challenge, one of most highest points I flagged and learned new things so had to do a short writeup.

chall
chall


What the challenge was

A FastAPI server guarded the flag behind a 10-character key. The server didn’t store the key anywhere; instead it tested properties of the key using Python’s “same object?” checks.

What the code basically did

It ran a bunch of yes/no tests in a fresh Python process:

# must all pass to get the flag
len(key) == 10
test(key[0]*5)      == True
test(key[0]*25)     == True
test(key[1])        == True
test(key[0]+key[1]) == False
test(key[2])        == False
test2(key[3:])      == False

# the oracles:
# test(s):   are two copies of s the *same object*?
# test2(s):  is a freshly rebuilt copy of s *already* the shared/global one?

How i used it

We chose key characters so each check answered the way we needed:

  • key[0] = a letter (e.g., a) → auto-interned ⇒ pass.
  • key[1] = a single ASCII char (e.g., !) → auto-interned ⇒ pass,
    and a! (letter+punct) → not auto-interned ⇒ fail (which we want).
  • key[2] = a non-ASCII char (e.g., , , 😀) → not auto-interned ⇒ fail (good).
  • key[3:] = a well-known Python name that’s already shared globally (e.g., "__doc__" or "compile") -> Two objects with the same text are not the same object ⇒ fail
text = (s + "a")[:-1]          # builds a NEW string object with the same letters
text is sys.intern(text)       # compare new object vs the global interned one

Example keys that work

a!中__doc__
a!€__len__
a!😀__doc__
a!€compile

Lessons learned

Python sometimes keeps one shared copy of common strings (called interning).

  • Many simple strings and single ASCII characters use that shared copy.
  • Special names like "__doc__" already have a global shared version.
  • Comparing with is asks “same object?” not “same text?”.
root@home:~/writeups$