Header-Bar

Showing posts with label Reported vulns. Show all posts
Showing posts with label Reported vulns. Show all posts

December 8, 2014

AliExpress DOM-Based XSS (Main Registration Page) And Reflected XSS in Alibaba WebATM Online chat



What is DOM-Based XSS?

"In order to understand DOM XSS, we need to describe a bit what DOM is, and why is it relevant to this context.
The Document Object Model is a convention for representing and working with objects in an HTML document (as well as in other document types). Basically all HTML documents have an associated DOM, consisting of objects representing the document properties from the point of view of the browser. Whenever a script is executed client-side, the browser provides the code with the DOM of the HTML page where the script runs, thus, offering access to various properties of the page and their values, populated by the browser from its perspective.
DOM XSS is a type of cross site scripting attack which relies on inappropriate handling, in the HTML page, of the data from its associated DOM. Among the objects in the DOM, there are several which the attacker can manipulate in order to generate the XSS condition, and the most popular, from this perspective, are the document.url, document.location and document.referrer objects."

Proof Of Concept


In this specific case, the XSS occur when user input is being rendered after being called by this Javascript code:


The vulnerable page is the main "Join Free" registration page:

http://us.ae.aliexpress.com/wsuser/buyerJoin/expressJoin.htm?return=http%3A%2F%2Fwww.aliexpress.com%2F

Adding the following parameter should populate the vulnerable field:
_fmw.e._0.e=[XSS]

Here's what happens on a regular input:


Once a user decided to input a supposedly email string, the following <input> tag is being called:

<input id="email-ipt" name="_fmw.e._0.e" value="" type="text" tabindex="1" autocomplete="off" maxlength="128" class="redborder">

The important part of that element is of course - its ID. Using the get() Javascript function we can get the input which was submitted to the following element.
In this case, the Javascript file will hold the following reference: get("email-ipt")

Next, the code will append a string from a short list of known email domains:

<div id="email-prompt" class="email-prompt" data-index="-1">
<ul>
<li data-domain="@gmail.com">XSS@gmail.com</li>
<li data-domain="@hotmail.com">XSS@hotmail.com</li>
<li data-domain="@yahoo.com">XSS@yahoo.com</li>
<li data-domain="@mail.ru">XSS@mail.ru</li>
<li data-domain="@aol.com">XSS@aol.com</li>
<li data-domain="@yandex.ru">XSS@yandex.ru</li>
</ul>
</div>


Notice how the list is being wrapped by an "email-prompt" div element which we should see later when we look into the Javascript file.

So now that we saw what the static code is up to, let's see the Javascript.
Since it's a pretty large Javascript file (600+ lines), I decided not to go through each chunk. Let's look at the incidents that we know that has something to do with our attack.

The first encounter is here: (line 375)

