URL found in nginx access.log along GET request - security

I am managing a site hosted on aws ec2 using nginx. To avoid threats continuously monitoring nginx logs ( access.log & error.log). Though many threats are well managed by tweaking nginx.conf, but this specific one I am not even able to figure out how attacker manage to send such request.
access.log
xx.xxx.xx.xxx - - [18/Aug/2021:09:04:13 +0000] "GET http://xxxxxxxxx.com/ HTTP/1.1" 200 1400 "-" "Go-http-client/1.1"
In above case let's say name of my website is "h ttp://abc-xyz-1234.com", attacker is passing url in path (i.e. http://xxxxxxxxx.com/ ), and nginx responding with "200". I am still scratching my head how was request made and what was responded with 1400 of bytes ( response length still much lesser than website response site for path "/" ).
As I believe its not possible through browser, I tried to simulate using curl but it wouldn't work.
it is considered 2 separate request to curl
curl -A Mozilla h ttp://abc-xyz-1234.com/ http://xxxxxxxxx.com
invalid domain
curl -A Mozilla h ttp://abc-xyz-1234.comhttp://xxxxxxxxx.com
it will hit host with path /http://xxxxxxxxx.com and get rejected. Attacker is manage to send it without prefix "/" and thats what trying to simulate
curl -A Mozilla h ttp://abc-xyz-1234.com/http://xxxxxxxxx.com

You can use --request-target for this:
curl -A Mozilla http://abc-xyz-1234.com --request-target http://xxxxxxxxx.com

Related

curl: (51) SSL Issue [duplicate]

I have a x.example which serves traffic for both a.example and b.example.
x.example has certificates for both a.example and b.example. The DNS for a.example and b.example is not yet set up.
If I add an /etc/hosts entry for a.example pointing to x.example's ip and run curl -XGET https://a.example, I get a 200.
However if I run curl --header 'Host: a.example' https://x.example, I get:
curl: (51) SSL: no alternative certificate subject name matches target
host name x.example
I would think it would use a.example as the host. Maybe I'm not understanding how SNI/TLS works.
Because a.example is an HTTP header the TLS handshake doesn't have access to it yet? But the URL itself it does have access to?
Indeed SNI in TLS does not work like that. SNI, as everything related to TLS, happens before any kind of HTTP traffic, hence the Host header is not taken into account at that step (but will be useful later on for the webserver to know which host you are connecting too).
So to enable SNI you need a specific switch in your HTTP client to tell it to send the appropriate TLS extension during the handshake with the hostname value you need.
In case of curl, you need at least version 7.18.1 (based on https://curl.haxx.se/changes.html) and then it seems to automatically use the value provided in the Host header. It alo depends on which OpenSSL (or equivalent library on your platform) version it is linked to.
See point 1.10 of https://curl.haxx.se/docs/knownbugs.html that speaks about a bug but explains what happens:
When given a URL with a trailing dot for the host name part: "https://example.com./", libcurl will strip off the dot and use the name without a dot internally and send it dot-less in HTTP Host: headers and in the TLS SNI field.
The --connect-to option could also be useful in your case. Or --resolve as a substitute to /etc/hosts, see https://curl.haxx.se/mail/archive-2015-01/0042.html for am example, or https://makandracards.com/makandra/1613-make-an-http-request-to-a-machine-but-fake-the-hostname
You can add --verbose in all cases to see in more details what is happening. See this example: https://www.claudiokuenzler.com/blog/693/curious-case-of-curl-ssl-tls-sni-http-host-header ; you will also see there how to test directly with openssl.
If you have a.example in your /etc/hosts you should just run curl with https://a.example/ and it should take care of the Host header and hence SNI (or use --resolve instead)
So to answer your question directly, replace
curl --header 'Host: a.example' https://x.example
with
curl --connect-to a.example:443:x.example:443 https://a.example
and it should work perfectly.
The selected answer helped me find the answer, even though it does not contain the answer. The answer in the mail/archive link Patrick Mevzek provided has the wrong port number. So even following that answer will cause it to continue to fail.
I used this container to run a debugging server to inspect the requests. I highly suggest anyone debugging this kind of issue do the same.
Here is how to address the OP's question.
# Instead of this:
# curl --header 'Host: a.example' https://x.example
# Do:
host=a.example
target=x.example
ip=$(dig +short $target | head -n1)
curl -sv --resolve $host:443:$ip https://$host
If you want to ignore bad certificates matches, use -svk instead of -sv
curl -svk --resolve $host:443:$ip https://$host
Note: Since you are using https, you must use 443 in the --resolve argument instead of 80 as was stated on the mail/archive
I had a similar need. Didn't have sudo access to update hosts file.
I use resolve parameter and also added the DNS host name as a header parameter.
--resolve <dns name>:<port>:<ip addr>
curl --request POST --resolve dns_name:443:a.b.c.d 'https://dns_name/x/y' --header 'Host: dns_name' ....
Cheers..

CUPS bad request

I have a little problem with CUPS 2.2.7
This is my /etc/hosts file:
127.0.0.1 example.com
127.0.0.1 localhost
in http://localhost:631/ CUPS is working right
but in http://example.com:631/ it doesn't work on the same pc.
The message error in View error log is that one:
E [21/Feb/2019:11:54:18 +0100] [Client 33] Request from "localhost" using invalid Host: field "example.com:631".
The web page on Firefox print an error message Invalid request and give me an Error (error code: 400) but seems point on CUPS.
How to solve this problem so that example.com:631 points to localhost and CUPS answers it successfully instead of Error 400: Access Denied.
By default cups servers HTTP requests only with HTTP Host header equal to "localhost". To allow it servicing requests for additional HTTP host headers use ServerAlias directive as described in the man cupsd.conf documentation. It's common to do the most unsafe thing and add
ServerAlias *
to /etc/cupsd.conf to allow all possible HTTP host headers to be serviced.
I know this is old, but I too was experiencing the same issue recently and I resolved it by updating the following line in cupsd.conf from:
Listen 0.0.0.0:631
changed to:
Listen *:631
For those that maybe care to know, I'm running CUPS within a docker container, and this change corrects the "Bad Request" response.

Nodejs HTTP/1.1 pipeline support

I'm almost newby to nodejs. I'm working on a small nodejs micro-service and its running well. But as per recent requirement this service need to support HTTP/1.1 pipeline. But I'm failing to find in nodejs doc that how to enable/support that.
Please guide me find appropriate doc/module/resource to implement HTTP/1.1 pipeline.
Thanks.
Comments from #shaochuancs and #Helen are about nodejs http client.
If you need a server implementation of HTTP pipeline that depends entirely on the the nodejs core library.
HTTP server-side pipelining support is built-in and already OK in nodejs (I've just made the tests on tested on v5.5.0 v7.0.9 and v6.2.1).
To test pipelining support simply chain two HTTP request in the same tcp/ip connection. You can do it using telnet or netcat (nc).
# telnet, connecting to port 80, chaining 2 requests on /login
# for host foo.com
(echo -en "GET /login HTTP/1.1\nHost: foo.com\nConnection: keep-alive\n\nGET /login HTTP/1.1\nHost: foo.com\n\n"; sleep 10) | telnet localhost 80
# same thing using printf and netcat
printf "GET /login HTTP/1.1\r\nHost: foo.com\r\nConnection: keep-alive\r\n\r\nGET /login HTTP/1.1\r\nHost: foo.com\r\n\r\n" | nc -q 10 localhost 80
Then count the number of responses, you should get 2 (or 1 if pipelining is not supported). Search for 'HTTP/1.1 200 OK' in the output.

NodeJS 0.10.46 not serving after lighttpd proxy anymore

today I've updated my nodejs installation (from official CentOS 7 repo).
I used to serve via a lighttpd proxy, nothing special:
proxy.server = ( "" =>
( "" =>
(
"host" => "127.0.0.1",
"port" => 2368,
)
)
)
NodeJS itself is working fine, I got two apps running well (if accessed directly), lighttpd also proxying a third app (provided by a Java runtime), that's full functional.
Problem started with NodeJS update to 0.10.46 (via yum package manager), changed nothing on my configuration.
Lighttpd proxy.debug output:
(mod_proxy.c.1158) proxy - start
(mod_proxy.c.1199) proxy - ext found
(mod_proxy.c.1333) proxy - found a host 127.0.0.1 2368
(mod_proxy.c.417) connect delayed: 11
(mod_proxy.c.1042) proxy: fdevent-out 1
(mod_proxy.c.1065) proxy - connect - delayed success
(mod_proxy.c.1030) proxy: fdevent-in 4
(mod_proxy.c.652) proxy - have to read: 0
(mod_proxy.c.1158) proxy - start
(mod_proxy.c.1199) proxy - ext found
(mod_proxy.c.1333) proxy - found a host 127.0.0.1 2368
(mod_proxy.c.417) connect delayed: 11
(mod_proxy.c.1042) proxy: fdevent-out 1
(mod_proxy.c.1065) proxy - connect - delayed success
(mod_proxy.c.1030) proxy: fdevent-in 4
(mod_proxy.c.652) proxy - have to read: 0
NodeJS output:
"GET / HTTP/1.0"
"GET /favicon.ico HTTP/1.0" 200
So request is forwarded in first step, but then only a
500 - Internal Server Error
is delivered by lighttpd.
Any ideas? Don't know what I can try anymore.
Thanks in advance!
First comment to question was the right hint:
lighttpd version were problematic, update to 1.4.43 was the solution.
Node Version
Firstly I'd like to also point out that nodejs 0.10.x is very out of date. NodeJS is currently on v4.5 LTS and v6.5 Current. As the Javascript world moves very rapidly, relying on your distro's packages can leave you stuck with a very old version of node. You can use the nodesource.com service to get a recent build for your system. For example.
curl -sL https://rpm.nodesource.com/setup_4.x | bash -
yum install -y nodejs
Issues to check first
With that out of the way is your NodeJS application available at localhost:2368 ? Try accessing it in your browser (or a text browser like w3m if 2368 isn't open to the outside world). This could be as simple as NodeJS not returning data to the user.
Your lighttpd.conf looks fine however it is nested needlessly deep while this probably won't fix your issues try:
proxy.server = (
"" => (
(
"host" => "127.0.0.1",
"port" => "2368"
)
)
)
Other Possibilities
While I can't know exactly what your system is doing, I would assume this is more likely to be a node issue than a lighty issue. Try writing a simple http server hello world application in node and see if that is available to proxy.

Verify path traversal vulnerability in web server

I want to verify that my web application does not have a path traversal vulnerability.
I'm trying to use curl for that, like this:
$ curl -v http://www.example.com/directory/../
I would like the HTTP request to be explicitly made to the /directory/../ URL, to test that a specific nginx rule involving proxy is not vulnerable to path traversal. I.e., I would like this HTTP request to be sent:
> GET /directory/../ HTTP/1.1
But curl is rewriting the request as to the / URL, as can be seen in the output:
* Rebuilt URL to: http://www.example.com/
(...)
> GET / HTTP/1.1
Is it possible to use curl for this test, forcing it to pass the exact URL in the request? If not, what would be an appropriate way?
The curl flag you are looking for is curl --path-as-is .
I'm not aware of a way to do it via curl, but you could always use telnet. Try this command:
telnet www.example.com 80
You'll see:
Trying xxx.xxx.xxx.xxx...
Connected to www.example.com.
Escape character is '^]'.
You now have an open connection to www.example.com. Now just type in your command to fetch the page:
GET /directory/../ HTTP/1.1
And you should see your result. e.g.
HTTP/1.1 400 Bad Request
You can use an intercepting proxy to capture a request to your application and repeat the request with parameters changed, such as the raw URL that is requested from the application.
The free version of Burp Suite will allow this using the Repeater.
However, there are alternatives that should also allow this such as Zap, WebScarab and Fiddler2.

Resources