2019年末逆向復(fù)習(xí)系列之知乎登錄formdata加密逆向破解

鄭重聲明:本項(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)《云爬蟲(chóng)技術(shù)研究筆記》的《2019年末逆向復(fù)習(xí)系列》的第五篇:《知乎登錄formdata加密逆向破解》

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

逆向背景

知乎作為國(guó)內(nèi)最大的、最優(yōu)質(zhì)的的問(wèn)答平臺(tái)之一,它的高質(zhì)量回答是作為自然語(yǔ)言處理的最好的語(yǔ)料來(lái)源之一,不過(guò)想要獲取更全的知乎回答數(shù)據(jù)必須要登錄,涉及登錄的話必然少不了做自動(dòng)化登錄的處理,不過(guò)知乎的登錄post請(qǐng)求中的formdata是加密的


因此我們需要去尋找它的加密邏輯,本篇文章就是講解如何尋找破解formdata的加密,實(shí)現(xiàn)自動(dòng)化登錄知乎。

分析流程與逆向破解

因?yàn)閒ormdata只要一個(gè)加密后的字符串,對(duì)于我們來(lái)說(shuō),沒(méi)有一個(gè)明顯的特征讓我們?nèi)ト炙阉?,因此我們采用的是xhr斷點(diǎn)的方法去尋找哪里加密了formdata,我們通過(guò)initiator進(jìn)入


根據(jù)登錄api的url: /api/v3/oauth/sign_in來(lái)打xhr斷點(diǎn)


重復(fù)我們之前的登錄邏輯,可以看到,xhr斷點(diǎn)打在如圖所示位置


接下來(lái),我們就可以通過(guò)call stack調(diào)用棧來(lái)尋找哪里加密了formdata,一個(gè)個(gè)調(diào)用分析之后,看到如圖所示的地方比較符合我們期待的加密點(diǎn)



url確實(shí)是登錄的api,并且在post請(qǐng)求的data處,使用了r.decamelizeKeys()方法來(lái)處理,初步估計(jì)是加密方法,我們?cè)賹?duì)r.decamelizeKeys打斷點(diǎn),同時(shí)去掉之前的xhr斷點(diǎn),這樣能夠幫助我們更快、更準(zhǔn)確的定位到加密處


我們現(xiàn)在定位到decamelizeKeys的加密方法邏輯,這個(gè)方法包含兩個(gè)參數(shù),e和t,t現(xiàn)在我們還不能夠準(zhǔn)確了解它的含義,e參數(shù)的值可以直接在console里面進(jìn)行打印

captcha: "mdgv"
clientId: "c3cef7c66a1843f8b3a9e6a1e3160e20"
grantType: "password"
lang: "en"
password: "asdd"
refSource: "people"
signature: "f45d273cd16f4f80e4fee3434d1c3009fb2248cf"
source: "com.zhihu.web"
timestamp: 1575300515085
username: "+8617610771895"
utmSource: undefined

我們分析,captcha和signature這兩個(gè)參數(shù)相對(duì)其他參數(shù)來(lái)說(shuō)還是比較重要,因此我們著重分析這兩個(gè)參數(shù)

1. 尋找signature加密參數(shù)的加密邏輯

signature這個(gè)參數(shù)還是具有明顯特征的,我們可以全局搜索



match的地方只有兩個(gè)js文件,我們具體查看,可以在其中一個(gè)文件搜索signature關(guān)鍵字,發(fā)現(xiàn)它的相關(guān)代碼段,這段代碼很明顯的是hmac算法


涉及到的值有clientId、timstamp、grandType等

插入一句:Hmac算法大致解釋如下



Python的簡(jiǎn)單實(shí)現(xiàn)

import hmac
from hashlib import sha1


def hash_hmac(key, code, sha1):
    hmac_code = hmac.new(key.encode(), code.encode(), sha1)
    return hmac_code.hexdigest()

