Sunday, April 1, 2018

Basic SQL Injection and XSS : OWASP Juice Shop and Beyond!

I've been learning how to use Burp Suite to speed up things I used to script. It's not a complete replacement for all projects (see my previous post about about shuffling MMS messages around, or polling scripts to alert me to changes in an upload folder, for example) but it's fantastic so far. A wonderful place to test has been OWASP Juice Shop, an intentionally vulnerable Javascript-based site, which has a score board for the various vulnerabilities found by its users.

One challenge was to find a hidden language file. It was easy to find the directory where the other language files were kept (and thus get the format of the file name, es_ES.json), but significantly more difficult to automate iterating over 4000 or more known language codes such as cs_CZ or es_ES to wait for a 200 OK status to come back.  I would have normally used a Python script here, but it could be tried in Burp Suite's "repeater" tool instead by loading the language codes into a payload and then running a custom packet (although, maybe not: the tricky part would be in the case of fictional languages that may not have a country code associated with it, so random 2-letter combinations may be brute forced faster with a script. Not sure - let me know in the comments if there's a Burp Suite way instead).

Long story short, Juice Shop is great practice tool... but what about other sites?

Hotel Rate and Hidden Variables


One hotel's reservation page can be edited so that it charges an incorrect room rate. This happens by editing two variables; one javascript variable for islovelyrate can be set to true, and, likewise, the lovelyrate variable can be set to any number. The islovelyrate variable forces a recalculation of the price just before the payment page, which then uses whatever rate amount the client-side code provided. There may be further server-side validation to prevent the bad amount from going through, but I stopped short of entering payment information, so I don't know.

Rental Site - SQLi, PHP


This one is full of fascinating issues. It is vulnerable to SQL injection, and has verbose SQL and PHP errors, which lead to finding the publicly readable directories where the .php files are stored. This included old copies of the PHP scripts, labeled as "reserve.php OLD" as opposed to "reserve.php". Because the file extension wasn't .php, the server allowed me to download and view the code in the old copies, instead of executing the PHP. It turns out that the old code must be very similar to the new version, because it was vulnerable to the same attacks that the old one was. The scripts included parameter names for PHP session variables, full SQL queries, other directories on the server, etc. Luckily no credentials were hard coded. Errors from trying to run PHP scripts as one-offs lead to more verbose errors which lead to several more readable directories with PHP scripts, including the admin section, and scripts for sending SMS to guests from the site (which functioned, as demonstrated with a temporary phone number). There was little to no input validation, so the product could be reserved for dates with a sooner start date than ending date, causing the product's final cost to be calculated as 0.00. Additionally, there were no upper bounds on date, so trying to get a quote for Dec 1, 1500 to Dec 1, 2020 seemed to cause a soft crash for a little while.

This site's one saving grace is that it did not allow me to upload my own file to one of these seemingly wide-open directories, despite the HTTP OPTIONS request returning POST. However, with a little more effort, I'm almost positive there would be a way to.

Organization - XSS, SQLi


This one was unusual. The SQL error returned revealed that the URL parameter passed to it was being used in various parts of the query in different ways, sometimes as a part of a column name, table name, or in the where clause parameter itself. I don't think I've ever seen that before, and at first, it was difficult to see how to SQL inject something like this. It was interesting that there were a lot of joins in the query, which showed a lot of table names. Other pages where more easily SQL injectable (with things like ‘ or ‘1’=‘1 (I couldn’t escape the end of the query with a - - comment, so I used the ending apostrophe). On one of these pages with a simpler query, I was able to SQL inject with a UNION which returned a different table's data (despite it only being designed to return one value, it luckily listed all of them). I got a privilege error when my output command failed to write the results to a file (which is okay because it was already displaying multiple results), but that gave me the current database user's account name.

A simple XSS attack worked in the search box of the site, mainly because it caused a SQL error which then executed the contents of the <script> tag when it displayed. I wonder if I would be able to insert the script tag so it would persist in the database, and execute for other users.