blahajctf-2024-writeups

SSTI golfing

A code golfing challenge for SSTI! Instance (down)

Restrictions

The server filters out a lot of good stuff, like __builtins__ and lipsum (used by HackMD). There’s also a 65 character limit on input, which rules out most payloads.

Bypassing

Someone managed to drop __builtins__ into an entry in Flask’s config global object (which I happened to see before FS reset it), but my solution is a bit less complicated :P

niebardzo’s SSTI payloads article was an interesting read, but ultimately unneeded.

Listing the available classes is easy - dict.mro()[1].__subclasses__() (34 char, including braces) does the trick.

Of interest (to me) was subprocess.Popen (at index 351), which would let us spawn a subprocess like cat. Unfortunately, a direct Popen payload is too long :(

So, what we can do is drop subprocess.Popen into a random field of the Flask global config object with something like config.update(a=dict.mro()[1].__subclasses__()[351]), and just config.a('cat *',shell=1,stdout=-1).communicate() to profit!

(Intended solution actually involves breakng the payload into pieces, so it’s not really golfing)


Fun fact: you can add files to the server. Thankfully, the flag is write-protected.

image