爬蟲基礎篇[Web 漏洞掃描器]

2021-02-23 信安之路

本文作者: fatez3r0  已獲得作者授權轉載

本文博客地址:http://blog.fatezero.org/2018/03/05/web-scanner-crawler-01/

點擊 閱讀原文 直達博客

Web 漏掃的爬蟲和其他的網絡爬蟲的技術挑戰不太一樣,漏掃的爬蟲不僅僅需要爬取網頁內容、分析連結信息, 還需要儘可能多的觸發網頁上的各種事件,以便獲取更多的有效連結信息。 總而言之,Web 漏掃的爬蟲需要不擇手段的獲取儘可能多新的連結信息。

在這篇博客文章中,我打算簡單地介紹下和爬蟲瀏覽器相關內容,爬蟲基礎篇倒不是說內容基礎,而是這部分內容在漏掃爬蟲中的地位是基礎的。

0x01 QtWebkit or Headless Chrome

QtWebkit or Headless Chrome, that is a question

QtWebkit 還是 Headless Chrome,我們一個一個分析。

QtWebkit

我們先說一下在漏掃爬蟲和 QtWebkit 相關的技術:

1、使用 QtWebkit

2、使用 PhantomJS (基於 Qt 編寫)

3、使用 PyQt (一個 Python 的 Qt bindings)

這也是我之前在 TangScan 調研 QtWebkit 系列的時候面對的技術,當時就首先就排除了 PyQt, 因為在 PyQt 中沒有辦法自定義 QPA 插件,如果不借用 xvfb, 是沒法在沒有 X Server 的伺服器上跑起來的,本來 PyQt 已經夠慢,再加上一個 xvfb,那就更慢了,所以直接排除 PyQt。

接著討論 PhantomJS,PhantomJS 的優點是簡單,不需要再次開發,直接使用 js 就可以操作一個瀏覽器, 所以 TangScan 內部的第一個版本也選擇了 PhantomJS,但後面也發現了 PhantomJS 的不足。

首先 PhantomJS 可以使用 js 操作瀏覽器是個優點,但也必須多出一個 js context (QWebPage) 開銷,而且有時候 js 的 callback 在一些情況下沒有被調用。 其次我所需要的功能 PhantomJS 並沒有提供,然而在 QtWebkit 中可以實現。

所以 TangScan 內部的第二版,我選擇了使用 QtWebkit 來重新寫一個類似 PhantomJS 的東西 (內部名為 CasterJS,AWVS 也是用 QtWebkit 寫了個名為 marvin 的爬蟲)。

但是直接使用 QtWebkit 還是有問題。 首先自從 Qt5.2 之後,對應的 WebKit 引擎就沒有再更新過,別說支持 ES6 了,函數連 bind 方法都沒有。 其次內存洩漏問題嚴重,最明顯的情況就是設置默認不加載圖片 QWebSettings::AutoLoadImages 的時候,內存使用率蹭蹭地往上漲。 最後也是最嚴重的問題,穩定性欠缺,也是自己實現了 CasterJS 之後才知道為什麼 PhantomJS 上為什麼會有那麼多沒處理的 issue, 這個不穩定的原因是第三方庫不穩定 (老舊的 Webkit),自己還不能更換這個第三方庫。 當時在 TangScan 的時候,就非常頭疼這些明知道不是自己的鍋、解決起來特麻煩、還必須得解決的問題。

所以如果沒有其他選擇,QtWebkit 忍一忍還是能繼續使用下去,但是 Headless Chrome 出現了。

Headless Chrome

Chrome 的 Headless 模式在 2015-08 開始低調開發,2016-06 開始對外公開,2017-04 在 M59 上正式發布。

後來 PhantomJS 的開發者 Vitaly Slobodin 在 PhantomJS 郵件組發出了公告 \[Announcement\] Stepping down as maintainer:

https://groups.google.com/forum/#!topic/phantomjs/9aI5d-LDuNE

聽到這個消息我真的一點都不意外,在 TangScan 中,也是使用 Qt 從頭開發起 CasterJS 的我來說, 已經受夠了由於老舊的 Webkit 版本帶來的各種 crash,內存洩漏,QtWebkit 這個坑實在是太坑了。

Vitaly Slobodin 在當時作為 PhantomJS 唯一的主要開發者, 面對著 PhantomJS 項目上那接近 2k 的 issue,心有餘而力不足,而且 crash 問題佔多數。

雖然說很多問題上遊的 Webkit 已經解決了,但偏偏 Qt 一直綁定的都是 Webkit 幾年前的版本, 所以 Vitaly Slobodin 就真的自個單獨維護一個 QtWebkit 倉庫,用於專門解決這樣的問題。

但是作為 PhantomJS 唯一的開發者,既要開發新功能,又要持續跟進 QtWebkit 各種 BUG,力不從心。 然後雪上加霜的是 Qt 在 Qt 5.2 的時候宣布打算放棄 QtWebkit,不在進行更新,轉而使用基於 Chromium 的 QWebEngine 取代 QtWebkit。

雖然後來 annulen

https://github.com/annulen/webkit/releases

扛起了大旗,說要繼續維護 QtWebkit,要從 Webkit 那裡一點一點地更新代碼, 但個人開發速度還是比不上一個團隊。

這個時候 Headless Chrome 出來了,Vitaly Slobodin 在這個時候退出 PhantomJS 的開發是最好的選擇了。

Headless Chrome 的出現也讓我哭笑不得,哭的原因是因為 Headless Chrome 讓我在 TangScan 開發的 CasterJS 變得毫無意義, 笑的原因因為 Headless Chrome 比其他基於 QtWebkit 寫的 Headless 瀏覽器更快速、穩定、簡單,讓我跳出了 QtWebkit 這個坑。

誇了那麼久 Headless Chrome 不過也並不代表 Headless Chrome 毫無缺點, 首先 Chrome 的 Headless 模式算是一個比較新的特性,一些功能還不算完善,只能等官方實現或者自行實現(比方說 interception 這個功能我就等了幾個月)。

其次 CDP 所提供的 API 不穩定,還會存在變動(比方說 M63 和 M64 中 Network.continueInterceptedRequest 的變動), 所以在使用 Headless Chrome 的時候,一定要先確定的 Chrome 版本,再編寫和 CDP 相關的代碼。

當然我也發現有些公司內部掃描器在使用 IE,大致過了一遍代碼,我個人並不覺得這是個好方案,所以我還是堅持使用 Headless Chrome。

0x02 小改 Chromium

OK,既然我們已經選定了 Headless Chrome,是不是可以擼起袖子開始幹了呢,很抱歉, 目前 Headless Chrome 還是不太滿足我們掃描器爬蟲的需求,我們還需要對其代碼進行修改。

官方文檔很詳細的介紹了如何編譯、調試 Chromium,只要網絡沒問題,一般也不會遇到什麼大問題,所以這裡也沒必要介紹相關知識。

hook location

我們先看一下這個例子

<script>
window.location = '/test1';
window.location = '/test2';
window.location = '/test3';
</script>

這個場景面臨的問題和 wivet - 9.php:

https://github.com/bedirhan/wivet/blob/master/pages/9.php

有點兒類似: 怎麼樣把所有跳轉連結給抓取下來?

可能熟悉 QtWebkit 的同學覺得直接實現 QWebPage::acceptNavigationRequest 虛函數就可以攔截所有嘗試跳轉的請求。

可能熟悉 Headless Chrome 的同學會說在 CDP 中也有 Network.continueInterceptedRequest 可以攔截所有網絡請求,當然也包括跳轉的請求。

但實際上這兩種方法都只能獲取到最後一個 /test3 連結,因為前面兩次跳轉都很及時的被下一次跳轉給中斷了, 所以更不會嘗試發出跳轉請求,類似 intercept request 的 callback 就不可能獲取到所有跳轉的連結。

要是 location 能夠使用 defineProperty 進行修改,那問題就簡單多了。但是在一般的瀏覽器中 location 都是 unforgeable 的,也就是不能使用 defineProperty 進行修改, 不過現在 Chromium 代碼在我們手上,所以完全可以將其修改為可修改的,直接修改 location 對應的 idl 文件即可:

