Example #1
0
    def exec(self, cmdline: str) -> str:
        '''在服务器上执行命令并获取结果
        '''
        fl = [self.method]
        if self.method in ('auto', None, ''):
            fl = [
                'exec', 'shell_exec', 'system', 'passthru', 'popen',
                'proc_open', 'wscript'
            ]
        for f in fl:
            tmp = self.exp.evalfile(f'php/{f}',
                                    cmd=cmdline,
                                    pwd=self.exp.session.pwd)
            if not tmp.is_success():
                return None
            r = json.loads(tmp.data)
            if r['code'] == 0:
                continue
            self.method = f
            result = base64.b64decode(r['result'].encode()).decode(
                self.exp.session.client.options.encoding, 'ignore')
            return result

        logger.warning(
            'No way to exec command!Maybe all functions is disabled.')
        return None
Example #2
0
    def run(self, args: Cmdline) -> int:
        args = self.parse.parse_args(args.options)

        text = self.load_config(self._name)
        if text is None:
            logger.warning("There is currently no memo!Will create a new.")
            text = {'note': ''}

        text = text['note']
        raw_text = base64.b64decode(text.encode())
        with tempfile.TemporaryDirectory() as tmpdir:
            path = os.path.join(tmpdir, 'note')
            with open(path, 'wb') as f:
                f.write(raw_text)

            if os.system(f"{config.editor} {path}") != 0:
                logger.error(
                    f"Run editor `{config.editor}` failed!The editor must edit file in console like `vim filename` or `notepad filename`"
                )
                logger.info(
                    f"You can change editor in config file `{os.path.join(config.root_path, 'config.py')}`"
                )
                return self.STOP
            with open(path, 'rb') as f:
                text = f.read()
            if text == raw_text:
                logger.warning(
                    'The content has not been changed, so it has not been saved!'
                )
            else:
                self.save_config(self._name,
                                 {'note': base64.b64encode(text).decode()})
                logger.info("Content has been updated!", True)
        return self.SUCCESS
Example #3
0
 def put(self, kanban_id, issue_id):
     request.get_json(force=True)
     if api.payload is None or api.payload == {}:
         return {"response": "Unable to decode payload"}, 400
     if (api.payload["stage"].replace(" ", "") == ""
             or api.payload["stage"] == "string"):
         return {
             "response": "Stage cannot be null or whitespaces only"
         }, 400
     elif api.payload["stage"] not in [stage.value for stage in Stages]:
         return {
             "response":
             "Stage cannot be anything other than todo, done or doing"
         }, 400
     issue_stage_hand = IssueStageHandler()
     logger.info(f"Changing issue with id {issue_id} current stage")
     try:
         issue_stage_hand.change_stage(
             kanbans_directory=config.kanbans_directory,
             kanban_id=kanban_id,
             issue_id=issue_id,
             stage_to_assign=api.payload["stage"],
         )
         return {}, 204
     except AttributeError:
         logger.error(
             f"Issue is not set to any stage! Check issue config xml")
         return {"response": "Issue is not set to any stage"}, 500
     except FileNotFoundError:
         logger.warning("Issue couldn't be found")
         return {"response": "Issue id not found"}, 400
     except Exception as e:
         logger.error("Couldn't update issue stage!")
         logger.exception(e)
         return {"response": "Unable to update issue stage"}, 500
Example #4
0
 def get(self, kanban_id):
     """ Return all issues info for given kanban board """
     kanban_finder = KanbanFinder()
     logger.info(f"Fetching kanban directory with id {kanban_id}")
     kanban_directory, kanban_check = kanban_finder.find_kanban_dir_with_id(
         kanban_id=kanban_id, kanbans_directory=config.kanbans_directory)
     logger.info(f"Kanban directory {kanban_directory}")
     if kanban_check:
         issue_finder = IssueFinder()
         try:
             logger.info(
                 f"Fetching all issues for kanban with id {kanban_id}")
             all_issues_info_list = issue_finder.return_all_issues_info_for_kanban(
                 kanbans_directory=config.kanbans_directory,
                 kanban_id=kanban_id)
             response = jsonify(all_issues_info_list)
             response.headers.add("Access-Control-Allow-Origin", "*")
             return response
         except Exception as e:
             logger.error("Unable to fetch issues!")
             logger.exception(e)
             return {"response": "Unable to fetch issues"}, 500
     else:
         logger.warning(
             f"Unable to fetch issues! Kanban with id {kanban_id} not found"
         )
         return {"response": "Kanban id not found"}, 400
Example #5
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)
Example #6
0
 def run(self, args: Cmdline)-> int:
     args = self.parse.parse_args(args.options)
     ret = self.SUCCESS
     if args.add:
         lhost = args.lhost if args.lhost else None
         lport = args.lport if args.lport else None
         rhost = args.rhost if args.rhost else None
         rport = args.rport if args.rport else None
         lf = True if args.L else (False if args.R else None)
         uploadsize = args.uploadsize
         info = (lhost, lport, rhost, rport, lf, uploadsize)
         if None in info:
             logger.error("Some options are not set.Check you input.")
             return self.STOP
         ret = self._add(*info)
     elif args.flush:
         for ID in args.flush:
             rule = self._forward_list.get(ID)
             if rule:
                 self._flush(ID)
             else:
                 logger.warning(f"No specified rules `{ID}`!")
     elif args.delete:
         self._delete(args.delete)
     else:
         ret = self._list()
     return ret
Example #7
0
 def delete(self, kanban_id, issue_id):
     """ Deletes issue for given kanban """
     kanban_finder = KanbanFinder()
     logger.info(f"Fetching kanban directory with id {kanban_id}")
     kanban_directory, kanban_check = kanban_finder.find_kanban_dir_with_id(
         kanban_id=kanban_id, kanbans_directory=config.kanbans_directory)
     logger.info(f"Kanban directory {kanban_directory}")
     if kanban_check:
         try:
             issue_deleter = IssueDeleter()
             issue_deleter.delete_issue_for_kanban(
                 kanbans_directory=config.kanbans_directory,
                 kanban_id=kanban_id,
                 issue_id=issue_id,
             )
         except FileNotFoundError as fe:
             logger.warning(
                 f"Unable to update issues! Issue with id {issue_id} not found"
             )
             logger.exception(fe)
             return {"response": "Issue id not found"}, 400
         except Exception as e:
             logger.error("Couldn't update issue")
             logger.exception(e)
             return {"response": "Couldn't update issue"}, 500
         return 204
     else:
         logger.warning(
             f"Unable to fetch issues! Kanban with id {kanban_id} not found"
         )
         return {"response": "Kanban id not found"}, 400
Example #8
0
    def _forward(self, sessionid: str):
        '''执行前需要把webshell超时时间设置为无限
        '''
        self.exp.session.client.options.set_temp_option('timeout', 0)
        self.exp.session.client.options.set_temp_option('verbose', 1)
        ret = self.exp.evalfile('forward/forward',
                                rhost=self.rhost,
                                rport=self.rport,
                                sessionid=sessionid)
        ret = ret.data
        if ret is None:
            logger.warning(
                "Forward request has exit!If forwarding is still working, please ignore this warning."
            )
            return
        ret = json.loads(ret)
        if ret['code'] == -1:  # connect failed
            error = base64.b64decode(ret['msg'].encode()).decode(
                self.exp.session.client.options.encoding, 'ignore')
            logger.error(error)
        elif ret['code'] == 1:
            logger.info(
                f"Connection has closed successfully for id `{sessionid}`!",
                False)

        self._close(sessionid)
