前程無憂接口分析
- 所需用到的工具
- URL解析
- 通過抓包軟件或者開發者選項抓取數據包
- 對代碼中的參數解析分析
- 對acw_sc__v2進行分析
- 對acw_sc__v2進行轉換代碼生成
- 生成outPutList數組
- 生成arg2參數
- 生成arg3參數
- 最終的效果
- 對詳情頁面的分析
- 對timestamp__1258的生成分析
所需用到的工具
- Charles抓包工具
- https://curlconverter.com/python/
URL解析
先訪問網頁https://www.51job.com/
輸入關鍵字點擊搜索
通過查看這個網址
https://we.51job.com/pc/search?jobArea=260200&keyword=%E5%85%BC%E8%81%8C&searchType=2&sortType=0&metro=
有以下參數
參數名 | 值 | 說明 |
---|---|---|
jobArea | 260200 | 城市代碼 |
keyword | 兼職 | 關鍵字(UrlEncode 編碼) |
sortType | 0 | 0代表綜合排序 1代表最新優先 3代表薪資優先 5代表活躍職位優先 |
通過抓包軟件或者開發者選項抓取數據包
復制cURL Request通過https://curlconverter.com/go/轉為Python代碼
運行代碼查看是否能獲取成功
對代碼中的參數解析分析
通過對代碼中的參數分析,最終發現修改acw_sc__v2的值會導致訪問失敗
所以基本上確定acw_sc__v2為我們需要破解的
對acw_sc__v2進行分析
現在我們需要去網站對acw_sc__v2逆向分析
先檢查一下acw_sc__v2,是本地生成的還是服務器生成
通過如下圖可知它是由本地js文件生成的
現在我們需要把這個值刪除,并編寫一個hook使其能夠快速的定位
cookie_cache = document.cookie;
Object.defineProperty(document, "cookie", {get: function () {console.log(cookie_cache);// 在獲取document.cookie時,執行你想要的操作return cookie_cache; // 返回原始的cookie值},set: function(value) {// 在設置document.cookie時,執行你想要的操作if(value.includes('acw_sc__v2')){debugger;}}
});
最終定位如下圖
開始對棧分析,定位到上一棧
通過查看我們可以知道arg3就是acw_sc__v2的值
在這里打上一個斷點,并重新加載頁面
搜尋arg3
通過閱讀這份代碼可知arg3是通過一個循環來生成的,但是循環的條件與arg2有關,arg2又與列表outPutList有關,outPutList與arg1有關
所以基本的思路為通過arg1生成outPutList,outPutList生成arg2,arg2生成arg3
搜尋arg1
在這里打上斷點,重新加載網頁
通過如上兩張圖片可知arg1來自于訪問一個URL所返回的body中
通過抓包軟件抓取并轉為Python代碼
我們可以通過正則表達式取出這個值
arg1=re.findall("arg1=('[^']*')",response.text)
arg1=arg1[0].replace("'","")
對acw_sc__v2進行轉換代碼生成
生成outPutList數組
通過arg1生成outPutList
for (var i = 0; i < arg1[_0x1e8e("0x1")]; i++) {var this_i = arg1[i];for (var j = 0; j < posList[_0x1e8e("0x1")]; j++) {if (posList[j] == i + 1) {outPutList[j] = this_i}}
}
分析這個js代碼可知這是通過循環來生成的
arg1[_0x1e8e(“0x1”)]是arg1的長度
posList[_0x1e8e(“0x1”)]是posList數組的長度
posList數組是固定值
轉為Python代碼如下
arg1='6AA3E7F5214AEB580A31B0B254C4795589509422'
posList = [15, 35, 29, 24, 33, 16, 1, 38, 10, 9, 19, 31, 40, 27, 22, 23, 25, 13, 6, 11, 39, 18, 20, 8, 14, 21, 32, 26, 2, 30, 7, 4, 17, 5, 3, 28, 34, 37, 12, 36]
outPutList = []
for i in range(len(arg1)):outPutList.append(0)for i in range(len(arg1)):this_i = arg1[i]for j in range(len(posList)):if posList[j] == i + 1:outPutList[j] = this_iprint(outPutList)
生成arg2參數
經過對代碼的分析可知arg2是由outPutList數組轉為字符串實現的
arg2 = outPutList[_0x1e8e("0x2")]("");
arg2 = ''.join(outPutList)
生成arg3參數
for (var i = 0; i < arg2[_0x1e8e("0x1")] && i < mask[_0x1e8e("0x1")]; i += 2) {var GxjQsM = _0x1e8e("0x3")[_0x1e8e("0x4")]("|"), QoWazb = 0;while (!![]) {switch (GxjQsM[QoWazb++]) {case "0":if (xorChar[_0x1e8e("0x1")] == 1) {xorChar = "0" + xorChar}continue;case "1":var strChar = parseInt(arg2[_0x1e8e("0x5")](i, i + 2), 16);continue;case "2":arg3 += xorChar;continue;case "3":var xorChar = (strChar ^ maskChar)[_0x1e8e("0x6")](16);continue;case "4":var maskChar = parseInt(mask[_0x1e8e("0x5")](i, i + 2), 16);continue}break}
}
arg2[_0x1e8e(“0x1”)]是arg2的長度
mask[_0x1e8e(“0x1”)]是mask的長度
mask是固定值3000176000856006061501533003690027800375
GxjQsM是固定的列表[‘1’, ‘4’, ‘3’, ‘0’, ‘2’]
轉為Python代碼
arg3=''
for i in range(0, 40, 2):strChar = int(arg2[i:i + 2], 16)maskChar = int(mask[i:i + 2], 16)xorChar = hex(strChar ^ maskChar)[2:]if len(xorChar) == 1:xorChar = '0' + xorChararg3 += xorChar
最終的效果
對詳情頁面的分析
隨便點擊一個頁面進入詳情頁面,抓包抓取數據
復制CURL命令轉為Python代碼,運行代碼
可以獲取數據
開始分析,最終發現只有修改req和timestamp__1258才會獲取失敗,并且這兩個是一對的,任何一個被修改都會導致獲取失敗
對timestamp__1258的生成分析
通過抓包軟件發現在跳轉頁面之前會訪問一個url獲取js代碼
把整個js代碼復制下來到瀏覽器去調試
搜尋_0x3baf44
搜尋_0x30f62c
最中發現這個_0x56d97c是一個函數,提交的參數為下面這種結構
-1837977873|0|1702035443735
number|0|number
0之后的數字的為時間戳,第一個數字暫不知道,所以去搜尋
大致閱讀可知_0x318558通過for循環來生成的,其中與_0x1117c9有關
搜尋_0x1117c9
打印_0x1117c9
這里你會很熟悉,這些數據都是搜索接口里所抓取的數據
也就是說timestamp__1258的生成思路為
構造如下的列表
{"protocol": "https:","host": "jobs.51job.com","hostname": "jobs.51job.com","port": "","pathname": "/guiyang-gshq/152094046.html","search": "?s=sou_sou_soulb&t=0_0&req=04608edfce87b123a2d4951514d63dc4","hash": "","original": "https://jobs.51job.com/guiyang-gshq/152094046.html?s=sou_sou_soulb&t=0_0&req=04608edfce87b123a2d4951514d63dc4"
}
通過for循環生成_0x318558,在通過_0x318558構造如下結構的數據
_0x318558|0|時間戳
提交到_0x56d97c函數生成timestamp__1258的值
_0x56d97c函數太過龐大并且這個js代碼是混淆后的,最終選擇補環境的方式來實現這個生成,讓后通過Python調用js代碼
補環境之后的效果