《吐血整理》高階系列教程-吃透Fiddler抓包教程(37)-掌握Fiddler中Fiddler Script用法,你會有多牛逼-下篇

宏哥發表於2022-12-20

1.簡介

  Fiddler是一款強大的HTTP抓包工具,它能記錄所有客戶端和伺服器的http和https請求,允許你監視,設定斷點,甚至修改輸入輸出資料. 使用Fiddler無論對開發還是測試來說,都有很大的幫助。Fiddler提供的功能基本上能滿足大部分人的基本要求。但是如果我們需要一些更復雜,更便捷的方式的功能來支援我們的工作(比如同時對多個指定的會話設定端點,不帶cookie發起會話等),那麼Fiddler提供的功能就往往力不從心了,或者使用起來比較複雜。Fiddler提供了Jscript指令碼,讓我們隨心所欲的改造Fiddler,實現一些其他更強大的功能。本文主要介紹的是透過編寫Fiddler的Jscript指令碼的方法來實現Fiddler功能的擴充。

2.準備篇

1.安裝fiddler,http://fiddler2.com/get-fiddler。選擇Fiddler2即可。

2.安裝 FiddlerScript editor,

http://fiddler2.com/docs/default-source/public-downloads/FiddlerSyntaxSetup.exe  這個低版本(比較老的版本,老古董老掉牙的Fiddler)需要自己安裝,現在最新版本都已經整合到安裝包中,不需要你自己安裝了。

官網是這麼說的:FiddlerScriptEditor is included in latest version of Telerik Fiddler and is not available as a separate download.(FiddlerScriptEditor 已經包含在最新版的 Fiddler 裡面,不需要單獨下載)。

Fiddler Script Editor 提供了語法高亮,以及智慧提示的功能, 如下圖所示:

3.簡單瞭解一下Jscript。JScript 是一種解釋型的、基於物件的指令碼語言。與javascript比較相似。主要是方便你瞭解程式碼的意思。

http://doc.51windows.net/jscript5/?url=/jscript5/dir.htm (一個JScript學習網址)

3.工具篇

3.1Main函式

FiddlerScript 基於JScript.NET 語言。在Fiddler 中點選選單“Rules > Customize Rules”開啟FiddlerScript Editor 編輯器,在這裡可以編寫Fiddler Script 指令碼,只要一儲存,Fiddler 將會重新編譯指令碼並自動載入,如果載入成功,則會播放聲音並在Fiddler 狀態列顯示"CustomRules.js was loaded at <datetime>" 提示資訊,如果編譯失敗,將會顯示錯誤提示資訊。

Main函式是在CustomRules.JS指令碼被Fiddler呼叫時,最先執行的函式。在裡面預設都有一個today變數,是獲取時間的。在我們開啟fiddler的時候,這下面就可以看到具體的內容。如下圖所示:

Fiddler的狀態列會提示,CustomRules.js指令碼被重新載入的時間。當每次CustomRules.js檔案被更新時,Fiddler感知CustomRules.js被修改,並重新載入一次。那麼該狀態列也會進行展示。

另外,可以點選Fiddler的選單欄,Tools=>Reset Script也可以觸發fiddler重新載入一次CustomRules.js指令碼。

如果我們需要對http請求的請求包和返回包進行修改,那麼就可以在OnBeforeRequest和OnBeforeResponse兩個函式中進行操作,新增相應的Jscript程式碼來實現。具體例項在後面介紹。

3.2.FiddlerScript editor

1.點選fiddler的Rules--->Customize Rules--->Fiddler ScriptEditor,FiddlerScript editor工具就會自動的開啟CustomRules.js檔案。如果該檔案是被其他編輯工具開啟(如NotePad++),說明我們沒有安裝fiddlerScript Editor。那麼我們需要按照安裝一下該指令碼編輯工具。

2.直接點選FiddlerScript頁籤,如下圖所示:

 

這裡之所以推薦使用FiddlerScript editor進行指令碼的修改,是因為當Fiddler處於開啟狀態時,該工具會對我們編輯的Jscript進行語法檢查。另外,該編輯工具也會根據相應的物件提示屬於該物件的函式或成員變數供我們選擇。這些都會大大的提高我們的程式設計效率。

當然,如果我們的程式設計能力足夠強。我們也可以使用NotePad++進行開發,然後儲存編輯即可。不過一旦由於語法錯誤,Fiddler會在執行的時候直接崩潰掉。

接下來我們先認識一下fiddlerScript Editor。介面如下圖所示:

如果沒有右邊的類檢視,我們可以點選FiddlerScript Editor選單欄View,然後勾選上Class Exploer。類檢視對我們的指令碼編寫提供了極大的變數,因為我們不知道,也不可能記得Fiddler提供了哪些物件和函式供我們使用,那麼我們可以在開發的過程中,類檢視中查詢相應的函式。

4.開發篇

4.1對某條CGI設定斷點

公共閘道器介面或者通用閘道器介面(Common Gateway Interface,CGI)是Web 伺服器執行時外部程式的規範,按CGI 編寫的程式可以擴充套件伺服器功能。CGI 應用程式能與瀏覽器進行互動,還可透過資料API與資料庫伺服器等外部資料來源進行通訊,從資料庫伺服器中獲取資料。格式化為HTML文件後,傳送給瀏覽器,也可以將從瀏覽器獲得的資料放到資料庫中。幾乎所有伺服器都支援CGI,可用任何語言編寫CGI,包括流行的C、C ++、Java、VB 和Delphi 等。CGI分為標準CGI和間接CGI兩種。標準CGI使用命令列引數或環境變數表示伺服器的詳細請求,伺服器與瀏覽器通訊採用標準輸入輸出方式。間接CGI又稱緩衝CGI,在CGI程式和CGI介面之間插入一個緩衝程式,緩衝程式與CGI介面間用標準輸入輸出進行通訊。

Fiddler比較強大的功能之一就是對http請求進行攔截,對request和response進行攔截。可以達到對請求包和返回包進行修改。

如上圖,點選Fiddler的Rules=>Automatic Breakpoints=>Before Requests(After Responses)。那麼我們就可以分別對所有的請求包或返回包進行攔截了。

但是我們往往需要攔截修改的是某一條重要的CGI,所以以上設定方式不是最理想的方式。

下面介紹兩種方法,來設定對指定的CGI進行攔截。

4.1.1透過指令碼命令,設定攔截

這種方法宏哥已經詳細介紹過,這裡再簡單的回憶一下即可。在Fiddler的命令輸入框中,輸入bpu URL(URL是我們需要攔截的CGI,或者是該CGI包含的部分字串),我們就可以對請求包進行攔截。取消對該CGI的攔截,我們輸入命令:bpu即可。

同理,我們在命令輸入框中,輸入bpafter URL,即可對CGI的返回包進行攔截。輸入bpafter命令,就可以取消對該CGI的斷點攔截。

以上bpu URL命令執行成功後,在Fiddler的狀態列會顯示,具體是被設定端點的CGI。

然後就可以看到對包含showcart/showcart字串的CGI進行端點。實現了對特定的一條CGI設定端點的功能。

4.1.2透過Jscript設定特定CGI的攔截

與設定特色URL進行標註,特色字型顯示類似。採用Fiddler指令碼命令輸入方式,需要在Fiddler重啟後,重新輸入相關命令。如果需要多條CGI進行攔截,就需要大量的命令。

下面透過JScript指令碼的方式實現對多條CGI的攔截。

在函式OnBeforeRequest中,輸入以下程式碼,可以對包括特色字串的多條CGI進行攔截。

if(oSession.uriContains( "showcart/showcart" )||oSession.uriContains("mod=event&act=getjson")){

 oSession["x-breakrequest"]="";

}

在官網上,透過oSession["ui-breakrequest"]="";進行請求或返回包的攔截,貌似不起作用,需要使用“x-breakrequest”標記。

4.2操作會話

4.2.1儲存會話內容到本地

方法一:選中需要儲存的會話,然後點選右鍵。選擇save=>Resonse=>Response Body。就可以對選中的會話返回內容進行儲存。

方法二:下面介紹另一種使用Jscript對會話內容進行儲存的方法,用Fiddler自帶的儲存會話內容函式。

儲存的會話檔案,這樣在Jscript讀取出來才不會是亂碼。在OnBeforeResponse中輸入以下程式碼:

if(oSession.fullUrl.Contains("shoppingcart/addproduct")) { 
    oSession. utilDecodeResponse();//如果儲存的內容有亂碼,加上這一句,對返回的內容進行解碼處理。 
    oSession.SaveResponseBody ("E:\\Users\\lenovo\\Desktop\\fiddler\\addproductresponse.txt"); 
}

其中,utilDecodeResponse是對返回包的內容進行解碼,常常http在傳輸之前會對傳輸的內容進行編碼。如果沒有這一句,儲存到本地的內容會出現亂碼的情況。

SaveResponseBody函式引數是檔名。

方法三:用Jscript指令碼新建檔案,並寫入返回包內容到本地。

if(oSession.fullUrl.Contains("showcart")){
    var ts,s;
    var fs= new ActiveXObject ("Scripting.FileSystemObject");
    var ts=fs.OpenTextFile ("E:\\Users\\lenovo\\Desktop\\fiddler\\addproductresponse2.txt",2 , true);
    var s=oSession.GetResponseBodyAsString();
    ts.Write(s);
    ts.Close(); 
}

OpenTextFile函式的使用方法可以參考:

http://doc.51windows.net/jscript5/?url=/jscript5/dir.htm

以上方法任意一種都可以對返回包的內容進行儲存。返回包儲存的內容如下:

Fiddler抓取的返回包內容,如下圖所示:

Fiddler的其他指令碼命令可以參考http://fiddler2.com/documentation/KnowledgeBase/QuickExec

以上的方式即可讀取本地檔案內容作為返回包的body,這種方法稍微有點麻煩。不過能確保讀取出來的中文沒有亂碼。

第一個引數是儲存會話的檔案,第二個引數是一個bool值,使用者控制儲存的返回內容是否包含respsonsebody。當第二個引數至是true時,指儲存http返回包的頭部

oSession.SaveResponse("C:\\Users\\DELL\\Desktop\\test\\addproductresponse.txt",true);

如果第二個引數是false時,則既有頭部又有body。

//true,只有頭部,false,既有頭部又有body oSession.SaveResponse("C:\\Users\\DELL\\Desktop\\test\\addproductresponse.txt",false);

如果儲存的檔案是本地某個資料夾,一定是“\\”,而不是“\”。

在Jscript中,“\”具有特殊的含義,主要用於一些特殊字元的轉義。因此在使用的“\”也需要轉義“\\”。

oSession. SaveResponse("F:\\fiddlertest\\fucengresponse.txt" ,false);

l如果是相對路徑儲存

oSession.SaveResponseBody ("./fucengBody.txt");

則儲存地方是安裝的fiddler目錄中。

loSession.SaveSession函式。該函式也有兩個引數,第一個是檔名,第二個是bool值。

//false既有請求包,又有返回包。true,只有請求包、返回包的頭部 oSession.SaveSession("E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponse.txt",true);

True只有請求包以及返回包的頭部。False既有請求包,又有返回包(頭部及body)

從以上可以看出,各種儲存的檔案內容按照大小順序為:session>=response>=responsebody

4.3會話請求自動應答

4.3.1AutoResponder

自動應答方法一:1.Fiddler自帶的AutoResponder。在會話列表中選中需要自動應答的會話,拖到到右邊的AutoResponder中。

2.然後在AutoResponder選中該CGI,然後右鍵,選擇Edit Response。

3.然後在TextView中,對返回內容進行編輯。進行儲存後,重新訪問需要自動應答的CGI,那麼該CGI自動應答就是我們剛才編輯的返回包。

以上方法有一個缺點是,必須是Rule Editor中的EXACT的URL和會話中的URL完全匹配。或者是透過正規表示式的方式進行匹配。才能是需要的CGI進行自動應答。但是對於一些重要的CGI,常常帶有gtk引數,該引數經常變化,從而導致設定的自動應答的URL不匹配,那麼就需要再一次進行編輯規則,比較麻煩。

4.在編輯完規則後,我們可以選中會話列表中的URL,然後與AutoResponder中的規則進行匹配測試。只有匹配測試透過的,才能自動應答。

