JS逆向实战23 某市wss URL加密+请求头+ws收发
聲明
本文章中所有內(nèi)容僅供學(xué)習(xí)交流,抓包內(nèi)容、敏感網(wǎng)址、數(shù)據(jù)接口均已做脫敏處理,嚴(yán)禁用于商業(yè)用途和非法用途,否則由此產(chǎn)生的一切后果均與作者無關(guān),若有侵權(quán),請(qǐng)聯(lián)系我立即刪除!
本文首發(fā)鏈接為: https://mp.weixin.qq.com/s/o5UCJFhBg-4JFdS0aEwDuw
前言
在此前。我們先來了解下什么是webscoket?什么是wss?什么是ws?
WebSocket協(xié)議是html5的一種通信協(xié)議,該協(xié)議兼容我們常用的瀏覽器。例如Chrome、 Firefox、IE等。它可以使客戶端和服務(wù)端雙向數(shù)據(jù)傳輸更加簡單快捷,并且在TCP連接進(jìn)行一次握手后,就可以持久性連接,同時(shí)允許服務(wù)端對(duì)客戶端推送數(shù)據(jù)。外加傳統(tǒng)模式的協(xié)議一般HTTP請(qǐng)求可能會(huì)包含較長的頭部,但真正有效的可能只有小部分,從而就占用了很多資源和帶寬。因此WebSocket協(xié)議不僅可以實(shí)時(shí)通訊,支持?jǐn)U展;也可以壓縮節(jié)省服務(wù)器資源和帶寬。
WS協(xié)議和WSS協(xié)議兩個(gè)均是WebSocket協(xié)議的SCHEM,兩者一個(gè)是非安全的,一個(gè)是安全的。也是統(tǒng)一的資源標(biāo)志符。就好比HTTP協(xié)議和HTTPS協(xié)議的差別。非安全的沒有證書,安全的需要SSL證書。(SSL是Netscape所研發(fā),用來保障網(wǎng)絡(luò)中數(shù)據(jù)傳輸?shù)陌踩裕饕沁\(yùn)用數(shù)據(jù)加密的技術(shù),能夠避免數(shù)據(jù)在傳輸過程被不被竊取或者監(jiān)聽。)其中WSS表示在TLS之上的WebSocket。WS一般默認(rèn)是80端口,而WSS默認(rèn)是443端口,大多數(shù)網(wǎng)站用的就是80和433端口。(在高防防護(hù)過程中,80和433端口的網(wǎng)站是需要備案才可以接入國內(nèi)的。)當(dāng)然網(wǎng)站也會(huì)有別的端口,這種如果做高防是方案是可以用海外高防的。WS和WSS的體現(xiàn)形式分別是TCP+WS AS WS ,TCP+TLS+WS AS WS。服務(wù)器網(wǎng)址就是 URL。
目標(biāo)網(wǎng)站
aHR0cDovL3d3dy5sdXhpLmdvdi5jbi9jb2wvY29sNDQ0NC9pbmRleC5odG1s
抓包分析
我們掏出我們的抓包工具看看。我們這里選擇charles去抓包。
這里吐出了兩個(gè)數(shù)據(jù)包,一個(gè)是https協(xié)議的,一個(gè)是wss協(xié)議的。
https協(xié)議:
每個(gè)都看了 其他的請(qǐng)求都沒用。只有這個(gè)v1 這個(gè)請(qǐng)求不確定。
這里我們簡單分析一下:
- 返回給我們的cookie的
dGg2aCfMMK97Ro270mqBFu5qjC8TQbL2opnHvbEpM這個(gè)的value的值 對(duì)應(yīng)的就是wssURLpr的后綴 - v1/sessions這個(gè)請(qǐng)求返回給我們的值是一段加密的值。
- 其他的頁面均無數(shù)據(jù)來源。
這里我們大膽猜測一下:這個(gè)v1session這個(gè)請(qǐng)求返回給我們的值。我們需要解密,解密出來的值,大概率就是這個(gè) dGg2aCfMMK97Ro270mqBFu5qjC8TQbL2opnHvbEpM cookie的值。然后我們提取出來。完成對(duì)wss這個(gè)URL的拼接。從而請(qǐng)求。當(dāng)然這些都是猜測。我們再來看看wss請(qǐng)求。
wss協(xié)議:
這里只有一個(gè)請(qǐng)求。就不搞那些彎彎繞繞了。話不多說 直接看contents里的內(nèi)容。
從這張圖我們可以知道很多
- 通過wss傳輸數(shù)據(jù)
- 數(shù)據(jù)很亂 肯定也是通過js進(jìn)行的一些打亂和拼接。
- 這個(gè)WSS的連接的某個(gè)值是通過v1/session的請(qǐng)求的cookie來獲得的。
其他的東西。我們還是需要一步一步來。首先需要把v1/sessions 這個(gè)請(qǐng)求請(qǐng)求且解密。
目的
- 獲取wss連接(偽造并且獲取v1/sessions請(qǐng)求中的cookies)
- wss 數(shù)據(jù)的解碼
數(shù)據(jù)接口分析
v1/session 接口分析
我們直接去網(wǎng)頁上找這個(gè)sessions棧。
根據(jù)我們的經(jīng)驗(yàn)之談。前兩個(gè)請(qǐng)求不是。后面這個(gè)anonymous匿名函數(shù)值也不是。所以大概率就是這個(gè)t.startSession。
追棧進(jìn)去。
這個(gè)位置大概率就是加密點(diǎn)。并且還做了一層Json序列化。但這個(gè)是v1/session 傳值的參數(shù)。那就很簡單了。這個(gè)重點(diǎn)不就是把P的值搞出來。然后調(diào)用這個(gè)encryptSessions這個(gè)方法就行了嗎。
首先打斷點(diǎn)追進(jìn)去看看是什么。
可以看到 加密了一組名為P的值。這個(gè)P我們繼續(xù)往上看。
可以看到 有些是瀏覽器的一些值。有一些則是自己封裝的值。都在上面連在一起。到時(shí)候扣下來就行。但其實(shí)經(jīng)過多次測試。只有這個(gè) tabId:c 這組值 需要封裝,其他的值寫死即可。
其實(shí)可以發(fā)現(xiàn)這個(gè)文件是個(gè)webpack打包的文件。這個(gè)tabId賦值給了加載器函數(shù),調(diào)用了其他的函數(shù)。那我們直接搜索這個(gè)tabId就好啦
我們找到了生成的這個(gè)值。可是這個(gè)值其實(shí)是找不到生成的位置的。但其實(shí)縱觀全局。這個(gè)tabId是有很多相等的值。所以我們改寫一下
function get_tabID() {
return Math.random().toString(36).slice(-10)
}
這樣 tabId的值就出來了。
當(dāng)然這只是第一步。后續(xù)把encryptSessions這個(gè)函數(shù)扣出來了。
當(dāng)然 分析到這里還不算難。后續(xù)就是把如何把這個(gè)東西扣代碼扣出來
wss接口請(qǐng)求分析
其實(shí)我們最主要的目的還是獲取這個(gè)wss的連接。那我們就簡單來看看這個(gè)wss連接是如何生成的。我們剛剛通過抓包軟件已經(jīng)簡單分析了一下。可以通過偽造v1/sessions這個(gè)請(qǐng)求來獲取cookie 從而填充wss鏈接。
老規(guī)矩 進(jìn)堆棧>>>>>>>>
搜索this.channelURL
獲取到this.channelURL的生成點(diǎn)。
經(jīng)過大量測試可知
ws_url = 'ws://www.xxx.xxx/1ywuKELSO2ahQuWZ/pr/' + urlPrefixToken + '/b/ws/' + tabID
而這個(gè)urlPrefixToken的生成處如下圖
urlPrefixToken 也和我們一開始抓包分析的一樣。就是通過cookie來生成的。
加密v1/sessions的data
我們進(jìn)棧點(diǎn)。發(fā)現(xiàn)是這個(gè)dynamicEncrypt 這個(gè)函數(shù)生成的加密值。
===? 繼續(xù)
那接下來我們只要封裝這個(gè)dynamicEncrypt 函數(shù)即可。
因?yàn)檫@個(gè)是在webpack里面。所以我們扣除加載器。然后缺啥補(bǔ)啥就可以了。
當(dāng)然。其實(shí)全部摳出來 內(nèi)容很多。而且很麻煩。所以本文使用扣代碼去解決。
這里就不講怎么扣代碼了
核心代碼請(qǐng)查看原文鏈接>>>> https://mp.weixin.qq.com/s/o5UCJFhBg-4JFdS0aEwDuw
當(dāng)然 值得注意的是這個(gè)iv。也是需要摳出來的。
function get_iv() {
var t = Math.random().toString(36).slice(-8) + "-" + Math.random().toString(36).slice(-8) + (new Date).getTime()
, e = dynamicEncrypt(t, l, u).replace("_", "");
return e.substring(1, 17)
}
上文提到的tabId 我們也重新封裝成一個(gè)函數(shù)
function get_tabID() {
return Math.random().toString(36).slice(-10)
}
獲取cookie
當(dāng)然。我們廢那么打力氣去偽造這個(gè)請(qǐng)求。不是獲取這里面的數(shù)據(jù)的。而是為了拿到請(qǐng)求v1/sessions中的cookie的。因?yàn)樵诘谝欢挝覀兙头治隽恕ss的有一部分值是可以通過v1/sessions中的cookie拿到的。
我們帶入python中運(yùn)行試試。
好。經(jīng)過測試。我們發(fā)現(xiàn)請(qǐng)求返回給我們的狀態(tài)碼是500。這是咋回事????
經(jīng)過我們反復(fù)測試。我們發(fā)現(xiàn)我們還需要添加上請(qǐng)求頭。而請(qǐng)求頭里還有一個(gè)值
'etag'而這個(gè)值恰恰又等于剛剛 AES加密中的IV值。
我們把這個(gè)值再添加進(jìn)去 請(qǐng)求看看。
這樣就能請(qǐng)求成功了。
在上文分析。我們可知。獲取內(nèi)容不是我們所需要的。我們真正需要的>>>>>>>> 獲取cookie
我們獲取這個(gè)cookie的value。然后拼接URL。
核心代碼請(qǐng)查看原文鏈接>>>> https://mp.weixin.qq.com/s/o5UCJFhBg-4JFdS0aEwDuw
請(qǐng)求WSS連接
這里有兩種方式
- 通過Python 模擬連接websocket 請(qǐng)求
- 缺點(diǎn):后續(xù)需要手動(dòng)解碼。兼容性不好
- 優(yōu)點(diǎn):高效快速。
- 通過JS 連接webscoket
- 缺點(diǎn):不好調(diào)用。需要手動(dòng)扣代碼
- 兼容性很好。得到的數(shù)據(jù)也比較完整。
這里我選擇用Python 模擬連接。因?yàn)?扣代碼的方式我試過。速度有點(diǎn)慢。而且好像也不太對(duì)的樣子。
這里貼下連接webscoket的代碼
ws = websocket.WebSocketApp(ws_url,on_message=on_message, )
ws.run_forever()
def on_message(ws, message):
print(message)
結(jié)果>>>>>>
這得到的是啥呀? 一堆亂碼。
但是這也很簡單判斷。wss一般傳輸?shù)臄?shù)據(jù)就兩種,文本和二進(jìn)制數(shù)據(jù)
這個(gè)很明顯是二進(jìn)制數(shù)據(jù)。而這個(gè)是通過Message pack的方式去壓縮的。再通過Message pack的方式去解包就行了。
這里簡單介紹下什么是Message pack:
MessagePack是一種有效的二進(jìn)制序列化格式。它使您可以在多種語言(如JSON)之間交換數(shù)據(jù)。但是它更快,更小。小整數(shù)被編碼為一個(gè)字節(jié),典型的短字符串除字符串本身外僅需要一個(gè)額外的字節(jié)。簡單來講,它的數(shù)據(jù)格式與json類似,但是在存儲(chǔ)時(shí)對(duì)數(shù)字、多字節(jié)字符、數(shù)組等都做了很多優(yōu)化,減少了無用的字符,二進(jìn)制格式,也保證不用字符化帶來額外的存儲(chǔ)空間的增加。
官網(wǎng): MessagePack: It's like JSON. but fast and small. (msgpack.org)
github:https://github.com/msgpack/
官網(wǎng)有示例代碼。直接使用即可。下面貼一個(gè)本人用的方式
import msgpack
def on_message(ws, message):
import ormsgpack
print(ormsgpack.unpackb(message))
然后我們?nèi)ヂ崛 ?/p>
然后發(fā)現(xiàn)可以成功提取。
但是這個(gè)請(qǐng)求中。標(biāo)題和時(shí)間倒還比較好獲取。
但是詳情頁的連接。好像還并沒有發(fā)給我們。
獲取詳情頁鏈接
我們繼續(xù)去看wss的這個(gè)連接。
發(fā)現(xiàn)我們每次點(diǎn)進(jìn)詳情頁。我們會(huì)向服務(wù)器發(fā)送一個(gè)請(qǐng)求。
然后服務(wù)器會(huì)再吐一個(gè)連接給我們。
并且詳情頁內(nèi)容也是wss傳給我們的。
說實(shí)話真的很麻煩>>>>>>>>>個(gè)人建議還是用其他方式去獲取吧。本文只做研究。
本文首發(fā)鏈接為: https://mp.weixin.qq.com/s/o5UCJFhBg-4JFdS0aEwDuw
總結(jié)
以上是生活随笔為你收集整理的JS逆向实战23 某市wss URL加密+请求头+ws收发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ACM 阶乘数位数
- 下一篇: 《Think in JAVA》之每日一读