Writeup - Safepy (UIUCTF 2022)
UIUCTF 2022 - safepy Writeup
- Type - Jail
- Name - safepy
- Points - 50
Description
1 | My calculator won't be getting pwned again... |
Writeup
When you unzip the provided file for the challenge, you’ll get the Python script run server-side along with some supporting files for the Docker setup. Outside of line 28 of the Dockerfile that shows the flag is located at /flag
, the only useful file is main.py
. The script is pretty short:
1 | from sympy import * |
Our input is taken, parsed using parse_expr
, and then stuck into the diff
function with the output printed out. The parse()
function gives us two very helpful links, one to the documentation and another about why sympify
is dangerous. Reading through this article gave me an idea for how to approach this - sympify
used eval()
internally, so if I could get either diff
or parse_expr
to do the same, that would be great!
While reading through the documentation provided, I read that an optional parameter for parse_expr
was evaluate
, with the default setting to True. This means that, by default, any expressions will be simplified if possible, which means it will use eval()
inside of it.
I started out with a test payload to see what it would do if I just input whatever code I wanted to - print('a')
:
1 | $ nc safepy.chal.uiuc.tf 1337 |
Since it looked like it ran the code, I decided to just put in a payload to print out the flag:
1 | nc safepy.chal.uiuc.tf 1337 |
And it worked!!
Flag: uiuctf{na1v3_0r_mal1ci0u5_chang3?}
Real-World Application
My favorite part of this challenge is the real world application. This entire question was completely based off of a StackOverflow answer, and - as everyone knows - StackOverflow is the source for all programming information. This particular answer was from someone who said putting user-controlled input to sympify()
is dangerous since it uses eval
natively, so the parse_expr
function should be used instead (implying this one was safe). As our problem demonstrated, that was not the case - parse_expr
was just as dangerous as sympify
. Did the user who submitted this answer know this? Not sure. But the moral of the story is you can’t always trust answers from random people on the internet…