2019年末逆向復習系列之努比亞Cookie生成逆向分析
轉載於https://zhuanlan.zhihu.com/p/93858575?from_voters_page=true
逆向背景
努比亞俱樂部的逆向有意思在它的Cookie
是動態生成的,是由Js
生成Cookie
的案例,並且這個網站還有前端反調試的機制,對於新手爬蟲工程師來說很值得學習和研究。
分析流程與逆向破解
我們以這個鏈接為例努比亞-牛仔俱樂部
,訪問並打開開發者工具,讀者會發現並沒有遇到什么異常情況。

等等,我們這次講的是生成Cookie
,我們首先需要把該網站的緩存、Cookie
清除才行,不過我們先分析分析它們的Cookie
的關鍵點。

看到Cookie
的組成,覺得acw_sc__v2
和acw_sc__v3
參數比較可疑,這個疑問我們先存在,之后再看看。
之后我們照例在Application
->Clear Storage
清除數據。

清除完之后我們依舊打開開發者工具重新刷新頁面進行訪問,可以發現,網站彈出debugger

知識點1:前端反調試
隨着現在爬蟲課程的普及,越來越多人都掌握了基本的爬蟲用法,類似利用開發者工具尋找網站接口或者進行調試逆向尋找加密方法,對於網站本身來說,如何簡單又有效地減緩這種行為是應該考慮的,所以一些網站在代碼中注入了檢測開發者工具是否打開的Js
代碼,這樣,當我們想要打開開發者工具的時候我們就會陷入網站的無限循環的debugger地獄
,而且這樣還會造成Js
的內存泄漏,你可以在遇到這種情況的時候檢查你的chrome頁面進程,會發現內存占用量越來越高,可你什么都沒干?所以,對於這種反調試手段,我們需要學習如何繞過。
1. 繞過debugger地獄
我們首先查看右邊的Call Stack
調用棧,我們一一分析,可以追溯到如圖所示的地方。

關鍵代碼是這樣的,也就是一開始會執行_0x4db1c
這個函數(初步理解是上文所說的檢測開發者工具是否打開的函數,之后setInterval
函數是每隔一定時間執行)
_0x4db1c();
setInterval(function() {
_0x4db1c();
}, 4000);
我們再看_0x4db1c
的函數,它停在_0x355d23
這個函數上面

面對這樣的情況,我們可以直接在Console
里面對這個函數進行重寫

重寫好之后我們執行下,會發現這個頁面就直接生成好Cookie
去訪問頁面了,這樣達不到我們之前想研究它Cookie
生成的邏輯的目的。

目前我們繞過了debugger
反調試,那我們該怎么獲取生成Cookie
的邏輯呢?我們接着分析
2. 破解Cookie生成邏輯
為了我們分析的方便,我們可以直接把這個debugger
的代碼保存下來,在我們本地代碼中刪除debugger
的邏輯之后進行調試。

我們直接打開這個html文件,我們會發現網頁一直卡在Sources
不動,為什么會出現這種情況?

仔細分析代碼,發現有些Regexp
的檢測代碼,根據以往的經驗可能是檢測代碼是否長開?防止有人本地調試?我們使用壓縮后的代碼,大家可以用Js壓縮/解壓工具進行壓縮

果然,壓縮之后還是正常的,那么可以驗證我們剛才的想法了。

我們刪除debugger
相關的代碼,也就是
_0x4db1c();
setInterval(function() {
_0x4db1c();
}, 4000);
打開網頁后發現頁面一直在閃?html代碼不長,我們再仔細看看,注意到一個細節setTimeout

setTimeout
是延后幾秒執行一次,我們看一下’\x72\x65\x6c\x6f\x61\x64\x28\x61\x72\x67\x32\x29’是什么意思,我們把它放在Console
里看看。

可以看到,setTimeout
執行reload
函數,我們看看reload
函數
function reload(x) {
setCookie("acw_sc__v2", x);
document.location.reload();
}
里面的邏輯是先設置Cookie
再重載頁面,所以我們這里一直閃的原因是先執行setTimeout
再重載頁面又執行setTimeout
,所以又是一個循環地獄,我們刪除setTimeout
這段代碼就行。等等,我們再看看上面Console
中的結果reload(arg2)
,然后到reload
函數中,acw_sc__v2
是由arg2
這個函數得來的,好,我們現在明白了哪個地方生成的Cookie
了,我們在html代碼中搜索arg2
,然后對它打上斷點。

3. 分析加密算法
我們先總體看下arg2
函數的構成

也就是需要_0x23a392
和_0x5e8b26
這個兩個關鍵參數,_0x23a392
來自arg1
的方法生成,它們都是有_0x55f3
這同一個方法,所以我們的思路就清晰了。
我們先看看_0x55f3
這個方法,並且做一些調試,可以發現_0x55f3
通過傳入的參數不同使用不同的方法,有些類似於控制流平坦化
。


知識點2:控制流平坦化
直接上圖

首先_0x5e8b26
這個參數我們多次調試后發現是個變量,可以先確定,"3000176000856006061501533003690027800375"
,當然我們也可以直接搜索_0x5e8b26

而我們獲取到_0x23a392
和_0x5e8b26
之后進行加密的方法如下


大致的加密就是如上這樣,因為整體代碼量也不大,可以直接改寫或者使用python
加載Js
都行。
4. 總結思路
這次的案例主要是可以學習到兩點,第一點就是我們懂得有些網站會進行前端反調試,手段之一就是會檢測開發者工具是不是打開,而且如果我們把代碼拿到本地,竟然還會檢測本地代碼是否是展開的?第二點我們需要習慣這種代碼混淆的方式,有些網站會用_0xxxx
等無意義的符號進行混淆,以及使用16進制來做混淆惡心我們,我們想要還原的話直接把代碼放到Console
里面執行一下就可以了,因為Js
也能讀取原始的16進制碼。

代碼實戰
有了上面這個分析流程,我們就可以開始Coding
了,以下是acw_sc__v2
加密的流程。
獲取arg1
參數的代碼

獲取arg2
參數的代碼

測試的代碼,先訪問官網動態獲取Cookie
再在請求頭的Header
中加入這個acw_sc__v2
參數去重載URL
訪問官網。

復習要點
從這個復習的案例我們可以總結下思路:
- 如何繞過前端反調試?
- 別害怕混淆的代碼,代碼雖然混淆,但是邏輯還是一樣的。