這是一篇嚴肅的技術分享文章缅叠,旨在向大家介紹一些網(wǎng)絡安全方面的知識,及相關工具的使用虏冻。閑話少說肤粱,直接進入正題。
實現(xiàn)目標
知乎上經(jīng)常有各種爆照及釣魚貼厨相,類似「胸大是一種什么樣的體驗领曼?」, 「女生有翹臀是什么樣的體驗?」等蛮穿。其實大家關心的只有照片庶骄,是不是?
我們的目標是在終端輸入:
./get.sh 胸大
就能從知乎將胸大(或者其他關鍵詞)相關的話題回答中的圖片践磅,一鍵下載到本地的文件夾中单刁。我試著跑了下腳本,有好多讓人看了就臉紅??的照片:
真的是來自知乎府适。羔飞。
著急的同學可以直接在我的公眾號(MrPeakTech)回復z,獲取可運行的腳本檐春。
準備工作
技術手段:中間人攻擊逻淌,replay attack。
工具:Mac疟暖,裝有知乎App的iPhone手機卡儒,mitmproxy,mitmdump誓篱,grep朋贬,wget。
知識儲備:http協(xié)議窜骄,python腳本锦募,基礎的安全知識。
實現(xiàn)思路
第一步:使用mitmdump記錄知乎App的搜索request邻遏,和進入回答的request糠亩。
第二步:replay搜索request,hook請求准验,修改request參數(shù)赎线。
第三步:獲取搜索結果后,replay回答的request糊饱,hook請求垂寥,修改request參數(shù)。
第四步:使用正則提取回答response中的圖片url。
第五步:使用wget將圖片下載到指定文件夾滞项。
動手
這次我們的主角是mitmproxy和mitmdump狭归。之前我寫過一篇文章介紹如何使用mitmproxy做https抓包。這次要使用到更高階一點的功能:replay attack文判。建議先看下我之前那篇文章过椎。
安裝mitmproxy
沒有安裝mitmproxy的同學可以先通過brew安裝下:
brew install mitmproxy
安裝好之后,在終端啟動mitmproxy:
mitmproxy
接下來需要在iPhone上設置http代理:
IP地址填你Mac系統(tǒng)當前的IP戏仓,端口默認8080疚宇,記住iPhone要和我們的Mac處于同一個局域網(wǎng)中。
如果是第一次使用mitmproxy赏殃,需要在iPhone上安裝CA證書敷待,打開iPhone Safari,輸入地址:mitm.it仁热,在下圖中點擊Apple安裝證書讼撒。
這樣就配置完畢了,下面我們來記錄知乎App的request股耽。
記錄App Request
首先我們先打開知乎App,進入搜索界面:
接著啟動mitmdump钳幅,來記錄手機端的https請求物蝙,在終端輸入:
mitmdump -w raw
回車之后,手機端的請求就都會寫進raw文件了敢艰。
下面在App端輸入關鍵字「胸大」诬乞,點擊搜索,翻頁(想要結果多點钠导,可以多翻幾頁)震嫉。
這樣我們在終端可以看到如下三個被捕捉請求。
有時候我們會捕捉到多余的請求牡属,需要手動刪除下票堵,可以先退出mitmdump,然后再終端輸入:
mitmproxy -r raw
進入請求的編輯界面逮栅,按d可以刪除我們不想要的請求悴势,編輯完之后,按w會提示保持到文件措伐,我將請求保持到searchReq文件:
在重復上面的操作特纤,在App端點擊進入回答的操作,將單個回答的request保存到文件detailReq侥加。
到這里我們就記錄完畢原始請求了捧存!
Replay Attack
經(jīng)過之前的操作,我們有了兩個原始請求文件:searchReq,detailReq昔穴。
接下來回放search請求镰官,回放的時候我們還需要hook一個python腳本來修改請求參數(shù)。先看下search請求的格式傻咖,通過mitmproxy可以查看詳情:
GET https://api.zhihu.com/search?excerpt_len=75&q=%E8%83%B8%E5%A4%A7&t=content
這是個非常簡單的GET請求朋魔,參數(shù)格式也一目了然。而且幸運的是知乎的后臺即沒有做參數(shù)的簽名卿操,也沒有加時間戳來防replay attack警检。看上去我們只需要替換q=xxx這個參數(shù)值即可害淤。所以寫段簡單的python腳本來替換吧:
class Replacer:
def __init__(self,dst):
self.dst = dst
def request(self,flow):
flow.request.path=flow.request.path.replace("%25E8%2583%25B8%25E5%25A4%25A7", urllib.quote_plus(urllib.quote_plus(self.dst)))
flow.request.path=flow.request.path.replace("%E8%83%B8%E5%A4%A7", urllib.quote_plus(self.dst))
def start():
parser = argparse.ArgumentParser()
parser.add_argument("dst", type=str)
args = parser.parse_args()
return Replacer(args.dst)
腳本很簡單扇雕,就是將我們輸入的關鍵字urlencode下,再替換原先的參數(shù)窥摄。
我的系統(tǒng)是python 2.xx镶奉,3.xx的encode方法調(diào)用有些差別,要注意崭放。
這里有點奇怪的是知乎搜索翻頁的接口哨苛,將關鍵字連續(xù)urlencode了兩次,不知道有神馬講究在里面币砂。不過不管啦建峭,我們繼續(xù)。
寫好腳本(replace_query.py)之后决摧,再寫個bash腳本來實施replay attack亿蒸。這個腳本也是我們的關鍵執(zhí)行腳本get.sh:
#!/bin/bash
#replay attack
mitmdump -dd -s "./replace_query.py $1" -znc searchReq -w searchRsp
參數(shù)我就不一一解釋啦,大家自己看mitmproxy的官方文檔掌桩,總之這段腳本會回放存在searchReq當中的搜索請求边锁,并執(zhí)行replace_query.py當中的替換方法,最后將請求的結果存放在searchRsp文件當中波岛。
大家可以先執(zhí)行這段腳本茅坛,看看searchRsp有沒有我們想要的請求結果。
chmod +x get.sh
./get.sh 胸大
如果一切正常则拷,我們會看到一段格式規(guī)范灰蛙,結構清晰的json串。類似:
{
"data": [
{
"content": {
"excerpt": "也要表現(xiàn)出來(基本上<em>胸大</em>的人.在<em>大胸</em>的對比下腰都是細的,腰圍和胸圍一樣大的<em>大胸</em>……那種應該不是<em>大胸</em>吧.只是<em>大胸</em>圍而已)很多<em>大胸</em>妹子的誤區(qū)都是喜歡穿寬松的上衣.配合含胸.以為自己",
"url": "https://api.zhihu.com/answers/61382005"
},
肉眼掃描下就可以發(fā)現(xiàn)我們的目標是https://api.zhihu.com/answers/61382005
隔躲。這種url是我們進入回答頁面的url摩梧,61382005應該就是我們的detail ID號。
接下來我們需要使用grep宣旱,寫個簡單的正則提取出這些ID號仅父。走你:
#extract answer url
cat searchRsp | grep -aoE 'https[^"]*(answers)[^"]*' | sed 's/\\//g' | grep -oE '[0-9]+' > answers
很簡單的正則,上面的腳本就將我們的ID號統(tǒng)統(tǒng)提取出來,并寫進answers文件笙纤。執(zhí)行下打開answers文件耗溜,看看ID有木有。
Replay Answer Request
接下來我們按同樣的步驟回放下進入回答的請求省容。
先看下請求的格式:
GET https://api.zhihu.com/answers/61382005
也是個光禿禿的url抖拴,替換ID號就OK拉。上腳本(replace_url.py):
import mitmproxy
import argparse
class Replacer:
def __init__(self,dst):
self.dst = dst
def request(self,flow):
flow.request.path=flow.request.path.replace("61382005", self.dst)
def start():
parser = argparse.ArgumentParser()
parser.add_argument("dst", type=str)
args = parser.parse_args()
return Replacer(args.dst)
很簡單的GET請求腥椒,替換ID號即可阿宅。
接著實施replay attack:
#replay attack
while IFS= read -r p; do
#echo "$p"
mitmdump -dd -s "./replace_url.py $p" -znc detailReq -w detailRsp | grep -aoE 'http[^"]*.jpg' | xargs wget -P ./magic
done < answers
這段bash腳本將之前保存在answers文件中的ID號,一行行讀取出來笼蛛,再通過mitmdump進行replay洒放,并通過replace_url.py替換ID號,最后將結果經(jīng)過grep過濾滨砍,xargs傳遞給wget來下載往湿,最后文件都會下載到magic目錄下。
沒有下載wget的同學惋戏,可以先通過brew安裝下:
brew install wget
到這里所有的工作就完成啦领追,所以我們有了最后的get.sh:
#!/bin/bash
#replay attack
mitmdump -dd -s "./replace_query.py $1" -znc searchReq -w searchRsp
#extract answer url
cat searchRsp | grep -aoE 'https[^"]*(answers)[^"]*' | sed 's/\\//g' | grep -oE '[0-9]+' > answers
#replay attack
while IFS= read -r p; do
#echo "$p"
mitmdump -dd -s "./replace_url.py $p" -znc detailReq -w detailRsp | grep -aoE 'http[^"]*.jpg' | xargs wget -P ./magic
done < answers
趕緊運行腳本,發(fā)揮想象力响逢,感受下知乎愛的供養(yǎng)吧蔓腐。
安全知識總結:
這里只是給大家提供個思路,我相信還有很多App都有類似的問題龄句,在安全方面投入太少。
這個小工具之所以能成功散罕,是由于:
知乎App的客戶端沒有做ssl pinning分歇,所以可以通過中間人攻擊分析請求。
知乎Server端也沒有針對replay attack做任何防范欧漱。
大家做App還是要多注意下安全方面的東西职抡,即使上了https,也要做多做一層加密保護误甚。安全方面的工作缚甩,做得再多也為過。
我這個腳本對應的賬號有可能會被停了窑邦,如果失效擅威,可以照著上面的步驟自己做一個:)
最后,溫馨提示:在公眾號恢復消息z冈钦,可以下載腳本郊丛。使用方式:
chmod +x get.sh
./get.sh 好好學習