David Fifield <david@bamsoftware.com>
Code and data download:
git clone https://www.bamsoftware.com/git/sniproxy.git
I found a set of strange HTTP servers that serve a 302 redirect to the nonexistent URL http://dns.auth.fail/. The servers have many other characteristics in common: they all run lighttpd 1.4.35 and many have a similar pattern of open ports. Despite some investigation, I was not able to determine the purpose of these hosts nor any source code referring to "dns.auth.fail".
It looks like these mysterious hosts are VPN proxies of SimpleTelly or My Private Network, which seem to be related services of Global Network Services Ltd. (both web sites share the same TLS certificate, SHA-1 fingerprint C7:2B:71:BC:23:5C:82:09:75:AA:C0:8A:C8:DE:2B:AE:3B:19:B3:62).
Kevin Wheal informed me about this possibility. While investigating some IP addresses posted to a forum [archive], he found that some of the hosts in question responded to DNS requests, and in particular, resolved the name dns.auth.fail to 174.127.126.11, whose reverse DNS is www.simpletelly.com.
$ dig +noall +comments +answer dns.auth.fail ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 46653 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 $ dig +noall +comments +answer dns.auth.fail @23.227.200.2 ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42993 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; ANSWER SECTION: dns.auth.fail. 5 IN A 174.127.126.11 $ dig +noall +comments +answer -x 174.127.126.11 ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23240 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; ANSWER SECTION: 11.126.127.174.in-addr.arpa. 86400 IN PTR www.simpletelly.com.
Limited testing has the DNS servers returning correct records for names other than dns.auth.fail:
$ dig +noall +comments +answer example.com ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49818 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; ANSWER SECTION: example.com. 57039 IN A 93.184.216.34 $ dig +noall +comments +answer example.com @23.227.200.2 ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46725 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; ANSWER SECTION: example.com. 86400 IN A 93.184.216.34
Accessing http://174.127.126.11/ redirects to
https://174.127.126.11/, which then redirects to
https://www.simpletelly.com/.
Accessing http://174.127.126.11/ with a
Host: dns.auth.fail
header,
on the other hand, redirects to
https://www.simpletelly.com/client/checkip.php.
(This is what would happen if you had configured one of these
dns.auth.fail hosts as your DNS server, and then tried
to access the HTTP service on the same host.)
$ wget -q -S --max-redirect=0 http://174.127.126.11/ --header 'Host: dns.auth.fail'
HTTP/1.1 302 Found
Date: Wed, 28 Jun 2017 03:46:45 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Location: https://www.simpletelly.com/client/checkip.php
Cache-Control: max-age=2592000
Expires: Fri, 28 Jul 2017 03:46:45 GMT
Content-Length: 230
Keep-Alive: timeout=61, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
The page https://www.simpletelly.com/client/checkip.php [archive] displays the client IP address and says "Check your SimpleTelly setup; This IP is not registered with the system." The funny name dns.auth.fail seems to be an artifact of some kind of IP address–based authentication system.
While investigating SNI proxies, I accidentally found some hosts with strange characteristics that I am calling "dns.auth.fail" hosts. These hosts:
OK
or the PHP source code checkPID();
PASS
;
clicking on the file dns.php
in the directory listing returns the string ("PASS");
.One of the SNI proxies in the GoProxy list, 103.15.187.54, has a strange response when contacted on port 80. It sends a 302 redirect to the URL http://dns.auth.fail/.
HTTP/1.0 302 Found Location: http://dns.auth.fail/ Content-Length: 0 Connection: close Date: Fri, 16 Sep 2016 17:53:57 GMT Server: lighttpd/1.4.35
A Google search for "dns.auth.fail" finds almost nothing, only 5 results, looking like web statistics reports:
A couple of the domains referred to in the Google search themselves redirect to http://dns.auth.fail/:
Although the URL http://dns.auth.fail/ does not exist,
.fail
is a real TLD since 2014-04:
https://www.iana.org/reports/c.2.9.2.d/20140421-fail
The DNS name dns.auth.fail does not resolve.
However just
auth.fail
is registered through Gandi.net and resolves to 217.70.184.38 (reverse DNS webredir.vip.gandi.net).
There is a parking page at
http://auth.fail/.
I searched the Project Sonar HTTP data set dated 20160830 for the "dns.auth.fail" fingerprint. "Project Sonar includes a regular HTTP GET request for all IPv4 hosts with an open 80/TCP." The input contains 61,683,005 IP addresses.
The search found 2,460 IP addresses
(grepsonar/dns.auth.fail-20160830.txt
in the source code):
I did an Nmap port scan of the 100 most common ports
(-F
option of Nmap).
The output is in grepsonar/dns.auth.fail-20160830.nmap
.
nmap -PS80 -F -v -iL dns.auth.fail-20160830.txt -oA dns.auth.fail-20160830
I followed that up with a scan of all 64K ports on two of the hosts
nmap -p- -Pn -oA dns.auth.fail-allports -v -sV --min-rate 1000 5.101.150.7 217.115.127.116
This gave us a list of ports likely to respond: 80,99,113,443,1723,8181,8888. I re-scanned all the hosts again.
nmap -Pn -p80,99,113,443,1723,8181,8888 -v -iL dns.auth.fail-20160830.txt -oA dns.auth.fail-selectedports
Nearly all the hosts have the same pattern of open and closed ports:
PORT STATE SERVICE 80/tcp open http 99/tcp open ssh 113/tcp closed ident 1723/tcp open pptp 8181/tcp open http 8888/tcp open http
A small number of them also have port 443 open:
PORT STATE SERVICE 443/tcp open https
A scan on of only ports 80,443,1723,8888 showed that nearly nearly all hosts had 80,1723,8888 open, but only a small number had 443 open:
PORT STATE SERVICE 2454 80/tcp open http 116 443/tcp open https 2442 1723/tcp open pptp 2441 8888/tcp open http
Another scan on , adding ports 99 and 8181, showed the same pattern, though about 400 hosts had gone offline since the 2016-09-28 scan:
PORT STATE SERVICE 1983 80/tcp open http 2025 99/tcp open ssh 80 443/tcp open https 1963 1723/tcp open pptp 2020 8181/tcp open http 2000 8888/tcp open http
There are HTTP downloads of port 8181 on all hosts in the directory
webarchive/dns.auth.fail/8181
in the source code.
There are two distinct responses, not counting no-responses:
2155 | OK response |
263 | checkPID response |
42 | no response |
The Server
header always has the exact value
lighttpd/1.4.35
.
lighttpd/1.4.35
was released on .
The current version is
1.4.41,
released .
OK
response on port 8181Example: http://184.154.139.95:8181/
HTTP/1.1 200 OK X-Powered-By: PHP/5.3.10-1ubuntu3.22 Content-type: text/html Transfer-Encoding: chunked Date: Sat, 17 Sep 2016 20:30:19 GMT Server: lighttpd/1.4.35 <HTML> <BODY> <H1> OK</H1> </BODY> </HTML>
The X-Powered-By
header always starts with
PHP/5.3.10-1ubuntu
but the number that follows
ranges from 14
to 22
.
checkPID
response on port 8181Example: http://104.250.97.24:8181/
HTTP/1.1 200 OK X-Powered-By: PHP/5.5.9-1ubuntu4.16 Content-type: text/html Transfer-Encoding: chunked Date: Sat, 17 Sep 2016 20:57:02 GMT Server: lighttpd/1.4.35 <HTML> <BODY> <H1> <? checkPID();?> </H1> </BODY> </HTML>
The X-Powered-By
header always starts with
PHP/5.5.9-1ubuntu
but the number that follows
ranges from 13
to 19
.
This looks like a PHP source code leak.
The delimiter <?
is a PHP
"short open tag",
which is not supported by all PHP servers.
The equivalent, universally accepted open tag would be
<?php
.
These servers evidently do not have short open tag support,
so they dump the source code
checkPID();
rather than its output OK
.
There are HTTP downloads of port 8888 on all hosts in the directory
webarchive/dns.auth.fail/8888
in the source code.
There are two distinct responses, not counting no-responses:
1873 | "dns.php directory listing" response |
541 | PASS response |
46 | no response |
Example: http://103.19.16.13:8888/
HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 1513 Date: Sat, 17 Sep 2016 21:05:12 GMT Server: lighttpd/1.4.35 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Index of /</title> <style type="text/css"> a, a:active {text-decoration: none; color: blue;} a:visited {color: #48468F;} a:hover, a:focus {text-decoration: underline; color: red;} body {background-color: #F5F5F5;} h2 {margin-bottom: 12px;} table {margin-left: 12px;} th, td { font: 90% monospace; text-align: left;} th { font-weight: bold; padding-right: 14px; padding-bottom: 3px;} td {padding-right: 14px;} td.s, th.s {text-align: right;} div.list { background-color: white; border-top: 1px solid #646464; border-bottom: 1px solid #646464; padding-top: 10px; padding-bottom: 14px;} div.foot { font: 90% monospace; color: #787878; padding-top: 4px;} </style> </head> <body> <h2>Index of /</h2> <div class="list"> <table summary="Directory Listing" cellpadding="0" cellspacing="0"> <thead><tr><th class="n">Name</th><th class="m">Last Modified</th><th class="s">Size</th><th class="t">Type</th></tr></thead> <tbody> <tr><td class="n"><a href="../">Parent Directory</a>/</td><td class="m"> </td><td class="s">- </td><td class="t">Directory</td></tr> <tr><td class="n"><a href="dns.php">dns.php</a></td><td class="m">2016-Jan-13 05:23:23</td><td class="s">0.1K</td><td class="t">application/octet-stream</td></tr> </tbody> </table> </div> <div class="foot">lighttpd/1.4.35</div> </body> </html>
Most of the time, on port 8888 there is a lighttpd directory listing showing one file, dns.php.
The Server
header always has the value
lighttpd/1.4.35
,
matching a version string in the HTML itself.
The "Last Modified" dates of dns.php range between
and
.
Hosts within a subnet usually have a "Last Modified" time that varies by at most a few minutes, for example
(from webarchive/dns.auth.fail/8888/dns.auth.fail-lastmodified-20160830.txt
):
103.39.133.234 2015-Sep-09 07:23:43 103.39.133.235 2015-Sep-09 07:23:43 103.39.133.236 2015-Sep-09 07:23:43 103.39.133.237 2015-Sep-09 07:23:43 103.39.133.238 2015-Sep-09 07:23:43 109.104.87.106 2015-Jul-08 03:58:05 109.104.87.107 2015-Jul-08 03:58:05 109.104.87.108 2015-Jul-08 03:59:44 109.104.87.109 2015-Jul-08 03:59:44 109.104.87.110 2015-Jul-08 03:59:49 109.104.87.111 2015-Jul-08 03:59:35 109.104.87.112 2015-Jul-08 03:59:35
Clicking on dns.php causes the following document to be returned:
Example: http://103.19.16.13:8888/dns.php
HTTP/1.1 200 OK X-Powered-By: PHP/5.3.10-1ubuntu3.22 Content-type: text/html Transfer-Encoding: chunked Date: Sat, 17 Sep 2016 01:38:42 GMT Server: lighttpd/1.4.35 ("PASS");
The headers may vary, for example the exact contents of
X-Powered-By
, or
Content-Length
versus Transfer-Encoding
.
Notice the unusual lowercasing in Content-type
.
PASS
response on port 8888Example: http://95.154.240.9:8888/
HTTP/1.1 200 OK Content-Type: application/octet-stream Accept-Ranges: bytes Content-Length: 31 Date: Sat, 17 Sep 2016 20:30:40 GMT Server: lighttpd/1.4.35 <HTML> <H1> PASS </H1> </HTML>
Some servers return PASS
HTML in the root document
rather than through dns.php. The format of the PASS
message is different, too.
The Server
header always has the exact value
lighttpd/1.4.35
.
lighttpd/1.4.35
was released on .
The current version is
1.4.41,
released .
The Content-Type: application/octet-stream
means your browser will try to download the response as a file,
despite it being HTML.