- category: web
- points: 612
- topic: python jail escape
Thanks for your reports at cypherpunk2077!
We found a new secret website, please, can you check it for any hidden information?
The page presented at the provided link prompts the user to “look around” for more information, and no endpoint from the
previous challenge (cypherpunk2077) seems to be exposed (
A quick look at the source provides a not-so-useful hint:
<div class="l-about__box" style="top: 31.1111vh; left: 0px;">
The comment is probably referring to Philip K. Dick’s novel, “Do Androids Dream of Electric Sheep?”, which was “Blade
Runner”‘s original title. Now back to the challenge.
robots.txt reveals two interesting routes.
Obviously, accessing those endpoints doesn’t provide any actual flag.
"flag? No. You don't need it"
But what those routes highlight is something that was present on the first challenge as well:
HTTP/1.1 200 OK
x-powered-by header shows that the API we are trying to access has been implemented
using FastApi, a “modern, fast (high-performance), web framework for building APIs
with Python 3.6+”.
Going through FastApi docs shows some interesting routes: FastApi provides docs-generation out of the box, and (as
stated here) it’s accessible through the
/docs (Swagger based
/redoc (Redoc based docs) paths.
/docs revealse a strange looking endpoint, Do Kek.
The Swagger generated docs, in particular, allow a quick interaction with the api, all directly
from the browser.
By providing a mathematical expression to the endpoint through the
calc_req parameter it’s possible to obtain the
result as a response: what’s interesting is how the endpoint behaves when not provided with a mathematical expression.
# 1 + 2 + 3
This seems to allow some interesting python expressions, which could mean
eval or some similar instruction is being
run on the provided input (this does not affect the
additional_text parameter though).
Requesting for some more useful python instruction leads to errors:
This could revolve around being allowed code execution inside some sort of jailed environment. Trying with something
more complicated yields better results:
It might be possible to build a payload starting from that, such as
which could be way more dangerous than an harmless calculator; time for the actual payload (more details about the
payload’s contents later).
One useful thing could be extracting the server source code
gives back this beauty:
Here’s the same thing but beautified (thanks
which shows our code gets executed inside a
jinja2 template (
Since the flag doesn’t seem to be in this directory, and that the source code refers to
t as a sub-directory, we can
list it the same way we did before:
The first file seems particularly juicy, let’s take a peek inside
()refers to a
.__class__allows access to the class reference of
.__bases__refers to the first base class of
tuple, which is
.__subclasses__()()goes through the loaded subclasses of
object, and by listing them locally (e.g. the
following piece of code) one can determine the approximate index for the desired class (in our
warnings.catch_warningswas at index 139 locally, but 140 remotely).
for i,c in enumerate(().__class__.__bases__.__subclasses__()):
.__builtins__is a constant exposed inside every module, containing python global builtin functions
__builtins__ it’s possible to access
open and many other builtin functions, allowing for actual code
Accessing the endpoint from Burp instead of using the Swagger-generated docs ¯_( ͠° ͟ʖ ͠° )_/¯