您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關網絡安全中漏洞自動化分析工具怎么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
pentestEr_Fully-automatic-scanner
為了省去繁瑣的手工測試和常用漏洞的搜索工作,提升工作的效率,才有了此工具,工具對于前期的收集采用了市面上大量的工具集合,不漏掃的原則,最大化的提升工具可用性,可擴展性等要求,開發次掃描器。使用方法
可以直接執行 python main.py -d cert.org.cn
|--dict |--dns_server.txt |--... |--lib |-- __init__.py |--cmdline.py |--... |--listen |--filer.py |--report |--result |--rules |--wahtweb.json |--commom.txt |--subbrute |--thirdlib |--utils |--api.keys |--BBScan.py |--bingAPI |--captcha.py |--config.py |--dnsbrute.py |--gxfr.py |--import1.php |--main.py |--report_all.py |--subDomainBrute.py |--sublist3r.py |--upload.py |--wahtweb.py |--wydomain.py |--啟動程序.bat |--wvs.bat
這個目錄結構讓我感覺很亂,尤其后面一大推py文件,缺少點軟件設計的思想,感覺時即興寫出來的代碼,很多文件還有錯誤,注釋很少,很多時候需要debug才能知道該段代碼實現的功能。
在進行掃描之前,按照慣例需要對目標網站的域名信息進行whois
查詢,該腳本whois的實現是通過第三方網站查詢得到的,不過原查詢函數因為日期久遠,而網站代碼也已經更新了,該函數已經無法準確的獲取到目標網站域名信息了
def sub_domain_whois(url_domain): """ 通過第三方網站查詢得到whois結果,然后對網頁進行正則匹配,以獲取到網頁內容中的whois結果 """ um=[] a1=requests.get("http://whois.chinaz.com/%s" %(url_domain)) if 'Registration' not in a1.text: print 'whois error' else: print a1.text # 使用正則匹配想要獲取的內容,假如目標網站的前端代碼改變了,那么該正則就失效了 out_result=re.findall(r'<pre class="whois-detail">([\s\S]*)</pre>', a1.text.encode("GBK",'ignore')) out_result_register=re.findall(r'http://(.*?)"', a1.text.encode("GBK",'ignore')) for x in out_result_register: if 'reverse_registrant/?query=' in x: um.append(x) break for x in out_result_register: if 'reverse_mail/?query=' in x: um.append(x) break print um[0], um[1] print out_result[0] # 將獲取到的結果存放在的一個html文件中,以便最后生成報告 with open('report/whois_email_user.html','w') as fwrite: fwrite.write('register_user:') fwrite.write('<a href="http://' + um[0] + '">注冊者反查詢</a>') fwrite.write('<br>') fwrite.write('email:') fwrite.write('<a href="http://' + um[1] + '">郵箱反查詢</a>') fwrite.write('<br>') fwrite.write('<pre>') fwrite.write(out_result[0]) fwrite.write('</pre>')
def sub_domain_whois(url_domain): import json a = requests.get("http://api.whoapi.com/?domain={}&r=whois&apikey=demokey".format(url_domain)) result = a.text r = json.loads(result) for k,v in r.items(): print(k,v)
當然如果需要一些詳細的信息,可能還是需要對一些網站的內容進行爬取才行。
對于子域名收集,這個系統在實現的時候,為了收集到盡可能多的代碼,使用了很多第三方腳本,這里就出現了一個問題,這種使用腳本的方法讓代碼可讀性很差,而且維護困難,很多代碼現在已經不適用了。
腳本名稱 | 介紹 | 使用方法 | 返回內容 |
---|---|---|---|
gxfr.py | 使用高級搜索引擎(bing,baidu,google)查詢來枚舉子域并執行dns查找,這個程序使用的是bing的API對子域名進行收集 | python gxfr.py --bxfr --dns-lookup -o --domain url_domain | 程序會將結果保存到一個domain_gxfr1.txt這樣的文件中,api已經不可用 |
subDomainsBrute.py | 提供的常用的子域名字符串字典,然后通過與域名進行組合,配合DNS服務器確定是否存在組合后的子域名 | python subDomainsBrute.py domain | 將字典枚舉組合解析成功后的域名存放在domain_jiejie.txt文件中 |
wydomain.py | 通過使用互聯網上的第三方接口或者爬取查詢結果來獲取目標的子域名 | python wydomain domain | 通過不同網站獲取的結果會存在本地的不同的.json文件中 |
sublist3r.py | 使用百度,雅虎,bing等第三方引擎對目標域名進行子域名收集,而且還提供字典枚舉的功能和端口掃描的功能 | python sublist3r -d doamin -o domain_sublistdir.txt | 將獲取到的子域名結果存在本地的txt文件中 |
該py文件是使用bing的API,谷歌的搜索引擎對目標域名的子域名進行查詢。主要的兩個函數為bxfr
函數和gxfr
函數。
bxfr
函數,使用Bing的API進行子域名解析和查詢,該函數需要提供Bing相關功能的API Key。然后訪問` https://api.datamarket.azure.com/Data.ashx/Bing/Search/Web?Query=domain&Misplaced &format=json經過測試該API接口已經不可用。通過該API獲取子域名結果后,使用
lookup_subs函數進行socket函數獲取地址并成功后(
socket.getaddrinfo(site, 80)`),將結果存儲在txt文件中中。
gxfr
函數,使用google搜索引擎的hack語法進行查詢(site:baidu.com
),然后通過正則表達式進行匹配pattern = '>([\.\w-]*)\.%s.+?<' % (domain)
。然后獲取匹配結果。最后經過lookkup_subs
函數驗證之后寫入txt文件中。
該py文件通過提供的子域名字典,對目標域名的子域名進行枚舉然后解析測試,最后輸出結果。這里提供了兩個字典文件,分別為dict/subnames.txt
和dict/next_sub.txt
。還有一個dns服務器列表
.114.114.114 .8.8.8 .76.76.76 .5.5.5 .6.6.6
程序簡介
def __init__(self, target, names_file, ignore_intranet, threads_num, output): self.target target.strip() self.names_file names_file self.ignore_intranet ignore_intranet self.thread_count self.threads_num threads_num self.scan_count self.found_count self.lock threading.Lock() self.console_width getTerminalSize()[0] self.resolvers [dns.resolver.Resolver() _ range(threads_num)] self._load_dns_servers() self._load_sub_names() self._load_next_sub() outfile target not output output self.outfile open(outfile, ) self.ip_dict {} self.STOP_ME False
該程序的執行流程就是,先從字典中加載字符串,然后將字符串與目標域名進行拼接得到一個子域名,通過第三方模塊dns.resolver
對其進行解析,解析成功就保存在txt文件中。關鍵代碼如下:
cur_sub_domain sub self.target answers d.resolvers[thread_id].query(cur_sub_domain) is_wildcard_record False answers: answer answers: self.lock.acquire() answer.address not self.ip_dict: self.ip_dict[answer.address] : self.ip_dict[answer.address] self.ip_dict[answer.address] > : is_wildcard_record True self.lock.release()
該程序是通過調用多個第三方接口對目標域名進行子域名查詢,然后將查詢結果分別存儲在一個json文件中。
fetch_chinaz
函數
url .format(self.domain) r http_request_get(url).content subs re.compile(r)
fetch_alexa_cn
函數
url .format(self.domain) r http_request_get(url).text sign re.compile(r).findall(r)
class Threatcrowd(object)
url .format(self.website, self.domain) content http_request_get(url).content sub json.loads(content).get():
class Threatminer(object)
url .format(self.website, self.domain) content http_request_get(url).content _regex re.compile(r) sub _regex.findall(content):
class Sitedossier(object)
url .format(self.domain) r self.get_content(url) self.parser(r) 部分代碼如下 npage re.search(, response) npage: sub self.get_subdomain(response): self.subset.append(sub) return list(set(self.subset))
class Netcraft(object)
self.site self.cookie self.get_cookie().get() url .format( self.site, self.domain) r http_request_get(url, self.cookie) self.parser(r.text) 部分代碼信息 npage re.search(, response) return list(set(self.subset))
class Ilinks(object)
self.url payload { : , : , : , : self.domain } r http_request_post(self.urlpayload).text subs re.compile(r)
class Chaxunla(object)
self.url url .format( self.url, timestemp, self.domain, timestemp, self.verify) result json.loads(req.get(url).content)
json_data read_json(_burte_file) json_data: subdomains.extend(json_data) ...... subdomains list(set(subdomains)) _result_file os.path.join(script_path, outfile) save_result(_result_file, subdomains)
該文件使用百度,雅虎,bing等第三方引擎對目標域名進行子域名收集,而且還提供字典枚舉的功能和端口掃描的功能在該系統中只用到了該程序的子域名收集功能。使用到的模塊也與之前的wydomain.py文件有很多重復的地方
該文件的類都是繼承至該類,而這個基類也是由作者自定義的一個類。簡單解釋一下該類的功能
print_banner
方法子類通過繼承,可以通過該函數打印出該類使用的一些接口的信息
send_req
方法發送請求的方法,該方法中自定義了大量的http頭部變量,該方法返回的服務器回復的數據
get_response
方法從response對象中獲取html內容,并返回
check_max_subdomains
方法該方法是用來設置尋找子域名最大個數的,如果得到子域名的數量到達該函數設置數量時,程序就會停止繼續尋找子域名
check_max_pages
方法比如google搜索引擎是需要指定探索的最大頁數,否則會無限制的探索下去。
check_response_errors
方法該方法檢查對服務器的請求是否成功完成
should_sleep
方法在進行子域名收集的時候,為了避免類似于google搜索引擎的機器識別,應該設置休眠時間
enumerate
方法通過該方法獲取子域名
而以下的子域名檢索方法是由enumratorBase類派生出來的,然后根據各自的特點進行修改后形成的類,簡單的介紹一下功能
類名稱 | 實現的功能 |
---|---|
GoogleEnum | 通過google搜索引擎檢索目標子域名 |
YahooEnum | 通過雅虎搜索引擎檢索目標子域名 |
AskEnum | 通過http://www.ask.com/web檢索子域名 |
BingEnum | 通過bing檢索子域名 |
BaiduEnum | 通過百度檢索子域名 |
NetcraftEnum | 通過http://searchdns.netcraft.com/?restriction=site+ends+with&host={domain}檢測子域名 |
Virustotal | 通過'https://www.virustotal.com/en/domain/{domain}/information/檢索子域名 |
ThreatCrowd | https://www.threatcrowd.org/searchApi/v2/domain/report/?domain={domain}檢索子域名 |
CrtSearch | 通過https://crt.sh/?q=%25.{domain}檢索子域名 |
PassiveDNS | 通過http://ptrarchive.com/tools/search.htm?label={domain}檢索子域名 |
此外該腳本還提供端口掃描功能和字子域名字典枚舉的功能,雖然該項系統并未使用這些功能
postscan
函數關鍵代碼,使用socket模塊去嘗試連接目標端口,如果超過2s目標沒有回復,則判斷目標沒有開放該端口
for port in ports: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(2) result = s.connect_ex((host, int(port))) if result == 0: openports.append(port)
對與子域名枚舉功能,該腳本調用了subbrute.py中的函數,用于對字典中字符串拼成的子域名進行驗證操作。 關鍵代碼
bruteforce_list subbrute.print_target(parsed_domain.netloc, record_type, subs, resolvers, process_count, output, json_output, search_list, verbose) print_target函數是subbrute文件中的函數,用于驗證子域名是否是可用的
最后通過一個make_domain
函數將所有的以.txt
為后綴名的文件全部復制到all_reqult.log文件中,通過讀取后格式化處理,將結果存儲到report/result.txt文件中關鍵代碼如下
os.system() print() list_domain [] f open(, ) ...... f.close() os.system() list_domain list(set((list_domain))) print list_domain, len(list_domain) with open(, ) as outfile: outfile.write(.join(list_domain)) fopen1 open(, ) fopen1.write(.join(list_domain)) fopen1.close()
對于獲取Web網頁的信息,這里主要是獲取網頁使用的是什么框架或者CMS,通過本地提供的一個json規則檢測文件,對目標網站進行檢測和指紋識別json文件中部分規則如下:
{ : [ { : , : }, { : , : , : } ], : [ { : , : }, { : , : } ], : [ { : , : , : } ], : [ { : , : [, ] } ], : [ { : , : } ], ......
實現的過程是將report/result.txt
中所有的域名根據json文件中的規則進行url拼接,然后對這個特定URL進行訪問獲取網頁內容,再將網頁內容與規則進行匹配,最后判斷使用cms或者框架名稱。關鍵代碼如下
r requests.get(url1 rule[], ) r.encoding r.apparent_encoding r.close() rule and hashlib.md5(r.content).hexdigest() rule[]: print (url1, cms) rule and rule[] r.headers and rule[] r.headers[rule[]]: print (url1, cms) rule: type(rule[]) is list: itext rule[]: itext r.text: print (url1, cms) rule[] r.text: print (url1, cms) rule: type(rule[]) is list: reg rule[]: re.search(reg, r.text): print (url1, cms) re.search(rule[], r.text): print (url1, cms) : print
注意該腳本還引入了一個第三方模塊from thirdlib import threadpool
該threadpool是一個簡單的實現線程池的框架,方便使用腳本使用多線程。腳本中調用的關鍵代碼
pool threadpool.ThreadPool(self.thread_num) reqs threadpool.makeRequests(self.identify_cms, self.rules, self.log) req reqs: pool.putRequest(req) pool.wait()
在系統的主函數中通過接受該腳本stdout輸出的流數據,將數據寫入到一個列表中,最后將結果保存到report/whatweb.html
。
該系統的漏洞掃描模塊是調用的第三方腳本BBScan.py,該文件代碼實現了一個輕量級的web漏洞掃描器。使用的規則庫為存放在本地的一個txt文件中rules/commom.txt
部分規則如下:
/admin/ } /config/ } /manage/ } /backup/ } /backend/ } /admin.php } } /admin.jsp } } /admin.do } } /examples } /examples/servlets/servlet/SessionExample } /manager/html } /db/ } /DB/ } /data/ } /sqlnet.log } } /data/user.txt } } /user.txt } } /phpinfo.php } } /mysql/add_user.php } /cachemonitor/statistics.jsp } } /jmx-console/ } /jmx-console/HtmlAdaptor } /cacti/ } /cacti/cacti.sql } } /../../../../../../../../../../../../../etc/passwd } /config/config_ucenter.php.bak } /shell.php } /shell.jsp } /{hostname}.zip } } /resin-doc/resource/tutorial/jndi-appconfig/test/etc/passwd } /WEB-INF/web.xml } } /WEB-INF/web.xml.bak } } /.svn/ /.svn/entries } } /wp-login.php } } /config.inc }} /config.ini } }
腳本通過從這個文件中讀取規則,對目標進行測試,然后根據服務器返回的內容進行判斷是否存在該類型的漏洞。代碼簡介
def __init__(self, url, lock, , ): self.START_TIME time.time() self.TIME_OUT timeout self.LINKS_LIMIT self.final_severity self.schema, self.host, self.path self._parse_url(url) self.max_depth self._cal_depth(self.path)[1] depth self.check_404() self._status : return None not self.has_404: print % self.host self._init_rules() self.url_queue Queue.Queue() self.urls_in_queue [] _path, _depth self._cal_depth(self.path) self._enqueue(_path) self.crawl_index(_path) self.lock threading.Lock() self.results {}
方法簡介
_parse_url
方法:解析URL,如果沒有指定通信協議,系統自動添加為http協議。然后判斷url中是否存在路徑,如果不存在就返回"/",否則返回協議,主機名,和資源路徑
return _.scheme, _.netloc, _.path _.path
_cal_depth
:該方法是用于計算URL的深度,返回一個元組,url和深度。以//或者javascript開頭的URL不做分析,以http開頭的URL先對URL進行解析,然后判斷hostnane是否為目標的hostname,在判斷path路徑的深度。關鍵代碼如下
_ urlparse.urlparse(url, ) _.netloc self.host: url _.path 。。。。 url url[: url.rfind()] depth len(url.split())
_init_rules
:該方法從文件中加載規則,使用正則表達式從文件中的每一行提取數據,正則表達式如下
p_severity re.compile() p_tag re.compile() p_status re.compile() p_content_type re.compile() p_content_type_no re.compile()
提取數據并進行判斷,沒有的置為空或者0
_ p_severity.search(url) severity int(_.group(1)) _ _ p_tag.search(url) tag _.group(1) _ _ p_status.search(url) status int(_.group(1)) _ _ p_content_type.search(url) content_type _.group(1) _ _ p_content_type_no.search(url) content_type_no _.group(1) _
最后將重組的規則存放在一個元組中,最后將這個元組追加到一個列表中
self.url_dict.append((url, severity, tag, status, content_type, content_type_no))
_http_request
方法:通過該方法獲取訪問目標url的狀態碼,返回http頭部和html內容部分代碼如下
conn.request, url, {: } ) resp conn.getresponse() resp_headers dict(resp.getheaders()) status resp.status
_decode_response_text
方法:該方法對服務器返回的頁面進行解碼操作,如果用戶沒有指定charset類型,那么該方法就會嘗試使用'UTF-8', 'GB2312', 'GBK', 'iso-8859-1', 'big5'編碼對目標返回的內容進行解碼,并將解碼后的內容返回部分代碼
encodings [, , , , ] _ encodings: try: return rtxt.decode(_) except: pass
check_404方法
:檢查目標返回的頁面的狀態碼是否為404部分代碼如下
self._status, headers, html_doc self._http_request() self._status : print % self.host self.has_404 (self._status ) return self.has_404
_enqueue
方法:該方法是判斷爬取的URL是否是已經爬取的,如果是一個新的鏈接就傳入隊列中,該隊列用于爬蟲部分代碼
url self.urls_in_queue: return False len(self.urls_in_queue) > self.LINKS_LIMIT: return False : self.urls_in_queue.append(url)
還通過該方法將漏洞檢測規則對應到URL上,然后組成一個元組,將這個元組傳入一個用于掃描漏洞的隊列中,代碼如下
_ self.url_dict: full_url url.rstrip() _[0] url_description {: url.rstrip(), : full_url} item (url_description, _[1], _[2], _[3], _[4], _[5]) self.url_queue.put(item)
crawl_index方法
:該方法使用beautifulSoup4爬取頁面中的url鏈接。部分代碼如下
soup BeautifulSoup(html_doc, ) links soup.find_all() l links: url l.get(, ) url, depth self._cal_depth(url) depth < self.max_depth: self._enqueue(url)
_update_severity
方法:該方法用于更新serverity,如果規則中存在serverty字段,那么就將默認的final_serverity進行修改
severity > self.final_severity: self.final_severity severity
_scan_worker
方法:該方法是用于執行漏洞掃描的關鍵代碼如下
try: item self.url_queue.get.0) except: return try: url_description, severity, tag, code, content_type, content_type_no item url url_description[] prefix url_description[] except Exception, e: logging.error( % e) continue not item or not url: break 。。。。 status, headers, html_doc self._http_request(url) (status [200, , , ]) and (self.has_404 or status!self._status): code and status ! code: continue not tag or html_doc.find(tag) > : content_type and headers.get(, ).find(content_type) < or \ content_type_no and headers.get(, ).find(content_type_no) >: continue self.lock.acquire() not prefix self.results: self.results[prefix] [] self.results[prefix].append({:status, : % (self.schema, self.host, url)} ) self._update_severity(severity) self.lock.release()
scan
方法:這是一個多線程啟動器,用來啟動_scan_worker方法,最后返回測試的主機名,測試的結果和嚴重程度代碼如下
i range(threads): t threading.Threadself._scan_worker) threads_list.append(t) t.start() t threads_list: t.join() key self.results.keys(): len(self.results[key]) > : del self.results[key] return self.host, self.results, self.final_severity
通過直接調用nmap對目標進行掃描,掃描結果儲存在nmap_port_services.xml
中,啟動的命令為
nmap banner,http-headers,http-title nmap_port_services.xml
使用命令行調用AWVS對目標網站進行掃描,并在系統中啟用一個線程去監測該進程的運行情況,代碼如下
not os.path.exists(): time.sleep(20) print print popen subprocess.Popen( , subprocess.PIPE, subprocess.STDOUT) True: next_line popen.stdout.readline() next_line and popen.poll() ! None: break sys.stdout.write(next_line)
wvs.bat
的代碼如下:
@echo off /p please input wvs path,eg: [D:\Program Files (x86)\Web Vulnerability Scanner ]:: /f %%i (result.txt) ( %%i running %%i ...... /scan %%i /Profile default /SaveFolder d:\wwwscanresult\%pp%\ /save /Verbose )
首先是將nmap生成的XML文件通過import1.php腳本進行格式化后重新輸出,核心代碼如下:
@file_put_contents(, .., FILE_APPEND); print .; foreach (>port as ){ []; (int)[]; >script[]; >service[]; ; ..................; print ; @file_put_contents(, , FILE_APPEND); }
最后將所有的結果通過repoert_all
函數將結果進行整合,將這些文件的路徑匯總到left,html中。代碼如下:
html_doc left_html.substitute({: , : , : , : , : }) with open(, ) as outFile: outFile.write(html_doc)
對于該系統而言只能說是能夠滿足個人的使用,且后期代碼維護難度過大,不易進行擴展,使用第三方腳本時,直接是使用命令執行來獲取數據,而不是通過導入模塊的方式。不過系統的思路是值得借鑒的,尤其是在前期搜集子域名信息的時候是花了大功夫的,調用了很多第三方腳本,為的是盡可能的將目標的域名下的子域名收集完整,值得學習。而對于漏洞掃描模塊而言,即使用了第三方腳本,也是用的AWVS對目標進行掃描,對于BBScan這個掃描儲程序的規則設計值得學習,自定義化程度很高。總體來說整個掃描器的設計還是不錯的,只是將這些第三方腳本進行整合時就顯得有點倉促了。
感謝各位的閱讀!關于“網絡安全中漏洞自動化分析工具怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。