測試代碼:


<script>
Object.defineProperty(window, "location", {
   set: function (newValue) {
       console.log("new value: " + newValue);
   },
   get: function () {
       console.log("get value");
       return 123;
   }
})

console.log(document.location);
console.log(window.location);
</script>

修改前:

修改後:

我之所以覺得偽造 location 這個特性很重要,是因為不僅僅在爬蟲中需要到這個特性,在實現 DOM XSS 檢測的時候這個特性也非常重要, 雖然說 Headless Chrome 官方文檔上有提過將來可能會讓用戶可以自由 hook location 的特性 (官方文檔上也是考慮到 DOM XSS 這塊), 但過了將近一年的時間,也沒有和這個特性的相關消息,所以還是自己動手豐衣足食。

popups 窗口

我們再來看看這個例子


<form action="http://www.qq.com" method="post" name="popup" target="_blank">
   <input type="submit" style="display:none"/>
</form>

<script type="text/javascript">
   document.getElementsByName("popup")[0].submit();
</script>

在 Headless Chrome 中會直接彈出一個 popups 窗口,CDP 只能禁止當前 page 跳轉,但是沒辦法禁止新 page 創建, 在 QtWebkit 中並沒有這樣的煩惱,因為所有的跳轉請求都由 QWebPage::acceptNavigationRequest 決定去留。

這個問題是 DM 同學提出來的,當時他和我討論該問題。其實當時我也沒有解決方法,於是我跑去 Headless Chrome 郵件組問了開發人員

Is there any way to block popups in headless mode?

https://groups.google.com/a/chromium.org/forum/#!topic/headless-dev/gmZU6xBv3Jk

開發人員建議我先監聽 Page.windowOpen 或 Target.targetCreated 事件,然後再使用 Target.closeTarget 關閉新建的 popups 窗口。

那麼問題就來了,首先如果等待 page 新建之後再去關閉,不僅僅浪費資源去新建一個無意義的 page,而且 page 對應的網絡請求已經發送出去了,如果該網絡請求是一個用戶退出的請求,那麼事情就更嚴重了。 其次開發人員推薦的方法是沒法區分新建的 page 是在某個 page 下新建的,還是通過 CDP 新建的。所以 Headless Chrome 開發人員的建議我並不是特別滿意。

得,最好的辦法還是繼續修改代碼,使其在 page 中無法新建 page:

忽略 SSL 證書錯誤

在 Headless Chrome 對外公開之後很長一段時間內,是沒法通過 devtools 控制忽略 SSL 證書錯誤的,也沒辦法去攔截 Chrome 的各種網絡請求。

直到 2017-03

https://bugs.chromium.org/p/chromium/issues/detail?id=659662

才實現了在 devtools 上控制忽略 SSL 證書錯誤的功能。

直到 2017-06

https://groups.google.com/a/chromium.org/forum/#!topic/headless-dev/uvms04dXTIM

才實現了在 devtools 可以攔截並修改 Chrome 網絡請求的功能。

這兩個特性對於掃描器爬蟲來說非常重要,尤其是攔截網絡請求的功能,可偏偏這兩功能結合在一起使用的時候,就會出現 BUG, 在 puppeteer 上也有人提了 ignoreHTTPSErrors is not working when request interception is on

https://github.com/GoogleChrome/puppeteer/issues/1159

直至現在(2018-03-05),Google 也並沒有修復該 BUG,我還能說啥呢,還是自己動手,豐衣足食。

最簡單的方法就是修改 Chromium 代碼直接忽略所有的網站的 SSL 證書錯誤,這樣也省了一個 CDP 的 callback,修改如下:

測試環境 badssl.com

https://badssl.com/

在 Chromium 中還有一些其他可改可不改的地方,這裡就不繼續吐槽了。

0x03 總結