AE.Wholesale.Join.prototype = {
    init: function() {
        return this.bindEvent(), this.initTimer(), this.isIE89() && this.initPlaceholder(), get("email-ipt").focus(), this.clickStat("new_regsiter_landing"), this.checkErrorType(), this
    }

focus() means "whenever a user clicks the field". This code is being called and returns 7 values into AE.Wholesale.Join.prototype. The 4th is our subject, once clicked.

And here is our interesting snippet:

YUE.on(get("email-ipt"), "keyup", function(t) {
       if (this.value.indexOf("@") >= 0) {
       e.showEmailPrompt(this.value);
       var n = get("email-prompt").getElementsByTagName("li"),
       r = [];
       ...
       ...
       ...
            } else e.hideEmailPrompt()


So email-ipt is our input and email-prompt is the actual action that prints our input to the screen, as we saw on the image above ("aaa@...").

if (this.value.indexOf("@") >= 0)

This says that only if a '@' character is located in the focus, please prompt the content list, else - e.hideEmailPrompt() Which hides the dropdown list.

Great! We are in the right location. Now let's dive and see if that's the code that executes our XSS.

e.showEmailPrompt(this.value);

This function takes the user input from its start until it bumps a '@' symbol. Than it looks for a static list of <li> elements with the data-domain attributes and embed the user input into it.
In any phase of the script, no validation on the user input is being taken.

Here is the showEmailPrompt()

showEmailPrompt: function(e) {
        var t = e.indexOf("@"),
            n = e.substr(t),
            r = e.substring(0, t),
            i = get("email-prompt").getElementsByTagName("li"),
            s = 0;
        for (var o = 0; o < i.length; o++) {
            var u = i[o].getAttribute("data-domain");
            u.indexOf(n) >= 0 ? (YUD.removeClass(i[o], "hide"), i[o].innerHTML = r + u, s++) : YUD.addClass(i[o], "hide")
        }
        s === 0 ? YUD.addClass(get("email-prompt"), "hide") : YUD.removeClass(get("email-prompt"), "hide")

    }

Now we can assume that injecting a Javascript code should reflect back, utilizing this domain object to generate the XSS prompt.

The following video illustrates how this could be accomplished:



Hope you enjoyed.

References:

https://www.owasp.org/index.php/DOM_Based_XSS
http://www.acunetix.com/blog/articles/dom-xss-explained/


This issue was reported to AliExpress.

TimeLine:
Reported on Dec 8th 2014.
Dec 10th, 2014: Alibaba security received the issue:
"Dear Naor.

         We have received your report, thanks!

Engineers are checking and fixing .and we will feedback in 24 hours.

We will follow the "Vulnerability Rewards Program", give a reward to you!

Thanks.


Another Reflected XSS was found and fixed a couple of days later. Very straight forward. This one is in the online chat feature called WebATM.



July 22, 2014

Ebay Multiple Cross Site Scripting vulnerabilities

A quick scan of eBay's network range got me to this server (anywhere.ebay.com). The server displayed eBay's front page and logo:
Browsing in the pages, I noticed the cookie "Country" which was reflected to the page as a part of a javascript code block AND a navigation href attribute. Surprisingly, no input validation was initiated, having an attacker to safely inject javascript into the page. Needless to say that the cookie was reflected in any page of the server.

Fix: Cookie parameter is now set to 0 and input validation was set.
<script type="text/javascript">
// share values with the client side
isIE9 = 1;
country = 0;
currentPage = 'all'; // not dynamic
trackingCode = '711-117568-2056-0';</script>


Timeline:
Me: May 30,2014 - XSS was discovered
eBay: May 30,2014 - Automatic Reply that the case is open
eBay: July 18,2014 - First Update:
Bug Type: XSS
URL: http://anywhere.ebay.com
Status: Validated and Awaiting Fix
eBay: Aug 10,2014 - Issue fixed. Bounty received. (***$)
eBay: Oct 21,2014 - Acknowledgement was sent. (Happy birthday to me).


Thank you.

December 23, 2013

DOM based XSS in Liveperson chat plugin

Hi,

Here is an interestig thought. What if you could chat with someone LIVE and infect him with a malicious script?

Well I thought its a nice idea in theory, untill I bumped into this:


Think of a malicious attacker that could of take advantage of this issue.

Here is the scenario:

Attacker side:
1. Open chat
2. Wait for the technitian to respond
3. Send him a malicious script that will capture the document.cookie with a link to your
website and hope for the best.

Technician side:
1. Getting another chat with some anonymous dude
2. Start chatting with him like his doing a 1000 times a day
3. Hmmm.... what is that link? I'm not familiar with security aspects... Let's click it /:

Conclusion:
The implications of capturing the Technician's cookie is analogous to an Administrator's one.
It could not have the same privileges, but it has to have privileges for accessing the system, or else how would he be talking to you.

That's a short one. Hope You enjoyed.

May 22, 2013

Stored Cross-site Scripting in Linkedin





Hello all,


Since Linkedin has no bug bounty program, all you need to do when finding one is to inform them about the vulnerability and you can post away.

The following vulnerability was found while I was using Linkedin's customer support, submitting a question regarding my account.


This request created a Ticket in the system with the form's details.
As you probably haven't noticed yet, the form has a [Browse] option to upload files regarding the form.
A smart move from Linkedin will be to send the attached file to an inaccessible directory within the application's server. for instance:
/var/www/help.linkedin.com/TheWebSite/upload-a-file-with-form --> user uploads file

/var/www/uploads/files/ --> file will be saved here

Instead of doing that, Linkedin created the ability for the user to watch his file after upload.

At first I didn't believe the possibility of this happening so I haven't even tried to upload a file.
Instead I went to the "Support History" Just to check that my ticket is Open.


Now after opening the ticket to review. I noticed an odd feature - Update your ticket.
So I thought to myself: "Well if I'm updating my ticket.. I will be able to view the update, right?"
The update includes a file.. so...


As you can see, after a quick exploit of that upload module I tried some more variants.

Furthermore, the blue marker  on the files names is of course a link to its path on the server.
Pressing that link will take you to the malicious Javascript.

Here is the path: http://help.linkedin.com/ci/fattach/get/2430905/1369216961/filename/ticket.html
**Don't worry, the script is only <script>alert(document.cookie)</script>



Let's fix that:

In order to prevent a malicious user from executing malicious scripts we first want to create a secured environment for the script to execute from. Away from the users permissions.
So first solution will be to store the file "behind" the application, and apply the right permission on that directory and files.

2nd solution will be to create a WhiteList of file extensions saying: "Hi dude, This file you're trying to upload is not registered in our list of permitted files, so please stop making a fool out of yourself!"
The code should look something like that:
---------------------------------------------------------------------------------------------------------------
if(file.extension(equals(jpg) || file.extension(equals(doc) || file.extension(equals(pdf)){
//upload the file
}
else {
 print("Hi dude, only the following are allowed: jpg, doc, pdf");
}
----------------------------------------------------------------------------------------------------------------

Consider restricting the size of the file to prevent exhausting the server resources and maybe also set the Content-type: HTTP header to render the page as text, preventing unrestricted executions.

I can think of more solutions, but I'll leave you to it.

Hope you enjoyed reading.

Ido Naor