Nginx potentially leaking real filenames? (hopefully properly formatted)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Nginx potentially leaking real filenames? (hopefully properly formatted)

pizwer88@wp.pl
Hi,

I am experimenting with various ways of annoying bots and automated
vulnerability scanners that reach my service. In one instance I am
serving a recursive decompression bomb for all requests for .php files.
Since none of my services run PHP, and never have, all such traffic can
be safely assumed malicious.
Recently (a couple of months since first deployment) I started seeing
repeated requests to the server trying to fetch the recursive
decompression bomb by its real file name, which should have never been
exposed anywhere.

Is it possible for nginx to leak the real file name? Through
misconfiguration or other means?

I am using nginx (version 1.14.2-2+deb10u1) as a reverse proxy and for
SSL termination.
The custom application behind it is not aware of the existence of the
decompression bomb and lives in its own completely separate directory
tree. It never reads nor serves any files from the local server, all its
data is in physically separate database and cache servers. While I
cannot prove absence of vulnerabilities in this custom app, I have not
found any evidence of it being used to (nor leaking) local directory
contents.
The decompression bomb does not contain its file name in its contents.

Given the above, I believe something in my nginx setup leaked the real
file name of the decompression bomb.
I've tried using all request methods (GET, HEAD, PUT, POST, DELETE,
CONNECT, OPTIONS, TRACE, PATCH) on the server from curl like following:
     $ curl --verbose -X <method> <redacted>.com/index.php
and (as expected) none of the responses leaked the file name in any of
the headers nor contents.

Below is a redacted and inlined version of my nginx configuration. There
is only one server defined, the Debian default server config has been
removed. The error code mapping is there to avoid triggering high error
rate alerts when hit by hundreds of consecutive bot requests.
I would appreciate any help in figuring out what I am doing wrong and
how could the <redacted-payload-filename> have been leaked?

Thanks,
Pizab

# nginx.conf
http {
     sendfile on;
     tcp_nopush on;
     tcp_nodelay on;
     keepalive_timeout 165;
     types_hash_max_size 2048;

     include /etc/nginx/mime.types;
     default_type application/octet-stream;

     limit_req_zone "php" zone=attackzone:10m rate=1r/s;

     ssl_certificate <redacted>;
     ssl_certificate_key <redacted>;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
     ssl_session_cache shared:SSL:10m;
     ssl_session_timeout 10m;

     server_tokens off;

     access_log /var/log/nginx/access.log;
     error_log /var/log/nginx/error.log;

     client_body_buffer_size 1M;

     server {
         listen   443  default_server ssl;
         listen   80;

         server_name <redacted>.com;
         rewrite_log on;

         location /.well-known/acme-challenge {
             alias /var/www/html/.well-known/acme-challenge;
         }

         location / {
             access_log /<redacted>/logs/nginx_access.log;
             proxy_set_header Host $http_host;
             proxy_redirect off;
             proxy_connect_timeout 60;
             proxy_read_timeout 160;
             proxy_pass <a href="http://localhost:10000;">http://localhost:10000;
         }

         error_page 429 =229 /error429;

         location ~ \.php$ {
             limit_rate_after 1k;
             limit_rate 2k;
             limit_req zone=attackzone burst=2;
             limit_req_status 429;
             keepalive_timeout 0;
             root /var/www/html/<redacted>/;
             default_type "application/xml";
             add_header Content-Encoding "br";
             try_files /<redacted-payload-filename> =400;
         }

         location = /error429 {
             return 229 "Too many requests.";
         }
     }
}
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Nginx potentially leaking real filenames? (hopefully properly formatted)

lists@lazygranch.com
In theory not a problem, but look at the text on this page about placing root in location blocks.
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/

I saw your first post and thought it was entertaining. Somebody needs to annoy those hackers. Since I don't use php I trap those requests in a map and return a 444. That way I can use some scripts and pull the hacker IPs out of the log file. If they come from a server, the IP space of that host gets blocked. There are no eyeballs at servers. But I do like the idea of feeding the hacker something unpleasant.





          Original Message  