4.3.2Willow

這個外掛前邊文章中宏哥已經詳細介紹過了,這裡不做贅述了,就簡單的提一下。它也可以實現自動應答。

4.3.3Jscript進行自動應答

自動應答方法三:透過Jscript進行自動應答。宏哥這裡演示的demo是,透過必應搜尋“北京宏哥”,然後修改響應結果,將“宏哥”修改成“宏鍋”。具體操作步驟如下:

1.LoadResponseFromFile函式引數是自動應答內容的檔名。該檔案的內容必須有HTTP返回包頭部。如果自己構造比較困難,我們先可以透過

oSession.SaveResponse("E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponse.txt",false);

先在本地儲存一份返回包內容,如下圖所示:

2.然後對返回包內容進行修改直接搜尋“宏哥”全部替換成“宏鍋”即可。如下圖所示:

3.將以下程式碼放置在OnBeforeResponse中。

if(oSession.fullUrl.Contains("showcart")) { 
    oSession.LoadResponseFromFile("E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponse.txt"); 
}

4.然後我們重新整理搜尋頁面就可以看到效果。這種方法常使用者對前端的測試。透過自己構造相應的返回包,對前端展示的設定。如下圖所示:

自動應答方法三:Session的flag標誌“x-replywithfile”。在OnBeforeResponse或OnBeforeRequest中增加以下程式碼:

if(oSession.fullUrl.Contains("showcart")){ 
    oSession["x-replywithfile"]="E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponse.txt";
}

x-replywithfile ---The value of this flag is the name of a file in the Captures/Responses folder (or a fully-qualified filename) containing a HTTP response to return to the client rather than sending the request to the server。

同樣,檔案中的內容也是有返回頭部以及body的。

自動應答方法四:Jscript讀取本地檔案。

我們需要讀取的檔案從從Http返回包中獲取,首先需要獲取返回包內容,儲存到本地,然後在本地修改該檔案為我們需要的返回包內容。這樣可以不需要注意返回包內容的格式,降低出錯率。

透過以下程式碼獲取返回包的內容:

//對返回包進行解碼處理
oSession.utilDecodeResponse(); //oSession.SaveResponseBody("E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponsebody.txt")
//對儲存到本地的資料進行UTF8編碼,否則讀取出來的中文是亂碼
var oBodyString = System.Text.Encoding.UTF8.GetString(oSession.ResponseBody);
//var oBodyString="hh";
//寫檔案,儲存會話內容
var fs,s,ts;
fs=new ActiveXObject("Scripting.FileSystemObject");
ts=fs.OpenTextFile("E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponsebody.txt",2 , true);
ts.Write(oBodyString);
ts.Close();

儲存的會話檔案,這樣在Jscript讀取出來才不會是亂碼。

if(oSession.fullUrl.Contains("showcart")){
    var fs,s,ts;
    fs=new ActiveXObject("Scripting.FileSystemObject");
    ts=fs.OpenTextFile("E:\\Users\\lenovo\\Desktop\\fiddler\\showcartresponsebody.txt");
    s = ts.ReadAll();
    oSession.utilSetResponseBody(sss);
    ts.Close();
}

以上的方式即可讀取本地檔案內容作為返回包的body,這種方法稍微有點麻煩。不過能確保讀取出來的中文沒有亂碼。

5.小結

1.宏哥為了演示,就沒寫如果檔案不存在或者儲存的路徑不存在的判斷程式碼,因此你要儲存檔案要麼已經在你本地存在,要麼加上判斷的程式碼自動建立即可。

2.要注意儲存的程式碼要寫對位置,否則儲存的檔案的內容就是空白什麼都沒有,儲存請求放在OnBeforeRequest方法裡,儲存響應放在OnBeforeResponse方法裡。

3.要注意提前在Fiddler上點選Decode後,再儲存檔案,否則沒有解碼儲存的檔案內容就會出現亂碼,不方便後期的修改自動應答的內容。

宏哥覺得Fiddler的功能基本上都可以透過Fiddler Script來實現的。好了,今天時間也不早了,宏哥就講解和分享到這裡,感謝你耐心地閱讀!!!

相關文章