It’s been a while – I have been crazy busy with work and life in general and unfortunately let the blog slip a little. All the plans I want to do are in the pipeline at some point. It’s just a case of finding the time!!
Anyway, today I give you a custom Metasploit module to add to your arsenal. Within MS SQL Server, there is a very easy way to elevate your privileges from the “Security Admin” server role. By default, the “Security Admin” role does not have permission to enable “xp_cmdshell” to allow you to get code execution on the machine. However, you can create new users. The user you create cannot be assigned a permission higher than the “Security Admin” (which makes sense). But what you can do is grant “Control Server” permissions instead.
I won’t go into detail on what the differences between “Control Server vs sysadmin” are here. But rest assured there are plenty of other blogs out there which highlight this / similar issues to what this Metasploit module exploits. With the “Control Server” permissions, you pretty much have the keys to the castle and have the ability to enable “xp_cmdshell” in order to get code execution.
I may be wrong, but I haven’t seen an equivalent Metasploit module for this? Anyway, I’ll just to give you a run down of what the script does:
Checks to see if the user has “securityadmin” role.
If so, then a new user is created.
Control Server permissions assigned to new user.
Then you will need to manually log in as your new user and enable xp_cmdshell.
So as you can see it’s straight forward. Installation instructions will be on the Github page.
If you would like to run these steps manually then these will be the steps after logging into SQL Server:
select is_srvrolemember('securityadmin') as IsSecAdmin
create login pwned with password=Password123!, check_policy=off;
grant control server to pwned;
It’s as simple as that.
Anyway, I hope this has helped someone. At some point I may change the script to automatically log in as the new user and then pwn using xp_cmdshell. This is my first go at a custom Metasploit module and I haven’t done a lot of Ruby yet, so it’ll be quite a nice project to continue with when I get the time.
I am currently in the process of developing another vulnerable machine (Windows) and had a plan/theme for what I wanted to do. While testing some various applications out for suitability I came across ADReset on GitHub.
ADReset was a cool application that would allow users to reset their password in a self service manner which is quite a typical thing in modern organisations. It was pretty simple to install and management was straight forward. Once configured, the Local Admin account (within ADReset) has the ability to create password reset questions and email resets. While testing around I stuck with the questions side of it.
While playing around and testing this application, I noticed a vulnerability which was very easy to exploit and essentially elevate yourself to any AD user account you want.
Elevation of privileges is accomplished through abusing the permissions granted to the “adresetuser” user in the MySQL backend which then allows you to do a password reset on any AD user account. So, in order for this to work you will need to know what these credentials are OR a MySQL user with insert access to one of the tables (emailreset). In my instance the file containing the credentials is located at “c:\inetpub\adreset\resources\core\init.php”. Additionally, it’s worth noting that the account you want to take over does NOT need to be registered for password resets.
Many users within a business may have the appropriate permissions, either through misconfiguration or by design with users such as Developers and DBA’s. So the point is, anyone who has the ability to insert a row into the “emailreset” table, can reset any AD users password.
First, we need to get the guid of the user we wish to conduct the password reset on. We can get this with the PowerShell command below. I have created a user jane_admin specifically for this demonstration.
Next we need to log into mysql then go into the adreset database.
Even though I do not have the email reset feature enabled – we still need to add an entry to the “emailreset” table.
Looking at the columns of the table.
Excluding “id” we have three fields to supply. “userguid” we have from the PowerShell command ran earlier. “code” can be anything we want and “createtime” should be set to NOW().
We need to craft an INSERT query to execute as follows:
INSERT INTO emailreset (userguid, code, createtime) VALUES ('971660b2-341e-4b2a-8169-99764935c1e6', 'blahblahblah', NOW())
After executing that, we simply need to head over to the new password page located at:
The user “jane_admin” does not have any secret questions set up and does not have email reset functionality enabled. However we are now prompted to supply a new password for her account.
As we can see, the “idq” value should be set the same as what we inserted into the “code” field on the INSERT query above. In this example it is “blahblahblah”.
I enter a new password and click “Set Password”. I then get a success message.
I then proceeded to log in as “jane_admin” to verify the new password I supplied actually works…and it did!!
So in a nutshell – if you have enough rights in MySQL (either adresetuser or another account), then you can very easily reset any users password regardless if they have set themselves up for password reset or not.
Due to the impact this potentially has to anyone currently using this solution, I did reach out privately to the developer at first and raised an Issue on GitHub. The developer has now since noted the application as “Not Maintained” and has also closed the Issue on GitHub after responding to the findings.
While I agree with the developer stating that the credentials should be guarded, we all know this is the ideal situation and in the wild, it unfortunately doesn’t always happen. I believe this is a vulnerability as anyone either finding the service account credentials or having another MySQL login which has the relevant permissions can essentially do what they want and end up with the keys to the castle.
A perfect example of this would be a DBA. A DBA logs into MySQL with their own set of credentials. This user has access to a whole host of databases including “adreset” and inserts a row into the table that allows them to reset the password of a domain admin account. A clear and plausible scenario of abusing the sql permissions to exploit the application and reset the password of anyone.
Yes I agree the likelihood for this attack may be low and the user has to have MySQL credentials, but the issue is still there. Whether the vulnerability lays within the the db config or the application doesn’t matter. Ultimately, both sides could be hardened to reduce this risk. If database access is compromised, your domain can also be compromised.
Just want to finish off by saying this is a cool application and clearly the developer put a lot of hard work into it. But if you read this and currently use it, please be weary of the above points and look to either mitigate, risk accept or implement fixes accordingly.
Ugen is the latest script I have added to my GitHub repository. It is nothing spectacular and is just a simple python script to transform a list of “firstname, lastnames” into potential username formats.
I made this script while working on a HTB Windows machine. The box had a webpage showing a list of employees (firstnames and lastnames) and I had no way of quickly and efficiently checking the username format they had chosen.
Names should be entered into a text file in the following format:
As you can see there are usually a number of manual steps to complete this privesc. However, if you find yourself in a position where you can use this exploit then simply running this script and passing the MySQL username and password will automate the process.
You may or may not have success with the root shell it attempts to open for you. In my experience I had to exit the shell it entered me in and return to the mysql instance before using the following commands to execute commands as root.
This was a quick Python script I put together to URL encode / decode lists.
Why did I create it?
This can have a lot of uses not just in pentesting / CTF exercises. The reason I made this in particular was because I was in a situation where I could not use a tool such as sqlmap to detect sql injection and instead of manually testing everything off my sql injection cheatsheet I could automate it with a tool like wfuzz.
Using Burp Intruder, you can upload a list and there is a tickbox option to automatically URL encode specific characters under Intruder >> Payloads >> Payload Encoding.
Now if you have the Community version of Burp, using Intruder like this can take a long time especially if you have a large list. It is simple enough to recreate the request for wfuzz (or similar) and use the output of this tool as your input file for wfuzz.
Soon I will be making a post on how to use tools such as wfuzz in order to look for SQL Injection without using a fully automated tool such as sqlmap.
Other ways of doing this?
There are lots of ways / scripts to do this and when you look online there are many encoders / decoders. However, what I found is that they all seem to encode the entire contents into a single line which doesn’t help you if you wanted to use it in an attack like mentioned above.
So I have been very busy with work lately among everyday life in these crazy times. Anyway this is just a quick post of a tool I created recently called RunAsUser (https://github.com/atthacks/RunAsUser).
What does it do?
During some CTF exercises I have been in a position where I have a low privilege shell on a machine and have found credentials for either another user or admin. Unlike Linux there isn’t a simple “su” switch user command for Windows.
This tool allows you you provide the credentials you found and execute a given program with arguments (optional).
Is there other ways to do this?
Yes there is. You can fairly easily accomplish this in PowerShell but in my experience and the CTF challenges I have used this tool on – I have usually had limited or no PowerShell access for one reason or another. In a cmd shell you can run applications as another user but again I have experienced issues with this in the past and not worked correctly.
On a lot of these machines there may be another way of utilising the credentials to pivot or escalate such as using them with Evil-WinRm. However in the instance that you are out of options, or as an alternative, this tool can help.
Where have you used it?
Most recently I have used it on HTB boxes JSON and ChatterBox.
On the JSON box, once you have a user shell you can obtain the “superadmin” credentials by decompiling a binary. The credentials are superadmin:funnyhtb. Now although there are other ways to root this particular machine, one avenue you can do it is via RunAsUser.
In the JSON instance I uploaded the RunAsUser.exe binary and then executed the following command.
The above command worked a treat and I got my reverse shell back as superadmin.
In the ChatterBox machine – this demonstrates another way you can use RunAsUser.
As we can see from from the winPEAS output, it found credentials for Alfred. Now some guides online port forward SMB and then use winexe to connect. Others use PowerShell and go through the process of creating a credential object and then using it with Start-Process to execute a command as that other user. This is how I did it:
RunAsUser supports command line arguments (shown in JSON example) and if no arguments are supplied it will walkthrough each step with you allowing you to enter them as seen in the picture above.
How does the tool work?
Its a very simple C# application that takes the arguments you supply and creates a process using those arguments supplied. The tool does the job and in the near future I will likely update it and tidy it up a bit.
This isn’t an every day tool but has certainly made my life easier on quite a few boxes now which is why I made it to be honest.
Anyway I hope this can help someone else. I have more tools and scripts I’ll be releasing soon.
Stay safe everyone 🙂
I have updated the GitHub page (https://github.com/atthacks/RunAsUser) to show an example of where “runas” does not work and “RunAsUser” does work. I created this tool for this exact reason. I was on a machine and had credentials and my initial thought was runas, however this would not work and kept skipping over the password prompt. I am aware there are other solutions to do the same thing, but I enjoyed making this quick tool and thought I would share it as it will hopefully be helpful to someone.
Firstly, thanks for being here. This blog is designed to share my knowledge and experience with the rest of the community.
This is my first post and I am still working on others (very busy at the moment). This blog is still under construction but I really wanted to get this out here 🙂
It was an idea that myself and @bootlesshacker came up with recently. We are currently collaborating on a new box together. Think the idea came after a few beers and has a unique kind of incentive. We have decided to reward the first person to complete the box including a detailed write-up with vouchers to TryHackMe (was put to a vote on bootlesshacker’s twitter).
The idea behind it is simple – both me and bootlesshacker care about giving to this community. By creating a box with the incentive, we hope to attract more people to try out the machine and share knowledge and experience with each other.
We understand this may put off some people just getting into CTF challenges, but we encourage everyone to have a go and get a feel for the box as we plan to release a series of them in the near future. Other boxes may have different prizes and we may review the process later.
So watch this space – soon we will have a shiny new box for you get cracking on!!
Thanks all and stay safe during these strange times.