HTTP協(xié)議入門與Fiddler抓包

HTTP協(xié)議入門與Fiddler抓包

堅(jiān)果 Jimbowhy 前后端腳本編程輕松篇集合文章:

HTTP 基礎(chǔ)

關(guān)于HTTP協(xié)議的完整資料在RFC2616, 這個(gè)文檔事無巨細(xì)地記錄相關(guān)內(nèi)容, RFC 全稱 Request For Comments.

先不必理會(huì)HTTP是基于TCP/IP協(xié)議的應(yīng)用層協(xié)議, HTTP可以簡(jiǎn)單理解一個(gè)約定, 一個(gè)用文本進(jìn)行約定的協(xié)議, 它本來面目就很容易看得懂, 只要有記事本就可以. 典型的HTTP是在瀏覽器和服務(wù)器之間使用的, 瀏覽器作為客戶端, 向服務(wù)器發(fā)送請(qǐng)求, 服務(wù)器接收到請(qǐng)求后進(jìn)行響應(yīng). 比如我要打開樹莓派的官方網(wǎng)站, 那么首先就要在瀏覽器的地址欄上輸入網(wǎng)址, 然后確認(rèn). 瀏覽器則根據(jù)地址構(gòu)造一個(gè)HTTP協(xié)議包, 然后通過TCP/IP聯(lián)網(wǎng)發(fā)送出去. 一個(gè)常見的HTTP請(qǐng)求包如下:

GET https://www.raspberrypi.org/ HTTP/1.1
Host: www.raspberrypi.org
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Chrome/55.0.2883.87
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: _ga=GA1.2.1434384935.1525184955; _gid=GA1.2.2106067700.1525184955

這是一個(gè)典型的只有頭部的HTTP協(xié)議包, 雖然一個(gè)完整包應(yīng)該包含協(xié)議頭和數(shù)據(jù)部分, 但數(shù)據(jù)部分是可選的. HTTP協(xié)議頭的第一行一定是一個(gè)單詞開頭表示一個(gè)請(qǐng)求動(dòng)作, 常見的如POST/GET, 這兩種方法也是網(wǎng)頁(yè)在提交表單時(shí)常用的. 動(dòng)作后面又跟著服務(wù)器地址, 地址后是協(xié)議版本號(hào), 通常是 HTTP/1.1. 第二行是服務(wù)器主機(jī)域名, 服務(wù)器一個(gè)IP地址可以配置運(yùn)行多個(gè)網(wǎng)站, 這個(gè)域名在服務(wù)器端就稱為虛擬主機(jī). 根據(jù)這個(gè)域名, 服務(wù)器會(huì)將接受到的請(qǐng)求, 網(wǎng)站默認(rèn)端口是80, 發(fā)送到相應(yīng)的網(wǎng)站程序, 交由程序來響應(yīng)客戶端的請(qǐng)求. 如以下是來自樹莓派服務(wù)器的響應(yīng):

HTTP/1.1 200 OK
Date: Tue, 01 May 2018 16:42:40 GMT
Server: Apache/2.4.10 (Debian)
Link: <https://www.raspberrypi.org/wp-json/>; rel="https://api.w.org/"
Link: <https://www.raspberrypi.org/>; rel=shortlink
Vary: Accept-Encoding
Content-Security-Policy: upgrade-insecure-requests; default-src https: data: 'unsafe-inline' 'unsafe-eval'; report-uri https://e46468ffd14a954844abf8fe208613d8.report-uri.com/r/d/csp/enforce
X-Clacks-Overhead: GNU Terry Pratchett
X-Served-By: piautoblog2
Content-Length: 37949
Connection: close
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
......

這里就是一個(gè)完整的HTTP協(xié)議包, 含有HTTP協(xié)議頭和數(shù)據(jù)兩部分, 數(shù)據(jù)只顯示一部分, 其余的省略. 協(xié)議頭和數(shù)據(jù)以兩個(gè)換行符分割, <!DOCTYPE html> 這句開始到結(jié)束部分就是數(shù)據(jù), 因?yàn)檎?qǐng)求的是網(wǎng)頁(yè), 所以返回的就是HTML頁(yè)面, 如果請(qǐng)求的是圖像, 那這里的數(shù)據(jù)就是二進(jìn)制數(shù)碼. 協(xié)議頭還有其他一些字段設(shè)置, 如 Server 表示服務(wù)是什么軟件搭建的, 這里是 Apache/2.4.10, Debian 則是linux操作系統(tǒng). 常用的還有 lighttped, nginx, iis, tomcat 等等. Content-Length 這個(gè)字段表示數(shù)據(jù)部分的字節(jié)數(shù), Content-Type 表示數(shù)據(jù)內(nèi)容如格式, 即HTML文本, 并且按 UTF-8 編碼.

這兩個(gè)步驟就是一個(gè)完整的HTTP通信, 這樣的一種發(fā)起請(qǐng)求-響應(yīng)結(jié)束的連接稱之為短連接, 這就是所謂的無狀態(tài)連接. 最早期的設(shè)計(jì)就是這樣簡(jiǎn)單的需求, 根本不需要什么狀態(tài), 只要能在地球另一端看到網(wǎng)頁(yè)就是 Perfect. 可是后來世界變了, 網(wǎng)站功能不再是一個(gè)只提供網(wǎng)頁(yè)的服務(wù)器了. 網(wǎng)站變得更像是一個(gè)完整的程序了, 它需要為通過瀏覽器連接服務(wù)器的用戶提供更復(fù)雜的功能, 比如說網(wǎng)購(gòu), 如果還像以前那樣, 瀏覽器發(fā)起請(qǐng)求-服務(wù)器響應(yīng)結(jié)束, 當(dāng)用戶在次進(jìn)入服務(wù)器是, 服務(wù)器根本不知道是誰, 是不是剛才的那位用戶, 因?yàn)榉?wù)器根本沒有幾錄用戶的相關(guān)信息.

一個(gè)解決方法是在客戶端使用 Cookie 或在服務(wù)器端使用 Session, 它們的產(chǎn)生都是為了解決無狀態(tài)連接的, 每一個(gè)用戶通過一個(gè)ID, 叫 SessionID 來實(shí)現(xiàn)連接狀態(tài)管理. 客服端使用 Cookie 又有很大的局限, 因?yàn)橛脩粢粋€(gè)不爽就可以關(guān)掉不用, 這時(shí)只在服務(wù)端記錄 Session 也沒用, 因?yàn)榭蛻舳藳]有發(fā)送關(guān)聯(lián)的 Cookie 到服務(wù)器, 網(wǎng)站程序根本無法知道是誰在請(qǐng)求網(wǎng)頁(yè), 這種情況下只是通過URL地址來傳輸 SessionID. 服務(wù)器想給客戶端設(shè)置 Cookie 時(shí), 會(huì)在協(xié)議頭添加一個(gè) Set-Cookie 字段, 瀏覽器收到后會(huì)將 Cookie 值保存下來, 在下次發(fā)出請(qǐng)求時(shí)將 所有 Cookie 信息回傳到服務(wù)器, 這個(gè)過程就可以實(shí)現(xiàn)連接狀態(tài)的保持:

注意看請(qǐng)求包的協(xié)議頭, Connection 字段指定了一個(gè) keep-alive 值, 也就是瀏覽器向服務(wù)器表達(dá)在TCP/IP層保持連接的意愿, 而服務(wù)器返回的是 Connection: close, 告訴客戶端, 連接已經(jīng)關(guān)掉了. 從客戶端來看, 保持連接是正確的做法, 請(qǐng)求一個(gè)網(wǎng)頁(yè), 很大可能還要一堆的資源文件如JS腳本, CSS樣式表, 其他一些圖片才能完成網(wǎng)頁(yè)的渲染, 保持連接更省資源. 而服務(wù)器可以完全不必理會(huì), 我行我素, 直接關(guān)掉連接, 客戶端只好在重新發(fā)起連接, 請(qǐng)求其他資源文件. 所以, 這一點(diǎn)來看, HTTP是一個(gè)不嚴(yán)格的應(yīng)用協(xié)議.

關(guān)于POST和GET方法, 在提交網(wǎng)頁(yè)表單時(shí)更能體現(xiàn)差別. GET方法提交表單, 表單的數(shù)據(jù)會(huì)被編碼到URL上, 作為請(qǐng)求地址的一部分, 也就是說瀏覽頁(yè)面的用戶可以直接在地址欄看到數(shù)據(jù). 而POST方法則不是, 它會(huì)將表單數(shù)據(jù)編碼到HTTP協(xié)議包的數(shù)據(jù)部分, 在表單的數(shù)據(jù)量大時(shí)就必須要這種方式來處理, 因?yàn)閁RL是有長(zhǎng)度限制的.

關(guān)于協(xié)議頭字段 Referrer, HTTP 協(xié)議中有一個(gè)字段用來表示當(dāng)前請(qǐng)求的來源,于上世紀(jì) 90 年代提出來,當(dāng)時(shí)把這個(gè)請(qǐng)求頭叫做 Referer,并最終寫進(jìn)了 RFC1945,即 HTTP/1.0 協(xié)議. 這個(gè)拼寫是錯(cuò)誤的, 正確的是 Referrer 即引薦者. 當(dāng)這個(gè)錯(cuò)誤被發(fā)現(xiàn)時(shí),已經(jīng)被大量使用各大網(wǎng)站社區(qū)了, 修改它似乎成本很高. 于是, 這個(gè)誤用就延續(xù)至今, 下面這段描述來自于 RFC2616,也就是著名的 HTTP/1.1 協(xié)議:

The Referer[sic] request-header field allows the client to specify, for the server's benefit, the address (URI) of the resource from which the Request-URI was obtained (the "referrer", although the header field is misspelled.)via

Fiddler工作原理

MITM攻擊,即中間人攻擊(Man-in-the-middle-attacks,簡(jiǎn)稱:MITM攻擊),是一種電腦黑客的攻擊模式。在 client 發(fā)出的請(qǐng)求、web server 返回?cái)?shù)據(jù)之間,布置一個(gè)代理服務(wù)器 proxy server 進(jìn)行轉(zhuǎn)發(fā),這個(gè) proxy server 就起到了一個(gè) middle man 的作用,F(xiàn)iddler 就是充當(dāng)這個(gè)中間人,代理設(shè)置在菜單 Tools -》Fiddler Options -》Connections,打開Fiddler的抓包功能后,它會(huì)自動(dòng)設(shè)置WinINET,將流量路由到Fiddler的代理服務(wù)器上來。

Fiddler主界面主要分為三塊, 上面是標(biāo)準(zhǔn)的菜單區(qū), 左側(cè)是請(qǐng)求列表, 右側(cè)是主功能區(qū), 選擇一個(gè)請(qǐng)求, 然后選擇一個(gè)功能如 Inspector, 它就會(huì)對(duì)請(qǐng)求進(jìn)行分析.

Inspector 提供了多種視圖, Headers 用來顯示請(qǐng)求和響應(yīng)的HTTP協(xié)議頭部信息. SyntaxView 則顯示語法高亮, 如 HTML, CSS, XML, Scripts 等內(nèi)容, 所以在響應(yīng)頭上使用. WebForm 視圖則是將POST/GET提交的表單以表格形式顯示出來. HexView 非常有用, 它可以將完整的 HTTP 協(xié)議包以十六進(jìn)制數(shù)碼顯示出來, 這對(duì)分析 HTTP 協(xié)議很有必要. 與之相似的 Raw 視圖則把 HTTP 協(xié)議包當(dāng)字符串來顯示, 假設(shè)請(qǐng)求響應(yīng)的二進(jìn)制文件等內(nèi)容, Raw 視圖就夠嗆, 如果內(nèi)容很多, Fiddler 突然就會(huì)卡了. WebView 和 ImageView 則是將響應(yīng)內(nèi)容當(dāng) HTML 和圖片來顯示. JSON 視圖可以將響應(yīng)的內(nèi)容按樹形視圖顯示, 如果內(nèi)容是 JSON 格式.

除了 Inspector 這個(gè)主要功能, Fiddler 還有 HTTP 協(xié)議包構(gòu)造器 Composer, 可以用他來構(gòu)造出任意的 HTTP 請(qǐng)求包, AutoResponder 是 Composer 的加強(qiáng)版, 通過制定規(guī)則, 可以實(shí)現(xiàn)自動(dòng)響應(yīng)客戶端的請(qǐng)求. 此外還有統(tǒng)計(jì)功能 Statistics, 日志記錄 Log, 過濾器 Filters 等.

要開始抓包, 可以按下快捷鍵 F12, 或界面左下角的區(qū)域點(diǎn)擊一下, 又或者在文件菜單選擇 Capture Traffic.

提示 Fiddler 右下角的 Quickexec 使用, 這是一個(gè)命令行工具, 可以通過快捷鍵 Alt+Q 激活, 然后快捷鍵 Ctrl+I 可以將當(dāng)前選中的 Session 的地址粘貼到這里, 確認(rèn)就可以在瀏覽器打開. 如果 Fiddler 不是處于激活狀態(tài), 全局快捷鍵 CTRL+ALT+F 可以激活 Fiddler.

?sometext: 查找URL中含有 sometext 的 Session

>size: 選擇響應(yīng)內(nèi)容字節(jié)數(shù)大于size的 sessions, 類似的還有 <size, 可以使用k做單位

=status: 選擇指定狀態(tài) Session
=method: 選擇指定請(qǐng)求方法的 Session
    =301 <-- Select 301 redirect responses
    =POST <-- Select POST requests

@host: 選擇指定主機(jī)的 Session
    @msn.com <-- Select www.msn.com, login.msn.com, etc

bold: 粗體標(biāo)記后續(xù)URL包含指定字符串的 sessions 
    bold /bar.aspx
    bold        <-- Call with no parameter to clear

bpafter: 設(shè)置斷點(diǎn) RequestURI 包含指定字符串時(shí)終斷
    bpafter /favicon.ico 
    bpafter        <-- Call with no parameter to clear

bps: 按響應(yīng)代碼設(shè)置中斷
    bps 404
    bps        <-- Call with no parameter to clear

bpv or bpm: 按請(qǐng)求方法POST/GET等設(shè)置斷點(diǎn)
    bpv POST
    bpv        <-- Call with no parameter to clear

bpu: 按 URI 包含的字符串設(shè)置斷點(diǎn)
    bpu /myservice.asmx
    bpu        <-- Call with no parameter to clear

cls or clear: 清除列表

dump: 以 zip 格式轉(zhuǎn)儲(chǔ)所有 Session 到C:\

g or go: 繼續(xù)執(zhí)行在中斷狀態(tài)下的 sessions

hide: 隱藏 Fiddler 到系統(tǒng)托盤

urlreplace: 對(duì)請(qǐng)求地址 URL 進(jìn)行替換
    urlreplace SeekStr ReplaceWithStr
    urlreplace        <-- Call with no parameters to clear

show: 恢復(fù)顯示 Fiddler 主界面通常用在 ExecAction.exe 條件觸發(fā)

select MIME: 選擇指定 Content-Type 類型的 Seesion

    select image
    select css
    select htm

select HeaderOrFlag PartialValue: 選擇包含指定頭信息的

    select ui-comments slow
    select ui-bold *     <-- unless preceded by a slash, * means any value
    select ui-comments \*     <-- Find comments with a *
    select @Request.Accept html     <-- Find requests with Accept: html
    select @Response.Set-Cookie domain <- Find responses that Set-Cookie on a domain

allbut 和 keeponly: 隱藏指定的 Session

    allbut xml
    allbut java

quit: Shutdown Fiddler.

!dns hostname: DNS查詢, 結(jié)果記錄在 LOG

    !dns www.example.com
    !nslookup www.example.com

!listen PORT [CERTHOSTNAME]: 偵聽命令

    !listen 8889
    !listen 4443 localhost
    !listen 444 secure.example.com

Fiddler 熱鍵

對(duì)于我這樣經(jīng)常離不開 Fiddler 的工作人員, 掌握 Fiddler 熱鍵是非常有必要的. 系統(tǒng)級(jí)別的熱鍵只有 CTRL+ALT+F, 它用來喚起 Fiddler, 無論當(dāng)前在運(yùn)行什么程序. 與之呼應(yīng)的是 Ctrl+M 用來收縮 Fiddler 界面到系統(tǒng)托盤. 更多熱鍵如下:

程序級(jí)別
Alt+Q - 激活 QuickExec 命令行
CTRL+F - 查找 sessions
CTRL+H - 視圖跳轉(zhuǎn) Header Inspector
CTRL+T - 視圖跳轉(zhuǎn) TextView Inspector
CTRL+Up - 選擇上一個(gè) session
CTRL+Down - 選擇下一個(gè) session

Session 列表

CTRL+A - 選擇所有 sessions
CTRL+I - 反選 sessions
CTRL+X - 清除 Session 列表
R - 重發(fā)請(qǐng)求, Shift+R 指定重發(fā)次數(shù)
U - 無條件重發(fā), 忽略緩存, Shift+U 指定次數(shù)
P - 定位到 Referer 引用頁(yè)請(qǐng)求
C - 定位到引用當(dāng)前URl的請(qǐng)求, 子請(qǐng)求
D - 查找重復(fù)請(qǐng)求
CTRL+1~6 標(biāo)記六種顏色
CTRL+0 - 清除顏色標(biāo)記
CTRL+C - 復(fù)制摘要
CTRL+U - 復(fù)制URL
CTRL+SHIFT+C - 復(fù)制協(xié)議頭
F2 - 打開編輯模式
Backspace - 回到上次選擇的 session
Delete - 刪除選擇的 sessions
Shift+Delete - 刪除未選擇的 sessions
Spacebar - 定位到選中的 session

協(xié)議頭

CTRL+C - 復(fù)制協(xié)議頭
CTRL+SHIFT+C - 復(fù)制協(xié)議頭
ENTER - 編輯選中的頭字段, 如果在編輯模式, 或在中斷時(shí)
Delete - 刪除選中的協(xié)議頭字段, 如果在編輯模式
INSERT - 添加協(xié)議頭字段

TextView

CTRL+G - 轉(zhuǎn)到指定行
F3 - 查找下一個(gè)

HexView

CTRL+G - Goto byte

HTTP 數(shù)據(jù)包構(gòu)造

實(shí)例:一個(gè)提交文件的表單,且只有一個(gè)文件。假設(shè)文件是文本,只有一行內(nèi)容:

1234,4321

在瀏覽器中選好文件,并點(diǎn)擊提交表單后,就會(huì)發(fā)送一個(gè)HTTP包,內(nèi)容類似:

POST http://ci.yob1.hy.8188188.net:889/InportTxt/GetFile HTTP/1.1
Host: ci.yob1.hy.8188188.net:889
Connection: keep-alive
Content-Length: 188
Cache-Control: max-age=0
Origin: http://ci.yob1.hy.8188188.net:889
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.3964.2 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOxZT0VqgpwJSg1hp
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://ci.yob1.hy.8188188.net:889/InportTxt/GetFile
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: ASP.NET_SessionId=ymg3yakf4qlz3azutcu4ivjf; kangle_runat=1; UserId=xxx; LoginName=xxx; NickName=k; DefaultCredit=196; UsedCredit=0; SuperCompanyName=sscmg; IsEnter=false; IsShowLottory=false; IsOddsUse=false; IsSingleBack=false; IsInheritTrading=false; IsInheritComm=false; SubNickName=RRR; PlayType=0; UserNo=67dffa7e1eec4edbbda51b97e530075b; CancelBet=3; SecondStopEarly=0; PeriodsNumber=20180422039; PeriodsID=280302; PeriodsStatus=1

------WebKitFormBoundaryOxZT0VqgpwJSg1hp
Content-Disposition: form-data; name="file"; filename="d.txt"
Content-Type: text/plain

1234,4321
------WebKitFormBoundaryOxZT0VqgpwJSg1hp--

注意最后面7行,用HEX碼將那些不可見的字符表達(dá)出來就是:

0x0D, 0x0A, 0x0D, 0x0A, 
------WebKitFormBoundaryOxZT0VqgpwJSg1hp, 0x0D, 0x0A, 
Content-Disposition: form-data; name="file"; filename="d.txt", 0x0D, 0x0A,
Content-Type: text/plain, 0x0D, 0x0A, 
0x0D, 0x0A, 
1234,4321, 0x0D, 0x0A,
------WebKitFormBoundaryOxZT0VqgpwJSg1hp--, 0x0D, 0x0A 

每個(gè)0x0D, 0x0A就代表一個(gè)換行符,HTTP數(shù)據(jù)包的頭部和數(shù)據(jù)部由兩個(gè)換行符作分界。后面的是數(shù)據(jù),這里一就那個(gè)上傳到服務(wù)器的文件。表單是可以上傳多個(gè)文件的,在HTTP頭部的Content-Type里,multipart/form-data向服務(wù)器表明這一次提交的表單是包含文件的,服務(wù)器接受表單時(shí)就會(huì)根據(jù)Content-Type里指定的boundary,也就是----WebKitFormBoundaryOxZT0VqgpwJSg1hp來分割HTTP的數(shù)據(jù)部,以提取完整的文件。再看看HTTP數(shù)據(jù)部,注意boundary前面由多加了兩個(gè)連字符--。兩個(gè)boundary之間包含以個(gè)文件信息,注意,以兩個(gè)換行符為界,前是文件基本信息,含有文件名、文件類型等,后面的就是文件內(nèi)容。

構(gòu)造表單是就要根據(jù)以上規(guī)則,boundary可以自行指定,只要不會(huì)和文件內(nèi)容有一樣的字符串就可以。

http數(shù)據(jù)包結(jié)構(gòu)

使用Fiddler構(gòu)造HTTP請(qǐng)求包

通過快捷鍵F9可以打開Composer,這就是構(gòu)造器,最簡(jiǎn)單的操作就是將前面抓包得到的RAW數(shù)據(jù)拷貝過來,貼到Composer的RAW中。


http數(shù)據(jù)包構(gòu)造

通過 Parsed 的 Upload file... 可以自動(dòng)創(chuàng)建帶文件上傳的表單。

Composer 的升級(jí)版, AutoResponder 自動(dòng)響應(yīng)是非常有用的一個(gè)工具. 如何使用, 首先在請(qǐng)求列表選中想要攔截并自動(dòng)響應(yīng)的請(qǐng)求, 然后在面板選擇 AutoResponder, 勾選 Enable rules, Unmatched requests passthrough, 再點(diǎn)擊 Add Rule, Fiddler 會(huì)自動(dòng)添加一條, URL映射規(guī)則, 匹配的URL請(qǐng)求就會(huì)被截取, 輸出自動(dòng)響應(yīng)的內(nèi)容.

在最下面的 Rule Editor 最下面的下拉框選擇響應(yīng)方式會(huì)或內(nèi)容, 其中有許多內(nèi)置模板文件, 比較好理解, 就是輸出和HTTP響應(yīng)代碼匹配的數(shù)據(jù), 文件位于 Fiddler 安裝目錄下的 ResponseTemplates. 例如 200 表示正常的響應(yīng), FiddlerGIf 是一個(gè)小提琴GIF文件:

200_FiddlerGif.dat
200_SimbpleHtml.dat
200_TransPixel.dat
204_NoContent.dat
302_Redirect.dat
303_RedirectWithGet.dat
304_NotModified.dat
307_RedirectWithMethod.dat
401_AuthBasic.dat
401_AuthDigest.dat
403_AuthDeny.dat
404_Plain.dat
407_ProxyAuthBasic.dat
502_Unreachable.dat

還有一些 * 號(hào)開頭的設(shè)置, 表示這是一個(gè)動(dòng)作 Action, 動(dòng)作和前面的 QuickExec 是一個(gè)概念, bpafter 表示設(shè)置一個(gè)中斷flag 表示設(shè)置程序標(biāo)志, ui-backcolor 則對(duì)應(yīng)程序界面的背景色. redir 表示產(chǎn)生一個(gè)跳轉(zhuǎn)向應(yīng), script 表示執(zhí)行一個(gè) Fiddler 腳步方法:

*bpu
*bpafter
*exit
*drop
*reset
*delay:100
*ReplyWithTunnel
*CORSPreflightAllow
*flag:ui-backcolor=#FFD700
*header:HeaderName=NewValue
*redir:http://www.example.com
*script:FiddlerScriptFunctionName

后面還有一個(gè) Find file ... 用來指定一個(gè)文件作為響應(yīng)內(nèi)容. 設(shè)置好響應(yīng)后, 點(diǎn)擊 Save 保存就可以生效了. 如果選擇 Create New Response…, 則進(jìn)入自定義響應(yīng), 點(diǎn)擊 Save 后會(huì)彈出一個(gè)對(duì)話框,跟 Inspectore 的 Response 面板的布局一樣的界面,在上面可以填寫編輯響應(yīng)數(shù)據(jù). 這時(shí)可以直接將之前的響應(yīng)內(nèi)容拷貝一份過來再進(jìn)行編輯. 改完保存, 返回到 AutoResponder 面板就可以看到響應(yīng)內(nèi)容變成類似 NEW_RESPONSE_18_38_10 這樣的文件了. 這時(shí)在請(qǐng)求列表中選擇配置號(hào)自動(dòng)響應(yīng)的請(qǐng)求, 按下快捷鍵 R 將請(qǐng)求重發(fā), 來測(cè)試自動(dòng)響應(yīng).

AutoResponder

特殊抓取設(shè)置

Windows平臺(tái)下,VBS和JScript腳本是通過 WinHTTP 來實(shí)現(xiàn)聯(lián)網(wǎng)的,默認(rèn)情況下 Fiddler 只配置了WinINET,即瀏覽器默認(rèn)使用的網(wǎng)絡(luò)API。要實(shí)現(xiàn)對(duì)WinHTTP、XMLHTTP等API的抓包功能,需要再配置Windows的網(wǎng)絡(luò):

Windows Vista 或以上版本,Windows 7或早期的版本運(yùn)行32bit、64bit的NETSH來對(duì)應(yīng)配置32bit、64bit WinHTTP。:
netsh winhttp set proxy 127.0.0.1:8888

Windows XP 或以下:
proxycfg -p http=127.0.0.1:8888;https=127.0.0.1:8888

或強(qiáng)制 WinHTTP 使用 WinINET 的代理配置:
proxycfg -u

配置 PHP/cURL 應(yīng)用程序使用 Fiddler 需要在發(fā)送請(qǐng)求前執(zhí)行以下代碼,ch 是 curl_init()的返回值: curl_setopt(ch, CURLOPT_PROXY, '127.0.0.1:8888');

或者在命令行中執(zhí)行以下命令修改 curl 的API的代理:
curl --proxy 127.0.0.1:8888

完整的配置請(qǐng)參考Fiddler官方網(wǎng)站的Configuration...

抓取手機(jī)軟件請(qǐng)求

我們需要查找自己電腦的 IP 地址,F(xiàn)iddler主界面的右上角有一個(gè)Online按鈕,鼠標(biāo)放上去等一會(huì)就會(huì)出來包含IP地址的提示信息。 或在命令行下輸入 ipconfig 就可以得到 Fiddler 運(yùn)行的機(jī)器IP地址,代理服務(wù)器端口默認(rèn)是8888。設(shè)置Fiddler的Connetions選項(xiàng),勾選Allow remote computers to connect,重啟軟件配置才生效。

接下來,要在手機(jī)上設(shè)置代理以連接到 Fiddler,隨便連接一個(gè) WIFI,然后點(diǎn)擊高級(jí)選項(xiàng),手動(dòng)設(shè)置代理,在主機(jī)名填入前面得到的IP地址,打開 Fiddler,就能看到手機(jī)上的給中請(qǐng)求數(shù)據(jù)了。如果手機(jī)程序沒有使用代理,F(xiàn)iddler就抓不到數(shù)據(jù)。

HTTPS抓包

要抓取走 HTTPS 的內(nèi)容,F(xiàn)iddler 必須解密 HTTPS 流量。瀏覽器需要檢查數(shù)字證書,會(huì)發(fā)現(xiàn)會(huì)話遭到竊聽。為了騙過瀏覽器,F(xiàn)iddler 通過使用另一個(gè)數(shù)字證書重新加密經(jīng)過Fiddler解密的 HTTPS 流量。Fiddler 被配置為解密 HTTPS 流量后,會(huì)自動(dòng)生成一個(gè)名為 DO_NOT_TRUST_FiddlerRoot 的 CA 證書,并使用該 CA 頒發(fā)每個(gè)域名的 TLS 證書。若 DO_NOT_TRUST_FiddlerRoot 證書被列入瀏覽器或其他軟件的信任 CA 名單內(nèi),則瀏覽器或其他軟件就會(huì)認(rèn)為 HTTPS 會(huì)話是可信任的、而不會(huì)再?gòu)棾觥白C書錯(cuò)誤”警告。

首先,打開 Fiddler,在菜單欄中依次選擇 【Tools】->【Fiddler Options】->【HTTPS】,勾上選項(xiàng):

  • Capture HTTPS CONNECTs
  • Decrypt HTTPS traffic

勾上后,F(xiàn)iddler 需要安裝一個(gè)根證書。安裝完后可以導(dǎo)出根證書到桌面,交給瀏覽使用。點(diǎn)擊對(duì)話框的Action按鈕,彈出選項(xiàng)操作:

  • Trust Root Certificate
  • Export Root Certificate to Desktop

DefaultCertficateProvider的Engine改成: MakeCert模式。

如果沒有安裝根證書,是不能通過 export root certificate to desktop 導(dǎo)出的,運(yùn)行時(shí)就會(huì)報(bào)一個(gè)錯(cuò)誤:

  • Fiddler “creation of the root certificate was not successful”

必要時(shí)可以手動(dòng)生成并安裝根證書,在fiddler目錄下有一個(gè)makecert.exe,它是一個(gè)X509格式證書頒發(fā)工具,相當(dāng)于OPENSSL,以下命令可以生成一個(gè)根證書,這個(gè)證書會(huì)安裝在Windows系統(tǒng)中,通過證書管理工具可以查看:

makecert.exe -r -ss my -n "CN=DO_NOT_TRUST_FiddlerRoot, O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com" -sky signature -eku 1.3.6.1.5.5.7.3.1 -h 1 -cy authority -a sha1 -m 120 -b 09/05/2012
證書管理

在客戶端安裝證書,打開 Fiddler Echo Service 頁(yè)面,默認(rèn)地址是 http://ipv4.fiddler:8888/ 在頁(yè)面上下載 FiddlerRoot certificate(文件名FiddlerRoot.cer)。導(dǎo)入證書進(jìn)行安裝這部分操作,Android和ios有一點(diǎn)不同。Android 可以連接到電腦上,從電腦上打開手機(jī)的內(nèi)存卡,直接把證書導(dǎo)入SD卡中,這里可以直接使用下載好的 FiddlerRoot.cer。還有稍微麻煩的步驟,需要先設(shè)置手機(jī)鎖屏密碼、PIN碼,安裝證書時(shí)會(huì)提示。點(diǎn)擊設(shè)置 => 安全 => 從SD卡安裝 => 從內(nèi)部存儲(chǔ)空間中找到證書,點(diǎn)擊安裝即可。不同的廠商提供的Android系統(tǒng)操作上還有些差別,我的樂2為例,打開設(shè)置界面 => 指紋和密碼 => 其他安全選項(xiàng)。這里可以選擇從存儲(chǔ)設(shè)備安裝證書,或?qū)σ呀?jīng)安裝好的證書進(jìn)行管理。

ios可以在手機(jī)瀏覽器上登錄郵箱,然后將證書發(fā)送到郵箱中,在手機(jī)上查看郵件,點(diǎn)擊附件進(jìn)行證書的安裝即可接下去:設(shè)置->安全和隱私->從存儲(chǔ)設(shè)備安裝。另一個(gè)類似Fiddler的工具是Charles,可以在IOS平臺(tái)上運(yùn)行,證書下載頁(yè)面是 http://chls.pro/ssl

HTTPS常見術(shù)語

TLS:傳輸層安全協(xié)議 Transport Layer Security的縮寫
SSL:安全套接字層 Secure Socket Layer的縮寫

TLS與SSL對(duì)于不是專業(yè)搞安全的開發(fā)人員來講,可以認(rèn)為是差不多的,這二者是并列關(guān)系,詳細(xì)差異見 http://kb.cnblogs.com/page/197396/

KEY 通常指私鑰。

CSR 是Certificate Signing Request的縮寫,即證書簽名請(qǐng)求,這不是證書,可以簡(jiǎn)單理解成公鑰,生成證書時(shí)要把這個(gè)提交給權(quán)威的證書頒發(fā)機(jī)構(gòu)。

CRT 即 certificate的縮寫,即證書。

X.509 是一種證書格式.對(duì)X.509證書來說,認(rèn)證者總是CA或由CA指定的人,一份X.509證書是一些標(biāo)準(zhǔn)字段的集合,這些字段包含有關(guān)用戶或設(shè)備及其相應(yīng)公鑰的信息. X.509證書文件一般以.crt結(jié)尾,根據(jù)該文件的內(nèi)容編碼格式,可以分為以下二種格式:

PEM - Privacy Enhanced Mail,打開看文本格式,以"-----BEGIN..."開頭, "-----END..."結(jié)尾,內(nèi)容是BASE64編碼.
Apache和*NIX服務(wù)器偏向于使用這種編碼格式.

DER - Distinguished Encoding Rules,打開看是二進(jìn)制格式,不可讀.
Java和Windows服務(wù)器偏向于使用這種編碼格式

OpenSSL 相當(dāng)于SSL的一個(gè)實(shí)現(xiàn),如果把SSL規(guī)范看成OO中的接口,那么OpenSSL則認(rèn)為是接口的實(shí)現(xiàn)。接口規(guī)范本身是安全沒問題的,但是具體實(shí)現(xiàn)可能會(huì)有不完善的地方,比如之前的"心臟出血"漏洞.

證書頒發(fā)的基本流程,首先證書應(yīng)該是由機(jī)構(gòu)來頒發(fā)的,即 Certificate Agent,公認(rèn)的CA機(jī)構(gòu)頒發(fā)證書具有公信力,瀏覽器獲取到證書的頒發(fā)機(jī)構(gòu)信息就可以知道網(wǎng)站是經(jīng)過公認(rèn)證書機(jī)構(gòu)認(rèn)證的,是可信的,地址欄通常會(huì)顯示綠色認(rèn)證標(biāo)記。這些CA頒發(fā)的證書是要收費(fèi)的,作為開發(fā)測(cè)試,或者一些不是很重要的場(chǎng)合,這顯然不劃算,那么就可以通過 openssl 給自己頒發(fā)證書。步驟如下,為了方便管理,先建一個(gè)cert目錄,cd到該目錄,以下所有命令的當(dāng)前路徑均為該目錄:

  1. 生成私鑰KEY,這一步執(zhí)行完以后,cert目錄下會(huì)生成server.key文件

    openssl genrsa -des3 -out server.key 2048

  2. 生成證書請(qǐng)求文件CSR,該命令先進(jìn)入交互模式,讓你填一堆東西

    openssl req -new -key server.key -out server.csr

要注意的是Common Name這里,要填寫成使用SSL證書的域名或主機(jī)名,否則瀏覽器不能確認(rèn)證書與網(wǎng)站的關(guān)系。例如https://www.domain.com/xxx 就填 www.domain.com

  1. 生成CA的證書

前面提過X.509證書的認(rèn)證者總是CA或由CA指定的人,所以得先生成一個(gè)CA的證書

openssl req -new -x509 -key server.key -out ca.crt -days 3650
  1. 最后用第3步的CA證書給自己頒發(fā)一個(gè)證書玩玩

    openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey server.key -CAcreateserial -out server.crt

執(zhí)行完以后,cert目錄下server.crt 就是我們需要的證書。

擴(kuò)展Fiddler功能

Fildder 的擴(kuò)展主要方式是通過重寫 Fiddler 規(guī)則腳本, 或編寫 Fiddler 插件實(shí)現(xiàn)特定功能. Fiddler是支持多種腳本編程的, 主要是 JScript.Net 和 C#, Fiddler 安裝目錄下有規(guī)則文件模板 SampleRules, 有 JScript.Net 和 C# 版本. 通過菜單 Rules => Customize Rule ... 打開腳本編輯器,如果初次使用會(huì)提示安裝腳本工具。這個(gè)腳本是fiddler在啟動(dòng)時(shí)加載的腳本,所有監(jiān)聽到的數(shù)據(jù)也都會(huì)流經(jīng)這個(gè)腳本進(jìn)行處理. FiddlerScript Editor 是自帶腳本編輯插件, 熱鍵 Ctrl+R 激活,新版本默認(rèn)是自帶的,舊版本可自行安裝。具體參考官方文檔JScript.NET Reference, FiddlerScript Reference, Extend Fiddler

編寫Fiddler插件需要安裝的開發(fā)環(huán)境:

  • .net framework ?本文安裝使用的是.net framework v4.5.2
  • visual studio fiddler官方推薦visual studio 2010以上版本

.net reflector反編譯軟件反編譯fiddler自帶的插件可以幫助理解插件工作原理,例如,在fiddler中查看Inspectors對(duì)應(yīng)的插件. 選中Inspectors中任意一個(gè)tab,然后右鍵點(diǎn)擊 inspector properties,查看inspector對(duì)應(yīng)的插件。


.Net Reflector 9.0

編寫代碼之前, 先來了解一下 Fiddler 對(duì)象模型結(jié)構(gòu), 如果使用 Fiddler ScriptEditor, 所有這些對(duì)象信息可以在 View => Class Explore 打開. 先來了解 FiddlerObject, 這是基礎(chǔ)服務(wù)類, 它包含了像日志記錄, 狀態(tài)信息修改等:

FiddlerObject 基礎(chǔ)類對(duì)象
    +--FileExtension:   System.String
    +--Language:        Fiddler.ScriptLanguage
    +--StatusText:      System.String 修改狀態(tài)欄信息
    +--UI:              Fiddler.frmViewer
    +--alert(sMesssage) 彈框提示
    +--createDictionary()
    +--flashWindow()
    +--log(sMessage)    記錄日志
    +--playSound(sSoundname)
    +--prompt(sMessage)
    +--prompt(sMessage, sDefaultValue)
    +--prompt(sMessage, sDefaultValue, sWindowTitle)
    +--ReloadScript()   重新加載規(guī)則腳本
    +--uiInvoke(oMI)
    +--uiInvokeAsync(oMI, args)
    +--utilIssueRequest(sRequest)
    +--WatchPreference(sPref, oFN)

FiddlerApplication 當(dāng)前運(yùn)行的應(yīng)用程序?qū)ο?    +--

FiddlerApplication.UI 當(dāng)前運(yùn)行的應(yīng)用程序UI對(duì)象
    +--

FiddlerApplication.oProxy 當(dāng)前運(yùn)行的應(yīng)用程序UI對(duì)象
    +--

CONFIG 配置類對(duì)象用來讀取Fiddler配置
    +--

Utilities 工具類對(duì)象
    +--

Session
    +--host     包含端口的主機(jī)名
    +--hostname 主機(jī)名
    +--port     主機(jī)端口

HTTPRequestHeaders
    +--

HTTPResponseHeaders
    +--

WebSocketMessage
    +--

自動(dòng)鏡像資源文件

現(xiàn)在我需要改寫規(guī)則腳本, 讓它來為我做點(diǎn)事, 當(dāng)我運(yùn)行小程序時(shí), 如果有大量的資源請(qǐng)求, 我希望通過規(guī)則腳本來實(shí)現(xiàn)資源文件的自動(dòng)鏡像功能. 一下是改寫后的規(guī)則腳步輸出的日志, 它記錄著每一個(gè)被鏡像的資源文件, 如果要手工去做這樣的事, 我想是不太現(xiàn)實(shí)的:

11:40:44:8230 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...jpg
11:40:44:8260 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...jpg
11:40:44:8700 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...jpg
11:40:44:8740 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...jpg
11:40:44:8880 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...jpg
11:40:44:9240 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...png
11:40:44:9780 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...png
11:40:45:0010 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...png
11:40:45:0040 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...png
11:40:45:0090 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...png
11:40:45:0190 【M】...\Mapping\lihe-1.oss-cn-hangzhou.aliyuncs.com\gift\...png

腳步代碼如下, 通過 RulesOption 給 Rules 菜單添加了一個(gè) Mapping Content 子菜單, 默認(rèn)為勾選狀態(tài). 一打開捕捉功能 就會(huì)開始做資源鏡像. 定義了 buildPath 方法來建立嵌套的子目錄. 重寫了 OnDone 事件, 這個(gè)事件會(huì)在 Session 得到響應(yīng)后發(fā)生, 這時(shí)合適將 ResponseBody 的數(shù)據(jù)保存到文件里. 將一下代碼復(fù)制粘貼到 class Handlers 開始的位置, 保存就可以運(yùn)行, 這種通過改寫規(guī)則的功能性擴(kuò)展來得更便利, 比編寫插件更快.

public static RulesOption("&Mapping Content")
var m_Mapping: boolean = true;
static function buildPath(fso, root, subs){
    if( !fso.FolderExists(root) ){
        FiddlerObject.log("Build Path: "+root);
        fso.CreateFolder(root);
    }
    if( subs.length ) buildPath( fso, root+subs.shift()+"\\", subs);
}
static function OnDone(oSession: Session) {
    if(!m_Mapping){
        FiddlerObject.StatusText = "Check [Rules=>Mapping Content] to save resources";
        return;
    }
    var rep = new RegExp(".+"+oSession.host,"ig");
    var ROOT = "C:\\Users\\Administrator\\Desktop\\Mapping\\";
    var path = oSession.fullUrl.Replace(rep.exec(oSession.fullUrl)[0],"")
        .replace(/[:\|\*]/g,"-").replace(/[\\\/]/g,"\\"); // NOTE: diff between Replace & replace
    var q = path.IndexOf("?");
    var s = path.IndexOf("#");
    if(q>0){
        path = path.Remove(q);
    }else if(s>0){
        path = path.Remove(s);
    }
    if( !path.length ) path = "index.dat";
    var isFileName = /\.\w+$/.test(path);
    path = (isFileName? path.replace("\\",""):path.replace(/[\/|\\]/g, "_").replace("_","")+".raw");
    var fileName = path.replace(/.+\\/,"");
    var folder = oSession.hostname + "\\" + path.replace(/[^\\]+$/,"");
    if(fileName.length>192) fileName = fileName.substring(fileName.length-192);
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    if( m_DisableCaching && fso.FileExists(ROOT + folder + fileName)) return;
    FiddlerObject.log("【M】" + ROOT + folder + fileName);
    
    try
    {
        buildPath( fso, ROOT, folder.split("\\") );
        if( !fso.FileExists(ROOT+"list.log") ){
            var log = fso.CreateTextFile(ROOT+"list.log");
        }
        var ForReading = 1, ForWriting = 2, ForAppending = 8;
        var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
        var f = fso.GetFile(ROOT+"list.log");
        var log = f.OpenAsTextStream(ForAppending, TristateUseDefault);
        log.WriteLine(folder+fileName);
        log.Close();

        oSession.SaveResponseBody(ROOT + folder + fileName);
        /*
        var fdr = fso.GetFolder(ROOT + folder);
        var f = fso.CreateTextFile(ROOT + folder + fileName, true);
        f.Write(oSession.ResponseBody); // CTL_E_ILLEGALFUNCTIONCALL
        f.Write(Utilities.ByteArrayToString(oSession.responseBodyBytes)); //???
        f.Close();
        */
    }
    catch (e)
    {
        FiddlerObject.log (e);
    }
}

以上腳本正常運(yùn)行需要目錄的讀寫權(quán)限, 否則 Fiddler 會(huì)出現(xiàn)類似一下的提示:

10:39:43:3270 【M】C:\Users\Administrator\Desktop\Mapping\www.gmail.com\index.dat
10:39:43:3280 Error: 異常來自 HRESULT:0x800A0046 (CTL_E_PERMISSIONDENIED)

另外, 這段代碼細(xì)節(jié)處理還不夠, 經(jīng)常會(huì)因?yàn)槲募窂絾栴}彈框, 不過這已經(jīng)夠我用了, 以后有時(shí)間再寫一個(gè)Fiddler插件.

微信掃一掃打賞堅(jiān)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容