def scan_dir(self, site, dir_file=None): ''' ''' self._dir_file = dir_file if dir_file else Settings.DIR_WEB_FILE file_list = open(self._dir_file, "rb").readlines() for item in file_list: path = item.strip() if path.startswith("#"): continue if site.endswith("/"): url = site[0:-1] + path else: url = site + path res = None try: res = wcurl.get(url, allow_redirects=False) status = res.get_code() if status is None: break msg = "Check URL:" + url + " code:" + str(status) log.info(msg) if status == 200: # unicode body = res.body if not is_404(body): msg = "Found URL:" + url + " code:" + str( status) + " 404 Check: False" print msg self._found_dir.append(url) if status == 301 or status == 302: next_res = wcurl.get(url, allow_redirects=True) if next_res.get_code() == 200: body = res.body if not is_404(body): msg = "Found URL:" + url + " code:" + str( status) + " 404 Check: False" print msg self._found_dir.append(url) except Exception, e: print "Http Request Error %s" % str(e) time.sleep(0.1)
def _verify_sql_vuln(self, http_request, vuln_inst, name, poc_type): ''' ''' if http_request.get_method() == "GET": param_dict = http_request.get_get_param() elif http_request.get_method() == "POST": param_dict = http_request.get_post_param() temp_param_dict = copy.deepcopy(param_dict) temp_value = temp_param_dict[name] if type(temp_value) is list: origin_value = "".join(temp_value) else: origin_value = temp_value if poc_type == "number": verify_value = '%s AND %s' % (origin_value, self._sql_verify_value) elif poc_type == "single": verify_value = "%s' and %s --" % (origin_value, self._sql_verify_value) elif poc_type == "double": verify_value = '%s" and %s --' % (origin_value, self._sql_verify_value) temp_param_dict[name] = verify_value if vuln_inst.get_method() == "GET": resp = wcurl.get(http_request.get_url().get_uri_string(), params=temp_param_dict) elif vuln_inst.get_method() == "POST": resp = wcurl.post(http_request.get_url().get_uri_string(), data=temp_param_dict) if self._find_verify_key(resp): return True else: return False
def check(self, t_request): ''' ''' log.info(u"正在检测目标是否存在命令执行漏洞...") http_request = copy.deepcopy(t_request) if http_request.get_method() == "GET": param_dict = http_request.get_get_param() if http_request.get_method() == "POST": param_dict = http_request.get_post_param() cmd_payload_list = self._get_payload_list(param_dict) for name, poc_info, pattern in cmd_payload_list: if http_request.get_method() == "GET": res = wcurl.get(http_request.get_url().get_uri_string(), params=poc_info) if self._find_vuln(res, pattern): v = vuln() url = res.get_url() v.set_url(url.get_uri_string() + "?" + str(poc_info)) v.set_method("GET") v.set_param(name) v.set_name("CMD Vuln") v.set_rank(severity.H) vm.append(self, url.get_host(), "cmd", v) log.info("CMD Vuln") print u"CMD Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name)
def check(self, t_request): ''' ''' log.info(u"正在检测目标是否存在Directory目录列举漏洞...") http_request = copy.deepcopy(t_request) url_obj = http_request.get_url() dir_list = url_obj.get_dirs() for item in dir_list: if item in self._already_dir_urls: return self._already_dir_urls.append(item) req_url = item.get_uri_string() res = wcurl.get(req_url) if self._find_vuln(res): v = vuln() v.set_url(req_url) v.set_method("GET") v.set_param("") v.set_name("Directory List Vuln") v.set_rank(severity.M) vm.append(self, http_request.get_url().get_host(), "directory", v) log.info("Directory List Vuln") print "----------Directory List Vuln" break
def check(self, t_request): ''' ''' log.info(u"正在检测目标是否存在文件包含漏洞...") http_request = copy.deepcopy(t_request) if http_request.get_method() == "GET": param_dict = http_request.get_get_param() if http_request.get_method() == "POST": param_dict = http_request.get_post_param() lfi_payload_list = self._get_payload_list(param_dict) vuln_name = set() for name, poc_info, pattern in lfi_payload_list: res = wcurl.get(http_request.get_url().get_uri_string(), params=poc_info) if self._find_vuln(res, pattern): if name in vuln_name: continue vuln_name.add(name) v = vuln() url = res.get_url() v.set_url(url.get_uri_string() + "?" + str(poc_info)) v.set_method("GET") v.set_param(name) v.set_name("LFI Vuln") v.set_rank(severity.H) vm.append(self, url.get_host(), "lfi", v) log.info("LFI Vuln") print u"LFI Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name)
def generate_404_kb(self, url): ''' ''' domain = url.get_domain() domain_path = url.get_domain_path() rand_file = rand_letters(8) + '.html' url_404 = domain_path.urljoin(rand_file) resp_200 = wcurl.get(domain_path) resp_404 = wcurl.get(url_404) if is_similar_page(resp_200, resp_404): #404页面与正常页面相同 pass else: self._404_already_domain.append(domain) self._404_kb.append((domain, resp_404))
def test_is_404(): ''' ''' url_200 = "http://www.anquanbao.com/" url_404 = "http://www.anquanbao.com/noexist.html" resp_200 = wcurl.get(url_200) resp_404 = wcurl.get(url_404) assert is_404(resp_200) == False assert is_404(resp_404) == True url_200 = "http://www.baidu.com/" url_404 = "http://www.baidu.com/noexist.html" resp_200 = wcurl.get(url_200) resp_404 = wcurl.get(url_404) assert is_404(resp_200) == False assert is_404(resp_404) == True
def check(self, url): ''' ''' log.info(u"正在检测目标是否存在:[%s]..." % self.get_title()) domain_path = url.get_domain_path() exp_url = domain_path.urljoin(self._vuln_file) error_sql, error_key = get_error_sql_key(type="floor") exp_params = self._vuln_param.replace("{SQL}", error_sql) res = wcurl.get(exp_url, params=exp_params) if self._find_vuln(res, error_key): self.security_hole(exp_url)
def check(self, url): ''' ''' log.info(u"正在检测目标是否存在:[%s]..." % self.get_title()) if not self._scan_mode: domain_path = url.get_domain_path() exp_url = domain_path.urljoin(self._vuln_file) chk_url = domain_path.urljoin(self._file_key) else: exp_url = url.urljoin(self._vuln_file) print exp_url chk_url = url.urljoin(self._file_key) data = "aid=1&cfg_dbhost=%s&cfg_dbuser=%s&cfg_dbpwd=%s&cfg_dbname=%s&cfg_dbprefix=%s" % self._db_info wcurl.get(exp_url, params=data) time.sleep(1) chk_res = wcurl.get(chk_url) if self._find_vuln(chk_res, self._data_key): print "test" self.security_hole(exp_url)
def check(self, t_request): ''' ''' log.info(u"正在检测目标是否存在XSS跨站漏洞...") http_request = copy.deepcopy(t_request) if http_request.get_method() == "GET": param_dict = http_request.get_get_param() if http_request.get_method() == "POST": param_dict = http_request.get_post_param() xss_payload_list = self._get_payload_list(param_dict) for name, poc_info in xss_payload_list: if name.lower() in self._white_param: continue # print "Fuzz Name:"+ name if http_request.get_method() == "GET": url_obj = http_request.get_url() res = wcurl.get(url_obj.get_uri_string(), params=poc_info) if self._find_vuln(res): v = vuln() url = res.get_url() v.set_url(url.get_uri_string() + "?" + str(poc_info)) v.set_method("GET") v.set_param(name) v.set_name("XSS Vuln") v.set_rank(severity.M) vm.append(self, url.get_host(), "xss", v) log.info("XSS Vuln") print u"XSS Vuln 漏洞URL:%s,漏洞参数%s" % (url, name) if http_request.get_method() == "POST": url_obj = http_request.get_url() res = wcurl.post(url_obj.get_uri_string(), data=poc_info) if self._find_vuln(res): v = vuln() url = res.get_url() v.set_url(url.get_uri_string() + ";" + str(poc_info)) v.set_method("POST") v.set_param(name) v.set_name("XSS Vuln") v.set_rank(severity.M) vm.append(self, url.get_host(), "xss", v) log.info("XSS Vuln") print u"XSS Vuln 漏洞URL:%s,漏洞参数%s" % (url, name)
def test_HtmlParser(): ''' ''' req_url = "http://192.168.126.147" real_contain_urls = [ 'http://www.w3.org/1999/xhtml', 'http://192.168.126.147/lnmp.gif', 'http://lnmp.org', 'http://192.168.126.147/p.php', 'http://192.168.126.147/phpinfo.php', 'http://192.168.126.147/phpmyadmin/', 'http://lnmp.org', 'http://bbs.vpser.net/forum-25-1.html', 'http://www.vpser.net/vps-howto/', 'http://www.vpser.net/usa-vps/', 'http://lnmp.org', 'http://blog.licess.com/', 'http://www.vpser.net' ] r = wcurl.get(req_url) parser = HtmlParser(r) re_urls, tag_urls = parser.urls print "Regex URL:" for item in re_urls: print item print "Tag URL:" for item in tag_urls: print item page_urls = [] page_urls.extend(re_urls) page_urls.extend(tag_urls) true_num = 0 for item in real_contain_urls: real_url = URL(item) if real_url in page_urls: true_num += 1 else: print real_url assert len(real_contain_urls) == true_num
def check(self, t_request): ''' 压缩文件,www.baidu.com,www.zip,wwwroot,w, ''' if self._report_num > self._bak_max_num: return log.info(u"正在检测目标是否存在文件备份漏洞...") http_request = copy.deepcopy(t_request) url_obj = http_request.get_url() scheme = url_obj.get_scheme() domain = url_obj.get_domain() uri_string = url_obj.get_uri_string() zip_file_list = gen_zip_name(domain) for fname in zip_file_list: for item in self._zip_ext: zip_file = fname + "." + item zip_url = URL(uri_string).urljoin(zip_file) res = requests.head(zip_url) ct = res.headers["content-type"].lower() if ct in self._res_zip_type: v = vuln() v.set_url(zip_url) v.set_method("GET") v.set_param("") v.set_name("Bak Vuln") v.set_rank(severity.H) vm.append(self, http_request.get_url().get_host(), "bak", v) log.info("Bak Vuln") print "Bak Vuln 漏洞URL:%s" % (zip_url) self._report_num += 1 url_ext = url_obj.get_ext() url_file = url_obj.get_filename() if url_file == "": return if url_ext not in self._key_ext.keys(): return for bak_ext in self._bak_ext: if bak_ext == ".swp": bak_file = "." + url_file + bak_ext bak_url = URL(uri_string).urljoin(bak_file) res = requests.head(bak_url) bak_ct = res.headers["content-type"] # (".swp","application/octet-stream") if bak_ct == "application/octet-stream": v = vuln() v.set_url(bak_url) v.set_method("GET") v.set_param("") v.set_name("Bak Vuln") v.set_rank(severity.H) vm.append(self, http_request.get_url().get_host(), "bak", v) log.info("Bak Vuln") print "Bak Vuln 漏洞URL:%s" % (bak_url) self._report_num += 1 else: bak_url = uri_string + bak_ext res = wcurl.get(bak_url) if self._find_vuln(res, url_ext): v = vuln() v.set_url(bak_url) v.set_method("GET") v.set_param("") v.set_name("Bak Vuln") v.set_rank(severity.H) vm.append(self, http_request.get_url().get_host(), "bak", v) log.info("Bak Vuln") print u"Bak Vuln 漏洞URL:%s" % (bak_url) self._report_num += 1
def check(self, t_request): ''' ''' log.info(u"正在检测目标是否存在SQL注入漏洞...") http_request = copy.deepcopy(t_request) # param {"id":"d","tp":"ttt","name":""} if http_request.get_method() == "GET": param_dict = http_request.get_get_param() if http_request.get_method() == "POST": param_dict = http_request.get_post_param() sql_payload_list = self._get_payload_list(param_dict) error_param_list = [] for name, poc_true, poc_false, poc_type in sql_payload_list: if name.lower() in self._white_param: continue # print "Fuzz Name:" + name +" Fuzz Type:" + poc_type if http_request.get_method() == "GET": url_obj = http_request.get_url() normal_resp = wcurl.get(url_obj.get_url_string()) true_resp = wcurl.get(url_obj.get_uri_string(), params=poc_true) false_resp = wcurl.get(url_obj.get_uri_string(), params=poc_false) if name not in error_param_list: error_param_list.append(name) # 404_resp temp_dict = copy.deepcopy(param_dict) temp_dict[name] = "'\")(wat)'\"%27" error_param = temp_dict error_resp = wcurl.get(url_obj.get_uri_string(), params=error_param) if self._find_sql_error(error_resp.body): v = vuln() url = error_resp.get_url() v.set_url(url.get_uri_string() + "?" + str(error_param)) v.set_method("GET") v.set_param(name) v.set_name("数据库运行错误") v.set_rank(severity.M) vm.append(self, url.get_host(), "dberror", v) log.info("DB Error Vuln") print "----------DB Error Vuln" if self._verify_sql_vuln(http_request, v, name, poc_type): v = vuln() url = error_resp.get_url() v.set_url(url.get_uri_string() + "?" + str(poc_true)) v.set_method("GET") v.set_param(name) v.set_name("SQL注入漏洞") v.set_rank(severity.H) vm.append(self, url.get_host(), "sql", v) log.info("SQL Vuln") print u"SQL Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name) break if true_resp.body == false_resp.body: continue if self._get_diff_ratio(false_resp.body, normal_resp.body) > self._false_threshold: continue if self._get_diff_ratio(normal_resp.body, true_resp.body) > self._true_threshold: # security_hole() v = vuln() url = true_resp.get_url() v.set_url(url.get_uri_string() + "?" + str(poc_true)) v.set_method("GET") v.set_param(name) v.set_name("SQL注入漏洞") v.set_rank(severity.H) if self._scan_mode == 0: vm.append(self, url.get_host(), "sql", v) log.info("SQL Vuln") print u"SQL Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name) break else: if self._verify_sql_vuln(http_request, v, name, poc_type): vm.append(self, url.get_host(), "sql", v) log.info("SQL Vuln") print u"SQL Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name) break if http_request.get_method() == "POST": url_obj = http_request.get_url() normal_resp = wcurl.post(url_obj.get_url_string()) true_resp = wcurl.post(url_obj.get_uri_string(), data=poc_true) false_resp = wcurl.post(url_obj.get_uri_string(), data=poc_false) if name not in error_param_list: error_param_list.append(name) # 404_resp temp_dict = copy.deepcopy(param_dict) temp_dict[name] = "'\")(wat)'\"%27" error_param = temp_dict error_resp = wcurl.post(url_obj.get_uri_string(), data=error_param) if self._find_sql_error(error_resp.body): v = vuln() url = error_resp.get_url() v.set_url(url.get_uri_string() + "?" + str(error_param)) v.set_method("POST") v.set_param(name) v.set_name(u"数据库运行错误") v.set_rank(severity.H) vm.append(self, url.get_host(), "dberror", v) log.info("DB Error Vuln") print "----------DB Error Vuln" if self._verify_sql_vuln(http_request, v, name, poc_type): v = vuln() url = error_resp.get_url() v.set_url(url.get_uri_string() + "?" + str(poc_true)) v.set_method("POST") v.set_param(name) v.set_name("SQL注入漏洞") v.set_rank(severity.H) vm.append(self, url.get_host(), "sql", v) log.info("SQL Vuln") print u"SQL Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name) break if true_resp.body == false_resp.body: continue if self._get_diff_ratio(false_resp.body, normal_resp.body) > self._false_threshold: continue if self._get_diff_ratio(normal_resp.body, true_resp.body) > self._true_threshold: # security_hole() v = vuln() url = true_resp.get_url() v.set_url(url.get_uri_string() + "," + str(poc_true)) v.set_method("POST") v.set_param(name) v.set_name("SQL注入漏洞") v.set_rank(severity.H) if self._verify_sql_vuln(http_request, v, name, poc_type): vm.append(self, url.get_host(), "sql", v) log.info("SQL Vuln") print u"SQL Vuln 漏洞URL:%s,漏洞参数:%s" % (url, name) break
#coding=utf-8 ''' HtmlParser.py ''' import sys import urllib import re import traceback from lxml import etree from teye_web.http.URL import URL from teye_web.http.Request import Request from teye_web.http.encode_decode import htmldecode from teye_web.util.smart_fill import smart_fill import teye_web.http.postdata as postdata from wCurl import wcurl from LogManager import log as om DEFAULT_ENCODING = "utf-8" class HtmlParser(object): ''' ''' URL_HEADERS = ('location') URL_TAGS = ('a', 'img', 'link', 'script', 'iframe', 'object', 'embed', 'area', 'frame', 'applet', 'input', 'base', 'div', 'layer', 'form') URL_ATTRS = ('href', 'src', 'data', 'action') URL_RE = re.compile('((http|https)://([\w:@\-\./]*?)[^ \n\r\t"\'<>)\s]*)', re.U) SAFE_CHARS = (('\x00', '%00'), ) def __init__(self, response):
def scan_finger(self, site): ''' ''' app_name_list = [] for item in self._app_db: if item.startswith("#"): continue dict_item = json.loads(item.strip()) app_name = "".join(dict_item.keys()).strip() app_info = dict_item.get(app_name) url = app_info.get("url") urlobj = URL(site) if self._scan_mode == 1: test_url = urlobj.get_uri_string() if test_url.endswith("/"): target_url = test_url[0:-1] + url else: target_url = test_url + url else: test_url = urlobj.get_netloc() target_url = urlobj.get_scheme() + "://" + test_url + url log.info(target_url) try: res = wcurl.get(target_url) except: continue dst_headers = res.headers dst_body = res.body self._http_code = res.get_code() try: self._server_finger = dst_headers["server"] except: pass if dst_body is None: continue md5_body = self.md5(dst_body) key_list = app_info.keys() if "headers" in key_list: app_headers = app_info.get("headers") app_key = app_headers[0].lower() app_value = app_headers[1] if app_key in dst_headers.keys(): dst_info = dst_headers.get(app_key) result = re.search(app_value, dst_info, re.I) if result: if "body" in key_list: app_body = app_info.get("body") result = re.search(app_body, dst_body, re.I) if result: app_name_list.append((target_url, app_name)) else: app_name_list.append((target_url, app_name)) elif "body" in key_list: app_body = app_info.get("body") result = re.search(app_body, dst_body, re.I) if result: app_name_list.append((target_url, app_name)) elif "md5" in key_list: app_md5 = app_info.get("md5") if app_md5 == md5_body: app_name_list.append((target_url, app_name)) return app_name_list
domain = url.get_domain() if domain not in self._404_already_domain: self.generate_404_kb(url) if code == 404: return True if code in self._404_code_list: for domain_404, resp_404 in self._404_kb: if domain == domain_404: if is_similar_page(http_response, resp_404): return True return False def is_404(http_response): if page_404._instance is None: page_404._instance = page_404() return page_404._instance.is_404(http_response) if __name__ == "__main__": url = "http://www.baidu.com/44444.html" res = wcurl.get(url) if is_404(res): print "404" #print res.body