Пример #1
0
    def audit(self):
        headers = self.requests.headers
        url = self.requests.url
        p = urlparse(url)
        for rule in conf.excludes:
            if rule in p.netloc:
                logger.info("Skip domain:{}".format(url))
                return

        # fingerprint basic info
        exi = self.requests.suffix.lower()
        if exi == ".asp":
            self.response.programing.append(WEB_PLATFORM.ASP)
            self.response.os.append(OS.WINDOWS)
        elif exi == ".aspx":
            self.response.programing.append(WEB_PLATFORM.ASPX)
            self.response.os.append(OS.WINDOWS)
        elif exi == ".php":
            self.response.programing.append(WEB_PLATFORM.PHP)
        elif exi == ".jsp" or exi == ".do" or exi == ".action":
            self.response.programing.append(WEB_PLATFORM.JAVA)

        for name, values in KB["fingerprint"].items():
            if not getattr(self.response, name):
                _result = []
                for mod in values:
                    m = mod.fingerprint(self.response.headers, self.response.text)
                    if isinstance(m, str):
                        _result.append(m)
                    if isListLike(m):
                        _result += list(m)
                if _result:
                    setattr(self.response, name, _result)

        # Fingerprint basic end
        if KB["spiderset"].add(url, 'PerFile'):
            task_push('PerFile', self.requests, self.response)

        # Send PerServe
        p = urlparse(url)
        domain = "{}://{}".format(p.scheme, p.netloc)
        if KB["spiderset"].add(domain, 'PerServe'):
            req = requests.get(domain, headers=headers, allow_redirects=False)
            fake_req = FakeReq(domain, headers, HTTPMETHOD.GET, "")
            fake_resp = FakeResp(req.status_code, req.content, req.headers)
            task_push('PerServe', fake_req, fake_resp)

        # Collect directory from response
        urls = set(get_parent_paths(url))
        for parent_url in urls:
            if not KB["spiderset"].add(parent_url, 'get_link_directory'):
                continue
            req = requests.get(parent_url, headers=headers, allow_redirects=False)
            if KB["spiderset"].add(req.url, 'PerFolder'):
                fake_req = FakeReq(req.url, headers, HTTPMETHOD.GET, "")
                fake_resp = FakeResp(req.status_code, req.content, req.headers)
                task_push('PerFolder', fake_req, fake_resp)
Пример #2
0
def start():
    logger.info("Myscan Python Moudle Listen ...")
    red = getredis()
    try:
        while True:
            try:
                data = red.rpop("burpdata")
                if data:
                    logger.debug("Get one data from burpdata")
                    try:
                        dictdata = json.loads(data)
                    except Exception as ex:
                        logger.warning("Process burpdata to json get error:" + str(ex))
                        continue
                    if dictdata is not None:
                        url = dictdata.get("url").get('url')
                        request = dictdata.get("request")
                        response = dictdata.get("response")
                        request_bodyoffset = int(dictdata.get("request").get("bodyoffset"))
                        response_bodyoffset = int(dictdata.get("response").get("bodyoffset"))
                        request_raw = base64.b64decode(dictdata.get("request").get("raw"))[request_bodyoffset:]
                        response_raw = base64.b64decode(dictdata.get("response").get("raw"))[response_bodyoffset:]
                        req = FakeReq(url, request.get('headers'), request.get('method'), request_raw)
                        resp = FakeResp(int(response.get('status')), response_raw, response.get('headers'))
                        KB['task_queue'].put(('loader', req, resp))
                else:
                    time.sleep(random.uniform(1, 2))
            except Exception as ex:
                logger.debug("Run start get error:{}".format(ex))
                traceback.print_exc()
                continue
    except KeyboardInterrupt as ex:
        logger.warning("Ctrl+C was pressed ,aborted program")
Пример #3
0
def main():
    # 检查版本信息
    version_check()

    # 获取绝对路径
    root = modulePath()
    # 解析命令行参数
    cmdline = cmd_line_parser()
    # 初始化执行
    init(root, cmdline)

    # 从命令行中或者文件中读取
    if conf.url or conf.url_file:
        urls = []
        # 判断命令行中是否填入了URL地址
        if conf.url:
            urls.append(conf.url)
        # 判断是否从文件中读取URL地址
        if conf.url_file:
            urlfile = conf.url_file
            if not os.path.exists(urlfile):
                logger.error("File:{} don't exists".format(urlfile))
                sys.exit()
            with open(urlfile) as f:
                _urls = f.readlines()
            _urls = [i.strip() for i in _urls]
            urls.extend(_urls)
        # 开始对每一条URL做处理,将其插入到队列中
        for domain in urls:
            # domain = "http://www.achr.net/activities-de.php?id=2"
            try:
                req = requests.get(domain)
            except Exception as e:
                logger.error("request {} faild,{}".format(domain, str(e)))
                continue
            # 解析URL地址
            fake_req = FakeReq(domain, {}, HTTPMETHOD.GET, "")
            fake_resp = FakeResp(req.status_code, req.content, req.headers)
            task_push_from_name('loader', fake_req, fake_resp)
        # 从队列中开始扫描
        start()
    # 如果是用代理模式启动
    elif conf.server_addr:
        KB["continue"] = True
        # 启动漏洞扫描器
        scanner = threading.Thread(target=start)
        scanner.setDaemon(True)
        scanner.start()
        # 启动代理服务器
        baseproxy = AsyncMitmProxy(server_addr=conf.server_addr, https=True)

        try:
            baseproxy.serve_forever()
        except KeyboardInterrupt:
            scanner.join(0.1)
            threading.Thread(target=baseproxy.shutdown, daemon=True).start()
            deinit()
            print("\n[*] User quit")
        baseproxy.server_close()
