Untitled

follow-the-rabbit-public.tar.gz

Nginx

HTTP response splitting exploitations and mitigations - Detectify Blog

In this challenge, we have to attack an nginx server loaded with this configuration:

user nginx;

worker_processes 4;

events {
    use epoll;
    worker_connections 128;
}

http {
    charset utf-8;

    access_log /dev/stdout combined;
    error_log /dev/stdout debug;

    upstream @deeper {
        server 127.0.0.1:8082;
    }

    server {
        listen 80;
        server_name _;

        location ~* ^(.*)$ {
            return 200 "I'm late! I'm late! For a very important date!";
        }

        location / {
            return 200 "Oh dear, oh dear! I shall be too late!";
        }

        location /deeper {
            proxy_pass http://@deeper$uri$is_args$args;
        }
    }

    server {
        listen 8082;
        server_name deeper;
        include flags.conf;

        location /deeper {
            add_header X-Original-Path "$uri";
            add_trailer X-Trailer "Coming to a nginx close to you" ;

            return 200 "No time to say hello, goodbye! I'm late! I'm late! I'm late!";
        }

        location /deepest {
            return 200 "$flag";
        }
    }
}

A whole docker setup is provided, so we are supposed to launch and dissect the stuff locally

Let’s start by analyzing the first server config:

        location ~* ^(.*)$ {
            return 200 "I'm late! I'm late! For a very important date!";
        }

What this route does is match every query and return useless text by matching everything in the query line

        location / {
            return 200 "Oh dear, oh dear! I shall be too late!";
        }

This one returns another text when the first block is not matched, it is probably here to help us see when we have successfully broken the query and also to give us an hint.

        location /deeper {
            proxy_pass http://@deeper$uri$is_args$args;
        }

This one passes the request to the backend server that contains the flag, this is the route we want to reach to begin with.

One way to break this request is to insert an URL-encoded newline so it breaks the regex: