日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

2019年末逆向复习系列之Boss直聘Cookie加密字段__zp_stoken__逆向分析

發(fā)布時(shí)間:2024/1/23 编程问答 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019年末逆向复习系列之Boss直聘Cookie加密字段__zp_stoken__逆向分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

鄭重聲明:本項(xiàng)目的所有代碼和相關(guān)文章, 僅用于經(jīng)驗(yàn)技術(shù)交流分享,禁止將相關(guān)技術(shù)應(yīng)用到不正當(dāng)途徑,因?yàn)闉E用技術(shù)產(chǎn)生的風(fēng)險(xiǎn)與本人無(wú)關(guān)。

這篇文章是公眾號(hào)《云爬蟲技術(shù)研究筆記》的《2019年末逆向復(fù)習(xí)系列》的第七篇:《Boss直聘Cookie加密字段__zp_stoken__逆向分析》

本次案例的代碼都已上傳到Review_Reverse上面,后面會(huì)持續(xù)更新,大家可以Fork一波。

具體加密JS可以在Review_Reverse.boss_zp.encrypt.js中看到,替換具體的參數(shù)即可。

背景分析

Boss直聘大概可以算是目前最火的招聘軟件了!幾個(gè)月前的火遍全網(wǎng)的“找工作,馬上,和老板談!”真的是洗腦了一遍又一遍啊!

鑒于Boss直聘的職位更新速度快,職位發(fā)布多的兩大特點(diǎn),很多做行業(yè)分析和各地崗位差距報(bào)告的人都會(huì)利用Boss直聘的數(shù)據(jù)來(lái)做分析,幾個(gè)月前,Boss直聘對(duì)他們的接口在Cookie方面做了__zp_stoken__字段的加密,這次案例就用它來(lái)做逆向分析。

__zp_stoken__字段生成流程分析

我們需要分析的是__zp_stoken__字段,我們看看它是在哪里生成的

我們要獲取Cookie生成的過(guò)程,先把網(wǎng)站的數(shù)據(jù)清空,在Chrome中的Application中利用Clear site data清理好該網(wǎng)站下的數(shù)據(jù),然后我們重新刷新網(wǎng)站(我們需要在具體的職位信息頁(yè)面刷新,因?yàn)槭醉?yè)不需要Cookie就能直接訪問(wèn)),看看Network列表中的Cookie生成過(guò)程

我們首先會(huì)訪問(wèn)具體的職位信息頁(yè)面,得到一個(gè)HttpCode是302的響應(yīng),代表這次的訪問(wèn)重定向到一個(gè)新的URL了,這個(gè)URL可以在響應(yīng)中的Location中看到,拿到的是security-check.html這個(gè)URL,我們看看這個(gè)URL是什么內(nèi)容


這個(gè)URL具體有幾個(gè)Param

  • seed
  • name
  • ts
  • callbackUrl
  • srcReferer

根據(jù)多次的訪問(wèn)測(cè)試,發(fā)現(xiàn)變化的字段主要是seed、name、ts,也就是這個(gè)URL是動(dòng)態(tài)的,我們直接下斷點(diǎn)是打不到具體的地方的,在Chrome里我們也拿不到這個(gè)鏈接的具體響應(yīng)內(nèi)容,我們利用Fiddler來(lái)獲取鏈接內(nèi)容

