javascript
【瑞数5】浅谈某普期刊JS逆向的环境检测点
【瑞數(shù)5】淺談某普期刊JS逆向的環(huán)境檢測點(diǎn)
- 前言
- JS加載流程
- 第一個(gè)JS
- 第二個(gè)JS
- 第三個(gè)JS
- AST簡單解混淆
- 環(huán)境檢測
- 前奏
- 異步執(zhí)行JS流程
- 高潮
- 運(yùn)行結(jié)果
- 總結(jié)
- 鳴謝
前言
這幾天把某期刊的rs5環(huán)境檢測看差不多了,所以寫篇文章簡單聊下rs5會(huì)檢測到的一些環(huán)境。我所用的方法基于瀏覽器“沙箱”的,可以做到邊調(diào)試邊補(bǔ)環(huán)境。
如果有想看算法運(yùn)行邏輯的同學(xué),出門左轉(zhuǎn)看十一姐的文章。
RPC方案可以看看這個(gè)視頻(陳不不大佬出品)。
PS:我菜所以不會(huì)分析算法邏輯…
本文以某普期刊的高級檢索接口作為示例,地址:aHR0cDovL3Fpa2FuLmNxdmlwLmNvbS9RaWthbi9TZWFyY2gvQWR2YW5jZT9mcm9tPWluZGV4
JS加載流程
第一步當(dāng)然是,輸入網(wǎng)址,F12,打上script斷點(diǎn)調(diào)試,回車!
訪問網(wǎng)頁先是返回一個(gè)這樣的html代碼,而不是維普首頁的內(nèi)容。并返回給我們一個(gè)Cookie,GW1gelwM5YZuS=xxxxxx。玩過某數(shù)都知道,我們需要在這個(gè)頁面得到一個(gè)GW1gelwM5YZuT參數(shù),然后寫在cookie中,再次訪問網(wǎng)址,即可得到首頁的內(nèi)容。
第一個(gè)JS
第一個(gè)JS是生成$_ts參數(shù)。我建議大家先copy一份源代碼以供后續(xù)本地調(diào)試。
然后這個(gè)JS的鏈接是在html頁面里的,用正則可以很快的匹配到。
第二個(gè)JS
我們點(diǎn)擊跳過斷點(diǎn),進(jìn)入第二個(gè)JS。JS在$_ts里push很多參數(shù),供后續(xù)使用。這個(gè)JS也是比較重要的,然后這個(gè)JS是在html頁面里的,是一個(gè)閉包函數(shù)。JS運(yùn)行結(jié)束時(shí)會(huì)用eval函數(shù)進(jìn)入第三個(gè)JS。
然后html標(biāo)簽的meta,它的content參數(shù),后續(xù)也是有使用到的。
第三個(gè)JS
這里就是eval函數(shù)入口。我們直接搜索]](_$ 字符串就能很快定位到這里了。打上斷點(diǎn)看一下。沒做過的同學(xué)可以自己試試各種方法去找到這里哈,博主用了hook cookie的方式找到了這里,貼上hook代碼(直接從v神插件里偷代碼,大佬的代碼用起來就是舒服,嘿嘿~)。
- 可以看到_$ya就是第三個(gè)JS了,并且這里的 $_ts已經(jīng)init完成了。
- 這時(shí)候,我把3份JS都保存到本地了,供后續(xù)本地調(diào)試。
- 本地調(diào)試的時(shí)候,可以把入口注釋掉,然后手動(dòng)eval 格式化好的代碼,這樣調(diào)試會(huì)更輕松一些。
- 博主這邊不依賴Node環(huán)境,使用vm2模塊構(gòu)建沙箱進(jìn)行調(diào)試,然后Promise需要手寫,否則V8運(yùn)行會(huì)報(bào)錯(cuò)。
AST簡單解混淆
第三份JS是重點(diǎn)需要調(diào)試并且查看代碼是如何檢測環(huán)境的。我們可以用AST簡單的脫個(gè)混淆。我是直接在調(diào)試的時(shí)候把這個(gè)數(shù)組值的拿出來,然后用AST直接匹配替換(這個(gè)混淆數(shù)組是由一個(gè)函數(shù)得到的,這里就不放出來了,很好找到)。效果如圖~
環(huán)境檢測
前奏
前奏是指上述3個(gè)js執(zhí)行完畢之后,會(huì)得到一個(gè)比較短的cookie(是可以直接訪問的首頁,檢測比較松),以及三個(gè)環(huán)境值,在localStorage里,分別是 nd、cDro、YWTU
這部分的dom檢測比較松,沒什么坑,很容易補(bǔ)出來。
這里它創(chuàng)建了一個(gè)div節(jié)點(diǎn),并使用了div.getElementsByTagName(“i”)方法獲取了一個(gè)值。不懂的同學(xué)可以去菜鳥教程里看看,或者在瀏覽器里輸入這些代碼查看返回值等。 并且還檢測了msCrypto以及ActiveObject。
每次調(diào)用xhr的open方法時(shí),都會(huì)走向這里。他創(chuàng)建了一個(gè)a 標(biāo)簽,并對a標(biāo)簽href進(jìn)行賦值。這里有做參數(shù)值校驗(yàn),并和location里的參數(shù)進(jìn)行比對,但是是有差異的,如果有問題會(huì)導(dǎo)致后面搜索接口里的得到的拼接url錯(cuò)誤。
我們?nèi)g覽器hook下 createElement 這個(gè)方法,然后進(jìn)到這個(gè)地方的代碼看下a標(biāo)簽下的 href、pathname 等參數(shù),將環(huán)境補(bǔ)的一模一樣即可。
用 dir(標(biāo)簽a) 就能得到標(biāo)簽下的值了,下圖是a標(biāo)簽下的值
與 location下的值還是有差異的,這里是有用的,對應(yīng)的值必須要補(bǔ)的完全一樣,然后這里其實(shí)有個(gè)小細(xì)節(jié),通過對a標(biāo)簽的href進(jìn)行賦值,a標(biāo)簽下的host hostname 等一些參數(shù)也會(huì)根據(jù)href的值來進(jìn)行賦值,然后rs6也是有檢測這個(gè)標(biāo)簽的。
這里就是使用了document.getElementsByTagName方法獲取到了html頁面里 meta 節(jié)點(diǎn),得到了content參數(shù),然后把這個(gè)節(jié)點(diǎn)刪除掉了。
這里是把頁面上 head下的所有script節(jié)點(diǎn)全部刪除
檢測了document.documentElement.style
頁面上還有2個(gè)這樣的函數(shù),是在script節(jié)點(diǎn)下的,別漏掉了。這里的方法會(huì)再頁面write一個(gè)節(jié)點(diǎn)出來,并刪除所有script節(jié)點(diǎn)。
write了一個(gè)節(jié)點(diǎn),若沒有body節(jié)點(diǎn),則會(huì)創(chuàng)建body節(jié)點(diǎn)并在body節(jié)點(diǎn)下加入一個(gè)子節(jié)點(diǎn)。
在這里獲取他的名字 and 值
rs5 檢測了location document navigator 等重要環(huán)境值,以及原型鏈toString檢測。當(dāng)我們使用代理(proxy)的時(shí)候(自行百度,不做介紹),就能監(jiān)測到他使用了哪些環(huán)境變量。這里就不一一列舉了,偏多~ 但是必須一致,否則會(huì)導(dǎo)致運(yùn)行軌跡變化。
異步執(zhí)行JS流程
前奏部分執(zhí)行完畢后,開始異步執(zhí)行最后的JS。這部分是得到localStorage里的 ff、f0 、f1 、fh1 環(huán)境變量,最后得到完整的cookie, 長度位279位。
下面是前奏的JS代碼中,添加的一些異步方法(巨坑!!)
這里檢測了navigator.getBattery方法,然后navigator.getBattery()后異步執(zhí)行_$mg方法。
這里就是_$mg方法執(zhí)行過程中會(huì)調(diào)用的一個(gè)地方,這里的 sy 再后續(xù)會(huì)用到,這里的level是一個(gè)環(huán)境值。Ap是BatteryManager。
然后是window.addEventListener 添加類型為 load 的監(jiān)聽事件,一共7個(gè),在這過程中就有用到上面提到的 sy 參數(shù), 若為undefined,就會(huì)導(dǎo)致JS運(yùn)行軌跡變化。 異步執(zhí)行方法的順序需要注意!
然后再執(zhí)行監(jiān)聽事件JS中,再次添加setTimeout 來實(shí)現(xiàn)異步執(zhí)行JS。
_$_w就是setTimeout , 后面則是要執(zhí)行的方法。
高潮
這部分尤其殘暴。檢測了各種節(jié)點(diǎn)操作,添加刪除,尋找子節(jié)點(diǎn) 等等
這部分關(guān)系到 fh1 參數(shù)的形成。_$UC 是后續(xù)進(jìn)行加密時(shí)會(huì)用到的數(shù)組。 創(chuàng)建div節(jié)點(diǎn),通過設(shè)置innerHTML添加子節(jié)點(diǎn),然后將div 加入到 body節(jié)點(diǎn)下。通過不斷修改style來改變節(jié)點(diǎn)的高度、寬度,若修改style后的 寬、高 與一開始的寬高不一致,就把style樣式的名稱存入數(shù)組。
檢測了 window 下的 matchMedia
這里是個(gè)小細(xì)節(jié),window instanceof Window 結(jié)果是true。
這里就是webgl指紋了
還有很多坑,需要同學(xué)們自己去踩了才知道。博主這篇文章只放了一些踩到的坑~ 并不是全部。再多說一點(diǎn),就不禮貌了~
運(yùn)行結(jié)果
附上運(yùn)行結(jié)果
其中ff是動(dòng)態(tài)的(環(huán)境檢測)。f0,f1在不同瀏覽器下會(huì)不一樣,2個(gè)值的變化取決于 canvas指紋、webgl指紋,fh1可能在別的瀏覽器中不存在。YWTU(每份JS生成的不同),cDro都是靜態(tài)的。
2022.7.7 補(bǔ)充
目前鼠標(biāo)事件分析的七七八八了,比較重要的是move、leave、enter、down。至于事件流程,大家先在代碼中找到賦值數(shù)組的位置,然后在瀏覽器上進(jìn)行斷點(diǎn),查看是哪個(gè)鼠標(biāo)事件觸發(fā)之后會(huì)走到這。最后經(jīng)過一系列的鼠標(biāo)事件過后,cookie的xxxT參數(shù)以及url的后綴長度都會(huì)和瀏覽器一致。下面是運(yùn)行結(jié)果測試,大致已經(jīng)算是完結(jié)了,撒花~
2022.7.21 補(bǔ)充
由于沙箱是v8環(huán)境,我之前用execjs庫運(yùn)行js,無法動(dòng)態(tài)緩存一些環(huán)境,所以是手動(dòng)在v8環(huán)境中調(diào)用獲取值來進(jìn)行訪問測試。然后就在今天,群里的泰迪佬告訴我py_mini_racer這個(gè)庫是可以執(zhí)行js并緩存環(huán)境的(在這里感謝下泰迪佬,愛你么么)。測試下來,執(zhí)行速度還不錯(cuò),連續(xù)訪問了20次都返回了200狀態(tài)碼。安利一波~
2022.8.29 補(bǔ)充
用了v神的插件之后,就自己寫了個(gè)hook 瀏覽器dom節(jié)點(diǎn)的腳本,能實(shí)現(xiàn)dom節(jié)點(diǎn)自吐調(diào)用了哪些函數(shù)和值,寫的還不是很好。然后順帶hook了鼠標(biāo)事件之后我才發(fā)現(xiàn),這樣去定位js代碼調(diào)用鼠標(biāo)事件的位置會(huì)更快一點(diǎn)。當(dāng)然如果用控制流去判斷,也能定位到位置,這樣去查看調(diào)用堆棧會(huì)更清晰些。hook 腳本代碼已經(jīng)放在新出的文章里了~
總結(jié)
-
補(bǔ)環(huán)境當(dāng)中,若遇到執(zhí)行時(shí)的參數(shù)有問題,導(dǎo)致的運(yùn)行軌跡變化,需要去瀏覽器上定位相同代碼位置查找問題、或翻JS代碼找到參數(shù)賦值的地方。
-
補(bǔ)環(huán)境的話,主要在意的就是在控制流循環(huán)下運(yùn)行的順序是否與瀏覽器上的一致。
PS:博主主要就是在這里比對瀏覽器的運(yùn)行順序,進(jìn)行問題排查(可以排查大部分,還有一些需要自己去想辦法找)。
-
博主文章寫的少,可能排版看起來不舒服,還請見諒~
-
本篇文章僅供學(xué)習(xí)參考,如有侵權(quán),請立即聯(lián)系博主刪除。未經(jīng)博主允許請勿私自轉(zhuǎn)發(fā)文章~
鳴謝
在這里感謝陳不不大佬,在JS逆向之路上提供了不少幫助~
有興趣的小伙伴們可以看看他在B站上發(fā)的視頻,對JS逆向提升有一定的幫助~
總結(jié)
以上是生活随笔為你收集整理的【瑞数5】浅谈某普期刊JS逆向的环境检测点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LC振荡器稳定度与品质因数的关系
- 下一篇: 理解电路:从电报机到门电路