Successful Hacking With XSS, Cookies & Session IDs

All too often I hear associates in security circles downplay the significance of cross-site scripting attacks(XSS). Until recently, I heard the same argument about AJAX and javascript
The truth of the matter is that XSS attacks are lethal when combined with other web application vulnerabilities that involve cookies and session IDs.
I read a fascinating article over the weekend at informit.com. The author, Seth Fogie, does an admirable job of pulling the pants off of those that downplay XSS threats.
Seth walks us through an attack on a real web site management application that resulted in shell access on the web host, every administrator's worst nightmare.
From the article, the author walks us through the XSS vulnerability:
… the code put an unfiltered "$email" into an $error message (line 10) after a check_email_address function rejects the input. Unfortunately, the same $error message was then printed out onto the page, thus allowing an attacker to inject pretty much anything they want right into the content of the webpage - including JavaScript code.
Whoops! Somebody has web coder that needs a good hit with a clue banana.
As if fate wanted to make it challenging, the maximum size of the HTML input field for the email address was 25 characters, and it only accepted POST data, which is somewhat limiting. As a result, I had to "outsource" my cross-site scripting attack to a third server. The end result was that I had to make a user click on a link that first took the victim to my server. From there, the code on my server directed the victim to the web application with a POST value that included the XSS code, which was then fed into the login script.
Read that section again. Seth had a very small input field (25 characters) that only accepted POST data. Utilizing a third server, he led the unsuspecting user to his server via a web link and then sent the user to the 'real' server with a quick POST. This takes milliseconds. Would you notice if this happened to you?
Seth mentions burp proxy, which is one of my favorite tools to manipulate data (cough) session IDs (cough) going to a web server. See for yourself:

You can 'freeze' your web request before it is sent to the victim server, manipulate some variables, add some evil fun and then send the request along it's way. Try it on some of your favorite financial sites for lots of late night fun.
Okay, back to the attack. Seth describes manipulating the session ID:
I viewed the captured value (i.e. 810fcb55ded4c14f75a8a1b8807266b3) and then loaded up Firefox and changed the Connection Setting under Tools - Options - General tab. In this screen, I added an HTTP Proxy value of 127.0.0.1 and port 8080, the default for Burp.
Alright, we've got the session ID, and we've adjusted Firefox to use our running burp proxy as a man-in-the-middle manipulator. This is where Seth overwrites the new session ID with the one that worked earlier allowing us entry into the site:
Once the value was overwritten, I disabled the intercept feature (on burp -Ed) and hit the Forward button. At this point, I was given access to the client portion of the application…
Nice and easy. If you skip down a few paragraphs in the story, you'll catch a nice URL value manipulation test that just makes you want to slap your head and wonder who wrote the application that he's testing!
During the update, I noticed something that peaked my interest: in the Pending Updates section of the application, there is a list of all the updates that need to be completed. When an update is selected and loaded, the URL reads something like this:
http://client.targetsite.com/view_detail.php?update=42
I took a chance and tried a different update number (i.e. update=36). Sure enough, via a simple URL change I was able to see and update another client's data.
Unreal. But it gets better! Wait until he messes with the 'upload' feature!
If I could upload a script, I could own the server. However, I took the simple non-intrusive non-exploit road and used a PHP script called PHP-Terminal, which is basically an emulator that gives the user "shell" access via a web browser. The limitations were only that the access is the same as the web application, thus I couldn't add users and the like. However, my target was the application - not the server.
Once I uploaded this file (after making a few changes to the PHP code), I was granted access to the server… and found a script called Create_admin.php…
How does he own the site?
Go read the article now and find out!
Lessons learned?
1) Secure coding practices are not optional - and have some peer (or outside) code review done.
2) Perform web application penetration tests on your application - or better yet, have someone else do it.
3) Consider using a program like WebInspect from SPI Dynamics to do automated testing for you.
4) Continue to test AFTER deployment!
The truth of the matter is that XSS attacks are lethal when combined with other web application vulnerabilities that involve cookies and session IDs.
I read a fascinating article over the weekend at informit.com. The author, Seth Fogie, does an admirable job of pulling the pants off of those that downplay XSS threats.
Seth walks us through an attack on a real web site management application that resulted in shell access on the web host, every administrator's worst nightmare.
From the article, the author walks us through the XSS vulnerability:
… the code put an unfiltered "$email" into an $error message (line 10) after a check_email_address function rejects the input. Unfortunately, the same $error message was then printed out onto the page, thus allowing an attacker to inject pretty much anything they want right into the content of the webpage - including JavaScript code.
Whoops! Somebody has web coder that needs a good hit with a clue banana.
As if fate wanted to make it challenging, the maximum size of the HTML input field for the email address was 25 characters, and it only accepted POST data, which is somewhat limiting. As a result, I had to "outsource" my cross-site scripting attack to a third server. The end result was that I had to make a user click on a link that first took the victim to my server. From there, the code on my server directed the victim to the web application with a POST value that included the XSS code, which was then fed into the login script.
Read that section again. Seth had a very small input field (25 characters) that only accepted POST data. Utilizing a third server, he led the unsuspecting user to his server via a web link and then sent the user to the 'real' server with a quick POST. This takes milliseconds. Would you notice if this happened to you?
Seth mentions burp proxy, which is one of my favorite tools to manipulate data (cough) session IDs (cough) going to a web server. See for yourself:
You can 'freeze' your web request before it is sent to the victim server, manipulate some variables, add some evil fun and then send the request along it's way. Try it on some of your favorite financial sites for lots of late night fun.
Okay, back to the attack. Seth describes manipulating the session ID:
I viewed the captured value (i.e. 810fcb55ded4c14f75a8a1b8807266b3) and then loaded up Firefox and changed the Connection Setting under Tools - Options - General tab. In this screen, I added an HTTP Proxy value of 127.0.0.1 and port 8080, the default for Burp.
Alright, we've got the session ID, and we've adjusted Firefox to use our running burp proxy as a man-in-the-middle manipulator. This is where Seth overwrites the new session ID with the one that worked earlier allowing us entry into the site:
Once the value was overwritten, I disabled the intercept feature (on burp -Ed) and hit the Forward button. At this point, I was given access to the client portion of the application…
Nice and easy. If you skip down a few paragraphs in the story, you'll catch a nice URL value manipulation test that just makes you want to slap your head and wonder who wrote the application that he's testing!
During the update, I noticed something that peaked my interest: in the Pending Updates section of the application, there is a list of all the updates that need to be completed. When an update is selected and loaded, the URL reads something like this:
http://client.targetsite.com/view_detail.php?update=42
I took a chance and tried a different update number (i.e. update=36). Sure enough, via a simple URL change I was able to see and update another client's data.
Unreal. But it gets better! Wait until he messes with the 'upload' feature!
If I could upload a script, I could own the server. However, I took the simple non-intrusive non-exploit road and used a PHP script called PHP-Terminal, which is basically an emulator that gives the user "shell" access via a web browser. The limitations were only that the access is the same as the web application, thus I couldn't add users and the like. However, my target was the application - not the server.
Once I uploaded this file (after making a few changes to the PHP code), I was granted access to the server… and found a script called Create_admin.php…
How does he own the site?
Go read the article now and find out!
Lessons learned?
1) Secure coding practices are not optional - and have some peer (or outside) code review done.
2) Perform web application penetration tests on your application - or better yet, have someone else do it.
3) Consider using a program like WebInspect from SPI Dynamics to do automated testing for you.
4) Continue to test AFTER deployment!
No comments: