8

About once per day, I'm seeing the following series of requests in my Apache 2.4 httpd logs, and I'm trying to figure out what vulnerability is being scanned for. Each occurrence of these scans has an identical pattern (replaced my domain name with DOMAIN):

89.123.16.10 - - [20/Dec/2017:05:35:37 +0000] "GET /https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:37 +0000] "GET /https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:38 +0000] "GET /https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:38 +0000] "GET /https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:38 +0000] "GET /https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:39 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:40 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:40 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:40 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:40 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:40 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:41 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:41 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:41 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:41 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:41 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:42 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236
89.123.16.10 - - [20/Dec/2017:05:35:42 +0000] "GET /https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://https://www.DOMAIN.com HTTP/1.1" 301 236

The requests are coming from the following hosts:

103.194.169.16 - Netherlands (Java 1.8 client running on an IIS 8.5 Windows Server)
109.102.111.66 - Bucharest, Romania (Java 1.6 client, banned by one service)
109.102.111.67 - Bucharest, Romania (Java 1.6 client, banned by several services, dictionary attacks, spam house)
109.102.111.76 - Bucharest, Romania (Java 1.7 client, banned by several services)
109.102.111.84 - Bucharest, Romania (Java 1.6 client, banned by one service)
109.102.111.89 - Bucharest, Romania (Java 1.6 client, banned by one service)
109.102.111.92 - Bucharest, Romania (Java 1.6, 1.8 clients, banned by several services, dictionary attacks, spam house)
172.111.130.9 - Bucharest, Romania (Java 1.6 client, banned by one service)
172.111.200.61 - Frankfurt, Germany (Java 1.6 client, banned by one service)
23.227.201.194 - [Swiftway Cloud - swiftwaycloud.com] Chicago, United States (Java 1.6 client running on an IIS 7.5 ASP.NET server, banned by one service)
79.5.128.38 - Piansano, Lazio, Italy (Java 1.6 client, banned by several services)
89.123.14.74 - Bucharest, Romania (Java 1.6 client, banned by several services, spam house)
89.123.16.10 - Bucharest, Romania (Java 1.6 client, banned by several services)
89.123.20.221 - Bucharest, Romania (Java 1.6 client, banned by several services, spam house)
89.123.31.76 - Bucharest, Romania (Java 1.6 client, banned by several services, dictionary attacks, spam house)
89.136.31.222 - Bucharest, Romania (possibly a home broadband address, Java 1.6 client, banned by several services, dictionary attacks, spam house)

Most of the hosts are Romanian, so I'm presuming that the source of these scans is based there. Also, the only pattern I can discern in the request times is that these requests have never occurred from 09:00 UTC to 12:00 UTC, which would be 11pm to 3am in Romania. Every other 30-minute block of time of day has been covered, with a maximum number of occurrences of 4 per day, and a minimum of 1 per day.

As mentioned in the comments, I use a redirect rule to forward HTTP requests to HTTPS:

RedirectMatch permanent ^ https://www.DOMAIN.com

It is worth noting that these requests are all appearing only in my non-SSL logs. My server configuration is returning a 301 (Moved Permanently), which redirects non-SSL requests to https://www.DOMAIN.com. The IP addresses that are performing these scans never make any requests via HTTPS, and are only performing scans of this type.

I have reproduced the exact log using curl:

C:\>curl -s -D - http://www.DOMAIN.com/https://https://www.DOMAIN.com
HTTP/1.1 301 Moved Permanently
Date: Thu, 21 Dec 2017 15:49:58 GMT
Server: Apache
Location: https://www.DOMAIN.com
Content-Length: 236
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://www.DOMAIN.com">here</a>.</p>
</body></html>

Results in the log entry (replaced my domain and IP address):

192.168.1.5 - - [21/Dec/2017:14:29:57 +0000] "GET /https://https://www.DOMAIN.com HTTP/1.1" 301 236

Summary

Initial malformed request from remote host:

GET http://www.DOMAIN.com/https://https://www.DOMAIN.com

My server returns:

301 https://www.DOMAIN.com

The above URL is never requested by the remote host.

Second malformed request from remote host:

GET http://www.DOMAIN.com/https://https://https://www.DOMAIN.com

My server returns (see above curl example for exact server response):

301 https://www.DOMAIN.com

The above URL is never requested by the remote host.

And so on, for 24 iterations. The fact that my server is always returning https://www.DOMAIN.com indicates that the malformed URLs are being deliberately constructed by the remote host.

Is there a specific known vulnerability or server misconfiguration that this is scanning for?

I believe any SSL certificate issues could be ruled out simply based on the fact that no SSL requests are ever made from these hosts (unless the scans are being compartmentalized to avoid implicating other hosts).

I have only found one other similar case of this (April 2016):

  1. Cannot map GET /https:///https:///https:/https:///https:/https:/https:/ ...

I have added metadata from Project Honeypot and the What Is My IP Address Blacklist. These hosts are all reported to be using Java clients, ranging from Java 1.4 to Java 1.8.

