def __init__(self, name, type, source=None, subtype=None, case_id=None): self.name = name self.created = timestamp() self.type = type self.subtype = subtype self.source = source self.parent = None self.children = [] self.case_id = case_id self.tags = [] self.notes = [] self.data = {} if self.type == 'host': if is_ipv4(self.name): self.subtype = 'ipv4' elif is_ipv6(self.name): self.subtype = 'ipv6' elif is_fqdn(self.name): self.subtype = 'fqdn' else: warning('host type cannot be determined. must be one of: ipv4, ipv6, fqdn') self.subtype = 'unknown' elif self.type == 'hash': result = is_hash(self.name) if result is None: warning('hash is not a valid md5, sha1, sha256, or sha512') self.subtype = 'unknown' else: self.subtype = result
def sanity_check(self): if not super(HTTP_CONNECT, self).sanity_check(): return False if not self.config.has_option(self.get_module_configname(), "proxyip"): common.internal_print( "'proxyip' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not self.config.has_option(self.get_module_configname(), "proxyport"): common.internal_print( "'proxyport' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not common.is_ipv4( self.config.get(self.get_module_configname(), "proxyip") ) and not common.is_ipv6( self.config.get(self.get_module_configname(), "proxyip")): common.internal_print( "'proxyip' should be ipv4 or ipv6 address in '{0}' section". format(self.get_module_configname()), -1) return False return True
def get_intermediate_hop(self, config): if config.has_option(self.get_module_configname(), "proxyip"): if common.is_ipv4(config.get(self.get_module_configname(), "proxyip")) or common.is_ipv6(config.get(self.get_module_configname(), "proxyip")): remoteserverip = config.get(self.get_module_configname(), "proxyip") return remoteserverip return ""
def sanity_check(self): if not super(WebSocket, self).sanity_check(): return False if not self.config.has_option(self.get_module_configname(), "proxyip"): common.internal_print( "'proxyip' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not self.config.has_option(self.get_module_configname(), "proxyport"): common.internal_print( "'proxyport' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not common.is_ipv4( self.config.get(self.get_module_configname(), "proxyip") ) and not common.is_ipv6( self.config.get(self.get_module_configname(), "proxyip")): common.internal_print( "'proxyip' should be ipv4 or ipv6 address in '{0}' section". format(self.get_module_configname()), -1) return False if not self.config.has_option("Global", "remoteserverhost"): common.internal_print( "'remoteserverhost' option is missing from 'Global' section", -1) return False if not common.is_hostname(self.config.get( "Global", "remoteserverhost")) and not common.is_ipv4( self.config.get( "Global", "remoteserverhost")) and not common.is_ipv6( self.config.get("Global", "remoteserverhost")): common.internal_print( "'remoteserverhost' should be a hostname 'Global' section", -1) return False return True
def sanity_check(self): if not super(SOCKS, self).sanity_check(): return False if not self.config.has_option(self.get_module_configname(), "proxyip"): common.internal_print( "'proxyip' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not self.config.has_option(self.get_module_configname(), "proxyport"): common.internal_print( "'proxyport' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not common.is_ipv4( self.config.get(self.get_module_configname(), "proxyip") ) and not common.is_ipv6( self.config.get(self.get_module_configname(), "proxyip")): common.internal_print( "'proxyip' should be ipv4 or ipv6 address in '{0}' section". format(self.get_module_configname()), -1) return False if not self.config.has_option(self.get_module_configname(), "version"): common.internal_print( "'version' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False version = self.config.get(self.get_module_configname(), "version") if version == "5": if not self.config.has_option(self.get_module_configname(), "usernamev5"): common.internal_print( "'usernamev5' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False if not self.config.has_option(self.get_module_configname(), "passwordv5"): common.internal_print( "'passwordv5' option is missing from '{0}' section".format( self.get_module_configname()), -1) return False return True
def get_nameserver(self): if common.get_os_type() == common.OS_LINUX: f = open("/etc/resolv.conf", "r") content = f.read() f.close() for line in content.split("\n"): if line.replace(" ", "").replace("\t", "")[0:1] == "#": continue if line.find("nameserver") != -1: break nameserver = line[line.find("nameserver")+len("nameserver "):len(line)+line.find("nameserver")] if common.is_ipv4(nameserver) or common.is_ipv6(nameserver): return nameserver else: return None
def __init__(self, name, type, source=None, subtype=None, case_id=None): self.name = name self.created = timestamp() self.type = type self.subtype = subtype self.source = source self.parent = None self.children = [] self.case_id = case_id self.tags = [] self.notes = [] self.data = {} if self.subtype is None: if self.type == 'host': if is_ipv4(name): self.subtype = 'ipv4' elif is_ipv6(name): self.subtype = 'ipv6' elif is_fqdn(name): self.subtype = 'fqdn' else: warning('host subtype is not one of: ipv4, ipv6, fqdn') elif self.type == 'hash': hash_type = is_hash(name) if hash_type is None: warning('hash is not a valid md5, sha1, sha256, or sha512') else: self.subtype = hash_type elif self.type == 'user': self.subtype = 'account' elif self.type == 'email': self.subtype = 'account' elif self.type == 'btc': self.subtype = 'cryptocurrency address'
def socks_handshake(self, server_socket): version = self.config.get(self.get_module_configname(), "version") if (version == "4") or (version == "4a"): if self.config.has_option(self.get_module_configname(), "userid"): userid = self.config.get(self.get_module_configname(), "userid") + "\x00" else: userid = "\x00" if version == "4": server_socket.send( struct.pack( ">BBH4s", self.socks.SOCKS4_VERSION, self.socks.SOCKS4_CD, int( self.config.get(self.get_module_configname(), "serverport")), socket.inet_aton( self.config.get("Global", "remoteserverip"))) + userid) else: if self.config.has_option("Global", "remoteserverhost"): if not common.is_hostname( self.config.get("Global", "remoteserverhost")): common.internal_print( "[Global] remoteserverhost value is not a hostname", -1) return False domain = self.config.get("Global", "remoteserverhost") + "\x00" server_socket.send( struct.pack( ">BBH4s", self.socks.SOCKS4_VERSION, self.socks.SOCKS4_CD, int( self.config.get(self.get_module_configname(), "serverport")), socket.inet_aton("0.0.0.1")) + userid + domain) else: common.internal_print( "Missing remoteserverhost attribute from config [Global] section", -1) return False response = server_socket.recv(8) if (response[0:1] == self.socks.SOCKS4_OK) and ( response[1:2] == self.socks.SOCKS4_RESPONSES[0]): common.internal_print( "Connection was made through the proxy server", 1) else: if len(response) > 1: if (response[1:2] in self.socks.SOCKS4_RESPONSES): for i in range(len(self.socks.SOCKS4_RESPONSES)): if response[1:2] == self.socks.SOCKS4_RESPONSES[i]: common.internal_print( "Connection failed through the proxy server: {0}" .format( self.socks.SOCKS4_RESPONSES_STR[i]), -1) return False common.internal_print( "Connection failed through the proxy server: Unknown error", -1) return False if version == "5": # send greeting with auth method list greeting = struct.pack(">BB", self.socks.SOCKS5_VERSION, len(self.socks.SOCKS5_AUTH_METHODS)) for i in range(len(self.socks.SOCKS5_AUTH_METHODS)): greeting += self.socks.SOCKS5_AUTH_METHODS[i][0] server_socket.send(greeting) # receive response with selected auth method response = server_socket.recv(2) if (len(response) != 2) or (response[0:1] != chr( self.socks.SOCKS5_VERSION)): common.internal_print( "Connection failed through the proxy server: Unknown error", -1) return False if response[1:2] == self.socks.SOCKS5_REJECT_METHODS: common.internal_print( "Connection failed through the proxy server: Authentication methods rejected", -1) return False for i in range(len(self.socks.SOCKS5_AUTH_METHODS)): if response[1:2] == self.socks.SOCKS5_AUTH_METHODS[i][0]: if self.socks.SOCKS5_AUTH_METHODS[i][1](self.config, server_socket): if self.config.has_option("Global", "remoteserverhost"): remoteserverhost = self.config.get( "Global", "remoteserverhost") if not (common.is_hostname(remoteserverhost) or common.is_ipv4(remoteserverhost) or common.is_ipv6(remoteserverhost)): common.internal_print( "[Global] remoteserverhost value is not ipv4, ipv6 or a hostname", -1) return False else: common.internal_print( "Missing remoteserverhost attribute from config [Global] section", -1) return False if common.is_ipv4(remoteserverhost): host_type = self.socks.SOCKS5_ADDR_TYPE[0] connect_string = struct.pack( ">BBBB4sH", self.socks.SOCKS5_VERSION, self.socks.SOCKS5_CD, 0, host_type, socket.inet_aton(remoteserverhost), int( self.config.get( self.get_module_configname(), "serverport"))) if common.is_hostname(remoteserverhost): host_type = self.socks.SOCKS5_ADDR_TYPE[1] connect_string = struct.pack( ">BBBBB", self.socks.SOCKS5_VERSION, self.socks.SOCKS5_CD, 0, host_type, len(remoteserverhost)) connect_string += remoteserverhost + struct.pack( ">H", int( self.config.get( self.get_module_configname(), "serverport"))) if common.is_ipv6(remoteserverhost): host_type = self.socks.SOCKS5_ADDR_TYPE[2] connect_string = struct.pack( ">BBBB16sH", self.socks.SOCKS5_VERSION, self.socks.SOCKS5_CD, 0, host_type, socket.inet_pton(socket.AF_INET6, remoteserverhost), int( self.config.get( self.get_module_configname(), "serverport"))) server_socket.send(connect_string) response = server_socket.recv(4096) if (len(response) < 4) or (response[0:1] != chr( self.socks.SOCKS5_VERSION)): common.internal_print( "Connection failed through the proxy server: Connection error to the server", -1) return False if response[1:2] == self.socks.SOCKS5_RESPONSES[0]: return True if response[1:2] not in self.socks.SOCKS5_RESPONSES: common.internal_print( "Connection failed through the proxy server: Unknown error code", -1) return False for i in range(len(self.socks.SOCKS5_RESPONSES)): if response[1:2] == self.socks.SOCKS5_RESPONSES[i]: common.internal_print( "Connection failed through the proxy server: {0}" .format( self.socks.SOCKS5_RESPONSES_STR[i]), -1) return False return False else: return False common.internal_print( "Connection failed through the proxy server: Strange response (Authentication method)", -1) return False return True
def __init__(self, argv): self.verbosity = 0 self.configfile = "xfltreat.conf" self.servermode = 0 self.clientmode = 0 self.checkmode = 0 self.short = "hsc" self.long = ["help", "server", "client", "check", "config=", "verbose="] self.forbidden_modules = ["Generic_module", "Stateful_module", "Stateless_module"] self.forbidden_modules_instance = [Generic_module, Stateful_module, Stateless_module] self.banner() try: opts, args = getopt.getopt(argv, self.short, self.long) except getopt.GetoptError: self.usage() exit(-1) for opt, arg in opts: if opt in ("-h", "--help"): self.usage() exit(0) elif opt in ("-s", "--server"): self.servermode = 1 elif opt in ("-c", "--client"): self.clientmode = 1 elif opt in ("--check"): self.checkmode = 1 elif opt in ("--config"): self.configfile = arg elif opt in ("--verbose"): try: self.verbosity = int(arg) except: common.internal_print("Invalid verbose value: {0}".format(arg), -1) exit(-1) if (not self.clientmode and not self.checkmode): self.servermode = 1 # checking for the config file if not os.path.isfile(self.configfile): common.internal_print("config file missing!", -1) exit(-1) # Looking for and parsing config file. common.internal_print("Parsing config file") config = ConfigParser.ConfigParser() try: config.read(self.configfile) except: common.internal_print("Invalid or malformed configuration file specified", -1) exit(-1) if not common.config_sanity_check(config, (self.servermode or (not self.clientmode and not self.checkmode))): exit(-1) # Loading modules from modules/ directory # 1. listing and loading all modules except forbidden ones common.internal_print("Loading all modules from 'modules' directory") for module in os.listdir("./modules/"): if module == '__init__.py' or module[-3:] != '.py' or (module[:-3] in self.forbidden_modules): continue module_list = __import__("modules."+module[:-3], locals(), globals()) modules = [] for m in dir(module_list): # 2. going thru all the modules if m != 'Generic_module' and m[:2] != "__": module_attributes = getattr(module_list, m) # 3. get the classes from the modules module_classes = [c for c in module_attributes.__dict__.values() if inspect.isclass(c)] # 4. select classes that are XFLTReaT modules real_modules = [c for c in module_classes if (issubclass(c, Generic_module) and (c not in self.forbidden_modules_instance))] for r in real_modules: # 5. actual instantiation of a module modules.append(r()) # if the module is enabled from config, we make store it in modules_enabled[] modules_enabled = [] for m in modules: enabled = "no" if not config.has_section(m.get_module_configname()): common.internal_print("No section in config for module: {0}".format(m.get_module_configname()), -1) continue enabled = config.get(m.get_module_configname(), "enabled") if enabled == "yes": # looks like the module is enabled, adding to modules|_enabled[] modules_enabled.append(m) # check if more than one module is enabled for client mode if self.clientmode and (len(modules_enabled)>1): common.internal_print("In client mode only one module can be used.", -1) exit(-1) # One Interface to rule them all, One Interface to find them, # One Interface to bring them all and in the darkness bind them common.internal_print("Setting up interface") interface = Interface() # Operating in server mode if self.servermode: server_tunnel = interface.tun_alloc(config.get("Global", "serverif"), interface.IFF_TUN|interface.IFF_NO_PI) interface.set_ip_address(config.get("Global", "serverif"), config.get("Global", "serverip"), config.get("Global", "servernetmask")) interface.set_mtu(config.get("Global", "serverif"), int(config.get("Global", "mtu"))) # start thread with socket-interface related pipes ps = PacketSelector(server_tunnel) ps.start() # Operating in client mode if self.clientmode: client_tunnel = interface.tun_alloc(config.get("Global", "clientif"), interface.IFF_TUN|interface.IFF_NO_PI) interface.set_ip_address(config.get("Global", "clientif"), config.get("Global", "clientip"), config.get("Global", "clientnetmask")) interface.set_default_route(config.get("Global", "remoteserverip"), config.get("Global", "serverip")) interface.set_mtu(config.get("Global", "clientif"), int(config.get("Global", "mtu"))) module_threads = [] module_thread_num = 0 for m in modules_enabled: if (self.servermode or (not self.clientmode and not self.checkmode)): module_thread_num = module_thread_num + 1 m.__init_thread__(module_thread_num, config, server_tunnel, ps, self.verbosity) m.start() module_threads.append(m) if self.clientmode: try: remoteserverip = config.get("Global", "remoteserverip") if not config.has_section(m.get_module_configname()): common.internal_print("No section in config for module: {0}".format(m.get_module_configname()), -1) continue if config.has_option(m.get_module_configname(), "proxyip"): if common.is_ipv4(config.get(m.get_module_configname(), "proxyip")) or common.is_ipv6(config.get(m.get_module_configname(), "proxyip")): remoteserverip = config.get(m.get_module_configname(), "proxyip") m.__init_thread__(0, config, client_tunnel, None, self.verbosity) if config.has_option(m.get_module_configname(), "proxyip"): interface.set_proxy_route(config.get("Global", "remoteserverip"), remoteserverip) m.client() interface.close_tunnel(client_tunnel) interface.restore_routes(remoteserverip) except KeyboardInterrupt: interface.close_tunnel(client_tunnel) interface.restore_routes(remoteserverip) pass except socket.error as e: interface.close_tunnel(client_tunnel) interface.restore_routes(remoteserverip) if e.errno == errno.ECONNREFUSED: common.internal_print("Socket does not seem to answer.", -1) else: common.internal_print("Socket died, probably the server went down.", -1) except: interface.close_tunnel(client_tunnel) interface.restore_routes(remoteserverip) raise if self.checkmode: m.__init_thread__(0, config, None, None, self.verbosity) try: m.check() except KeyboardInterrupt: pass # if not module_threads: common.internal_print("Exiting...") if (self.servermode or (not self.clientmode and not self.checkmode)): ps.stop() else: try: common.internal_print("Please use CTRL+C to exit...") while True: time.sleep(1000) except KeyboardInterrupt: common.internal_print("Interrupted. Exiting...") ps.stop() for t in module_threads: t.stop()