Lukas App
Last updated
Last updated
After the excellent success of the luca-app we now decided to build our own tracing apps. We still have some technical difficulties but you may still want to have a look: https://lukas-app.de. At least we managed to get the TLS certificates for all hosts!
Hint 1: Read the challenge description carefully. There already is a big hint in it.
Hint 2: There is only a tiny bit of guesswork involved, and it's not hard to find. A lot of teams already found it. Also again: Automated tooling like dirbuster or sqlmap will not help you with this challenge.
Hint 3: We at Lukas App are proud to be running our software in the cloud. We don't even need to care about server updates or weird protocol headers anymore.
The contents of https://lukas-app.de are not very interesting. It's only a static site, with a non-working captcha. The web challenges in this CTF don't involve any scanning and brute-forcing, so there's nothing else for us here.
The description said "At least we managed to get the TLS certificates for all hosts!", and the hints point us in that direction, so I decided to do a crt.sh
certificate search.
This indeed revealed two additional subdomains! beta.lukas-app.de
is another web app. There's a login page, but not much else.
I noticed that the logo here is fetched from https://cdn.lukas-app.de/static/logo.png
. But when visiting this URL, we are actually redirected to another domain: https://cdn-eu-west.lukas-app.de/static/logo.png
.
Looking at the response headers, I immediately noticed that we have hit the jackpot - this server, unlike the others, returned Server: Apache/2.4.50 (Unix)
, which was vulnerable to a recent path traversal vulnerability (CVE-2021-42013)!
Using the usual payload (.%%32%65
), however, gave us a 400 Bad Request. I think this was due to the server using both Nginx (which would have already performed one round of URL decoding) and Apache (which would then receive the URL-decoded path). To overcome this, I had to URL-encode the PoC payload again (a triple URL encoding by now!)
Now we get a different error (403 Forbidden) using GET /cgi-bin/.../etc/passwd
.
I was stuck here for a while, until I came across some inspiration from Twitter: instead of /cgi-bin/
maybe the /static/
path, where the logo is stored, is an Alias
to some directory?
I finally got a working path traversal: GET /static/%25%2532%2565%25%2532%2565%2F%25%2532%2565%25%2532%2565%2Fetc/passwd HTTP/2
I then read the Apache configuration file (at /usr/local/apache2/conf/httpd.conf
), which confirmed my hypothesis. Interestingly, the /static/
URL maps to /app/static
. Could this be the same directory where the web app is stored?
Indeed, I was able to read the source code from /app/app.py
.
The final nail in the coffin came from the following programming error in the secret key (it's a string):
We simply need to change our session username
to root
, in order to get the flag.
Since the server uses client-side cookies, we can simply sign the Flask cookie with our desired username.
Change the session cookie and get the flag!