Example #9
0
    def post(self, kanban_id):
        request.get_json(force=True)
        if api.payload is None or api.payload == {}:
            return {"response": "Unable to decode payload"}, 400

        try:
            if (api.payload["name"].replace(" ", "") == ""
                    or api.payload["creator"].replace(" ", "") == ""):
                return {
                    "response":
                    "Name/creator cannot be null or whitespaces only"
                }, 400
        except KeyError as ke:
            logger.exception(ke)
            return {"response": "Name/description is missing"}, 400

        logger.info("Creating issue xml config")
        issue_creator = IssueCreator()

        try:
            logger.info("Creating issue directory if needed")
            issue_creator.create_issue_folder(
                kanbans_directory=config.kanbans_directory,
                kanban_id=kanban_id)
        except FileNotFoundError as fe:
            logger.error(f"Unable to create issue directory! "
                         f"Kanban with id {kanban_id} doesn't exist")
            logger.exception(fe)
            return {"response": "Kanban id not found"}, 400
        except Exception as e:
            logger.error("Unable to create issues directory!")
            logger.exception(e)
            return {"response": "Unable to create issues directory!"}, 500

        try:
            logger.info("Creating new issue")
            issue_creator.create_new_issue_config(
                kanbans_directory=config.kanbans_directory,
                kanban_id=kanban_id,
                issue_description=api.payload["description"],
                issue_name=api.payload["name"],
                creator=api.payload["creator"],
            )
            return {
                "response":
                f"Issue with name {api.payload['name']} for kanban with id {kanban_id} created!"
            }, 201
        except FileExistsError as fe:
            logger.warning("Issue already exists!")
            return {
                "response": "Unable to create new issue!",
                "exception": str(fe),
            }, 500
        except Exception as e:
            logger.error("Unable to create issue!")
            logger.exception(e)
            return {"response": "Unable to create new issue!"}, 500
Example #10
0
 def _upload(self, remote: str, data: bytes, force: bool,
             uploadsize: int) -> int:
     '''将数据写入到远程文件
     '''
     sign = 1 if force else 0
     total = math.ceil(len(data) / uploadsize) if uploadsize > 0 else 1
     progress = 0
     while data:
         block = data[:uploadsize] if uploadsize > 0 else data
         data = data[uploadsize:] if uploadsize > 0 else b''
         ret = self.evalfile('upload',
                             pwd=self.session.pwd,
                             path=remote,
                             data=block,
                             sign=sign)
         sign = 2
         ret = ret.data
         while ret is None:
             if total > 1:  # 如果分片上传时失败,则重传一次该分片
                 ret = self.evalfile('upload',
                                     pwd=self.session.pwd,
                                     path=remote,
                                     data=block,
                                     sign=sign)
                 if ret.is_success():
                     ret = ret.data
                     break
             logger.error("upload file error!")
             return self.STOP
         if ret == '0':
             logger.warning(f"Remote file `{remote}` is exist.")
             if utils.input("Are you sure to overwrite the file? (y/n) "
                            ).lower() == 'y':
                 return self._upload(remote, block + data, True, uploadsize)
         elif ret == '-1':
             logger.error("Remote file open failed!")
             logger.error(
                 'Check if the path is correct or if you have write permission.'
             )
             return self.STOP
         elif ret == '1':
             if total > 1:
                 progress += 1
                 per = str(int(progress / total * 100)) + '%'
                 per = per.rjust(4, ' ')
                 print(f"Upload progress {per} ({progress}/{total}).",
                       end='\r',
                       flush=True)
             continue
         else:
             logger.error("Unknow error!")
             return self.STOP
     logger.info(f"Upload file `{remote}` successfully!")
     return self.SUCCESS
Example #11
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)
Example #12
0
 def _delete(self, id_list: list):
     if not id_list:
         return
     logger.info("Deleting the specified forwarding rules...")
     for ID in id_list:
         rule = self._forward_list.get(ID)
         if rule:
             if rule['forwd']:
                 rule['forwd'].close()
             self._forward_list.pop(ID)
             logger.info(f"Delete a forward rule `{ID}`", False)
         else:
             logger.warning(f"No specified rules `{ID}`!")
Example #13
0
 def _close(self, sessionid: str):
     self.lock.acquire()
     if sessionid in self.connections:
         sock = self.connections.pop(sessionid)
         if sock:
             try:
                 sock.shutdown(socket.SHUT_RDWR)
             except OSError:
                 pass
             sock.close()
         self.exp.evalfile('reverse/close', sessionid=sessionid)
         logger.warning('Connection is closed!')
     self.lock.release()
Example #14
0
 def _close(self, sessionid: str):
     self.lock.acquire()
     if sessionid in self.connections:
         client = self.connections.pop(sessionid)
         if client:
             try:
                 client.shutdown(socket.SHUT_RDWR)
             except OSError:
                 pass
             client.close()
         self.exp.evalfile('forward/close', sessionid=sessionid)
         logger.warning('Connection is closed!')
     self.lock.release()
Example #15
0
 def _error_handler(self, error: dict, result: EvalResult)-> bool:
     '''处理webshell返回的错误信息
     '''
     if error['code'] != 1:
         for msg in error['msg']:
             err = self.EvalError(msg[0], base64.b64decode(msg[1].encode()).decode(self.options.encoding, 'ignore'), 
                 True if error['code'] == 0 or msg[2] else False, True)
             result.add_error_info(err)
             if err.iswarning and self.options.verbose > 1:
                 logger.warning(err)
             elif not err.iswarning and self.options.verbose > 0:
                 logger.error(err)
         if error['code'] == -1:
             return False
     return True
Example #16
0
    def run(self, args: Cmdline) -> int:
        args = self.parse.parse_args(args.options)
        if args.interactive:
            self.interactive(args.interactive, args.type)
        elif args.show_methods:
            self.show_methods()
        elif args.executor_method:
            self.executor.method = args.executor_method
            self.show_methods()
        elif args.command == '':
            logger.warning("You entered an empty command!")
        else:
            self.exec(args.command, args.raw_executor)

        return self.SUCCESS
Example #17
0
    def get(self, kanban_id):
        """Returns kanban board with given id"""
        kanban_finder = KanbanFinder()
        logger.info(f"Fetching kanban with id {kanban_id} info")
        kanban_directory, kanban_found = kanban_finder.find_kanban_dir_with_id(
            kanban_id=kanban_id, kanbans_directory=config.kanbans_directory)

        if kanban_found:
            kanban_info_list = kanban_finder.return_kanban_info(
                kanban_directory=kanban_directory)
            response = jsonify(kanban_info_list)
            response.headers.add("Access-Control-Allow-Origin", "*")
            return response
        else:
            logger.warning(f"Kanban with id {kanban_id} not found!")
            return {"response": "Kanban id not found"}, 400
Example #18
0
    def _create_from_client(self, session: Session, nosave: bool,
                            save_id: int) -> int:
        '''从指定session中的webshell client建立连接
        '''
        webshell = session.client
        if webshell is None:
            logger.error('You must use a webshell client first.')
            return self.STOP
        if len(webshell.options.unset_list()) > 0:  # 检测选项设置
            logger.error("There are some unset options!")
            return self.STOP
        # explot 当前目标
        if webshell.connect():
            ID = 1 if len(self.manager.session_map) == 0 else max(
                self.manager.session_map) + 1
            s = WebshellSession(webshell, ID)
            self.manager.session_map[ID] = s
            if save_id:
                s.state['save_id'] = save_id  # 表示该session是从保存的连接建立的
            if isinstance(session, MainSession):
                session.client = None
                session[
                    'Prompt'] = lambda: f"{colour.colorize(config.app_name, 'underline')} {colour.colorize(config.prompt, fore='blue')} "
            logger.info(f'A session is created, id is `{ID}`', True)

            if not nosave:  # 存储建立的连接
                self._save(s)
            else:
                s.state['nosave'] = True  # 给session增加一个不保存的标志

            webshell.hook_start(s)
            s['Prompt'] = lambda :colour.colorize(s.server_info.domain+'\\'+s.server_info.user, 'bold', 'cyan')+'@'+\
                colour.colorize(s.state['name'], fore='purple')+\
                ':'+f"({colour.colorize(s.pwd, fore='red')})"+' \n'+colour.colorize(config.prompt, 'bold', 'blue')+' '
            self.manager.loadexploit_to_session(
                self.manager.modules.get('exploit', {}), 'exploit', s)  # 载入命令
            # 全部命令加载成功后调用命令回调
            s._hook_loaded()
            webshell.hook_loaded()
            self.manager.exec(["sessions", '-i', str(ID)])
            return self.SUCCESS

        logger.warning("Session create failed!")
        return self.STOP
Example #19
0
 def delete(self, kanban_id):
     """ Delete kanban board with given id """
     logger.info(f"Deleting kanban with id {kanban_id}")
     try:
         kanban_deleter = KanbanDeleter()
         kanban_deleter.delete_kanban(
             kanbans_directory=config.kanbans_directory,
             kanban_id=kanban_id)
         return {"response": "Kanban deleted"}, 204
     except FileNotFoundError:
         logger.warning(f"Kanban with id {kanban_id} not found")
         return {"response": "Kanban id not found"}, 400
     except Exception as e:
         logger.error("Unable to delte kanban")
         logger.exception(e)
         return {
             "response": "Unable to delte kanban",
             "exception": str(e)
         }, 500
Example #20
0
 def run(self, args: Cmdline) -> int:
     args = self.parse.parse_args(args.options)
     local = args.local
     if local is None:
         local = utils.pathsplit(args.source)[1]
     local = local.replace('/', os.sep)
     local = os.path.join(config.work_path, local)
     d, fname = utils.pathsplit(args.source)
     if os.path.exists(local):
         if os.path.isfile(local):
             logger.warning(f"Local file `{local}` is exist.")
             if utils.input(
                     colour.colorize("Are you sure to overwrite it?(y/n) ",
                                     'bold')).lower() != 'y':
                 return self.STOP
         elif os.path.isdir(local):  # 如果指定的本地路径为目录,那么会把下载的文件或目录放在该目录下
             for f in os.listdir(local):
                 if f.lower() == fname.lower():
                     if os.path.isdir(f):  # 不准有同名目录
                         logger.error(
                             f"Local folder `{local}` contain a same name directory `{f}`!"
                         )
                         return self.STOP
                     logger.warning(
                         f"Local folder `{local}` contain a same name file `{fname}`."
                     )
                     if utils.input(
                             colour.colorize(
                                 "Are you sure to overwrite it?(y/n) ",
                                 'bold')).lower() != 'y':
                         return self.STOP
                     break
     else:
         dirname = os.path.dirname(local.rstrip(os.sep))
         if not os.path.exists(dirname):
             logger.error(f"Local directory `{dirname}` is not exist!")
             return self.STOP
     logger.info("Downloading...")
     ret = self.download(args.source, local, args.recursive)
     if ret == self.SUCCESS:
         logger.info("All items downloaded!")
     return ret
Example #21
0
    def _list(self) -> int:
        table = [['ID', 'Webshell Type', 'Target']]
        try:
            tree = ET.parse(config.webshell_save_path)
            root = tree.getroot()
            for c in root:
                l = []
                l.append(c.attrib.get('id', 1))
                l.append(c.find("./webshell").attrib.get("value"))
                l.append(
                    c.find("./options/option[@name='target']").attrib.get(
                        'value'))
                table.append(l)
        except (FileNotFoundError, ET.ParseError):
            logger.warning(
                f"Load or parse file `{config.webshell_save_path}` failed!")
            return self.STOP

        print(tablor(table, border=False, title="Saved Webshell Connections"))
        return self.SUCCESS
Example #22
0
    def _kill(self, ID: int, force=False) -> int:
        if ID not in self.manager.session_map:
            logger.error(f"No session id is `{ID}`.")
            return self.STOP

        if isinstance(self.session, WebshellSession) and ID == self.session.id:
            logger.warning('You will kill the session you live on!')
        if force or utils.input(
                f"Are you sure to kill the session with id `{ID}` (y/n)"
        ).lower() == 'y':
            s = self.manager.session_map[ID]
            # 执行销毁时的回调函数
            s._hook_destroy()
            del self.manager.session_map[ID]
            logger.info(f"A session `{ID}` has been killed.", False)

            if isinstance(self.session,
                          WebshellSession) and ID == self.session.id:
                return self._switch(0)

        return self.SUCCESS
