Exemple #1
0
    def port_scan(self, ip: str, connect_timeout: int, ports: list,
                  isudp: bool, threads: int):
        logger.info(f"Start {'UDP' if isudp else 'TCP'} port scan on {ip}...")
        block_ports = []
        for i in range(0, len(ports), 10):  #每次检测10个端口
            block_ports.append(ports[i:i + 10])
        job = Worker(self._port_scan_handler, block_ports, threads)
        job.set_param(ip, connect_timeout, isudp)
        job.start()
        try:
            while job.is_running():
                workdone_count = 0
                opened_count = 0
                for v in job.current_vlist:
                    if v.solved:
                        opened_count += len(v.ret[0])
                        workdone_count += v.ret[1]
                per = int(workdone_count / len(ports) * 100)
                print(
                    f"Progress {per}% ({workdone_count}/{len(ports)}), {opened_count} opened ports on {ip}.",
                    end='\r',
                    flush=True)
                utils.sleep(0.3)
        except:
            job.stop()
            logger.warning("Work is over!")

        for v in job.current_vlist:  # 线程结束后统计
            if self._scan_result.get(ip) is None:
                self._scan_result[ip] = []
            self._scan_result[ip].extend(v.ret[0])
        logger.info(
            f"All {'UDP' if isudp else 'TCP'} ports have been detected, total `{len(self._scan_result[ip])}` opened on {ip}."
            + ' ' * 20)
Exemple #2
0
    def cmdloop(self):
        self.running = True
        thread_list = []
        keepthread = threading.Thread(target=self._keep_shell_alive,
                                      name="keep shell alive")
        shellthread = threading.Thread(target=self._shell, name="shell")
        readerthread = threading.Thread(target=self._reader, name="reader")
        keepthread.setDaemon(True)
        shellthread.setDaemon(True)
        readerthread.setDaemon(True)

        thread_list.append(keepthread)
        keepthread.start()
        utils.sleep(1)
        if self.running:
            thread_list.append(shellthread)
            thread_list.append(readerthread)
            shellthread.start()
        else:
            return

        utils.sleep(1)
        readerthread.start()
        try:
            if self.exp.session.server_info.isUnix(
            ) and self._is_supported_shell():
                logger.info(
                    'You can type `:getfshell` to upgrade to a fully interactive shell(The premise is that Pty has been obtained.)'
                )
                logger.info(
                    "Type `Ctrl + c` three times in a row to exit the fully interactive shell"
                )
            while self.running:
                cmd = utils.input()
                if not cmd:
                    continue
                if self.exp.session.server_info.isUnix(
                ) and cmd == ':getfshell' and self._is_supported_shell():
                    if not self.enter_fully_shell():
                        logger.error(
                            "Unable to get a fully interactive shell!")
                        continue
                    break
                self._writer(cmd + '\n')
        except KeyboardInterrupt:
            pass

        self.close()
        logger.info("Wait for thread exit...")
        for t in thread_list:
            t.join(5)
            if t.is_alive() and not utils.kill_thread(t.ident):
                logger.error(
                    f"Exit thread `{t.name}` failed, thread id is `{t.ident}`!"
                )
        logger.info("All have been cleaned up!")
Exemple #3
0
    def enter_fully_shell(self) -> bool:
        '''获取完全交互式shell,仅支持Unix(服务器和本机),需要首先获取一个tty
        '''
        self.writer('tty && echo -e "ok\\tok" || echo -e "not\\ta\\ttty"\n')
        msg = ''
        sign = False
        while True:
            self._lock.acquire()
            msg = self.last_recv
            self._lock.release()
            if msg is not None:
                if "not\ta\ttty" in msg:
                    logger.error("There is no Pty at present!")
                    break
                elif "ok\tok" in msg:
                    sign = True
                    break
            if not self.running:
                return False
            utils.sleep(0.1)
        if sign:
            rows = os.get_terminal_size().lines
            columns = os.get_terminal_size().columns
            term = os.environ.get('TERM', 'linux')
            self.writer(
                f'export TERM={term};export SHELL=bash;stty rows {rows} columns {columns}\n'
            )
            # 设置当前terminal
            termios = importlib.import_module('termios')
            tty = importlib.import_module('tty')
            fd = ioconfig.stdin.fileno()
            old = termios.tcgetattr(fd)
            new = old[:]
            new[3] &= ~termios.ECHO
            termios.tcsetattr(fd, termios.TCSANOW, new)
            tty.setraw(fd, termios.TCSANOW)
            logger.info("Now you have acquired a fully interactive shell!",
                        True)

            # 进入完全交互式shell
            exit_code = b''
            while self.running:
                cmd = ioconfig.stdin.getbytes()
                if cmd == b"\x03":
                    exit_code += b'\x03'
                else:
                    exit_code = b''
                if exit_code == b'\x03\x03\x03':
                    break
                self.writer(cmd)

            # 还原终端设置
            termios.tcsetattr(fd, termios.TCSANOW, old)
            return True
        return False