if __name__ == '__main__':
    print(hash_hmac('08F5B4886112BC6F1E04FE42DACDB2E8', 'xinxin', sha1)

大概了解hmac算法是什么之后,我們?cè)倩仡^看看signature的hmac算法的邏輯是什么



具體的思路如圖所示,使用sha-1作為hash函數(shù),key是寫(xiě)死的,使用其他四個(gè)參數(shù)值作為message進(jìn)行加密,整理思路可以用python表達(dá)出來(lái)

def _get_signature(timestamp: int) -> str:
    ha = hmac.new(
        b"d1b964811afb40118a12068ff74a12f4",
        digestmod=hashlib.sha1
    )
    grant_type = _login_data["grant_type"]
    client_id = _login_data["client_id"]
    source = _login_data["source"]
    ha.update(
        bytes(
            (grant_type + client_id + source + str(timestamp)),
            "utf-8"
        )
    )
    return ha.hexdigest()

分析完signature參數(shù)之后,我們接著來(lái)分析captcha參數(shù)

2. 分析captcha的不同場(chǎng)景

captcha,顧名思義是驗(yàn)證碼結(jié)果相關(guān)的參數(shù),這個(gè)參數(shù)的值應(yīng)該是驗(yàn)證碼相關(guān),如圖所示,驗(yàn)證碼圖片是由這個(gè)接口來(lái)返回的




我們請(qǐng)求了這個(gè)接口,返回了圖片的base64格式,我們可以這么進(jìn)行保存

with open("./captcha.jpg", "wb") as f:
            f.write(base64.b64decode(img_base64))

關(guān)于captcha的分析呢不涉及到具體的js,因?yàn)閏aptcha的值我們可以很明顯的看出來(lái)

當(dāng)我們請(qǐng)求中文驗(yàn)證碼lang=cn-也就是翻轉(zhuǎn)漢字點(diǎn)選,我們傳的值是:

captcha: "{"img_size":[200,44],"input_points":[[43.39996337890625,30.79999542236328],[135.39996337890625,22.79999542236328]]}"
clientId: "c3cef7c66a1843f8b3a9e6a1e3160e20"

當(dāng)我們請(qǐng)求英文驗(yàn)證碼lang=en-也就是四位英文字符,我們傳的值是:

captcha: "mdgv"

所以關(guān)于captcha,是根據(jù)我們請(qǐng)求驗(yàn)證碼類(lèi)型不同傳不同的值的,captcha參數(shù)也分析到這里,我們?cè)侔哑渌膮?shù)整理一下

3. 分析剩余其他參數(shù)

其他的參數(shù)就比較好看出來(lái)了

clientId: "c3cef7c66a1843f8b3a9e6a1e3160e20"   多次試驗(yàn),寫(xiě)死的
grantType: "password" 非第三方登錄的話都是這個(gè)值
lang: "en" 針對(duì)不同驗(yàn)證碼類(lèi)型
password: "asdd" 密碼
refSource: "people" 不變
source: "com.zhihu.web" 不變
timestamp: 1575300515085 時(shí)間戳
username: "+8617610771895" 用戶(hù)名
utmSource: undefined 不變

到這里我們關(guān)于decamelizeKeys加密方法的e參數(shù)已經(jīng)分析好了,t參數(shù)還未知,那我們就繼續(xù)從剛才decamelizeKeys函數(shù)那里繼續(xù)往下找,分析decamelizeKeys函數(shù)的加密邏輯

4. 分析decamelizeKeys的加密邏輯

同樣是針對(duì)decamelizeKeys函數(shù)下斷點(diǎn),看到跳到這個(gè)地方,m方法返回n方法



查看o方法的具體邏輯


o = function e(t, n, r) {
        if (!d(n) || p(n) || h(n) || v(n) || l(n)) //基本沒(méi)什么用,可以跳過(guò)
            return n;
        var i, o = 0, a = 0;
        if (f(n))  //這里做邏輯判斷,可以扣具體js
            for (i = [],
            a = n.length; o < a; o++)
                i.push(e(t, n[o], r));
        else
            for (var s in i = {}, // 循環(huán)n(也就是data),不斷的和下面那個(gè)c函數(shù)做處理
            n)
                Object.prototype.hasOwnProperty.call(n, s) && (i[t(s, r)] = e(t, n[s], r));
        return i
    }
c = function(e, t) {
        return function(e, t) {
            var n = (t = t || {}).separator || "_"
              , r = t.split || /(?=[A-Z])/;
            return e.split(r).join(n)
        }(e, t).toLowerCase()
    }

加密的邏輯主要是上面這個(gè)部分,沒(méi)有混淆和平坦化什么的,大家可以自行扣扣

代碼實(shí)戰(zhàn)

根據(jù)上面的思路,我們完善代碼

關(guān)于加密部分



注意下圖我們?cè)谡?qǐng)求headers中加了兩個(gè)參數(shù)

  • "x-zse-83": "3_1.1" 這個(gè)參數(shù)是用來(lái)驗(yàn)證客戶(hù)端的版本,大概是和clientId相關(guān),如果我們不傳的話,會(huì)提示請(qǐng)求參數(shù)異常,請(qǐng)升級(jí)客戶(hù)端后重試這個(gè)錯(cuò)誤
  • "x-xsrftoken": _get_xsrf() 這個(gè)參數(shù)是跟跨域相關(guān),是為了防Xsrf跨站的Token認(rèn)證,訪問(wèn)首頁(yè)時(shí)從Response Headers的Set-Cookie字段中可以找到

關(guān)于實(shí)戰(zhàn)部分



注意,我們獲取的是加密方法返回的headers、data、session,之所以要拿headers,是因?yàn)槲覀冊(cè)谡?qǐng)求驗(yàn)證碼的時(shí)候,返回的Response Headers的Set-Cookie中有個(gè)CAPSION_TICKET字段,如果我們?cè)趐ost的時(shí)候不傳這個(gè)cookie字段,會(huì)報(bào)錯(cuò)

{"error":{"message":"缺少驗(yàn)證碼票據(jù)","code":120002,"name":"ERR_CAPSION_TICKET_NOT_FOUND"}}

最后注意請(qǐng)求的順序,先獲取驗(yàn)證碼,再post,如果你成功的看完這篇文章,那么你會(huì)收到登錄成功的結(jié)果。

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

從這個(gè)復(fù)習(xí)的案例我們可以總結(jié)下思路:

  1. 在參數(shù)沒(méi)有明顯特征的時(shí)候,打xhr斷點(diǎn)
  2. 在做自動(dòng)化登錄的時(shí)候,每一步的header都很重要,如果你算出加密的結(jié)果卻還是報(bào)錯(cuò),看看是不是你漏了哪一個(gè)請(qǐng)求返回給你的某樣?xùn)|西

作者相關(guān)

號(hào)主介紹

多年反爬蟲(chóng)破解經(jīng)驗(yàn),AKA“逆向小學(xué)生”,沉迷數(shù)據(jù)分析和黑客增長(zhǎng)不能自拔,虛名有CSDN博客專(zhuān)家和華為云享專(zhuān)家。

私藏資料

嘔心瀝血從浩瀚的資料中整理了獨(dú)家的“私藏資料”,公眾號(hào)內(nèi)回復(fù)“私藏資料”即可領(lǐng)取爬蟲(chóng)高級(jí)逆向教學(xué)視頻以及多平臺(tái)的中文數(shù)據(jù)集

小學(xué)生都推薦的好文

2019年末逆向復(fù)習(xí)系列之今日頭條WEB端_signature、as、cp參數(shù)逆向分析

2019年末逆向復(fù)習(xí)系列之百度指數(shù)Data加密逆向破解

2019年末逆向復(fù)習(xí)系列之努比亞Cookie生成逆向分析

2019年末逆向復(fù)習(xí)系列之淘寶M站Sign參數(shù)逆向分析

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容