Plaid Parliament of Pwning hosted their Plaid CTF 2013 event this past weekend and I participated with a number of other members from the SUNIYIT NCS club. This marks the first time that I’ve tried my skills at the Plaid event, and counts as one of only a few CTF events that I’ve been able to dedicate time to. I did make some significant progress on a few challenges but this post will highlight one of the challenges that I was able to fully complete with some of the other club members.
I recently finished my OSCP training and exam certification and he charsheet challenge ended up being right down my alley as being web app exploitation challenge. The challenge, as shown below (Fig 1), is to retrieve web site administrator’s character name.
Fig 1. My quest, should I choose to accept it
Clicking the link directed me to a website shown in Fig 2 which was “A web-based application for editing and storing RPG character sheets.”
Fig 2. Checking out my target
Since I knew that I was looking for a specific character, I immediately headed to the search link at the top of the page to see what my options looked like. I had a strange inkling that I’d be doing some SQL injection to retrieve my flag but I had to find out for sure. The search page was pretty simple: I could look for characters or campaigns.
Fig 3. Poking around
Naturally, I went straight to the search box to check if the search function escapes a single apostrophe.
Fig 4. Sweet, error details!
The site was nice enough to tell me that there was an error and, additionally, told me what query it was trying to execute. This provided information about the underlying database and field names required to craft a query that would retrieve the data I was after. The single apostrophe escape broke me out of the query at “LIKE UPPER (‘%’)” To add to this, the Character Search input box only allowed 20 characters for input, but this will be addressed later. First up was to figure out what to add to the query.
The error message showed a character table (c) and a campaign table (ca), along with interesting fields like c.id and c.public. I assumed that the administrator of the site would have created one of the first characters in the database so my custom query would check for characters with an id of 0 or 1. Additionally I figured that the character wouldn’t be publicly accessible so I also decided to check for private characters as well. I decided on the following injection:
‘) or c.id=1 and c.public like (‘n
This would escape me out of the LIKE UPPER matching, and complete the query normally on the other end at the LIKE UPPER match with the %’) part of the query. It would also query for any non-public characters with a character id of 1. With my injection, the server would execute the following:
SELECT c.id, c.cname, DATE_FORMAT(c.lastedited, ‘%d %M %Y @ %H:%i’) as lastedited, c.owner, st.name as tname, ca.name as caname FROM sheet_templates st, characters c LEFT JOIN campaign ca on ca.id = c.campaign WHERE c.public = ‘y’ AND c.template_id = st.id AND UPPER(c.cname) LIKE UPPER(‘‘) or c.id=1 and c.public like (‘n%’) ORDER BY UPPER(c.cname), UPPER(c.cname) LIMIT 15
However, I still had one more hurdle to overcome: the input limitation on the character search box. Thankfully, the search string is submitted via URL with the input name of cname, so I could pass my injection via URL instead of the search box. Figure 5 shows the URL after a blank search is submitted from the Character Search field.
Fig 5. URL after a blank character search
Thus, my injection was sent with the following URL request: http://184.108.40.206/search.php?type=begins&cname=’) or c.id=1 and c.public like (‘n
I was treated to the following results:
Fig 6. And there was much rejoicing
Submitting the character name r3al50ftwar3ftw rewarded the team with 150 points but no in-game items 🙁