Exemple #4
0
    def host_survival_scan(self, hosts: str, timeout: int, threads: int,
                           host_detect_udp: bool):
        '''测试主机是否存活,timeout超时时间,单位毫秒
        '''
        logger.info("Start host survival detection...")
        if not host_detect_udp:  # 若使用ping扫描,则检查是否有ping命令使用权限
            ret = None
            if self.session.server_info.isWindows():
                ret = self.exec_command(
                    f'cmd /c "ping -n 1 -w {timeout} 127.0.0.1 && echo pingok"'
                )
            else:
                ret = self.exec_command(
                    f'ping -c 1 -W {timeout//1000} 127.0.0.1 && echo pingok')
            if ret is not None and 'pingok' in ret:
                logger.info("Ping scan is currently available!")
            else:
                logger.error(
                    "Currently, there is no permission to use ping command, or ping command does not exist!"
                )
                return
        block_hosts = []
        for i in range(0, len(hosts), 10):  #每次检测10个主机
            block_hosts.append(hosts[i:i + 10])
        job = Worker(
            self._host_survival_scan_handler_by_ping if not host_detect_udp
            else self._host_survival_scan_handler_by_udp, block_hosts, threads)
        job.set_param(timeout)
        job.start()
        try:
            while job.is_running():
                workdone_count = 0
                alive_count = 0
                for v in job.current_vlist:
                    if v.solved:
                        alive_count += len(v.ret[0])
                        workdone_count += v.ret[1]
                per = int(workdone_count / len(hosts) * 100)
                print(
                    f"Progress {per}% ({workdone_count}/{len(hosts)}), {alive_count} alive hosts.",
                    end='\r',
                    flush=True)
                utils.sleep(0.3)
        except:
            job.stop()
            logger.warning("Work is over!")

        for v in job.current_vlist:  # 线程结束后统计
            for ip in v.ret[0]:
                self._scan_result[ip] = []
        logger.info(
            f"All hosts have been detected, total `{len(self._scan_result)}` alive."
            + ' ' * 20)
Exemple #5
0
    def run(self):
        try:
            self.sock.bind((self.lhost, self.lport))
            self.sock.listen(self.max_listen_count)
        except OSError as e:
            logger.error(e)
            return
        thread_list = []
        while True:
            try:
                sock, addr = self.sock.accept()
            except OSError:
                break
            logger.info(f"A connection created!From {addr}")

            sock.setblocking(False)
            sessionid = utils.randomstr(16)
            self.connections[sessionid] = sock

            forwardwork = threading.Thread(
                target=self._forward,
                args=(sessionid, ),
                name=f"{sessionid}-forward on rule `{self._rule_name}`")
            readerthread = threading.Thread(
                target=self._reader,
                args=(sessionid, ),
                name=f"{sessionid}-reader on rule `{self._rule_name}`")
            writerthread = threading.Thread(
                target=self._writer,
                args=(sessionid, ),
                name=f"{sessionid}-writer on rule `{self._rule_name}`")
            thread_list.append(forwardwork)
            thread_list.append(readerthread)
            thread_list.append(writerthread)

            forwardwork.setDaemon(True)
            readerthread.setDaemon(True)
            writerthread.setDaemon(True)
            forwardwork.start()
            utils.sleep(1)
            readerthread.start()
            writerthread.start()

        for t in thread_list:
            t.join()
Exemple #6
0
    def run(self):
        thread_list = []
        sessionid = utils.randomstr(16)
        self.connections[sessionid] = None

        forwardwork = threading.Thread(target=self._forward,
                                       args=(sessionid, ))
        forwardwork.setDaemon(True)
        thread_list.append(forwardwork)
        forwardwork.start()
        utils.sleep(1)
        if self._test_connect(sessionid):
            sock = socket.socket()
            self.connections[sessionid] = sock
            sock.settimeout(5)
            try:
                sock.connect((self.lhost, self.lport))
            except OSError as e:
                logger.error(
                    f"Connect to `{self.lhost}:{self.lport}` on rule `{self._rule_name}` failed!"
                )
                logger.error(e.strerror)
                self._close(sessionid)
                for t in thread_list:
                    t.join()
                return

            sock.setblocking(False)
            readerthread = threading.Thread(target=self._reader,
                                            args=(sessionid, ),
                                            name=f"{self._rule_name}-reader")
            writerthread = threading.Thread(target=self._writer,
                                            args=(sessionid, ),
                                            name=f"{self._rule_name}-writer")
            readerthread.setDaemon(True)
            writerthread.setDaemon(True)
            thread_list.append(readerthread)
            thread_list.append(writerthread)
            readerthread.start()
            writerthread.start()

        for t in thread_list:
            t.join()
Exemple #7
0
    def cmdloop(self):
        self.running = True
        start_thread = threading.Thread(target=self.start_shell)
        reader_thread = threading.Thread(target=self.reader)
        thread_list = [start_thread, reader_thread]
        start_thread.setDaemon(True)
        reader_thread.setDaemon(True)
        start_thread.start()
        utils.sleep(1)
        reader_thread.start()

        try:
            if self.exp.session.server_info.isUnix(
            ) and self._is_supported_shell():
                logger.info(
                    'You can type `:getfshell` to upgrade to a fully interactive shell(The premise is that Pty has been obtained.)'
                )
                logger.info(
                    "Type `Ctrl + c` three times in a row to exit the fully interactive shell"
                )
            while self.running:
                cmd = utils.input()
                if not cmd:
                    continue
                if self.exp.session.server_info.isUnix(
                ) and cmd == ':getfshell' and self._is_supported_shell():
                    if not self.enter_fully_shell():
                        logger.error(
                            "Unable to get a fully interactive shell!")
                        continue
                    break
                self.writer(cmd + '\n')
        except KeyboardInterrupt:
            pass
        except BaseException as e:
            logger.error(e)

        self.close()
        for t in thread_list:
            t.join(5)
            if t.is_alive():
                utils.kill_thread(t.ident)