Example #23
0
    def put(self, kanban_id):
        """Updates kanban board with given id"""
        kanban_finder = KanbanFinder()
        logger.info(f"Updating kanban with id {kanban_id}")
        kanban_directory, kanban_found = kanban_finder.find_kanban_dir_with_id(
            kanban_id=kanban_id, kanbans_directory=config.kanbans_directory)
        response = dict()
        if kanban_found:
            config_file_dir = os.path.join(kanban_directory, "config.xml")
            logger.info(config_file_dir)

            request.get_json(force=True)
            if api.payload is None or api.payload == {}:
                return {"response": "Unable to decode payload"}, 400

            try:
                if api.payload["name"].replace(" ", "") == "":
                    return {
                        "response": "Name cannot be null or whitespaces only"
                    }, 400
                elif api.payload["name"] != "string":
                    update_xml_attribute(config_file_dir, "name",
                                         api.payload["name"])
                    response[
                        "response_name"] = f"Updated with {api.payload['name']}"
                if api.payload["description"] != "string":
                    update_xml_attribute(config_file_dir, "description",
                                         api.payload["description"])
                    response[
                        "response_desc"] = f"Updated with {api.payload['description']}"
            except KeyError as ke:
                logger.error("Key not matching model used!")
                logger.exception(ke)
                return {"response": "Wrong key! Use given model"}, 400

            return response, 204

        else:
            logger.warning(f"Kanban with id {kanban_id} not found!")
            return {"response": "Kanban id not found"}, 404
Example #24
0
 def get(self, kanban_id, issue_id):
     kanban_finder = KanbanFinder()
     logger.info(f"Fetching kanban directory with id {kanban_id}")
     kanban_directory, kanban_check = kanban_finder.find_kanban_dir_with_id(
         kanban_id=kanban_id, kanbans_directory=config.kanbans_directory)
     logger.info(f"Kanban directory {kanban_directory}")
     if kanban_check:
         issue_finder = IssueFinder()
         issues_directory = issue_finder.return_issues_directory_for_kanban(
             kanbans_directory=config.kanbans_directory,
             kanban_id=kanban_id)
         issue_check = issue_finder.check_if_issue_extists(
             issues_directory=issues_directory, issue_id=issue_id)
         if issue_check:
             try:
                 logger.info(
                     f"Fetching issues with id {issue_id} for kanban with id {kanban_id}"
                 )
                 issue_info_list = issue_finder.return_issue_info_for_kanban(
                     kanbans_directory=config.kanbans_directory,
                     kanban_id=kanban_id,
                     issue_id=issue_id,
                 )
                 response = jsonify(issue_info_list)
                 response.headers.add("Access-Control-Allow-Origin", "*")
                 return response
             except Exception as e:
                 logger.error("Unable to fetch issues!")
                 logger.exception(e)
                 return {"response": "Unable to fetch issues"}, 500
         else:
             logger.warning(
                 f"Unable to fetch issues! Issue with id {issue_id} not found"
             )
             return {"response": "Issue id not found"}, 400
     else:
         logger.warning(
             f"Unable to fetch issues! Kanban with id {kanban_id} not found"
         )
         return {"response": "Kanban id not found"}, 400
Example #25
0
    def run(self, args: Cmdline) -> int:
        args = self.parse.parse_args(args.options)
        if args.force or utils.input(
                "Are you sure to delete these files? (y/n) ").lower() == 'y':
            flist = "\n".join(args.dest)
            ret = self.evalfile('payload', flist=flist, pwd=self.session.pwd)
            ret = ret.data
            if ret is None:
                logger.error("Remove file error!")
                return self.STOP
            ret = json.loads(ret)
            for msg in ret['msg']:
                msg = base64.b64decode(msg).decode(
                    self.session.client.options.encoding, 'ignore')
                if 'failed' in msg or 'exist' in msg:
                    logger.warning(msg)
                else:
                    logger.info(msg)
            if ret['code'] == -1:
                return self.STOP

        return self.SUCCESS