var Cookie = {get: function(name) {var arr,reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");if ((arr = document.cookie.match(reg))) {return unescape(arr[2]); } else {return null;}},set: function(name, value, time, domain, path) {var str = name + "=" + encodeURIComponent(value);if (time) {var date = new Date(time).toGMTString();str += ";expires=" +date;}str = domain ? str + ";domain=" + domain : str;str = path ? str + ";path=" + path : str;document.cookie = str;} };var url = window.location.href; var seed = decodeURIComponent(getQueryString("seed")) || ""; var ts = getQueryString("ts"); var fileName = getQueryString("name"); var callbackUrl = docodeURIComponent(getQueryString("callbackUrl")); var srcReferer = decodeURIComponent(getQueryString("srcReferer")||'');if (seed && ts && fileName) {seriesLoadScripts("security-js/" + fileName + ".js", function() {var expiredate = new Date().getTime() + 32 * 60 * 60 * 1000 * 2;var code = "";var nativeParams = {};var ABC = window.ABC || frame.contentWindow.ABC;try {code = new ABC().z(seed, parseInt(ts) + (480+new Date().getTimezoneOffset())*60*1000);} catch (e) {}if (code && callbackUrl) {Cookie.set("__zp_stoken__", code, expiredate, COOKIE_DOMAIN, "/");// 據(jù)說(shuō)iOS 客戶端存在有時(shí)寫cookie失敗的情況,因此調(diào)用客戶端提供的方法,交由客戶端額外寫一次cookieif (typeof window.wst != "undefined" && typeof wst.postMessage == "function") {nativeParams = {name: "setWKCookie",params: {url: COOKIE_DOMAIN,name: "__zp_stoken__",value: encodeURIComponent(code),expiredate: expiredate,path: "/"}};window.wst.postMessage(JSON.stringify(nativeParams));}if(srcReferer && isSeo(srcReferer) && srcReferer != 'https://m.baidu.com/'){window.location.replace(srcReferer);} else {window.location.replace(callbackUrl);}} else {window.history.back();}}); } else {if(srcReferer && isSeo(srcReferer) && srcReferer != 'https://m.baidu.com/'){window.location.replace(srcReferer);}else if (callbackUrl) {window.location.replace(callbackUrl);} else {window.history.back();} }

可以看出__zp_stoken__是這么生成的

var seed = decodeURIComponent(getQueryString("seed")) || ""; var ts = getQueryString("ts"); code = new ABC().z(seed, parseInt(ts)+(480+new Date().getTimezoneOffset())*60*1000);

簡(jiǎn)化一下

480+new Date().getTimezoneOffset() = 0 code = ABC.z(seed, ts)

如上所示,通過(guò)傳入的seed和ts參數(shù)調(diào)用實(shí)例ABC的c方法來(lái)生成,給當(dāng)前的document對(duì)象加上帶__zp_stoken__的Cookie之后重新加載頁(yè)面,這樣整個(gè)從無(wú)Cookie訪問(wèn)到生成Cookie重載頁(yè)面訪問(wèn)的流程就分析到這里。

__zp_stoken__生成逆向分析

1. 切中關(guān)鍵語(yǔ)句,下斷點(diǎn)

剛才說(shuō)了security-check.html這個(gè)問(wèn)題是動(dòng)態(tài)的,我們不能去給這個(gè)文件下斷點(diǎn),重新看看security-check.html的頁(yè)面源碼

var fileName = getQueryString("name"); seriesLoadScripts("security-js/" + fileName + ".js", function())

加載了包含加密方法的Js文件,fileName是security-check.html的params中的name字段,我們?cè)赟ources的Page中找到該Js文件,整個(gè)文件一共是5381行

上面我們分析了加密使用ABC的z方法,在文件中搜索ABC字符,找到了z方法

先對(duì)最后的return語(yǔ)句打斷點(diǎn)

重新刷新頁(yè)面,可以獲取的整個(gè)方法中各個(gè)參數(shù)的值,接下來(lái)開(kāi)始分析整個(gè)加密方法的流程

2. 刪繁就簡(jiǎn),核心流程分析

分析z加密方法

ABC[_0x56ae('0x3e')]['z'] = function(_0x172aa3, _0x38e762) {//_0x56ae('0x3e') 是 prototype,ABC[_0x56ae('0x3e')]['z']也就是給ABC方法的prototype屬性中的鍵z指定方法,_0x172aa3是seed,ts是時(shí)間戳var _0x3a1f8c = {};_0x3a1f8c[_0x56ae('0x3f')] = function(_0x5362ae, _0x320fdd) {return _0x5362ae == _0x320fdd;};_0x3a1f8c[_0x56ae('0x40')] = _0x56ae('0x41');_0x3a1f8c[_0x56ae('0x42')] = _0x56ae('0x43');_0x3a1f8c[_0x56ae('0x44')] = function(_0x2e473d, _0x3ad5ac, _0x1c497c) {return _0x2e473d(_0x3ad5ac, _0x1c497c);};_0x3a1f8c[_0x56ae('0x45')] = function(_0x1f3c2a, _0x218684) {return _0x1f3c2a + _0x218684;};try {if (document && _0x3a1f8c[_0x56ae('0x3f')](_0x3a1f8c[_0x56ae('0x40')], typeof document[_0x56ae('0x46')])) {_0x5606fe = _0x172aa3;_0x2f4975 = _0x38e762;} else {_0x5606fe = _0x3a1f8c[_0x56ae('0x42')];}} catch (_0x1f6304) {_0x5606fe = _0x3a1f8c[_0x56ae('0x42')];}//上面幾項(xiàng)是給dict賦值,沒(méi)有什么難度,可以不做修改,重點(diǎn)是最后的return語(yǔ)句中的方法return _0x3a1f8c[_0x56ae('0x44')](_0x49423a, this, _0x3a1f8c[_0x56ae('0x45')](_0x172aa3[_0x56ae('0x47')], 0xb));

return 語(yǔ)句是這樣

我們?cè)赾onsole中獲取每個(gè)參數(shù)的值,看看能不能做精簡(jiǎn)

  • _0x3a1f8c[_0x56ae('0x44')]
function(_0x2e473d, _0x3ad5ac, _0x1c497c) {return _0x2e473d(_0x3ad5ac, _0x1c497c); }

_0x3a1f8c[_0x56ae(‘0x44’)]是這樣一個(gè)方法,參數(shù)一是方法,參數(shù)二、三作為參數(shù)一方法的參數(shù)

  • this
function ABC() {this['i0'] = 0x0;this['d'] = [this]; }

this就是ABC實(shí)例,可以在同一個(gè)文件中搜索ABC可以得到

_0x3a1f8c[_0x56ae('0x45')](_0x172aa3[_0x56ae('0x47')], 0xb)

這個(gè)參數(shù)直接放在console里面運(yùn)行,得到固定值是55,

從上面分析來(lái)看,return語(yǔ)句可以直接簡(jiǎn)化成

_0x49423a(ABC, 55)

3. 還是那句話,缺啥補(bǔ)啥

我們現(xiàn)在拿到了關(guān)鍵語(yǔ)句,接下來(lái)就是調(diào)試_0x49423a方法,往js文件里面添加缺少的變量和函數(shù)方法,出于簡(jiǎn)單的考慮,直接使用node來(lái)調(diào)用js文件

直接拿node運(yùn)行js文件得出來(lái)的結(jié)果和在Chrome的console里運(yùn)行js內(nèi)容得到的結(jié)果不一樣,看來(lái)還需要調(diào)試在哪個(gè)地方引用的windows,this之類的值兩個(gè)運(yùn)行環(huán)境有差別

__zp_stoken__參數(shù)生成注意要求

  • Js加密函數(shù)所在文件不同,不過(guò)文件內(nèi)容邏輯基本相同,只用分析一個(gè)文件即可
  • __zp_stoken__參數(shù)生成之后,不能直接在Cookie中使用,需要做URLencode才能使用

復(fù)習(xí)要點(diǎn)

1.這個(gè)案例也是很好的動(dòng)態(tài)Cookie生成的案例,和之前的努比亞論壇的Cookie生成案例類似,利用window.location.href/replace/reload()這些機(jī)制來(lái)重載頁(yè)面,具體如下圖所示:

2.在調(diào)試的時(shí)候注意關(guān)鍵詞的值,比如this,document,windows這些,往往有時(shí)候雖然方法走通了,但是值不對(duì),很有可能就是上面這些值在賦值時(shí)發(fā)生了錯(cuò)誤。

?

總結(jié)

以上是生活随笔為你收集整理的2019年末逆向复习系列之Boss直聘Cookie加密字段__zp_stoken__逆向分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。