淺談web指紋識別技術

目前網絡上開源的web指紋識別程序很多,如Wapplyzer,BlindElephant,plecost,w3af,whatweb, wpscan, joomscan等等,基本都是國外的,使用的時候因各方面因素會有一些限制,在某些特定環境下需要自己定製指紋識別工具,本文會淺析這些指紋識別程序的原理以及如何編寫一個web應用指紋識別程序,完全沒有技術含量,有不妥的地方還望各種SM。

0×01:識別的幾種方式

目前常見的web應用指紋識別主要有以下幾種方式,澤總已經總結的很明確了。

1:網頁中發現關鍵字

2:特定文件的MD5(主要是靜態文件、不一定要是MD5)

3:指定URL的關鍵字

4:指定URL的TAG模式

以上4種模式結合起來識別的話正確率一般在95%以上,除非個別BT的站點修改的體無完膚,如meta、文件路徑、css等都刪除了或故意修改成其他的webapp等,那我只能說你屌爆了。

0×02:識別方式詳解

一般應用程序在html、js、css等文件中多多少少會包含一些特徵碼,這跟ips、waf等產品的特性有點類似,有特徵碼匹配模式。比如wordpress如果沒有特細隱藏的話,在robots.txt中會包含wp-admin之類,首頁index.php中會包含generator=wordpress 3.xx,後面爲版本號,頁面中會包含wp-content路徑等等。
這幾條都是存在網頁中的關鍵字。其他的應用也有類似的例子,如discuz、dedecms、phpwind等在頁面中都會發現一些固定的特徵碼。特徵碼如何查找這裏不詳細說明了,下期會有文章詳細說明如何批量查找特徵碼,接下來先介紹一下幾款常見的web應用指紋識別程序。

1:Wapplyzer

Wapplyzer是基於正則表達式來識別web應用的,如下圖:

仔細看看Wapplyzer的規則其實很簡單,挑一條看看,如下:

'WordPress':             { cats: { 1:  1, 2: 11 }, meta: { 'generator': /WordPress/i }, html: /

 

2:plecost

plecost是基於python架構,利用了Beautiful Soup 來解析html、xml文件識別網站使用的插件及版本。要了解plecost的原理,必須先知道Beautiful Soup是幹啥用的,簡單科普下Beautiful Soup:

Beautiful Soup 是一個 Python HTML/XML 處理器,設計用來快速地轉換網頁抓取。以下的特性支撐着 Beautiful Soup:

  • Beautiful Soup 不會選擇 即使你給他一個損壞的標籤。 他產生一個轉換DOM樹,儘可能和你原文檔內容含義一致 。這種措施通常能夠你搜集數據的需求。

  • Beautiful Soup 提供一些簡單的方法以及類Python語法 來查找、查找、修改一顆轉換樹:一個工具集幫助你解析一棵樹並釋出你需要的內容。你不需要爲每一個應用創建自己的解析工具。

  • Beautiful Soup 自動將送進來的文檔轉換爲 Unicode 編碼 而且在輸出的時候轉換爲 UTF-8,。 除非這個文檔沒有指定編碼方式或者Beautiful Soup 沒能自動檢測編碼,你需要手動指定編碼方式,否則你不需要考慮編碼的問題。

再看看plecost代碼,如下圖:

加載並讀取wp_plugin_list.txt,利用urlopen探測目標url是否存在該插件。Plecos編寫插件也非常方便,在wp_plugin_list.txt裏面寫上插件名稱、最新版本號和cve即可。

3:whatweb

whatweb是一個web應用程序指紋識別工具,可以鑑別出內容管理系統(CMS)、博客平臺、統計分析軟件、javascript庫、服務器和其他更多Web程序。whatweb擁有超過900個插件,插件是用來鑑別Web應用系統的。因此,開發者呼籲更多的人幫助開發插件,不用擔心作者聲稱插件是十分容易編寫的。
可以說whatweb是目前網絡上比較強大的一款應用識別程序了。它支持正則表達式、md5 hash匹配、url識別、HTML標記模式、蜘蛛爬行等等。

Whatweb插件編寫需要理解一些變量的定義,通過下面的例子就可以看出個大概,如下:

Plugin.define "Plone" doauthor "Andrew Horton"version "0.2"description "CMS http://plone.org"examples %w| www.norden.org www.trolltech.com www.plone.net www.smeal.psu.edu|dorks ['"powered by plone"']matches [{:name=>"meta generator tag",:regexp=>//},{:name=>"plone css",:regexp=>/(@import url|text\/css)[^>]*portal_css\/.*plone.*css(\)|")/}, #"{:name=>"plone javascript",:regexp=>/src="[^"]*ploneScripts[0-9]+.js"/}, #"{:text=>'

‘}, {:name=>”div tag, visual-portal-wrapper”, :certainty=>75, :text=>’


‘}, ] def passive m=[] #X-Caching-Rule-Id: plone-content-types #X-Cache-Rule: plone-content-types m << {:name=>”X-Caching-Rule-Id: plone-content-types” } if @meta["x-caching-rule-id"] =~ /plone-content-types/i m << {:name=>”X-Cache-Rule: plone-content-types” } if @meta["x-cache-rule"] =~ /plone-content-types/i m end end

{:name=>”meta generator tag”,  : 包含匹配的文件名稱,這個文件必須是網站中唯一存在的文件。

:regexp=>是包含的要匹配的模式,它是一個正則表達式,可以有以下選項:

:regexp 標準的ruby正則表達式

:text  字符

:ghdb google hack數據庫,包含以下幾個模式

inurl: 包含的字符串在url

intitle: 包含的字符串在title

filetype: 包含的文件名,如PDF, JPG, RB等

:md5 請求頁面的md5 hash值

:tagpattern html標籤

:version 可以設置正則表達式或直接字符串匹配

:string    可以設置正則表達式或直接字符串匹配

:filepath可以設置正則表達式或直接字符串匹配,通常顯示系統錯誤或配置文件等

:account 經常用在登陸頁面或用戶列表等

:module 可以設置正則表達式或直接字符串匹配,如網絡設備可能使用了一個ruby模塊等

:model 可以設置正則表達式或直接字符串匹配

:firmware 可以設置正則表達式或直接字符串匹配,設備的固件版本

瞭解了以上選項我們可以寫出一個簡單的識別discuz的插件,如下:

Plugin.define "discuz" doauthor "[email protected]" # 2012-05-28version "0.1"description "discuz - homepage: http://www.discuz.net/"# Examples #examples %w|www.discuz.net|matches [# Version detection # Powered by text{ :version=>// },{ :version=>/Powered by .*Discuz!.*([Xx\d\.]+)\s*/ }, # HTML Comment { :text=>'discuz_uid' }, ] end

運行如下圖:

更多whatweb插件開發參考:whatweb

0×03:如何編寫web指紋識別程序

現在網絡上做指紋識別用的最多的是BeautifulSoup,這個插件上面已經介紹過了,並且很多web應用指紋識別程序使用了該插件,這裏就不多介紹了,今天主要介紹下另外一個框架:scrapy

Scrapy,Python開發的一個快速,高層次的屏幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結  Scrapy Pthyon爬蟲框架 logo[1]構化的數據。Scrapy用途廣泛,可以用於數據挖掘、監測和自動化測試。

Scrapy吸引人的地方在於它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種類型爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支持。

Scrapy 使用 Twisted 這個異步網絡庫來處理網絡通訊,架構清晰,並且包含了各種中間件接口,可以靈活的完成各種需求。整體架構如下圖所示:

綠線是數據流向,首先從初始 URL 開始,Scheduler 會將其交給 Downloader 進行下載,下載之後會交給 Spider 進行分析,Spider 分析出來的結果有兩種:一種是需要進一步抓取的鏈接,例如之前分析的“下一頁”的鏈接,這些東西會被傳回 Scheduler ;另一種是需要保存的數據,它們則被送到 Item Pipeline 那裏,那是對數據進行後期處理(詳細分析、過濾、存儲等)的地方。另外,在數據流動的通道里還可以安裝各種中間件,進行必要的處理。

如果想做一個好的準確的,非常牛逼的web指紋識別,自然少不了爬蟲機制,而做一個爬蟲主要分兩部分:

一:下載 Web 頁面,有許多問題需要考慮,如何最大程度地利用本地帶寬,如何調度針對不同站點的 Web 請求以減輕對方服務器的負擔等。一個高性能的 Web Crawler 系統裏,DNS 查詢也會成爲急需優化的瓶頸。

二:一些“行規”需要遵循(例如 robots.txt)。而獲取了網頁之後的分析過程也是非常複雜的,Internet 上的東西千奇百怪,各種錯誤百出的 HTML 頁面都有,要想全部分析清楚幾乎是不可能的事;另外,隨着 AJAX 的流行,如何獲取由 Javascript 動態生成的內容成了一大難題;除此之外,Internet 上還有有各種有意或無意出現的Spider Trap ,如果盲目的跟蹤超鏈接的話,就會陷入 Trap 中萬劫不復了

不過,其實並沒有多少人需要做像 Google 那樣通用的 Crawler ,我們做一個 Crawler 就是爲了去爬特定的某個網站來進行指紋識別,所謂知己知彼,百戰不殆,我們可以事先對需要爬的網站結構做一些分析,事情就變得容易多了。通過分析,選出有價值的鏈接進行跟蹤,然後再進行指紋識別。這樣就可以避免很多不必要的鏈接或者 Spider Trap。

舉個例子,我們添加一個discuz的識別程序,
Discuz我簡單例了2個特徵碼如下:
頁面中meta標籤的generator屬性爲Discuz
robots.txt 裏面也會有版本信息

OK,以上2個特徵碼已經能簡單識別該應用了,我們利用scrapy來提取數據並識別應用。scrapy提取數據主要用到了XPath,它有提供兩個XPath選擇器,HtmlXPathSelector和XmlXPathSelector,一個用於HTML,一個用於XML,XPath選擇器有三個方法:

  • select(xpath): 返回一個相對於當前選中節點的選擇器列表(一個XPath可能選到多個節點)

  • extract(): 返回選擇器(列表)對應的節點的字符串(列表)

  • re(regex): 返回正則表達式匹配的字符串(分組匹配)列表

瞭解了以上方法,寫起來就比較簡單了,下面舉個非常簡單的例子:

from scrapy.spider import BaseSpiderfrom scrapy.selector import HtmlXPathSelectorfrom scrapy.utils.url import urljoin_rfc,urllib,reclass XSSSpider(BaseSpider):
	name="freebuf"
	allowed_domains=["freebuf.com"]
	start_urls=["http://forum.freebuf.com"]

	def parse(self, response):
		hxs = HtmlXPathSelector(response)
		c = hxs.select('//meta[@name="generator"]/@content').extract()
		urls = urljoin_rfc(response.url,"robots.txt")
		t = urllib.urlopen(urls)
		#print a
		a = re.findall("[Dd]iscuz.*",t.read())
		if (a or c):
				print "Web application details : Discuz"
		else:
			print "Web application version not found!"

到主項目目錄運行:scrapy crawl freebuf

以上只是個簡單的例子,當然你也可以多種條件結合到一起寫成插件的方式調用,如下:

FreebuF["WordPress"] = {
  '//meta[ () name="generator" and starts-with(@content,"WordPress")]',
  '//head/link[ () rel="stylesheet" and @type="text/css" and contains( @href, "/wp-content/")]',
  '//div[ () id="content"]/div[ () class="post" and starts-with(@id, "post-") and div[ () class="posttitle"] and div[
() class="postmeta"] and div[ () class="postbody"] and div[ () class="postfooter"]]',}

0×04:後續的一些思考

簡單的web應用識別不會涉及到爬蟲機制,但是如果需其他更詳盡的信息以及更準確的識別web應用,以及後期擴展其他功能,不可缺少的是爬蟲機制,而爬蟲也直接影響到程序的執行效率、速度是否夠快,識別是否準確等。這裏就涉及到大規模遞歸抓取了,如果使用scrapy來做爬蟲的話,可能要修改scrapy來處理以下幾個問題:

1:快速的link extractor

python的SGMLParser實在是太慢了,使用SgmlLinkExtractor會讓爬蟲把大部分的時間都浪費在解析網頁上,最好自己寫一個link extractor,也可以用正則表達式來寫link extractor,速度快,問題是不理解html語義,會把註釋裏的鏈接也包含進來。另外基於javascript重定向url也要在這裏提取出來。

2:Spider Trap

因爲spider trap一般是由動態網頁實現的,最簡單的方案就是先通過url是否包含”?”來判斷一個網頁是否是動態網頁,然後取得不包含參數的url地址,對這個地址進行計數,設置一個閾值,超過閾值之後不再抓取。

3:增量抓取

一個針對多個網站的爬蟲很難一次性把所有網頁爬取下來,並且網頁也處於不斷更新的狀態中,爬取是一個動態的過程,爬蟲支持增量的抓取是很必要的。

4:快速識別
爬蟲抓取數據的時候我們可以定位抓取的數據爲js、css、html等,也可指定特定的文件夾文件名稱,如gif、jpg、 png之類。

參考文章:

http://anantshri.info/articles/web_app_finger_printing.html
http://luoq.net/ais/1181/
http://www.biaodianfu.com/scrapy-architecture.html
http://blog.pluskid.org/?p=366


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章