Пример #4
0
def scan(url, module_name, conf={}, headers={}):
    root = modulePath()
    cmdline = {"level": 5}
    cmdline.update(conf)
    init(root, cmdline)
    r = requests.get(url, headers=headers)
    req = FakeReq(url, headers, HTTPMETHOD.GET)
    resp = FakeResp(r.status_code, r.content, r.headers)

    poc_module = copy.deepcopy(KB["registered"][module_name])
    poc_module.execute(req, resp)
Пример #5
0
def main():
    # 检测python版本是否大于3.6
    version_check()

    # init
    # 获取根路径
    root = modulePath()
    # 获取命令后参数 cmdline是命令行参数字典
    cmdline = cmd_line_parser()
    init(root, cmdline)

    if conf.url or conf.url_file:
        urls = []
        if conf.url:
            urls.append(conf.url)
        if conf.url_file:
            urlfile = conf.url_file
            if not os.path.exists(urlfile):
                logger.error("File:{} don't exists".format(urlfile))
                sys.exit()
            with open(urlfile) as f:
                _urls = f.readlines()
            _urls = [i.strip() for i in _urls]
            urls.extend(_urls)
        for domain in urls:
            try:
                req = requests.get(domain)
            except Exception as e:
                logger.error("request {} faild,{}".format(domain, str(e)))
                continue
            fake_req = FakeReq(domain, {}, HTTPMETHOD.GET, "")
            fake_resp = FakeResp(req.status_code, req.content, req.headers)
            task_push_from_name('loader', fake_req, fake_resp)
        start()
    elif conf.redis:
        KB["continue"] = True
        # 启动漏洞扫描器
        scanner = threading.Thread(target=start)
        scanner.setDaemon(True)
        scanner.start()
        # 启动代理服务器
        # https拦截需要安装证书
        # baseproxy = AsyncMitmProxy(server_addr=conf.server_addr, https=True)
        set_conn()
        cleandb()
        try:
            redis_run.start()
            # 使用SockectServer模块的serve_forever()函数后,程序就一直挂起等待处理socket连接了
            # baseproxy.serve_forever()
        except KeyboardInterrupt:
            scanner.join(0.1)
            # threading.Thread(target=baseproxy.shutdown, daemon=True).start()
            deinit()
            print("\n[*] User quit")
Пример #6
0
    def do_GET(self):
        '''
        处理GET请求
        :return:
        '''
        if self.path == 'http://baseproxy.ca/' or self.path == 'http://w13scan.ca/':
            self._send_ca()
            return
        request = None
        try:
            if not self.is_connected:
                # 如果不是https,需要连接http服务器
                try:
                    self._proxy_to_dst()
                except Exception as e:
                    try:
                        self.send_error(
                            500, '{} connect fail because of "{}"'.format(
                                self.hostname, str(e)))
                    except BrokenPipeError:
                        pass
                    finally:
                        return
            else:
                self._target = self.ssl_host + self.path
            # 这里就是代理发送请求,并接收响应信息
            request = Request(self)
            if request:
                if self.is_connected:
                    request.set_https(True)
                self._proxy_sock.sendall(request.to_data())
                # 将响应信息返回给客户端
                errMsg = ''
                try:
                    response = Response(request, self._proxy_sock)
                except ConnectionResetError:
                    response = None
                    errMsg = 'because ConnectionResetError'
                except _socket.timeout:
                    response = None
                    errMsg = 'because socket timeout'
                except http.client.BadStatusLine as e:
                    response = None
                    errMsg = 'because BadStatusLine {}'.format(str(e))

                if response:
                    try:
                        self.request.sendall(response.to_data())
                    except BrokenPipeError:
                        pass
                    except OSError:
                        pass
                else:
                    self.send_error(404, 'response is None {}'.format(errMsg))
                if not self._is_replay() and response:
                    netloc = "http"
                    if request.https:
                        netloc = "https"
                    if (netloc == "https" and int(request.port) == 443) or (
                            netloc == "http" and int(request.port) == 80):
                        url = "{0}://{1}{2}".format(netloc, request.hostname,
                                                    request.path)
                    else:
                        url = "{0}://{1}:{2}{3}".format(
                            netloc, request.hostname, request.port,
                            request.path)
                    method = request.command.lower()
                    if method == "get":
                        method = HTTPMETHOD.GET
                    elif method == "post":
                        method = HTTPMETHOD.POST
                    elif method == "put":
                        method = HTTPMETHOD.PUT
                    req = FakeReq(url, request._headers, method,
                                  request.get_body_data().decode('utf-8'))
                    resp = FakeResp(int(response.status),
                                    response.get_body_data(),
                                    response._headers)
                    KB['task_queue'].put(('loader', req, resp))

            else:
                self.send_error(404, 'request is None')
        except ConnectionResetError:
            pass
        except ConnectionAbortedError:
            pass
        except (BrokenPipeError, IOError):
            pass
        except Exception:
            errMsg = "W13scan baseproxy get request traceback:\n"
            errMsg += "Running version: {}\n".format(VERSION)
            errMsg += "Python version: {}\n".format(sys.version.split()[0])
            errMsg += "Operating system: {}".format(platform.platform())
            if request:
                errMsg += '\n\nrequest raw:\n'
                errMsg += request.to_data().decode()
            excMsg = traceback.format_exc()
            dataToStdout(errMsg)
            dataToStdout(excMsg)