From: [hidden email]
Sent: June 18, 2020 4:08 AM
To: [hidden email]
Reply-to: [hidden email]
Subject: Nginx potentially leaking real filenames? (hopefully properly formatted)


Hi,

I am experimenting with various ways of annoying bots and automated
vulnerability scanners that reach my service. In one instance I am
serving a recursive decompression bomb for all requests for .php files.
Since none of my services run PHP, and never have, all such traffic can
be safely assumed malicious.
Recently (a couple of months since first deployment) I started seeing
repeated requests to the server trying to fetch the recursive
decompression bomb by its real file name, which should have never been
exposed anywhere.

Is it possible for nginx to leak the real file name? Through
misconfiguration or other means?

I am using nginx (version 1.14.2-2+deb10u1) as a reverse proxy and for
SSL termination.
The custom application behind it is not aware of the existence of the
decompression bomb and lives in its own completely separate directory
tree. It never reads nor serves any files from the local server, all its
data is in physically separate database and cache servers. While I
cannot prove absence of vulnerabilities in this custom app, I have not
found any evidence of it being used to (nor leaking) local directory
contents.
The decompression bomb does not contain its file name in its contents.

Given the above, I believe something in my nginx setup leaked the real
file name of the decompression bomb.
I've tried using all request methods (GET, HEAD, PUT, POST, DELETE,
CONNECT, OPTIONS, TRACE, PATCH) on the server from curl like following:
     $ curl --verbose -X <method> <redacted>.com/index.php
and (as expected) none of the responses leaked the file name in any of
the headers nor contents.

Below is a redacted and inlined version of my nginx configuration. There
is only one server defined, the Debian default server config has been
removed. The error code mapping is there to avoid triggering high error
rate alerts when hit by hundreds of consecutive bot requests.
I would appreciate any help in figuring out what I am doing wrong and
how could the <redacted-payload-filename> have been leaked?

Thanks,
Pizab

# nginx.conf
http {
     sendfile on;
     tcp_nopush on;
     tcp_nodelay on;
     keepalive_timeout 165;
     types_hash_max_size 2048;

     include /etc/nginx/mime.types;
     default_type application/octet-stream;

     limit_req_zone "php" zone=attackzone:10m rate=1r/s;

     ssl_certificate <redacted>;
     ssl_certificate_key <redacted>;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
     ssl_session_cache shared:SSL:10m;
     ssl_session_timeout 10m;

     server_tokens off;

     access_log /var/log/nginx/access.log;
     error_log /var/log/nginx/error.log;

     client_body_buffer_size 1M;

     server {
         listen   443  default_server ssl;
         listen   80;

         server_name <redacted>.com;
         rewrite_log on;

         location /.well-known/acme-challenge {
             alias /var/www/html/.well-known/acme-challenge;
         }

         location / {
             access_log /<redacted>/logs/nginx_access.log;
             proxy_set_header Host $http_host;
             proxy_redirect off;
             proxy_connect_timeout 60;
             proxy_read_timeout 160;
             proxy_pass <a href="http://localhost:10000;">http://localhost:10000;
         }

         error_page 429 =229 /error429;

         location ~ \.php$ {
             limit_rate_after 1k;
             limit_rate 2k;
             limit_req zone=attackzone burst=2;
             limit_req_status 429;
             keepalive_timeout 0;
             root /var/www/html/<redacted>/;
             default_type "application/xml";
             add_header Content-Encoding "br";
             try_files /<redacted-payload-filename> =400;
         }

         location = /error429 {
             return 229 "Too many requests.";
         }
     }
}
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Nginx potentially leaking real filenames? (hopefully properly formatted)

Marcin Wanat

On Thu, Jun 18, 2020 at 5:04 PM lists <[hidden email]> wrote:
In theory not a problem, but look at the text on this page about placing root in location blocks.
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/

I saw your first post and thought it was entertaining. Somebody needs to annoy those hackers. Since I don't use php I trap those requests in a map and return a 444. That way I can use some scripts and pull the hacker IPs out of the log file. If they come from a server, the IP space of that host gets blocked. There are no eyeballs at servers. But I do like the idea of feeding the hacker something unpleasant.


