Umbraco LFI Exploitation
In my first post I mentioned a Local File Inclusion vulnerability (LFI) that I discovered in Umbraco without realising it wasn’t patched by the update at the time.
Well, as promised here are the details on how to exploit it. As with anything security related, keeping exploitation details quiet just doesn’t work. The bad guys will find this out anyway, and the good guys that don’t have the time to spare and just want to run their site are left wondering whether they are vulnerable.
Releasing exploitation details enables the vulnerability to be detected by automated scanners, which is a very good thing if you regularly check your systems with such in efforts to improve your own security. At the moment I don’t know of any scanners that detect this vulnerability, except of course AppCheck our own scanner at Sec-1 which we updated to detect this vulnerability. Hopefully more will follow now the details are published.
How to exploit the original vulnerability are here. In a nutshell, Umbraco includes a ClientDependency handler that is accessed as follows:
s parameter is a base64 encoded parameter, normally referencing local file paths of client-side resources to minify or concatenate at run-time (e.g.
/assets/foo.js). The Umbraco framework will reference the handler instead of
.js files directly, as the handler returns the processed file contents in its HTTP response.
In the above case, the
s parameter is
file://localhost/c$/Windows/win.ini encoded, which due to the original bug allows the private Windows file to be read and displayed from the HTTP response:
; for 16-bit app support [fonts] [extensions] [mci extensions] [files] [Mail] MAPI=1
There are a few variations on this that may work depending on the server configuration and where Umbraco was originally installed from:
and also some Remote File Inclusion (RFI) variations where the path is set to e.g.
http://google.com and then setting the
Host header in the HTTP request to match. This could be used to read from HTTP requests sent to other servers in the web server’s private network or DMZ, or it could be used to turn the Umbraco server into a proxy in order to cover tracks when attacking other systems on the internet. This post in an excellent write-up of this type of vulnerability. I won’t go into any more detail here or further explanations into the original Umbraco vulnerability because the Dionach article already does that very well.
Now, as said, this is addressed by the original patch, but the vulnerability I discovered was a variation on the RFI/SSRF in order to exploit the LFI.
This is surprisingly simple and allows access to any file within the web root that the IIS Application Pool user has read access to. Basically you take the fully qualified URL of the file you want to retrieve, ensuring the host name in the URL matches your
Host header, base64 encode it, and then drop it in the
s parameter. For unknown reasons, requesting files this way bypasses ASP.NET restrictions on normally private files.
Request before base64’ing:
When we encode and send it we get the following:
As you can see, the
web.config file is returned, even though this is normally protected by ASP.NET. We can then look for interesting things within this file. The thing that caught my eye on the penetration test I was undertaking was this snippet:
This was of particular interest on this external test because the following had been returned from my earlier port scan:
$ sudo nmap umbraco.example.com Starting Nmap 7.40 ( https://nmap.org ) at 2017-05-01 09:00 BST Nmap scan report for umbraco.example.com (xxx.xxx.xxx.xxx) Host is up (0.00032s latency). rDNS record for xxx.xxx.xxx.xxx: umbraco.example.com Not shown: 998 filtered ports PORT STATE SERVICE 80/tcp open http 1433/tcp open ms-sql-s MAC Address: XX:XX:XX:XX:XX:XX (XXXXXX) Nmap done: 1 IP address (1 host up) scanned in 4.86 seconds
This allowed me to repeat the LFI, this time dropping in
sa (system administrator) username and password for the database, which I can now log into externally. Sweeeeet! In this case it was a double whammy:
- I could log into the server, enable
xp_cmdshelland then get a remote shell (as easy as running this).
- The Umbraco admin page at
http://umbraco.example.com/umbraco/umbraco.aspxalso reused this password for the default administrator account.
Upgrade your Umbraco to a version newer than 4.11.10, 6.2.6 or 7.2.2, and also ensure that ClientDependency has been upgraded to a version newer than v188.8.131.52.
This is the advisory from Umbraco.
You can use this tool to test your Umbraco installation:
Is newer exploit? to test local file paths like
Base URL: http://example.com File path: C:\Windows\win.ini
…would cause the following request to be sent:
http://example.com/DependencyHandler.axd?s=QzpcV2luZG93c1x3aW4uaW5p&t=CSS&cdv=1 where the base64 string is
Is newer exploit? to test URLs pointing to files within the web root like
Base URL: http://example.com File path: web.config
…would cause the following request to be sent:
http://example.com/DependencyHandler.axd?s=aHR0cDovL2V4YW1wbGUuY29tL3dlYi5jb25maWc%3D&t=CSS&cdv=1 where the base64 string is
RFI/SSRF cannot be tested using this tool due to the requirement to set a
Ensure that the file path exists on your server and a new tab will open, and if this retrieves the file contents from your server you are vulnerable.
The tool works completely client-side, meaning you will be able to use this in order to test development versions of your site on your PC or local network.
I’d be interested to know about any quirks across different versions of Umbraco, and if there are any configuration options that affect the vulnerabilities (either the original or the newer one).