Example #26
0
    def _parse_hosts(self, hosts: list) -> list:
        '''解析ip范围,返回ip字符串的列表
        '''
        ret = []
        if not hosts:  # 若未指定hosts,则使用上传扫描结果中存活的主机
            logger.warning(
                "No host specified, use the host that alive the last scan.")
            for ip in self._scan_result:
                ret.append(ip)
                logger.info(f"Using alive host {ip}")
            return ret
        for h in hosts:
            h = h.strip()
            min_ip = 0
            max_ip = 0
            try:
                if '/' in h:
                    ip, mask = h.split('/')
                    ip = struct.unpack("!L", socket.inet_aton(ip))[0]
                    mask = int(mask)
                    if mask <= 0 or mask >= 32:
                        raise ValueError('mask is error!')
                    min_ip = ip & (2**32 - 2**(32 - mask)) + 1
                    max_ip = min_ip + 2**(32 - mask) - 3
                elif '-' in h:
                    ip0, ip1 = h.split('-')
                    min_ip = struct.unpack("!L", socket.inet_aton(ip0))[0]
                    max_ip = struct.unpack("!L", socket.inet_aton(ip1))[0]
                    if min_ip > max_ip:
                        raise ValueError('IP range is error!')
                else:
                    min_ip = max_ip = struct.unpack("!L",
                                                    socket.inet_aton(h))[0]
                for ip in range(min_ip, max_ip + 1):
                    ret.append(socket.inet_ntoa(struct.pack('!L', ip)))
            except:
                logger.error(f"Host `{h}` format error!")

        return ret
Example #27
0
 def start_shell(self):
     self.exp.session.client.options.set_temp_option("timeout", 0)
     self.exp.session.client.options.set_temp_option(
         "verbose", self._verbose)
     ret = self.exp.evalfile("interact_normal/shell",
                             shell=self.shell,
                             pwd=self.exp.session.pwd,
                             infile=self.in_file,
                             outfile=self.out_file)
     ret = ret.data
     if ret is None:
         logger.warning(
             "Request `start_shell` has exit, if the shell is running normally please ignore the warning"
         )
         return
     if ret == "-1":
         logger.error(
             "Cannot run interactive shell!The remote server is missing a necessary component!"
         )
     elif ret == "-2":
         logger.error("The interactive shell process failed to start!")
     self.close()
Example #28
0
    def interactive(self, shell: str, type: str):
        if shell == "ok":
            if self.session.server_info.isWindows():
                shell = "cmd 2>&1"
            else:
                shell = "sh -i 2>&1"
        interact_shell = BaseShell(self)
        if type is None:
            type = "base"
        if type == "normal":
            interact_shell = NormalShell(self, shell)
        elif type == "namedpipe":
            if self.session.server_info.isWindows():
                logger.warning(
                    "Windows system has not yet implemented interactive shell execution through named pipes!"
                )
                logger.info(
                    "The same effect can be achieved by using `normal` type")
                return
            else:
                interact_shell = NamedpipeUnixShell(self, shell)

        interact_shell.cmdloop()
Example #29
0
 def cmdloop(self):
     logger.info(
         "Simply execute commands without maintaining any state.Type `exit` or `Ctrl-C` to exit."
     )
     logger.warning(
         "This shell is just a loop to execute the input commands, not a real interactive shell!"
     )
     self.running = True
     try:
         while self.running:
             cmd = utils.input(">> ")
             if cmd:
                 if cmd.lower() == 'exit':
                     self.running = False
                     break
                 msg = self.exp.exec_command(cmd + " 2>&1")
                 if msg is None:
                     logger.error(f"Exec `{cmd}` failed!")
                     continue
                 print(
                     msg.decode(self.exp.session.client.options.encoding,
                                'ignore'))
     except KeyboardInterrupt:
         pass
Example #30
0
 def get(self, kanban_id, issue_id):
     """ Check on which stage issue is """
     issue_stage_hand = IssueStageHandler()
     logger.info(f"Checking issue with id {issue_id} current stage")
     try:
         stage = issue_stage_hand.check_stage(
             kanbans_directory=config.kanbans_directory,
             kanban_id=kanban_id,
             issue_id=issue_id,
         )
         response = jsonify(stage)
         response.headers.add("Access-Control-Allow-Origin", "*")
         return response
     except AttributeError:
         logger.error(
             f"Issue is not set to any stage! Check issue config xml")
         return {"response": "Issue is not set to any stage"}, 500
     except FileNotFoundError:
         logger.warning("Issue couldn't be found")
         return {"response": "Issue id not found"}, 400
     except Exception as e:
         logger.error("Couldn't check issue stage!")
         logger.exception(e)
         return {"response": "Couldn't check issue stage"}, 500