Archive for the 'Web Application Security' Category
Thursday, October 11th, 2012
A few years ago, I discovered a peculiar design decision described in the PDF specification. This design flaw allows for an attacker to conduct XSS attacks against some websites that would not normally have XSS vulnerabilities. I reported this issue to Adobe in late 2009. Apparently, there are some challenging back-compat issues which make changing this design difficult. Given it’s been nearly three years since I first reported the issue to Adobe and a fix from Adobe doesn’t seem likely (Chrome has already fixed their internal PDF reader), I figured I should let web application community know about the exposures. I don’t expect “APT” or other 31337 $country “cyber liberation armies” to use this anytime soon, but it is interesting behavior and I hope web application security folks find it interesting. Hopefully some researcher who’s smarter than me can take this to the next level. Oh, and I apologize for the ugly PoCs in advance!
If we take a look at section 3.4.1, “File Header” of Appendix H in the PDF specification, we see the following:
13. Acrobat viewers require only that the header appear somewhere within
the first 1024 bytes of the file.
Anyone who has read the PDF specification probably knows about this behavior, in fact Julia Wolf mentioned this behavior in her epic OMG WTF PDF talk at CCC in 2010. This peculiar design allows for the creation of a hybrid file that is both some arbitrary file type (such as gif, png, doc…etc) and PDF. We do this by cramming a PDF header after another file header. An example of this is shown in the screenshot below:
Hopefully, by now we’ve already realized that hosting user controlled PDFs and serving those PDFs from a sensitive domain is dangerous from a web security perspective. However, with this quirky file header behavior, we’ll have the ability to smuggle PDFs onto a website that only accepts “benign” file types. As an example, I’ve uploaded such a file to an appspot web application I created. The PoC shows that we can load a single file as both a GIF (or any other file type we want) and a PDF. Adobe PDF reader needs to be set as your default PDF handler for the PoC to work.
The only difference in the two displays in the PoC above is the way we reference the file. In the case of the image, we simply use an IMG tag. When we want to force the browser to hand the file to the default PDF reader, we make use of the OBJECT tag and explicitly specify a content type to force the content to be handled by the default PDF reader. Of course, this technique can be generalized for other plugins.
<img src="http://pdfxss.appspot.com/Son-of-Gifar/NotAPDF.gif" height=10 width=10></img>
<object data="http://pdfxss.appspot.com/Son-of-Gifar/NotAPDF.gif" type="application/pdf" width="500" height="500"></object>
The following link demonstrates how this issue would be used against a website. The domain xs-sniper.com (the attacker’s domain in this example) loads a smuggled GIF/PDF from http://pdfxss.appspot.com (the victim domain in this example). Once the PDF is loaded, we make use of the built in XML APIs to retrieve a file /secret.txt from http://pdfxss.appspot.com (the victim domain).
IE users will see a warning in the PDF reader. This is because IE actually downloads the PDF and opens a local copy You can verify the IE behavior by browsing to this PoC with Internet Explorer (Adobe PDF Reader must be set as the default reader).
Lastly, you can inject a PDF into a website if you have already XSS. This might be helpful in bypassing XSS filters or application filtering. This is accomplished by injecting a PDF into the vulnerable site using the OBJECT tag.
<object data="http://vulnerable-domain/xss.asp?vulnerable-param=<injected PDF HERE>" type="application/pdf" width="500" height="500"></object>
An example of how this could be done is given below (this PoC best viewed in FireFox with Adobe PDF Reader, but the technique is possible for all browsers).
What’s the impact? Well, I suspect there are plenty of Internet facing web sites that are vulnerable to this bug. Any web application that accepts uploads of “benign” file types and then serves those files back to the user could be affected. This also affects websites which rely on content-type headers to prevent XSS (btw, this strategy doesn’t work). See Phil Purviance’s blog for tips on spotting (and exploiting) websites that use content-type to protect against XSS. This bug can also be used to exploit the applications that use content-disposition headers to prevent XSS bugs. The most common attack surface here will likely be internal content portals. Pretty much every internal content portal used in the enterprise is vulnerable to this issue (think Sharepoint).
You can test for this issue by trying to upload this file to a vulnerable web application. If you see the PDF header in the uploaded file AND the file is served from a sensitive domain (ex. it has auth cookies), then the application is vulnerable.
The proper defense for this is the usage of alternate domains for user supplied content (aka sandboxed domains). Sandboxed domains can be tricky to implement. Some of the most popular web applications on the web already make extensive use of sandbox domains, but the vast majority of web applications do not. Once again, internal content portals are in a hard spot as it’s more difficult to implement a sandboxed domain on an internal network. Sandboxed domains is a subject many “web application security specialists” understand poorly and probably deserves its own blog post. How to properly implementing a sandboxed domain is a great interview question for senior web application security roles because it tests design and implementation skills. It also requires a really solid understanding of browser/plugin same origin policy. I haven’t seen much written about sandboxed domains, but this blog post does a nice job of summing up some of the challenges of content hosting. http://googleonlinesecurity.blogspot.com/2012/08/content-hosting-for-modern-web.html
Friday, June 10th, 2011
I’m posting some of the research I’ve been working on over the last few months. I planned on submitting some of this research to the Blackhat/DEFCON CFP, but it looks like I’ll be tied up for most of the summer and I won’t be able to make it out to Vegas for BH or DEFCON this year (pour some out and “make it rain” for me). The gist of the research is this: I’ve collected of number of malware C&C software packages. I set up these C&Cs in a virtual network and audited the applications and source code (when available) for bugs. The results were surprising; most of the C&C software audited has pretty crappy security.
This week’s sample is an auth bypass and SQL injection on a BlackEnergy C&C page. The first of the samples can be found here: http://software-security.sans.org/blog/2011/06/10/spot-the-vuln-rabbit-authbypass-and-sqli
I’ll post more samples in the coming weeks.
Attacking malware C&C is an interesting proposition. Exploiting a single host can result in the transfer of hundreds or even thousands of hosts from one individual to another. I’m not the first to note that malware and C&C software is evolving. Gone are the days of simple IRC bots receiving clear text commands from an IRC server. Today’s C&C’s are full fledged, feature rich applications with much complexity. Complexity is the enemy of security, even malware authors cannot escape this. There is no magic bullet, even malware authors face the difficulties of writing secure code. This is especially so if their customers are paying money for C&C software and demand newer features and robust interfaces. Today’s malware landscape looks much like a typical software enterprise with paying customers, regularly scheduled feature updates, marketing, and a sprinkling of PR. Who knows, maybe in the near future these malware enterprises will have dedicated, on-call security engineering teams and a formal SDL process
Wednesday, September 22nd, 2010
*** UPDATE ***
Rex Grossman is out for the season. ESPN has fixed the issues I discussed below. However, before you give up on your fantasy football season, apparently there is a stored XSS that I missed. This guy will have details posted soon –> http://lanmaster53.com/?p=182 . The fun never stops
*** UPDATE ***
First, some background. I love American football. My team is the Chicago Bears. I’ve been a Bears fan since the 80’s when Walter Payton, Mike Singletary, and Jim McMahon dominated the field. The last few years as a Bears fan has been difficult, but I’ve hung in there. A few years ago the Bears had a quarterback named Rex Grossman. To put it lightly, he wasn’t the greatest QB a team could have, in fact the Bears have traded him away. I never really liked him.
Earlier this month, I was invited to play in a fantasy football league. I’ve never played fantasy football, but I understood the rules and had many friends who played. My friends (none of which work with computers for a living) needed one more player to round out a league of 10 teams so I decided to give it a shot. Before the “season” begins, each player selects the football players they think will be the most successful during the season. As my best player, I selected a running back named Ryan Grant who runs for the Green Bay Packers. I was shocked to see my star player injured in the first game of the season with a season ending injury. As I navigated the fantasy football website to find a replacement player, I came across several interesting issues. There are some issues that allow me to cheat and win (dropping arbitrary players from another teams roster, modifying another teams starting lineup), but I want to win fair and square (I guess that Midshipman honor code has stuck with me)… but as a notorious prankster I figured I could have a little fun with the bugs I discovered.
When a team decides to add a new player to their roster the player navigates through several menus and selection screens. The final confirmation URL for adding a player to the bench looks something like this:
The leagueId represents the “league” in which our teams are playing. The trans parameter represents the actual transaction. Looking at the trans parameter, I’ve broken the various pieces into the following:
2 <– this is the type of transaction to be executed
4480 <– This is the unique player ID for Rex Grossman
-1 <– some sort of increment value/ counter?
1002 <– another value that describes the transaction
3 <– team id for my team
20 <– not sure what this number is
Unfortunately for the other players in my league, the fantasy football application does a poor job of authorization checking. These poor checks allow me to manipulate the trans parameter to add an arbitrary player to any teams roster. I decided to add Rex Grossman to one of my rivals bench (not the starting lineup).
Soon after adding Rex to my rival’s bench, I spoofed an email from Rex Grossman with a plea to play.
A few days later, my rival was posting to the entire league that Rex Grossman had magically added himself to his roster and had emailed him to play. My rival then dropped him from the roster before the next weeks play.
Unfortunately for my rival, Rex is a persistent player. This week I traded him from waivers for another player on my rivals team. Trading from waivers/free agency is a bit more complicated and the query string is a bit more complicated, but the overall gist is the same (I also had to fake the waiver transaction ID).
The numbers before the “|” character belong to the player who is to be dropped from the roster (the bench) to waivers while the numbers after the pipe character represent the player to be added to the roster (to the bench, not the starting lineup). In this example, I’ve dropped T.J. Houshmandzadeh off of my rival’s bench roster and added Rex Grossman back to the bench.
Of course, another spoofed email goes out to explain the situation.
We’ll see what next week brings. I’ve contacted the fantasy football game provider (probably the largest provider in the US), hopefully they’ll fix it soon…