Parker
  • 400
  • 1
  • 3
  • 15
  • 2
    This looks like an apache redirect loop, not any sort of malicious activity. Are you certain you are only seeing this behavior from certain hosts? – John Dec 21 '17 at 14:55
  • 1
    How is your redirect rule written? Looks like a misconfiguration somewhere. – ThoriumBR Dec 21 '17 at 15:00
  • @John That was my first thought as well, but I confirmed that these requests are being constructed by specific hosts. When I try these requests in a web browser, it results in forwarding to `https://www.DOMAIN.com/https://https://www.DOMAIN.com`, with no looping and produces SSL log entries. I am only seeing the non-SSL behavior from certain hosts, and the majority of them being from a single country (where we get near zero traffic from) makes me suspicious. – Parker Dec 21 '17 at 15:00
  • @ThoriumBR My redirect rule is `RedirectMatch permanent ^ https://www.DOMAIN.com`. Very simple, no URL construction. – Parker Dec 21 '17 at 15:02
  • If you look at your redirect, `^` will continue to match, even after it redirects to https. I would expect you would see this redirect loop everywhere. Try the following to redirect http to https: `RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{SERVER_NAME}/$1 [R,L]` – John Dec 21 '17 at 15:11
  • 1
    Another indication that the uri is not being formed properly due to an incorrect apache config is in the GET request itself `GET **/https**://https://www.DOMAIN.com` If the beginning of the request is a forward slash, it's looking for a relative path from the webroot. – John Dec 21 '17 at 15:16
  • @John Yes, but that is the initial request from the remote host that is malformed. My current `RedirectMatch` produces the expected behavior in that case, by expanding the URL to `https://www.DOMAIN.com/https://https://www.DOMAIN.com`, which results in a 301 followed by a 404. I am going to try your `RewriteRule` and will report back. – Parker Dec 21 '17 at 15:23
  • @John Your `RewriteRule` works in many but not all cases (e.g., a trailing slash on `http://www.DOMAIN.com/` is not handled). I think this may be due my need for `AllowEncodedSlashes NoDecode` to properly support REST URLs in my web framework. This rewrite rule also causes the initial malformed request to result in a 404 instead of a 301, which means the pattern does not handle that case. – Parker Dec 21 '17 at 15:40
  • 4
    Just some dodgy romanian crawler not handling your redirect properly. Almost 25% of web traffic is generated by bots like this one. – Aria Dec 21 '17 at 18:45
  • @Aria Ultimately, yes, you're right. There was just something about this specific one that was irritating me. This specific pattern has not been reported anywhere, yet I have a lot of information available about it. I'm doing my best to get to the bottom of it in case others see similar web log entries in the future. – Parker Dec 22 '17 at 03:18

1 Answers1

1

I updated the question to add information about the remote hosts making these requests. It turns out that all but one are already on public blacklists for a variety of reasons (dictionary attacks, spam, misbehaved site crawling). The requests are being made by a variety of obsolete Java VMs, which may indicate that all of these hosts are compromised (however, since most of them are coming from a single country, this could serve as a counterpoint to that argument).

Interestingly, two of the three non-Romanian hosts are running IIS Servers (v7.5 and v8.5) - I strongly suspect these are compromised hosts. Just for kicks, I attempted the same malformed HTTP requests against those servers, and simply received 404 errors. The Romanian hosts are not (apparently) running IIS, but are (ostensibly) running ancient versions of Java.

The thing about making these requests with older versions of Java (1.4 to 1.6) is that those versions do not support any common SSL implemented on the web. Java 1.6 supports SSLv3 and TLS 1.0, nor do they support SNI. This just happens to be the same server I described in the SNI Hole question.

Ultimately, a redirect loop may have been encountered by the remote client, not due to a misconfiguration but more likely due to a lack of SNI support in their old Java VMs. The requests would pass through to my default host (www.DOMAIN.com) via IP address only, which would then redirect back to the default hostname. Essentially, my server is returning a SNI hostname but their client does not understand it.

I presume that the reason these requests are coming from a variety of older Java VMs is that they were compromised via some known Java vulnerability(ies) and/or known IIS vulnerabilities.

The accumulation of "/https://" in the redirected URLs is potentially due to the protocol not being supported in the crawler/scanner Java code, which would make sense since that same code is (likely) running on Java 1.4 (no SSL, no SNI, lowest common denominator), 1.6 SSLv3+TLS1.0, 1.7 (SSL+SNI), and 1.8 (SSL+SNI). If the code is meant to run on ancient Java VMs, then there is no real reason to support or even understand SSL in the code, therefore it might have considered an HTTPS protocol URL to be relative instead of absolute.

What it comes down to is that in order to determine the exact nature of these requests, I would need a copy of the WAR, JAR or class file that is being used to make these requests. I have contacted Swiftway Cloud to see if they could provide a copy from their compromised server in Chicago that is participating in this activity.

Update: Swiftway Cloud responded that they could not identify any "malicious" activity on their host, even with the information provided here. This is a problem, because the separation of responsibility ("innocuous" crawling/probing vs. "malicious" spamming), even with clear evidence of complicity among hosts, appears to have led to a point where it isn't possible to convince cloud providers to take reactive measures to a documented problem.

Parker
  • 400
  • 1
  • 3
  • 15