這篇不講圖片的還原和滑動軌跡的模擬,直接分析js逆向加密點
1、首先滑動驗證碼查看請求,發現主要的參數為w,接下來本篇就圍繞着w的生成
查看堆棧打斷點,最后的第四個堆棧,找到加密點
由代碼可以看出:w值為 h+u,h的生成又跟l的有關,最后w參數變為了分析三行代碼
var u = r[$_CAGEe(750)]() , l = V[$_CAGEe(342)](gt[$_CAGEe(209)](o), r[$_CAGEe(742)]()) , h = m[$_CAGEe(733)](l)
2、參數加密分析
參數u的分析
打上斷點,找到加密點
最后u的生成點找到了,看一下傳的16位字符串怎么生成的,進入函數打上斷點
函數返回的值為Ot函數,Ot的賦值為rt()函數,進入rt()函數,最后找到t()函數,得到正確的加密,此處打上斷點后需要重新刷新頁面才能斷住
(65536 * (1 + Math[$_BFBDL(75)]()) | 0)[$_BFBDL(396)](16)[$_BFBDL(476)](1)
可以看到16位的字符串最后有4個`(65536 * (1 + Math'random') | 0)'toString''substring'、組成
接下來分析,new X()[$_CBEEc(342)]
的加密,
斷住new X(),發現了setpublic這個是在RSA中特有的,初步分析為RSA加密。進入函數,扣一下加密
此處就是setpublic,可以得出對應的加密公鑰。python構建rsa加密就好。
import rsa
from binascii import b2a_hex
def rsa_encrypt_text(key, _text: str):
"""
RSA加密
:param key: 公鑰的參數
:param _text: 待加密的明文
:return: 加密后的數據
"""
e = int('010001', 16)
n = int(key, 16)
pub_key = rsa.PublicKey(e=e, n=n)
return b2a_hex(rsa.encrypt(_text.encode(), pub_key)).decode()
此處加密值u就完成了,當然你也可以扣代碼,扣代碼的時候使用全局的思想,將整個X函數扣下來后分析執行狀態。刪掉相應的一些代碼,讓js正常執行就行。
加密值l的分析
由代碼可以看到l的生成傳遞了兩個參數。
一個經過轉換的o,和生成的隨機16位參數,打印出對象o的參數,分析一波
aa:參數為加密值
ep:為和時間戳有關的數組
passtime:和軌跡有關的時間
rp:網站的返回值
userresponse:加密參數
直接分析o的生成,向上分析代碼,發現o的生成位置找到對應的aa和userresponse
可以看出加密的aa直接返回為e的值,e由函數傳遞,aa處打上斷點(或者在函數的第一行),向上溯源。
定位到加密點,可以看到此處的加密變為了
var u = parseInt(_)
, l = n[$_CJJIW(1078)][$_CJJJd(1069)](n[$_CJJIW(1078)][$_CJJJd(1051)](), n[$_CJJJd(13)][$_CJJIW(1045)], n[$_CJJIW(13)][$_CJJIW(307)]);
r[$_CJJJd(1034)](u, l, n[$_CJJIW(840)]),
加密值變為分析l的生成,u和n[$_CJJIW(840)]分別為滑動距離和滑動的時間。
分析下l的參數
后兩個參數為請求url的時候服務器返回
而第一個參數就是跟軌跡有關的加密了:
打上斷點進入函數。向下走可以看到傳遞的滑動軌跡
此處還是全局扣代碼的思想,將包含此處代碼的函數都摳出來,也就是整個W[$_CJET(261)]
看下$_CJET(261)的值,命令行打印一下,發現為"prototype"
那么找到W函數,也摳出來,執行代碼,扣完的代碼結構大概類似這樣
按照網站的調用方式調用發現報錯,
定位到代碼,發現網站中此處傳入的是滑動軌跡,而在pycharm中打印直接報錯TypeError: $_BEGJJ is not a function
手動將軌跡傳遞進函數。重新執行
和網頁生成的比對一下。
一致,那么接下來扣l的加密函數n[$_CJJIW(1078)][$_CJJJd(1069)]
也是全局的思想,直接扣代碼,執行
一致,那么此處的aa就扣完了。
userresponse就相對簡單了,直接扣H函數就行,加密參數為滑動距離和challenge
rp參數:對gt、challenge、passtime進行了md5加密
至此所有的參數分析基本完結,給出成功截圖