Sunday, April 17, 2016

Gone in Few Hours: Infooby's Fake or Questionable Bug Bounty Program

Bug bounty programs are great in many folds: learning perspective, monetary benefits for bug hunters and a step towards safe and secure web applications. Bug bounty programs are a win-win situation for both parties i.e., bug hunter(s) and the organization(s). The bug bounty hunters get money/reward (or entry in a hall of fame) for finding and reporting legitimate bugs, improve their pentesting skills by looking at the live targets and at the same time organizations improve their security by fixing the bugs reported by bug hunters around the world. Please keep in mind that bug hunters have different skills-set, mind-set and culture so organizations receive a variety of reports including high quality stuff. 

I like participating in bug bounty programs in my free and spare time (though I am not very active). Few days ago, when I was reading my Twitter feed, I came across the following Tweet by @disclosedh1.


"Curiosity killed the cat". I thought lets look at Infooby's web application for quick XSSing because in the program announcement (now gone and no more available), they're interested in having XSS reports. Initially, I have no idea that Infooby're acting maliciously and these guys have announced the program only to have the reports so that they can fix it and improve their web application. They wanted to have a win situation but only for them. One aspect of bug bounty program's announcement is marketing stunt or getting a media attention. I think Infooby wants limelight.

In a matter of few minutes, I found 2 XSS issues in their web application and reported these (#130596 & #130733) via Hackerone. One of the XSS is still live. Open the following URL in Firefox browser.


The screen-shot is also given below. The other XSS was here (now I think they fixed it): https://infooby.com/places?address="><img src=x onerror=prompt(1);>.


I found 2 XSSes in quick time so I thought there're many more and I wanted to continue testing but soon started getting the error message i.e., "Resource limit is reached" and/or 508 status code and/or even site was getting down again and again. It shows that Infooby is not fully prepared for the initial onslaught from the HackerOne's community. The homework from Infooby's side was missing because if you will announce the bug bounty program, there is a great chance that several people will immediately start scanning your web application with the help of automation tools (may be as a part of initial and quick probe). The automation tools mean bombardment of attack payloads. The other testers have also noticed the error message and in the meantime, Infooby awarded someone a 20$ bounty but in the program announcement, they had mentioned the minimum bounty amount will be 50$. Meanwhile the Infooby's main site was going down and up again and again because of ongoing testing from the community.

On the next day, I received an email from HackerOne regarding the status of Infooby's bug bounty program. In short, it was no longer there. The contents of the email can be seen in the screen-shot.


It raises the following questions in my mind and still there are no clear answers. How can we stop this type of thing or fake/questionable bounty program in the future? What mediators or facilitators like HackerOne and BugCrowd can do in this regard? What happened to the bug reports (current status is "Not Applicable") Infooby had received in the meantime and Isn't they will fix bugs for free?
 
I think we can not stop announcement of fake bug bounty program(s) given if it is announced on the company's own web page. Any web site can do this and no one from outside can ask a question about its credibility given it is the company's sole jurisdiction. The bug bounty mediation/facilitator platforms like HackerOne and BugCrowd still can do something like e.g., "security deposit for guarantee or best practices". The idea is same as we see in real life e.g., if we rent a house or apartment, we used to pay some deposit and at the time of leaving the house, we normally get the money back. HackerOne and BugCrowd should ask for this deposit money in order to make sure that company is serious in bug bounty program and if in case company does some questionable practices, HackerOne and BugCrowd may take the money from this deposit or pool and distribute it to the valid bug submitters. If there will be a pool of money like that (e.g., initially it can be a pool of 5K USD per bug bounty program announcement) than there will be no more free bugs even if the bug bounty program is gone or vanish. This pool of money will motivate both parties to work in a best possible way.

Now a days, in general, we (i.e., bug submitters) participate in a bug bounty program like a race. We try to find bugs (especially low hanging fruits) as soon as possible, immediately after the program announcement, without keeping an eye on how genuine a bounty program is. I think this is the wrong approach at the moment (unless we have a deposit or pool as I mentioned earlier) given we do not know in start how reputable a program is. Believe me, the bugs are there and it is not necessarily to treat it like a race. Trust in your capabilities and you will find bugs given you will have enough motivation. Happy Hunting.

Note: If you guys have any other good idea on how can we stop fake program(s) or wants to share your bad experience(s) with the bug bounty program(s), please feel free to comment.  

Wednesday, April 6, 2016

Pairing Single Quotes

During pentest, I came across an interesting and unusual case where developers're trying to escape a single quote (') via a single quote (') in an script context. Further, I noticed that they were adding ' on the right hand side of the injected single quote. The developers're trying to have single quotes in pair but why? Are they trying to escape or something else? It sounds unfortunately funny and at the same time shows XSSing is not going anywhere in the near future.

The screen-shot given below shows the reflection of our interest. Please keep in mind that I had used the harmless XSS probe string i.e., "xxxxxxxx'yyyyy. The < sign is not part of probe string given site has enabled .NET's XSS protection. The site forcefully redirects me to an error page if I inject < character. 


It can be seen in the screen-shot above that site has added or appended an extra ' for escaping (the apparent reason I can think of) a single quote from the probe string. As you could aware of the fact that \ may be used as an escape character for ' and " quotes in an script context like \' and \" respectively. The site was adding/appending an extra ' as an escape character for the injected ' so payload(s) like '-confirm(1)-' and ');confirm(1);// do not work. Soon I realized during testing that \ is not escaped or controlled or filtered. The attack payload I used to XSS this case is: \');confirm(1);//. It starts with \'.  The screen-shot is given below and later I will explain why the payload works.


The attack payload was \');confirm(1);//. It starts with \' in order to make single quote as an escape character. After that application has added/appended one single quote because application developers want to have or see single quotes in pair. So we have a situation like this: '\''. It is perfectly legit given in a pair of single quotes there is an escaped single quote. After that ) character closes the function call prematurely followed by a semi-colon i.e., ; as a statement terminator. The next is a proof of concept JavaScript function call i.e., confirm(1); followed a single line comment i.e., // in order to avoid syntax error or neutralizes the effect of remaining parts of function call i.e., notyAlert. This XSS shows how one can leverage application's unusual functionality against it.

Sunday, February 28, 2016

Stored, Reflected and DOM XSS in Google for Work Connect (GWC)

Google for Work Connect (GWC) is "a community for system/application administrators and partners". GWC is in scope for Google bug bounty program though Google considers it a low priority application as far as reward amount is concerned. It is not about reward all the time. This blog (i.e., Respect XSS) is about XSS. Some time ago, I found Stored, Reflected and DOM XSS in GWC. 

Stored XSS

In GWC community, application administrators can share their ideas and help each other. The application allows users to create a document/posting/thread/message and among other features (e.g., mark as question, tags and category etc), the posting has a title or name and message body. The title of posting is of our interest in this case. The site was doing good in encoding < character into &lt; (if found in the title) (see screen-shot).


As you can see in the above screen-shot that < is encoded in an HTML context (i.e., <a> tag around reflection), so no need to waste time here. The site has another feature where one can do the same stuff but via Google Drive. The feature is labelled as "Add a file from Google Drive". In that case, at that time (now site has been updated and things may be bit different), the name of Google Drive file becomes the title of the post. The screen-shot shows the site's behavior when a file has been added from Google Drive. Please keep in mind that in Google Drive, I had first created a file named "xxxxxxxx'yyyyy</img>.PNG so that I can used that file here in GWC.


The screen-shot above shows reflection in GWC and and it can be seen that reflection was in script context in general and as a part of var declaration (i.e., object literal) in particular. The developers were using " for holding the title of file and at the same time, " and </ were not controlled or filtered or escaped. The XSS is now pretty straight forward, Please make sure that you have a file in Google Drive named </script><script>confirm(document.domain)</script>


This was an stored XSS because posting on GWC is available for all logged-in users. The root cause of this stored XSS was that GWC application forgot to control/encode/filter input from other application (i.e., Google Drive) though they were doing good on direct user-supplied input.

Reflected XSS

If somehow you're able to cause an error (e.g., file was not properly uploaded from Google Drive) in GWC then application throws an error message in a GET parameter named "googleDriveError". This GET parameter is vulnerable to a classical reflected XSS. Further if you're able to cause an authentication error, then application throws an error message as a part of GET parameter named "error". Both error related GET parameters were vulnerable and both were using the same code base. The screen-shot shows the reflection of our harmless probe string "xxxxxxxx'yyyyy</img as a part of  "googleDriveError" GET parameter.


It can be seen in the screen-shot that < is not filtered in an HTML context. It is enough of information. The next screen-shot shows reflected XSS in "googleDriveError" GET parameter followed by a reflected XSS in "error" GET parameter.



DOM XSS

I also found a DOM XSS in GWC. The culprit for DOM XSS was window.location.hash.substring(1) but the problematic JavaScript code executes only if someone marked/clicked the reply of a posting "Mark as Helpful". The vulnerable dynamic JavaScript code was part of a JavaScript file at that time (site has been updated and you will see a not found message). The vulnerable JavaScript code looks like ...

... {if(window.location.hash){c.scrollTo("a[name='"+window.location.hash.substring(1)+"']")} ...

There are two screen-shots given below. One shows where posting has not been marked "Helpful" and one shows where posting has been marked "Helpful". The DOM XSS payload was part of both cases but executes only in the later case.


GWC received an update recently so there is a great chance that this update has introduced some bugs. Happy Hunting ...  

Sunday, February 14, 2016

Keep An Eye On $.html, $.get and $.ajax Functions

The $.html(), $.get() and $.ajax() are potential XSS venues. Some of you're already aware of this but lets see real life examples from the wild.  Finding a real example from the wild is itself not an easy task but fortunately, I live on the web in general and view-source in particular, so I found one. At the same time, instead of cosmetic bypasses i.e., bypasses based on assumptions or without examples or bypass for the sake of bypass, I am only interested in real cases. It is always good to see how developers use jQuery's features in the wild. Some time ago I did a blog post on third-party jQuery based sinks.

$.html(htmlString)

According to jQuery, $.html(htmlString) sets the HTML contents of each element in the set of matched elements. Please open the following URL.


The screen-shot shows the reflection of our interest i.e., in $.html(htmlString) function. The developers're using single quote for holding the HTML contents inside $.html(htmlString) function and it can be seen that ' from the probe string ( i.e., "xxxxxxxx'yyyyy</img) is not controlled.


The XSS in this case should not be a problem. The URL at the time of XSSing is given below and the screen-shot is also there.




$.get()

According to jQuery, $.get() loads the date from the server via HTTP GET method. Open the following URL (q GET parameter holds our harmless XSS probe string i.e., "xxxxxxxx'yyyyy</img).  The screen-shot shows the reflection of probe string in $.get() function.



It can be seen in the screen-shot that developers're using " for holding the value of first parameter of $.get() function i.e., url and " is not filtered or encoded or escaped. The XSS in this case should not be a problem and it is simple and straight forward. The URL at the time of XSSing is given below and the screen-shot is also there.



$.ajax()

It is used to perform asynchronous HTTP request. The screen-shot shows the reflection of XSS probe string inside $.ajax() function. The developers're using ' for the data section of $.ajax() and it can be seen that ' is not controlled. Further </ is also there in its hard-coded form. I would like to refer you to the article for the detailed syntax of $.ajax().



It is an easy and simple task to XSS this case given ' and </ are not controlled in $.ajax() function. The XSS attack payloads like '-confirm(1)-' and </script><script>confirm(1)</script> work here. I already explained in earlier posts how payloads like '-confirm(1)-' or "-confirm(1)-" work. The screen-shot shows an XSS.


Before conclusion, I would like to say that I am still looking at $.post() and $.load() based XSS in the wild ( both are also potential XSS venue ). If I will find one, I will update this post. I conclude on a saying: "Simplicity is natures first step, and the last of art." Philip James Bailey.

Sunday, February 7, 2016

Find The Root Cause

This time instead of publishing a new blog post, I present two real life XSS example cases from the wild. I already XSSed both cases for you. Your job is to find the root cause and explain it in the comment section or send it to me via Twitter or email. The first best detailed explanation of the following two real life example cases will receive a small token of appreciation from my side. 

1) Open the following URL in Firefox browser:


The screen-shot is also given below.


Your task is to explain how this XSS works to a naive user or beginner. A sort of indirect hint is available in one of my earlier blog posts.

2) Open the following URL in Chrome browser:


Isn't my harmless XSS probe string ("xxxxxxxx'yyyyy</img) part of URL :D The screen-shot is also given below.


Your task is to explain this XSS to a naive user or beginner. In fact the root cause of this XSS is: developers often do not follow the very basic and first principle of security.

I hope it would be fun.

Participants

-- Serious effort by @Zemnmez:

http://pastie.org/private/zgr3xxoj7e6shanmixrlwhttp://pastie.org/private/lpxgyc9iikn9z674pswsqg

-- Attempt by @omeriko_9:

https://twitter.com/omeriko_9/status/696299928717565952

Sunday, January 31, 2016

The Magic of Connecting The Dots

Macy's (http://www.macys.com/) calls itself "the magic of macy's" (at least the word magic is mentioned on their main home page logo). It has a global Alexa rank of 241 at the time of writing. It is a high profile web application. I think not from security perspective but from traffic point of view. Let the game begin. Please open the following URL (keyword GET parameter holds our harmless XSS probe string i.e., "xxxxxxxx'yyyyy</img). The following screen-shot shows reflection of our interest and some other cool things.



Lets start connecting few dots ...

The following line (in particular line #1911 in the screen-shot above and I marked it with label "Seems Interesting (3)") of JavaScript code (keywordsearch = kws.replace(/"/g,'\\\"');) replaces the " globally in the input with \\\" i.e., developers try to escape " with the help of three backslashes. Though escaping with three backslashes works fine given developers're using double quotes for holding the input in script context in general. Normally one backslash like \" (for double quotes) or \\ (for backslash) is enough (e.g., see line #21 in the source code in Chrome).


Note: FYI, on YouTube Gaming web site, you will find escaping with single backslash (i.e., \") and escaping with three backslashs (i.e., \\\") on the same page. Please see line #204 and line #200 in the source code in Chrome browser respectively.

So far so good from the application perspective but wait ... What about backslash (\) if injected in the attack payload? Are they escape backslash? Some of you might remember the blog post I did sometime ago and it was related to backslash. At that time I mentioned, my quest for backslash based XSS will continue and I think I am done with it (you will see when you're done reading this post). For example, open the following URL (http://www1.macys.com/shop/search?keyword=\) and if you will look into the source code, backslash is not escaped (see screen-shot below).


The following XSS attack attack payload can do the job for us i.e., \"; confirm(1); //. The URL looks like: www1.macys.com/shop/search?keyword=\";%20confirm(1);%20//. Some of you might be thinking why I started the payload with \. I explain but first look at the screen-shot of injection i.e., \"; confirm(1); //.


The injected XSS payload \"; confirm(1); // becomes \\\\"; confirm(1); // because " is replaced by \\\" in order to make it an escape character and at the same time, \ is not escaped. In short we have four backslashes in the reflection. Further, please remember, we're inside double quotes because developers're using them for keywordsearch variable declaration. The JavaScript code snippet looks like keywordsearch = "\\\\"; confirm(1); //"; How to interpret this code? The number of backslashes as far as one or three or five (i.e., odd number) is concerned, it is fine but if the count is even number i.e., two or four or six ... & so on then it will make the effect of escaping NULL N VOID.

In short, double quote is no more an escaping character because of four backslashes. The browser will consider it a proper closing double quote (in pair) for a variable declaration. In the XSS attack payload, now comes ; which is a statement terminator. It is followed by a proof of concept JavaScript function call i.e, confirm(1);. Last but not the least, we have a single line comment (i.e., //) in order to neutralize the effect of closing ";. It seems all set for an XSS and the following URL will result in an XSS: www1.macys.com/shop/search?keyword=\";%20confirm(1);%20//. Unfortunately NOT... but why? The game is still on ... It is about connecting some dots.

If you look at one line (i.e., line #1949 because line #1950 is a comment ) above the keywordsearch variable declaration that holds our reflection then you will realize that there is a conditional statement and it is not executed. It means that the control never reaches at the reflection or injection point because the conditional statement evaluates to false at the moment. Why false? The conditional statement is:

if(currentPageUrl.indexOf("cm_kws")!= -1) 

while currentPageUrl is a variable i.e., var currentPageUrl = window.location.href.  The window.location.href returns the current location of the document and assigns it to the variable currentPageUrl. The URL at the moment is http://www1.macys.com/shop/search?keyword=\%22;%20confirm(1);%20//. The JavaScript string function indexOf returns the first occurrence of the specified value, otherwise returns -1. The specified value in the indexOf function is "cm_kws". The current URL has no occurrence of "cm_kws". It means inside conditional statement, currentPageUrl.indexOf("cm_kws") evaluates to -1 and we all know that -1 != -1 is false :) The end goal is to make this conditional statement true so that the control reaches at the point of reflection and we will be able to execute JavaScript code of our choice.

I think, it is possible to force conditional statement so that it evaluates to true by appending the specified value i.e., "cm_kws" in the URL given currentPageUrl gets the value from window.location.href as I mentioned earlier and can be seen in the screen-shots. The job can be done by adding a new GET parameter named "cm_kws" like http://www1.macys.com/shop/search?keyword=\%22;%20confirm(1);%20//&cm_kws or by simply padding the string "cm_kws" at the end of URL like http://www1.macys.com/shop/search?keyword=\%22;%20confirm(1);%20//cm_kws.  In case of adding a new GET parameter "cm_kws", the statement currentPageUrl.indexOf("cm_kws") inside if evaluates to 66 and we all know 66 != -1 is true. In case of padding "cm_kws" at the end of URL, the statement inside if evaluates to 65 and we all know that 65 != -1 is true. The screen-shot given below shows the results of evaluation for better understanding.


It seems all set for an XSS i.e., dots have been connected. The following URL shows a confirm box followed by screen-shot.



For the sake of completeness, I wanted to XSS it with </script><script>confirm(1)</script> given in the reflection (see first screen-shot) </ is not filtered or encoded. The URL looks like ...


It has been blocked by some kind of protection layer. I think WAF or any other protection mechanism (e.g., IPS/IDS) stops the payload. The screen-shot shows Access Denied.


I had seen the same screen-shot on Akamai's site. It makes sense to believe or reasonable to believe that Akamai is not using other vendor's security solutions :) Isn't it? Akamai has its own WAF also i.e., Kona. Builtwith also gives some information that site is using Akamai's hosting services. Further, I am still interested if somebody will tell me or confirm which WAF is in place over there. Your feedback is always welcome.


WAF is meant to bypass and this one is not different. As I said earlier that </script> was blocked but </script%0Aanything> was not blocked. The following are quick bypasses and the screen-shot related to the second URL is also given below.




Before conclusion, I noticed that Macy's allowed to have single (') and double quotes (") in the product name (in case if required). I was thinking that it would not be easy for them to handle single (') and double quotes ("). For example, see the following two products ...




A question came to my mind: what will happen if I will do a search query of the product that have single (') and double quotes (") in their name. How site will treat it? Lets make a search query. I query for the following string i.e., a legit product name having both types of quotes ...

Under Armour Men's Raid Performance 10" Shorts

The resulting URL is:


It returns 3 results at the time of writing. Now lets look at the source code and try to figure out any thing interesting. As expected, site starts breaking itself :) The first thing I noticed is a legit search query breaks the attribute context (see screen-shot below).


The second interesting reflection in that case was in script context. It can be seen in the following screen-shot. The screen-shot shows that " from the product name is not escaped or filtered or encoded.


It means that we can leverage the " from the existing product name in constructing the XSS attack string. The XSS payload looks like (please see that the proof of concept JavaScript code does not start with " because we will use the " from the product name):

-confirm(1)-"

Now combine this proof of concept XSS payload with the legit search query we made earlier. The final attack string will be ...

                        Under Armour Men's Raid Performance 10"-confirm(1)-" Shorts

The URL at the time of XSS is given below followed by a screen-shot.



I conclude on a saying: "When You Really Pay Attention, Everything Is Your Teacher." (Ezra Bayda)

Sunday, January 24, 2016

Unusual Reflections

This post is about unusual reflections i.e., when user-supplied input reflects back or ends-up at an unusual place. I will show unusual reflections with the help of four live examples.

-- Reflection in src Attribute of <script> Tag:

This is really unusual when you're getting a reflection as a part of src attribute of <script> tag. The site FAKT.PL has a global Alexa rank of 2296 at the time of writing. Please open the following URL (our harmless probe string ("xxxxxxxx'yyyyy</img) is part of q GET parameter's value):


The screen-shot shows the reflection of our interest.


It can be seen in the screen-shot that developers're using " for holding the value of src attribute and " from the XSS probe string are not filtered. At the same time, </ is not controlled and in my experience, there is a great chance that > is also not controlled. The URL at the time of XSSing is given below followed by a screen-shot.



-- Reflection in SQL Statement:

The title of this heading sounds interesting i.e., when user-supplied input reflects back on the web page as a part of SQL statement. Isn't it? This is happening in the wild. Please open the following URL: http://search.gmw.cn/epaper.jsp. The site GMW.CN has a global Alexa rank of 54 at the time of writing. On the URL, you will find a search bar and lets input our harmless XSS probe string ("xxxxxxxx'yyyyy</img) in the search bar. The screen-shot shows the reflection of our interest. 


The screen-shot above shows our XSS probe string reflects back on the page as a part of where clause of SQL statement. Further <textarea> tag is around the input reflection (HTML context) and its style attribute has been set to "display:none". Furthermore, </ is not filtered or encoded in reflection. Though this is an HTML context and one can assume that the XSS attack payload <img src=x onerror=confirm(1)> will simply work but in-fact it does not because of <textarea> tag around. The </textarea> tag engulfs the contents except its closing counterpart. In order to make the attack payload works, first close the </textarea> tag prematurely and then you can execute the XSS attack payload of your choice. In short, the final attack payload looks like: </textarea><img src=x onerror=confirm(1)> . The screen-shot given below shows the XSS. I was also thinking: WTF SQL statement is doing on the page? Why developers're exposing their database table(s) structure on the web page?


 -- Reflection in alert() Function:

As a part of XSS proof of concept demonstration, we normally use alert() function. I found an exceptional case where user-supplied input ends-up as a part of alert(). Sometime ago, I did a write-up on JavaScript's built-in functions as reflections but alert() is somehow unique because reflections in other functions are common. I can not name the web site in this case but the following screen-shot shows the reflection of XSS probe string ("xxxxxxxx'yyyyy</img) in alert(). The screen-shot also shows " and < from the probe string are filtered but ' is not filtered while at the same time, developers're using single quotes for holding the value.  


For better understanding and XSS this case, first look at the source code of our interest without any injection: <script>alert('For input string: "83845138c47691"');</script>. The numeric value in the alert() function was part of a GET parameter i.e., it might be controlled by the attacker. In order to XSS this case, we have an apparent two choices (given " and < are filtered as can be seen in the screen-shot above).

  1. '-confirm(1)-' 
  2. ');confirm(1);//

In the first case, we break the context with ' and than with the help of JavaScript string operation (minus operator used in this case i.e., In JavaScript, you can subtract anything from anything as long as the syntax is valid), we execute arbitrary JavaScript code (i.e., during string expression evaluation inside alert(), we execute confirm(1).). The second choice lies under the category of "respect the syntax". It means first break the context with ' and than prematurely closes the alert function call with small parenthesis i.e., ) followed by a statement terminator ;. After that proof of concept confirm(1); followed by a single line comments (//) in order to neutralize the affect of closing "');. Here is the screen-shot shows the XSS. I used the second choice from above as a payload.


 -- Reflection in GET parameter name:

This is the case where you will see reflection as a part of GET parameter name along with the value. Normally, the value of a GET parameter is or may be controlled by the attacker but in this special case, an attacker may controlled the name of GET parameter. The BAIDU.COM has a global Alexa rank of 4. Please open the following URL (our harmless probe string ("xxxxxxxx'yyyyy</img) is part of q GET parameter's value):


The screen-shot shows the reflection. It can also be seen that ", ' and / are escaped so it seems no chance to XSS this particular injection point.


So far there is nothing unusual. The interesting thing is if I replace the GET parameter q with probe string ("xxxxxxxx'yyyyy</img) and see the reflection after submission again. I mean now the above URL looks like:


The screen-shot shows the reflection.


The site has recently added protection i.e., escaping of ", ' and / on the Left-Hand-Side (LHS) of =. Sometime ago, they're only doing escaping on the Right-Hand-Side (RHS). I was able to XSS it because of this exceptional reflection on the LHS of =. I conclude on a question: How often during a pen-test you guys try to manipulate a GET parameter name? 

Sunday, January 17, 2016

if --- Reflection Point

In this post, I will discuss with the help of two real examples about `if` reflection point i.e., when user-supplied input reflects back as a part of conditional statement in JavaScript. Please open the following URL (our harmless XSS probe string "xxxxxxxx'yyyyy</img is part of GET parameter q). The screen-shot given below shows the reflection of our interest i.e., part of conditional statement. 



The screen-shot shows that developers're using single quote (') for holding the value of user-supplied input and ' from the probe string ("xxxxxxxx'yyyyy</img) is not filtered or encoded. Further </ is also there in hard-coded form. One potential way to XSSed this case is '-confirm(1)-'. This will execute because at the time of expression evaluation inside `if`, our proof of concept JavaScript is executed. The URL at the time of XSSing is: http://www.pressdemocrat.com/search?q=%27-confirm(1)-%27 and the screen-shot is also given.


For the sake of completeness, I wanted to XSS this case with the help of </script><script>confirm(1)</script> but realized that this does not work even though </ was not filtered or encoded as I mentioned earlier when we're looking at the probe string reflection (see first screen-shot on the page). In short, the URL does not result in an XSS:


I decided to dig deep and found that they have some sort of filtering in place. The screen-shot given below shows the XSS vector </script><script>confirm(1)</script> does not reflect back at all.


If you will come across that type of case, I would suggest try the following valid variations (there are some others ... please figure out and take it as an exercise, now you have a live test-bed from the wild) and have already seen in the wild (at least 3 to 4 different occasions) that they work and bypassed the filtering mechanisms. The valid means: browsers render it.

</script%20><script%20>confirm(1)</script%20> // a space (i.e., %20) before closing > sign
</script%0a><script%0a>confirm(1)</script%0a> // new line (i.e., %0a) before closing > sign

The following URLs result in an XSS (choice is yours) and the screen-shot related to the %0a case is also given. The effect of %0a can also be seen in the screen-shot.



Now lets see another example from the wild. Please open the following URL (our harmless XSS probe string "xxxxxxxx'yyyyy</img is part of GET parameter rgnCd). The screen-shot given below shows the reflection of our interest i.e., part of conditional statement.



The screen-shot shows that developers're using single quote (") for holding the value of user-supplied input and " from the probe string ("xxxxxxxx'yyyyy</img) is encoded. Further < is also in its HTML encoded form. It seems no chance to break the context but the point I wanted to make is `if` is also a reflection point in the wild. Some of you might remember the blog post I did for breaking the SAP's SuccessFactor's XSS filter. In that case, the reflection of our interest was also part of conditional statement.

Wednesday, January 13, 2016

Persistent XSS in Mozilla Add-Ons Site

I do not know how but somehow I ends up on Mozilla's add-ons site. The site provides logged-in user an option or feature to create collections. According to Mozilla, "collections are group of similar add-ons that anyone can create and share". The collections are publicly view-able because site provides a unique URL per collection. The site has a form (available here) having fields like Name, Description and the add-ons for the creation of collection. The Name field of the collection form was vulnerable to a stored XSS. 

I created a collection having a Name "xxxxxxxx'yyyyy</img in order to see the behavior of site regarding special characters in the Name. The collection can be seen here: https://addons.mozilla.org/en-US/firefox/collections/soaj1664/xxxxxxxx-yyyyy-img/. The screen-shot shows the reflection of our interest i.e., as a part of <title> tag. One can see in the screen-shot that < is not encoded or filtered in an HTML context i.e., <title> tag around the reflection of probe string. 


For XSSing, when you're in <title> tag and < is not encoded or filtered then by simply closing the title tag prematurely with the help of </title> does the job for you and after that one can execute JavaScript code of his or her choice.  The payload I used for XSS looks like </title><svg/onload=confirm(document.domain)//. The screen-shot shows the persistent XSS. The URL where it can be seen at that time (before fixed is deployed) is: https://addons.mozilla.org/en-US/firefox/collections/soaj1664/a-img-src-1-gif-onerror-alert/. The stored XSS is now fixed. Isn't it that simple :)


I filed a bug (https://bugzilla.mozilla.org/show_bug.cgi?id=1235190) on 26-12-2015 and it was fixed on 07-01-2016. Mozilla awarded me 2500$ for this persistent XSS that can be used to serve malware, malicious campaign or drive by download. I was informed that soon Mozilla will release a notice/advisory here: https://www.mozilla.org/en-US/security/advisories/.

Further I found two more XSSes (low profile) i.e., one in Mozilla add-on (https://addons.mozilla.org/en-US/firefox/) and one in Mozilla Support site (https://support.mozilla.org/en-US/). The XSSes are not yet fixed and I will update this post once fixed will be deployed for these two XSSes. The XSSes are now fixed.

1) Self-XSS in Edit Review Feature of Mozilla Add-on Site: The bug can be found here: https://bugzilla.mozilla.org/show_bug.cgi?id=1237967 and deployed fix information can be seen here:

2) Self-XSS in Mozilla Support Mobile Site's Main Search Bar: The reported bug is here: https://bugzilla.mozilla.org/show_bug.cgi?id=1238252 and the deployed fix can be seen here: https://github.com/mozilla/kitsune/commit/8eefb30593013e1fb69ed4b4724ef5d457e020bf

Sunday, January 10, 2016

When Reflected Becomes Stored

In this post, I will discuss an interesting case of XSS i.e., when a classical reflected XSS becomes stored XSS. The transition from reflected to stored happens because developers convert user-supplied input into some form of encoding, make it part of a URL and permanently store it in the database. I was thinking why developers do this at first place? The apparent reason, I can think of from the top of my head is tracking or for analytic purpose e.g., popular searches. If you know any other reason, please let me know. At the same time, I think, this type of practice makes the exploitation easy i.e., an attacker may hide the payload as a part of legit URL. Vishal Sharma in his blog-post also points out that cloud-based WAF can be bypassable with the help of this feature of web application because WAF never sees the harmful payload unless decode.    

Lets see this with two real life examples from the wild. On the following URL: http://www.akc.org/, if you will enter a letter `a` in the main search bar and hit enter. The site will give you a URL that looks like: http://www.akc.org/search/YQ/. Now if you will query for the letter `b` in the search feature then site will ends up on a URL like: http://www.akc.org/search/Yg/. You may continue to see the behavior of web application on different inputs and may try to figure out the type of encoding in place. Lets input our harmless probe string "xxxxxxxx'yyyyy</img and as a result the site will give you a URL: http://www.akc.org/search/Inh4eHh4eHh4J3l5eXl5PC9pbWc/. The source code inspection shows the reflection of our interest in the following screen-shot.  


The screen-shot shows the probe string reflects back as a part of JavaScript's built-in function i.e., encodeURIComponent. The developers're using single quote (') for holding the value of function and it can be seen that single quote (') from the probe string ("xxxxxxxx'yyyyy</img) is not filtered or encoded. I already did a write-up on reflections in JavaScript's built-in functions. The XSSing in this case is not difficult. The payload '-confirm(1)-' does the job. The URL at the time of XSSing looks like: http://www.akc.org/search/Jy1jb25maXJtKDEpLSc/ and the screen-shot is also given below.


Now see another example in the wild (sorry for hiding the URL). The screen-shot shows the reflection of probe string but if you will see the value of SysSearch GET parameter, you will find some sort of encoding in the URL instead of hard-coded probe string ("xxxxxxxx'yyyyy</img). The screen-shot also show that < is not encoded in an HTML context. The game is over for them given < is not filtered or encoded in an HTML context.


The next screen-shot shows XSS with the help of simple and popular payload i.e., <img src=x onerror=confirm(1)>. The payload does not start with ' or " quotes because we're in HTML context. Please look at the value of SysSearch GET parameter. It is not hard-coded XSS payload but you will find encoded form.


If as a developer you still wants to use this type of feature then please make sure to follow the basic , well known and million dollar principle of "Filter Input,  Encode Output".