MidnightsunCTF Quals 2019 - bigspin
bigspin was a challenge for the MidnightsunCTF Quals 2019
On visiting the linked website you get a message, asking if you are a user
,
admin
or uberadmin
, or just a usual pleb
(all links to identically named
subdirectories).
We are all usual plebs
Visiting anything but pleb
fails. Visting pleb
results in the content of
example.com showing on your screen.
With a bit of trial and error it becomes obvious that it’s a reverse proxy
for example.com with a missing /
after the domain name, making it possible
to visit something like /pleb.localhost.localdomain/user
.
nginx.cönf
Accessing the directory gives us a directory listing with a single file called
nginx.cönf
(including a space at the end of the filename).
Just clicking on the file results in a 404, we have to double encode the
filename because nginx decodes it first before it’s used in the reverse
proxy url.
Something like /pleb.localhost.localdomain/user/nginx.c%25C3%25B6nf%2520
works and gives us a copy of the used nginx config:
worker_processes 1;
user nobody nobody;
error_log /dev/stdout;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
# Set an array of temp and cache files options that otherwise defaults to
# restricted locations accessible only to root.
client_body_temp_path /tmp/client_body;
fastcgi_temp_path /tmp/fastcgi_temp;
proxy_temp_path /tmp/proxy_temp;
scgi_temp_path /tmp/scgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
resolver 8.8.8.8 ipv6=off;
server {
listen 80;
location / {
root /var/www/html/public;
try_files $uri $uri/index.html $uri/ =404;
}
location /user {
allow 127.0.0.1;
deny all;
autoindex on;
root /var/www/html/;
}
location /admin {
internal;
autoindex on;
alias /var/www/html/admin/;
}
location /uberadmin {
allow 0.13.3.7;
deny all;
autoindex on;
alias /var/www/html/uberadmin/;
}
location ~ /pleb([/a-zA-Z0-9.:%]+) {
proxy_pass http://example.com$1;
}
access_log /dev/stdout;
error_log /dev/stdout;
}
}
I’m an admin!
We can see that /admin
is an internal
block, which can’t be accessed directly
but since we have control over the reverse proxy URL we can use it to point to a
server of our control and add a header like X-Accel-Redirect: /admin/
, which
instructs nginx to do an internal redirect and delivers us the content as if we’d
have been able to access /admin/
directly.
In the admin directory is a flag.txt
, but it only tells us that the flag is only
for uberadmins
.
I lied, I’m really an uberadmin.
Since the location blocks are not terminated with a slash but the alias in the /admin
block is terminated we can inject dots to access a higher directory.
Setting the header on our server to X-Accel-Redirect: /admin../uberadmin/flag.txt
results in the flag.
Lesson learned: Terminate all paths and URLs with slashes.