3kCTF-2021
Web
online_compiler
Compile & run your code with the 3k online compiler. Our online compiler supports multiple programming languages like Php, Python,...
We're given source code of a web app - interesting snippets:
@app.route('/save',methods = ['POST'])
@cross_origin()
def save():
c_type=request.form['c_type']
print('ctype-(>'+c_type)
if (c_type == 'php'):
code=request.form['code']
if (len(code)<100):
filename=get_random_string(6)+'.php'
path='/home/app/test/'+filename
f=open(path,'w')
f.write(code)
f.close()
return filename
else:
return 'failed'
"""elif (c_type == 'python'):
code=request.args.get('code')
if (len(code)<30):
filename=get_random_string(6)+'.py'
path='/home/app/testpy/'+filename
f=open(path,'w')
f.write(code)
f.close()
return filename
else:
return 'failed'"""
@app.route('/compile',methods = ['POST'])
@cross_origin()
def compile():
c_type=request.form['c_type']
filename=request.form['filename']
if (c_type == 'php'):
if (filename[-3:]=='php'):
if (check_file('/home/app/test/'+filename)):
path='/home/app/test/'+filename
cmd='php -c php.ini '+path
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
return stdout
else:
return 'failed'
else:
return 'noop'
elif (c_type == 'python'):
if (filename[-2:]=='py'):
if (check_file('/home/app/test/'+filename)):
cmd='python3 '+filename
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
print(f"{stdout=} {stderr=}")
return stdout
else:
return 'failed'
else:
return 'noop'
We see that we have two routes: /save
, which will write provided code to a .php
file (and its handler for Python is commented out), and /compile
, which will execute either a PHP or Python file and return the output.
The obvious solution here is to write a shell or some code into a PHP file, then execute it. However, we immediately run into the first roadblock: disable_functions
in php.ini
disables most useful functions. Comparing with a list of internal functions, we find that we can only use the following functions:
The plan of attack shifts slightly - could we utilise some of the above functions to write Python code into a file, then execute it? It appears that the Python runner does not enforce any form of restrictions.
The session management functions jump out - if we take a look at the documentation, we see that sessions are written to disk.
The following code results in /tmp/sess_hpy
being created:
Conveniently, the use of #
as the session key comments out the session management bits. /tmp/sess_hpy
is thus valid Python that we can execute for our flag.
➜ onlinecompiler python3 exec.py
zxfboj.php
3k{JuSt_A_WaRmUp_O.o}