OK,折騰了那麼久,終於把一個類似 wget 的功能實現好了(笑, 相對於我之前基於 QtWebkit 從頭實現一個類似 PhantomJS 的 CasterJS 來說, 目前使用 Headless Chrome 穩定、可靠、快速,簡直是漏掃爬蟲的不二選擇。

這篇博客就簡單講了一下和漏掃爬蟲相關的 Headless 瀏覽器的知識,接下來就到了漏掃爬蟲中最為重要的一點, 這一點也就決定了漏掃爬蟲連結抓取效果是否會比其他掃描器好,能好多少,這都會在掃描器的下一篇文章中繼續介紹。

相關焦點

  • 爬蟲 JavaScript 篇[Web 漏洞掃描器]
    0x00 前言上一篇主要講了如何通過修改 Chromium 代碼為 Web 漏洞掃描器的爬蟲打造一個穩定可靠的
  • Web漏洞掃描器-Xray使用基礎
    /xray webscan --plugins cmd_injection --url http://example.com/目前提供的插件列表如下:SQL 注入檢測 (key: sqldet):支持報錯注入、布爾注入和時間盲注等XSS 檢測(key: xss):支持掃描反射型、存儲型 XSS命令/代碼注入檢測 (key: cmd_injection)
  • Web漏洞掃描器的設計與實現(一)
    目前主流的漏洞掃描器大概分為以下三類。主動型:直接主動發起掃描請求。只需要點到即可,驗證漏洞,不需要後續的漏洞利用環節。https://shell01.top/2018/11/11/web-scan-01/ - 信息收集其中信息收集不管是在人為的滲透測試,還是掃描器中都是至關重要的一步,沒有信息收集,那就不會為下一步的發現漏洞做鋪墊,越多的信息對整個滲透測試或者掃描過程來說都是愈好的。
  • web漏洞掃描器 Acunetix 10中文介紹
    倫敦時間,2015年6月24日發布了Acunetix 10,這是非常好用的一款web漏掃,國外很多同類產品還是比不上它的,國內的破漏掃就更不用說了。這包括可以掃描使用單點登錄(SSO)和基於OAuth認證的Web應用程式。它極大地提高了反CSRF令牌能力,隨機數或其它一次性令牌都是經常用在限制區域的。2、檢測WP核心和WP插件的漏洞。
  • 【乾貨分享】Django 初次嘗試編寫 Web 漏洞掃描器挖坑記錄
    漏洞檢測實際上國光我一開始是不打算寫的,因為我對漏洞檢測的算法沒有信心,另外國光也看了網上那些看上去 NB 哄哄的 Web 漏掃,發現漏洞檢測的效果也就是 just soso。但是一個掃描器還是要有漏洞檢測功能的,所以國光在寫這個功能前把 AWVS 13 APi 全部親自測試了一遍,然後把長亭科技的 xray 的官方文檔也過了一遍。
  • 掃描器倉庫 - Scanners Box
    /boy-hack/gwhatweb (CMS識別 python gevent實現)https://github.com/Mosuan/FileScan (敏感文件掃描 / 二次判斷降低誤報率 / 掃描內容規則化 / 多目錄掃描)https://github.com/Xyntax/FileSensor (基於爬蟲的動態敏感文件探測工具)https://github.com
  • 今日好書丨《白帽子講Web掃描》
    《白帽子講Web掃描》Web掃描器首著問世 從零開始學習和開發屬於自己的Web掃描器建立自己的Web掃描體系 小編推薦:本書關鍵詞:Web 2.0爬蟲,掃描設計,漏洞審計,雲掃描,企業掃描,掃描反制。第 1章為掃描器基礎,主要介紹掃描器的一些基礎和必備知識,幫助讀者更快地進入掃描器的世界並開始進行有目標的學習。第 2章和第 3章分別為 Web爬蟲基礎和 Web爬蟲進階。
  • 黑客喜歡的掃描器盒子
    · https://github.com/ring04h/wyportmap(目標埠掃描+系統服務指紋識別)· https://github.com/ring04h/weakfilescan(動態多線程敏感信息洩漏檢測工具)· https://github.com/EnableSecurity/wafw00f(標識和指紋web應用防火牆)·
  • 最好用的開源Web漏洞掃描工具梳理
    如果你在用WordPress,SUCURI的另一份報告也顯示,超過70%的被掃描網站也都存在一個或多個漏洞。如果你剛好是某個網絡應用程式的所有者,怎樣才能保證你的網站是安全的、不會洩露敏感信息?如果是基於雲的安全解決方案,那麼可能只需要進行常規漏掃。但如果不是,我們就必須執行例行掃描,採取必要的行動降低安全風險。
  • Web掃描器淺析
    Web 掃描器可以自動地檢查Web 應用程式的安全弱點和風險,它主要通過探測和分析Web應用的響應,從而發現其中潛在的安全問題和架構缺陷。4、常見的掃描器下面介紹幾種常見的掃描器。(1)Acunetix Web Vulnerability ScannerAcunetix Web Vulnerability Scanner 是一款國外知名的 Web 應用安全掃描器,運行在Windows平臺,可以檢測Web應用程式中的SQL注入漏洞、XSS跨站腳本漏洞、敏感信息洩露等常見 Web 漏洞。
  • Web滲透-掃描工具之burpsuite
    紅客突擊隊Web滲透——掃描工具之burpsuite前言
  • 第四十八節課 信息收集之WEB安全漏洞掃描
    信息收集之Web漏洞掃描Web漏洞掃描器實在是太多了。
  • 主流WEB漏洞掃描器種類及其指紋特徵分析
    ,有收費的,也有免費的,國內的大部分都是收費的,除了長亭的X-ray,但是長亭的Xray高級版一樣是收費的,其開放的是社區版,而我們日常滲透中常用的WEB漏洞掃描器可能就是AWVS、Nessus、APPScan這三款。
  • Web應用漏洞掃描:將運維理念融合
    本篇,我們將注重Web應用漏洞掃描產品應用場景與業務需求現狀,從安全運維角度展開探討:將資產和任務管理雙結合 融合網站安全運維理念的Web漏洞掃描產品,必須具備站點信息全面搜集和多級權限分離的功能。無損式掃描,保障網站運行 融合網站安全運維理念的Web漏洞掃描產品,必須具備無損掃描能力,來儘可能地降低掃描全過程對目標站點的幹擾,保障網站業務持續運行。目前這方面的創新技術層出不窮,但簡單歸納有如下幾方面:速度自調節。
  • xray掃描器使用
    --url-file value  從本地批量讀取並掃描這些url--url value  掃描單個url--data value  數據字符串通過POST--raw-request File  從一個文件中加載原始的http請求--json-output File 文件輸出結果到json格式的文件--html-output
  • 被動掃描器之插件篇
    最近被動掃描器的話題如火如荼,好多公司都在做自己的被動掃描器。而獲取質量高的流量是被動掃描器起作用的關鍵。
  • 十大Webserver漏洞掃描工具
    只是,並不是每一次檢查都能夠找出一個安全問題,儘管多數情況下是這種。有一些項目是僅提供信息(「info only」 )類型的檢查,這種檢查能夠查找一些並不存在安全漏洞的項目,只是Web管理員或安全project師們並不知道。這些項目通常都能夠恰當地標記出來。為我們省去不少麻煩。2.
  • 網絡安全掃描平臺 - Gryffin
    環境要求:       Go       PhantomJS, v2       Sqlmap (for fuzzing SQLi)       Arachni (for fuzzing XSS and web vulnerabilities)
  • 不懂漏洞掃描?看這篇就懂了!
    漏洞掃描系統是用來自動檢測遠程或本地主機安全漏洞的程序(安全漏洞通常指硬體、軟體、協議的具體實現或系統安全策略方面存在的安全缺陷)。漏洞掃描按功能大致可分為:作業系統漏洞掃描、網絡漏洞掃描和資料庫漏洞掃描。
  • 利用chrome_remote_interface實現程序化、自動化Web安全測試
    方案肯定是有的,簡單來說要實現自動化web安全測試無非要解決幾個問題,首先是流量怎麼產生?然後是怎麼從流量中分析出漏洞?自動化測試方案:主動掃描器  市面上基於爬蟲的主動掃描器就是一種自動化安全測試工具,首先它的流量是通過爬蟲爬取url主動產生的,然後利用一些漏洞插件去構造不同的訪問請求。