wordpress 突然404債務(wù)優(yōu)化是什么意思
聲明:本篇文章內(nèi)容是整理并分享在學(xué)習(xí)網(wǎng)上各位大佬的優(yōu)秀知識(shí)后的實(shí)戰(zhàn)與踩坑記錄
前言
這篇文章主要是研究如何動(dòng)態(tài)生成后綴參數(shù)MmEwMD的,它是在文章爬蟲(chóng)逆向?qū)W習(xí)(六):補(bǔ)環(huán)境過(guò)某數(shù)四代的基礎(chǔ)上進(jìn)行研究的,代碼也是在它基礎(chǔ)上增加補(bǔ)點(diǎn)的,且下文破解的接口所需的cookie也可以直接用它的代碼得到。
MmEwMD
某數(shù)針對(duì)xhr
請(qǐng)求會(huì)在其后綴增加MmEwMD
參數(shù),它魔改了xhr
的open
方法,而MmEwMD
就是在open
方法執(zhí)行時(shí)生成的,某數(shù)并沒(méi)有強(qiáng)制請(qǐng)求一定要攜帶MmEwMD
參數(shù),但是如果攜帶了它就一定會(huì)校驗(yàn),校驗(yàn)失敗則返回400。
實(shí)戰(zhàn)
生成位置定位
站點(diǎn):aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuL25ld19ob3VzZS9uZXdfaG91c2UuaHRtbA==
目標(biāo)接口:aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuL3NlcnZpY2UvZnJlc2hIb3VzZS9nZXRTZXZlbkRheXNSYW5raW5nLmFjdGlvbg==
其實(shí)就是這個(gè)排行版,不過(guò)所有接口都是一套邏輯,都可以用來(lái)實(shí)驗(yàn)。
查看包的調(diào)用棧,點(diǎn)擊下圖紅框的堆棧進(jìn)入執(zhí)行代碼
前面我們知道了某數(shù)魔改了xhr
的open
方法并在此實(shí)現(xiàn)MmEwMD
生成的,這時(shí)就直接鎖定s.open
,在這里打斷點(diǎn),重新刷新頁(yè)面,將斷點(diǎn)在這里斷住后跟進(jìn)去
可以看到這里就是生成位置了,至于更深入的生成位置這里不研究,因?yàn)槲以谏钊胙芯亢蟀l(fā)現(xiàn)這個(gè)位置比較適合補(bǔ)環(huán)境,當(dāng)然大家學(xué)習(xí)時(shí)可以深入研究,MmEwMD
的生成邏輯并不難,算法實(shí)現(xiàn)也未嘗不可。
補(bǔ)環(huán)境思考
這里是選擇補(bǔ)環(huán)境的方式進(jìn)行破解的,如果想算法破解,可以參考瑞數(shù)4——MmEwMD逆向分析,這篇文章很詳細(xì)得分析了MmEwMD
參數(shù)的生成邏輯。
在實(shí)現(xiàn)參數(shù)的補(bǔ)環(huán)境時(shí),其實(shí)有過(guò)思考:
既然某數(shù)是魔改了xhr,那能不能在nodejs模擬xhr發(fā)包,直接拿到魔改后的url呢?
如果這種方式可以實(shí)現(xiàn),那不需要深入研究代碼就能快速拿到加密結(jié)果了,但是很遺憾,我使用nodejs包xmlhttprequest進(jìn)行hook發(fā)包,但是沒(méi)法hook到,瀏覽器端使用的window.XMLHttpRequest
,沒(méi)法復(fù)現(xiàn)。
生成代碼中哪個(gè)位置是比較容易執(zhí)行的?
這個(gè)位置其實(shí)就是前面生成位置定位
中指明的,我是這么思考的
這里選擇的是通過(guò)_$O3
得到加密結(jié)果,如果直接調(diào)用_$xI
,那得創(chuàng)建xhr對(duì)象,執(zhí)行會(huì)報(bào)錯(cuò)。大家可以去看_$O3
的代碼,它只需要一個(gè)參數(shù)也就是url,且它的代碼本身就是在處理url,如果使用比它更細(xì)的維度方法,可能會(huì)執(zhí)行異常。
MmEwMD是在VM層生成的,且每次代碼都會(huì)變化,怎么實(shí)現(xiàn)動(dòng)態(tài)生成的?
只要我們能動(dòng)態(tài)拿到_$O3
方法然后將其導(dǎo)出,那無(wú)論VM怎么變都不影響了。
這里說(shuō)一下,VM這一層是調(diào)用.call執(zhí)行得到的,它的代碼會(huì)根據(jù)content和外鏈js變換而變化,我們?cè)谡{(diào)試時(shí)可以直接拿到call后的代碼,寫(xiě)死能方便我們調(diào)試。在補(bǔ)成功拿到加密結(jié)果后,就可以使用正則匹配在執(zhí)行call前匹配替換加入自己的導(dǎo)出代碼。
破解
這里我們還是在原來(lái)的代碼上處理,我們直接把call后的代碼復(fù)制給ret,它本身是自執(zhí)行函數(shù),然后我們創(chuàng)建全局變量params_enc
導(dǎo)出關(guān)鍵代碼函數(shù)_$d0
注意我調(diào)試的代碼方法名變了,大家根據(jù)自己實(shí)際的代碼情況處理
這時(shí)我們就拿到了目標(biāo)函數(shù),直接執(zhí)行它
看執(zhí)行結(jié)果發(fā)現(xiàn)并沒(méi)有加密,這時(shí)我們就知道是document.createElement('a')
出的問(wèn)題了
這里使用debugger將它斷住,看看是哪里調(diào)用的它
看代碼知道它對(duì)取值結(jié)果做了很多判斷
做以下處理,將a加入hook環(huán)境中,看看它都做了啥
缺啥補(bǔ)啥,值去瀏覽器拿
最終需要補(bǔ)全,都是必須要的,補(bǔ)好就能拿到結(jié)果了
動(dòng)態(tài)獲取
上面我們?cè)诖a寫(xiě)死條件下實(shí)現(xiàn)了參數(shù)加密,不過(guò)在調(diào)用時(shí)總歸是要實(shí)現(xiàn)動(dòng)態(tài)的,畢竟我們每次獲取的content和自執(zhí)行函數(shù)是不同的,上面我們說(shuō)要用正則匹配來(lái)拿到目標(biāo)函數(shù),其實(shí)就是兩個(gè)地方
- 找到
ret = _$b6.call(_$Yq, _$cZ)
并將_$cZ
拿出來(lái) - 將
params_enc = _$d0;
放進(jìn)_$cZ
思路就是這個(gè)思路,給大家看看我實(shí)現(xiàn)的正則匹配后結(jié)果
匹配前
匹配后
我實(shí)在python層實(shí)現(xiàn)的正則匹配