diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b416ab..087a70d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -239,3 +239,8 @@ Cross-platform shell code generation * add more poc attribute to result dict * allow custom module path in console mode * fix some compatibility problems + +# version 1.8.0 +----------------- +* fix the timeout problem in shell mode leads to confusing results +* made some improvements with network address related issues diff --git a/manpages/poc-console.1 b/manpages/poc-console.1 index e4df22c9..486f68c1 100644 --- a/manpages/poc-console.1 +++ b/manpages/poc-console.1 @@ -31,7 +31,7 @@ is maintained at: .I https://github.com/knownsec/pocsuite3/blob/master/docs/USAGE.md .PP .SH VERSION -This manual page documents pocsuite version 1.7.8 +This manual page documents pocsuite version 1.8.0 .SH AUTHOR .br (c) 2014-2021 by Knownsec 404 Team diff --git a/manpages/pocsuite.1 b/manpages/pocsuite.1 index 9f7b89d7..5038b1ec 100644 --- a/manpages/pocsuite.1 +++ b/manpages/pocsuite.1 @@ -250,7 +250,7 @@ is maintained at: .I https://github.com/knownsec/pocsuite3/blob/master/docs/USAGE.md .PP .SH VERSION -This manual page documents pocsuite version 1.7.8 +This manual page documents pocsuite version 1.8.0 .SH AUTHOR .br (c) 2014-2021 by Knownsec 404 Team diff --git a/pocsuite3/__init__.py b/pocsuite3/__init__.py index ca3401f0..46c12585 100644 --- a/pocsuite3/__init__.py +++ b/pocsuite3/__init__.py @@ -1,5 +1,5 @@ __title__ = 'pocsuite' -__version__ = '1.7.8' +__version__ = '1.8.0' __author__ = 'Knownsec Security Team' __author_email__ = 's1@seebug.org' __license__ = 'GPL 2.0' diff --git a/pocsuite3/lib/core/common.py b/pocsuite3/lib/core/common.py index 78d4a03a..9d02b70b 100644 --- a/pocsuite3/lib/core/common.py +++ b/pocsuite3/lib/core/common.py @@ -12,6 +12,8 @@ import sys import time import collections +import chardet +import requests from collections import OrderedDict from functools import wraps from ipaddress import ip_address, ip_network @@ -19,9 +21,11 @@ from subprocess import call, Popen, PIPE from colorama.initialise import init as coloramainit from termcolor import colored - -import chardet -import requests +from scapy.all import ( + WINDOWS, + get_if_list, + get_if_addr +) from pocsuite3.lib.core.convert import stdout_encode from pocsuite3.lib.core.data import conf @@ -448,25 +452,46 @@ def is_local_ip(ip_string): return ret -def get_local_ip(all=False): - ips = list() - ips.append(get_host_ip()) - try: - for interface in socket.getaddrinfo(socket.gethostname(), None): - ip = interface[4][0] - ips.append(ip) - except Exception: - pass +def get_local_ip(all=True): + """Fetches all the local network address + """ + ips = OrderedSet() + wan_ipv4 = get_host_ip() + ips.add(wan_ipv4) + if not all: + return list(ips) + + wan_ipv6 = get_host_ipv6() + if wan_ipv6: + ips.add(wan_ipv6) + + if WINDOWS: + from scapy.all import IFACES + for iface in sorted(IFACES): + dev = IFACES[iface] + ips.add(dev.ip) + else: + for iface in get_if_list(): + ipv4 = get_if_addr(iface) + if ipv4 != '0.0.0.0': + ips.add(ipv4) + + return list(ips) - ips = list(set(ips)) - return ips if all else ips.pop(0) +def get_host_ip(dst='8.8.8.8'): + """ Fetches source ipv4 address when connect to dst + Args: + dst : target ip or domain + + Returns: + : source ip address + """ -def get_host_ip(): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.connect(('8.8.8.8', 80)) + s.connect((dst, 80)) ip = s.getsockname()[0] except Exception: ip = '127.0.0.1' @@ -807,7 +832,7 @@ def index_modules(modules_directory): modules = [] for root, _, files in os.walk(modules_directory): files = filter(lambda x: not x.startswith("__") and x.endswith(".py"), files) - modules.extend(map(lambda x: os.sep.join((root, os.path.splitext(x)[0])), files)) + modules.extend(map(lambda x: os.path.join(root, os.path.splitext(x)[0]), files)) return modules @@ -952,10 +977,19 @@ def encoder_powershell_payload(powershell: str): return command -def get_host_ipv6(): +def get_host_ipv6(dst='2001:db8::'): + """ Fetches source ipv6 address when connect to dst + + Args: + dst : target ip or domain + + Returns: + : source ipv6 address + """ + s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) try: - s.connect(('2001:db8::', 1027)) + s.connect((dst, 1027)) except socket.error: return None return s.getsockname()[0] diff --git a/pocsuite3/lib/core/interpreter.py b/pocsuite3/lib/core/interpreter.py index ca0e8981..ea129312 100644 --- a/pocsuite3/lib/core/interpreter.py +++ b/pocsuite3/lib/core/interpreter.py @@ -200,8 +200,7 @@ def __init__(self, module_directory=paths.POCSUITE_POCS_PATH): self.main_modules_dirs = [] for module in self.modules: temp_module = module - temp_module = temp_module.replace( - self.module_parent_directory, '').lstrip(os.sep) + temp_module = ltrim(temp_module, self.module_parent_directory).lstrip(os.sep) self.main_modules_dirs.append(temp_module) self.__parse_prompt() diff --git a/pocsuite3/lib/core/option.py b/pocsuite3/lib/core/option.py index 3d895fa9..e3b4ec29 100644 --- a/pocsuite3/lib/core/option.py +++ b/pocsuite3/lib/core/option.py @@ -15,7 +15,7 @@ from pocsuite3.lib.core.common import boldify_message, check_file, get_file_items, parse_target, \ get_public_type_members, data_to_stdout from pocsuite3.lib.core.common import check_path, extract_cookies -from pocsuite3.lib.core.common import get_local_ip, desensitization +from pocsuite3.lib.core.common import get_local_ip, desensitization, get_host_ip from pocsuite3.lib.core.common import single_time_warn_message from pocsuite3.lib.core.common import OrderedSet from pocsuite3.lib.core.convert import stdout_encode @@ -283,6 +283,7 @@ def _set_threads(): def _set_connect_back(): + wan_ipv4 = get_host_ip() ips = get_local_ip(all=True) if ips: kb.data.local_ips = ips @@ -290,7 +291,12 @@ def _set_connect_back(): data_to_stdout("[i] pocsusite is running in shell mode, you need to set connect back host:\n") message = '----- Local IP Address -----\n' for i, ip in enumerate(kb.data.local_ips): - message += "{0} {1}\n".format(i, desensitization(ip) if conf.ppt else ip) + v = ip + if conf.ppt: + v = desensitization(v) + if ip == wan_ipv4: + v = colored(f'{v} *wan*', 'green') + message += "{0} {1}\n".format(i, v) data_to_stdout(message) while True: choose = None diff --git a/pocsuite3/modules/httpserver/__init__.py b/pocsuite3/modules/httpserver/__init__.py index 2a54e971..c4d68fa6 100644 --- a/pocsuite3/modules/httpserver/__init__.py +++ b/pocsuite3/modules/httpserver/__init__.py @@ -140,10 +140,10 @@ def start(self, daemon=True): self.setDaemon(daemon) threading.Thread.start(self) # Detect http server is started or not + logger.info('Detect {} server is runing or not...'.format(self.scheme)) detect_count = 10 while detect_count: try: - logger.info('Detect {} server is runing or not...'.format(self.scheme)) if check_port(self.host_ip, self.bind_port): break except Exception as ex: diff --git a/pocsuite3/modules/listener/reverse_tcp.py b/pocsuite3/modules/listener/reverse_tcp.py index 366028ff..b41a3551 100644 --- a/pocsuite3/modules/listener/reverse_tcp.py +++ b/pocsuite3/modules/listener/reverse_tcp.py @@ -76,31 +76,30 @@ def listener_worker(): def list_clients(): results = '' for i, client in enumerate(kb.data.clients): - # try: - # client.conn.send(str.encode('uname\n')) - # time.sleep(0.01) - # ret = client.conn.recv(2048) - # if ret: - # ret = ret.decode('utf-8', errors="ignore") - # system = "unknown" - # if "darwin" in ret.lower(): - # system = "Darwin" - # elif "linux" in ret.lower(): - # system = "Linux" - # elif "uname" in ret.lower(): - # system = "Windows" - # - # except Exception as ex: # If a connection fails, remove it - # logger.exception(ex) - # del kb.data.clients[i] - # continue + try: + client.conn.send(str.encode('uname\n')) + time.sleep(0.2) + ret = client.conn.recv(2048) + if ret: + ret = ret.decode('utf-8', errors="ignore") + system = "unknown" + if "darwin" in ret.lower(): + system = "Darwin" + elif "linux" in ret.lower(): + system = "Linux" + elif "uname" in ret.lower(): + system = "Windows" + + except Exception as ex: # If a connection fails, remove it + logger.exception(ex) + del kb.data.clients[i] + continue results += ( str(i) + " " + (desensitization(client.address[0]) if conf.ppt else str(client.address[0])) + " " + - str(client.address[1]) + - # " ({0})".format(system) + + " ({0})".format(system) + '\n' ) data_to_stdout("----- Remote Clients -----" + "\n" + results) @@ -179,7 +178,7 @@ def send_shell_commands(client): break -def poll_cmd_execute(client, timeout=8): +def poll_cmd_execute(client, timeout=3): if has_poll(): p = select.poll() event_in_mask = select.POLLIN | select.POLLPRI @@ -191,7 +190,7 @@ def poll_cmd_execute(client, timeout=8): ret = '' while True: - events = p.poll(timeout) + events = p.poll(200) if events: event = events[0][1] if event & select.POLLERR: @@ -221,7 +220,7 @@ def poll_cmd_execute(client, timeout=8): count = 0 ret = '' while True: - ready = select.select([client.conn], [], [], 0.1) + ready = select.select([client.conn], [], [], 0.2) if ready[0]: ret += get_unicode(client.conn.recv(0x10000)) # ret += str(client.conn.recv(0x10000), "utf-8") diff --git a/setup.py b/setup.py index 415e68f1..73b22019 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ def find_packages(where='.'): setup( name='pocsuite3', - version='1.7.8', + version='1.8.0', url='http://pocsuite.org', description='Pocsuite is an open-sourced remote vulnerability testing framework developed by the Knownsec Security Team.', long_description="""\