如何利用mitmproxy來批量修改Android中HTTP流量
背景
有時候我們常常在調試Android程序時,常常需要對API返回的response進行修改,以達到測試特殊情況的目的。比如有時候我們需要某個字符串顯示超過某個限制來看看此時Android上面顯示是否正常,有時候我們需要特定高度的圖片來顯示頁面是否異常。
對于這些場景,其實通過調試工具mitmproxy就能完成。利用mitmproxy可以讓我們的APP開發調試事半功倍。對于從來沒有聽說過mitmproxy的朋友,推薦查看我之前的兩篇博客:如何調試 Android 上 HTTP(S) 流量 和 mitmproxy基礎實踐教程。
之前所講的關于mitmproxy的使用教程都是比較基礎的。比如我們可以攔截某些特定的request,然后修改這個request的某些屬性,有必要還可以修改response的某些屬性,這樣就可以解決本文開頭所講的場景里面的問題。但是,這樣做的效率很低,我在手機上發起某個API請求,然后被電腦上的mitmproxy截獲了,然后我更改這個請求返回的response,然后這個response就會到了手機上了。
Mitmproxy的Inline Scripts 特性介紹
這樣聽起來好像有點麻煩。可以不可以自動的修改這些resquest和respones。當然可以!這就是我們今天要說的主題,mitmproxy還一個非常極客的特性,叫做 Inline Scripts。有了它,我們就不要在手機和電腦上來來回回地調試了。mitmproxy的Inline Scripts可以讓我們對通過mitmproxy的所有HTTP(S)流量進行可編程的定制,這里的script指的是python腳本。Inline Scripts是一種靠HTTP中的事件進行驅動的API,這有點類似于Android的Activity的生命周期。Inline Scripts提供了HTTP請求中各個時間點的hook函數,比如HTTP請求啟動的時候,request到達mitmproxy的時候,response到達mitmproxy的時候等等。下面我就簡單介紹一下Inline Scripts中的一些Event:
Inline Scripts 中常用的Event介紹
- start(context, argv)
HTTP請求開始啟動的時候,這個event在所有event之前。 - clientconnect(context, root_layer)
客戶端向代理(mitmproxy)建立一個connection的時候,一個connection可以對應多個request。 - request(context, flow)
客戶端的HTTP請求被代理(mitmproxy)接收到的時候。flow里面包含了request對象,比如request的方法,request的url,參數等等。 - serverconnect(context, server_conn)
代理(mitmproxy)向服務器端建立一個connection的時候,同理一個connection可以對應多個request。 - responseheaders(context, flow)
當服務器的response header被代理(mitmproxy)接收的時候,這個event在接下來的response event之前。 - response(context, flow)
當服務器的response被代理(mitmproxy)接收的時候,這個event在responseheaders事件之后。 - error(context, flow)
當flow出現異常的時候會產生該事件。比如connection被中斷等。 - serverdisconnect(context, server_conn)
當代理(mitmproxy)斷開到服務器的連接時 - clientdisconnect(context, root_layer)
當客戶端斷開到代理(mitmproxy)的連接時 - done(context, argv)
Inline Scripts被關閉的時候。
</ol>
- 首先我們將已有的相關API 流量通過mitmproxy截獲
- 將這些API中response中特性屬性的value全部改為我們想要的value </ol>
Inline Scripts 使用示例
下面的示例為了說明 mitmproxy 中的 Inline Scripts是如何使用的。具體思路:
假設我們要測試的某個請求返回的數據格式如下:
{"data":[{"key":"value1"},{"key":"value2"},{"key":"value3"}]}
因此接下來我們就可以寫相應的python腳本(change.py)了:
from libmproxy.protocol.http import decoded #來自mitmproxy中的庫 from libmproxy.protocol.http import HTTPResponse import jsonmitmproxy中代理所有HTTP請求的response全部會經過這里
def response(context, flow):
#如果request的url里面包含了某個關鍵字(需要按照你的需要設置) if 'KEYWORD' in flow.request.pretty_url(hostheader=True): #解碼請求的response with decoded(flow.response): #使用json封裝response body = json.loads(flow.response.content) if body['data']: list = body['data'] for item in list: if item['key']: #將符合條件的屬性進行更改 item['key']='value_special' #將更改后的數據重新封裝為response flow.response.content = json.dumps(body)</pre><br />
然后咱們再結合之前兩篇教程,我們只需執行以下命令就可以完成我們的需求:
./mitmproxy -b YOUR_LOCAL_IP_ADDRESS -p PORT -s change.py
1</div> </td> ./mitmproxy -b YOUR_LOCAL_IP_ADDRESS -p PORT -s change.py</div> </td> </tr> </tbody> </table> </div> </div>當這個命令行運行的時候,每次手機請求這個api,請求經過mitmproxy的時候,mitmproxy會把請求轉發給服務器端,接著服務器端講 response返回給mitmproxy。mitmproxy拿到數據之后,將response中的數據按照前面的python腳本進行了更改,最后這個被修改過的response回到手機上了。
這一切都是自動的,你只需拿著手機發起請求就行了。
來自:https://greenrobot.me/devpost/how-to-use-mitmproxy-custom-android-api-call/本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!相關經驗
相關資訊
sesese色