Self Service AD Password Reset – Vulnerability

Application: ADReset (

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.

powershell { (get-aduser -identity jane_admin).ObjectGUID }

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.

Thanks for reading 🙂