Pooot Writeup

DEFCON CTF Quals

FHantke
FHantke
May 18 · 4 min read

Yes… DEFCON is really cancelled this year, nevertheless I did not miss the chance to play the DEFCON CTF Quals. I participated with the team Sauercloud and spent most of the time with the pooot web challenge. Unfortunately, we were not successful in solving the challenge before the end of the Quals, but I continued and eventually figured the solution out. To document the solution for myself and hopefully help anyone who did not solve the challenge, here is my writeup.


What do we have?

When we open the website, we see a field to enter a URL and surf anonymously. After submitting, the website renders the corresponding website. The first interesting hint is the comment in the HTML that leads us to the source of the website which I uploaded here.

The index page (left) and the feedback form (right)

The website uses Flask and provides the following endpoints:

  • /
  • /<string:domain>/<path:path>
  • /source
  • /feedback

The URL uses python requests to GET the requested website and modifies all links to work with the proxy. Afterwards it renders the content. The feedback path is used to give feedback about a broken page. It uses a Redis queue to schedule the tasks. The whole service is hidden behind a proxy.

What are we looking for?

The first idea that we had was to use SSRF to communicate with Redis. So, we set up a nginx server which replied with a redirect to and it worked. We received two requests. However, as soon as we tried to redirect to an internal IP, we received the error “The server checks if the request is sent from a local IP, and since our origin address is from our own PC, the request is blocked.

if request.headers.getlist("X-Forwarded-For"):
client_ip = request.headers.getlist("X-Forwarded-For")[0]
else:
client_ip = request.remote_addr
if isIP(domain):
protocol = “http”
if client_ip != “172.25.0.100”:
app.logger.error(f”Internal IP address [...] not allowed.” )
return “Internal IP address not allowed”, 400

Next, we wondered what the workers job is.

from worker import task
url = re.sub(r'http[s]*://', '', form.url.data)
job = q.enqueue(task,url)

When we submitted our server domain in the form, a request appeared in our nginx access log. Next, we tested by replying an html document (below) executing JS to request our server — XSS. And yes, we received two requests. The html is called by a headless chrome that executes the JS. From this point, we have a request initiated by the internal browser. Consequently, we can call /<IP> and would pass the internal IP check. Now it was time to find and speak to Redis… Well, I will skip this part, as it led us to a dead-end from which we would never escape...

The html content to request internal IPs

Final Solution

After the CTF ended, someone in Discord suggested combining the XSS in the workers task with a service worker to check other URLs that are visited. This led me to research service workers, a concept I was previously unaware of. Service workers are essentially a proxy on your website/in your browser that can intercept requests from your browser and pull them from the cache. What it can also do is, it can send the request or information about the request to another server!

I crafted a service worker, registered it for the task and immediately received another request. In the access log below, we can see that the headless chrome also visits . Using the method above, I requested this IP and I finally had the flag!!!

The service worker js
The html content to register the service worker
The access log

Summary

The challenge was great fun and I learned a lot. And that is for me the most important part — I love to learn new things when playing CTFs. Thanks to Order of the Overflow for organizing the challenges and thanks to my team who showed me many cool tricks. Keep on hacking!

InfoSec Write-ups

A collection of write-ups from the best hackers in the…

FHantke

Written by

FHantke

Computer Science Student. Interested in IT security and forensics.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

FHantke

Written by

FHantke

Computer Science Student. Interested in IT security and forensics.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store