If you have enough resources you can send them a 200 OK response with 10MB html file with an enormous DOM tree using chunked transfer and no content-length header. They will lost huge amount of resources to download and parse this (probably multiple times).

On Thu, Jun 18, 2020 at 5:04 PM lists <[hidden email]> wrote:
In theory not a problem, but look at the text on this page about placing root in location blocks.
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/

I saw your first post and thought it was entertaining. Somebody needs to annoy those hackers. Since I don't use php I trap those requests in a map and return a 444. That way I can use some scripts and pull the hacker IPs out of the log file. If they come from a server, the IP space of that host gets blocked. There are no eyeballs at servers. But I do like the idea of feeding the hacker something unpleasant.





          Original Message     


From: [hidden email]
Sent: June 18, 2020 4:08 AM
To: [hidden email]
Reply-to: [hidden email]
Subject: Nginx potentially leaking real filenames? (hopefully properly formatted)


Hi,

I am experimenting with various ways of annoying bots and automated
vulnerability scanners that reach my service. In one instance I am
serving a recursive decompression bomb for all requests for .php files.
Since none of my services run PHP, and never have, all such traffic can
be safely assumed malicious.
Recently (a couple of months since first deployment) I started seeing
repeated requests to the server trying to fetch the recursive
decompression bomb by its real file name, which should have never been
exposed anywhere.

Is it possible for nginx to leak the real file name? Through
misconfiguration or other means?

I am using nginx (version 1.14.2-2+deb10u1) as a reverse proxy and for
SSL termination.
The custom application behind it is not aware of the existence of the
decompression bomb and lives in its own completely separate directory
tree. It never reads nor serves any files from the local server, all its
data is in physically separate database and cache servers. While I
cannot prove absence of vulnerabilities in this custom app, I have not
found any evidence of it being used to (nor leaking) local directory
contents.
The decompression bomb does not contain its file name in its contents.

Given the above, I believe something in my nginx setup leaked the real
file name of the decompression bomb.
I've tried using all request methods (GET, HEAD, PUT, POST, DELETE,
CONNECT, OPTIONS, TRACE, PATCH) on the server from curl like following:
     $ curl --verbose -X <method> <redacted>.com/index.php
and (as expected) none of the responses leaked the file name in any of
the headers nor contents.

Below is a redacted and inlined version of my nginx configuration. There
is only one server defined, the Debian default server config has been
removed. The error code mapping is there to avoid triggering high error
rate alerts when hit by hundreds of consecutive bot requests.
I would appreciate any help in figuring out what I am doing wrong and
how could the <redacted-payload-filename> have been leaked?

Thanks,
Pizab

# nginx.conf
http {
     sendfile on;
     tcp_nopush on;
     tcp_nodelay on;
     keepalive_timeout 165;
     types_hash_max_size 2048;

     include /etc/nginx/mime.types;
     default_type application/octet-stream;

     limit_req_zone "php" zone=attackzone:10m rate=1r/s;

     ssl_certificate <redacted>;
     ssl_certificate_key <redacted>;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
     ssl_session_cache shared:SSL:10m;
     ssl_session_timeout 10m;

     server_tokens off;

     access_log /var/log/nginx/access.log;
     error_log /var/log/nginx/error.log;

     client_body_buffer_size 1M;

     server {
         listen   443  default_server ssl;
         listen   80;

         server_name <redacted>.com;
         rewrite_log on;

         location /.well-known/acme-challenge {
             alias /var/www/html/.well-known/acme-challenge;
         }

         location / {
             access_log /<redacted>/logs/nginx_access.log;
             proxy_set_header Host $http_host;
             proxy_redirect off;
             proxy_connect_timeout 60;
             proxy_read_timeout 160;
             proxy_pass http://localhost:10000;
         }

         error_page 429 =229 /error429;

         location ~ \.php$ {
             limit_rate_after 1k;
             limit_rate 2k;
             limit_req zone=attackzone burst=2;
             limit_req_status 429;
             keepalive_timeout 0;
             root /var/www/html/<redacted>/;
             default_type "application/xml";
             add_header Content-Encoding "br";
             try_files /<redacted-payload-filename> =400;
         }

         location = /error429 {
             return 229 "Too many requests.";
         }
     }
}
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx