javascript
【JS 逆向百例】DOM 事件断点调试,某商盟登录逆向
文章目錄
- 聲明
- 逆向目標
- DOM 簡介
- 逆向過程
- 完整代碼
- JavaScript 加密關鍵代碼架構
- Python 登錄關鍵代碼
聲明
本文章中所有內容僅供學習交流,抓包內容、敏感網址、數據接口均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關,若有侵權,請聯系我立即刪除!
逆向目標
- 目標:某商盟登錄
- 逆向參數:Query String Parameters:j_mcmm: 351faaef3ba8f4db2001ec621344dbbf
DOM 簡介
在以前的案列中,我們都是通過直接搜索來定位加密參數的位置的,直接搜索出來的定位通常是比較準確的,但是有個弊端就是搜索的結果可能會非常多,需要人工去過濾,需要一定的經驗去判斷準確的加密位置,而且對于一些反爬力度較大的站點來說,可能做了很多混淆,根本就搜索不到,那么今天的案列中,我們將介紹另一種方法,即 DOM 事件斷點,需要注意的是,DOM 事件斷點也是有弊端的,通過這種方法找到的位置通常在加密處理之前,也就是說想要找到準確的加密位置,還需要進一步分析上下文才能確定。
DOM 全稱 Document Object Model,即文檔對象模型,是 HTML 和 XML 文檔的編程接口,定義了訪問和操作 HTML 文檔的標準方法。
一個網頁其實就是一個 HTML 文件,經過瀏覽器的解析,最終呈現在用戶面前,一個簡單的 HTML 頁面代碼如下:
<!DOCTYPE html> <html><head><meta charset="utf-8"><title>我的第一個HTML頁面</title> </head><body><h1>我的第一個標題</h1><p>我的第一個段落</p> </body></html>在 HTML 頁面代碼中,head、body 等標簽不是隨意排列的,它們有自己的規則。首先,它們是嵌套的,一層套一層,比如 html 套 body,body 又套 h1,其次, 每一層可以同時存在很多標簽,比如 head 和 body 屬于同一層,它們被外面的 html 套著,這樣的結構很像計算機里的文件夾,例如,我的電腦是最外層,里面套著 C、D、E、F 盤,每個盤里又有很多文件夾,文件夾里又有文件夾,逐個打開后才能看到具體的文件。
為什么要按照這種結構來組織呢?目的其實是方便解析和查詢,解析的時候,從外向里循序漸進,好比按照圖紙蓋房子,先蓋圍墻,再蓋走廊,最后才蓋臥室。查詢的時候,會遵循一條明確的路線,一層一層地縮小范圍,查找效率會非常高。
所以,瀏覽器在解析 HTML 文檔時,會把每個標簽抽象成代碼里的對象,按照這種層次分明的結構組織,這就是 DOM,HTML DOM 結構如下圖所示:
逆向過程
本次逆向的目標是某商盟的登錄密碼,本案例的加密參數為 j_mcmm,加密比較簡單,直接全局搜索也很容易找到加密的地方,但是本次我們不使用全局搜索,改用 DOM 事件斷點來定位加密位置。
打開開發者工具,點擊左上角箭頭按鈕,再點擊登陸按鈕,即可定位到該按鈕元素的位置,在 Elements 面板,右邊選擇 Event Listeners,即事件監聽列表,可以看到一些鼠標點擊、鼠標移動、提交、加載等事件:
我們將這些事件展開具體看一下,submit 提交事件,定位到 div 標簽,div 標簽下有一個 form 表單,form 的作用就是為用戶輸入創建 HTML 表單,向服務器傳輸數據,跟進這個 submit 用到的 JS 文件,大概率就能夠找到加密的地方,這里還有個小技巧,如果事件太多,不太好判斷哪個是提交數據的,或者哪個是登錄事件的,可以選擇性的點擊 Remove,移除一些事件,再登錄,如果登錄不能點擊,或者 Network 里沒有提交請求,就說明 Remove 的這個事件剛好就是目標事件。
跟進 submit 事件用到的 JS,會定位到 function e() 的位置,往下看,就可以找到疑似加密的地方,這里出現了兩個 j_mcmm,分別是 g.j_mcmm 和 P.j_mcmm,埋下斷點進行調試,經過對比可以發現 g.j_mcmm 是最終需要的值:
在 g.j_mcmm = b 語句中,b 的值就是最終加密后的值,往上找,第 1125 和 1126 行 var e = b; b = F(F(b) + c);,把明文密碼賦值給 b,c 為驗證碼,經過 F 這個函數的處理后得到加密值,繼續跟進 F 函數:
可以看到其實就是經過以下函數的處理:
function d(a) {return n(e(o(m(a + "{1#2$3%4(5)6@7!poeeww$3%4(5)djjkkldss}")), 32)) }這個函數中,又包含 n, e, o, m 函數,這里不再每個函數去剝離,直接將這個函數往下所有單個字母的函數 copy 下來本地調試即可。
完整代碼
GitHub 關注 K 哥爬蟲,持續分享爬蟲相關代碼!歡迎 star !https://github.com/kgepachong/
**以下只演示部分關鍵代碼,不能直接運行!**完整代碼倉庫地址:https://github.com/kgepachong/crawler/
JavaScript 加密關鍵代碼架構
function getEncryptedPassword(a, b, c) {// a: 用戶名, b: 密碼, c: 驗證碼function d(a) {return n(e(o(m(a + "{1#2$3%4(5)6@7!poeeww$3%4(5)djjkkldss}")), 32))}function e(a, b) {}function f(a, b, c, d, e, f) {}function g(a, b, c, d, e, g, h) {}function h(a, b, c, d, e, g, h) {}function i(a, b, c, d, e, g, h) {}function j(a, b, c, d, e, g, h) {}function k(a, b) {}function l(a, b) {}function m(a) {}function n(a) {}function o(a) {}c.hex_md5 = db = d(d(b) + c);return b }// 測試樣例 // console.log(getEncryptedPassword('123123', '1231234', '6798'))Python 登錄關鍵代碼
#!/usr/bin/env python3 # -*- coding: utf-8 -*-import time import randomimport execjs import requests from PIL import Imageindex_url = '脫敏處理,完整代碼關注 GitHub:https://github.com/kgepachong/crawler' login_url = '脫敏處理,完整代碼關注 GitHub:https://github.com/kgepachong/crawler' ver_code_url = '脫敏處理,完整代碼關注 GitHub:https://github.com/kgepachong/crawler' headers = {'Referer': '脫敏處理,完整代碼關注 GitHub:https://github.com/kgepachong/crawler','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' } session = requests.session()def get_verification_code():response = session.get(url=ver_code_url, headers=headers)with open('code.png', 'wb') as f:f.write(response.content)image = Image.open('code.png')image.show()code = input('請輸入驗證碼: ')return codedef get_encrypted_password(username, password, code):with open('encrypt.js', 'r', encoding='utf-8') as f:js = f.read()encrypted_password = execjs.compile(js).call('getEncryptedPassword', username, password, code)return encrypted_passworddef login(username, encrypted_password, code):timestamp = str(round(time.time() * 1000))jsonp = ''for _ in range(20):jsonp += str(random.randint(0, 9))jsonp = 'jQuery' + jsonp + '_' + timestampparams = {'jsonp': jsonp,'protocol': ' http:','loginIndex': index_url,'j_mmrm': username,'j_mcmm': encrypted_password,'j_valcode': code,'_': timestamp}response = session.get(url=login_url, params=params, headers=headers)response.encoding = 'utf-8'print(response.text)def main():username = input('請輸入登錄賬號: ')password = input('請輸入登錄密碼: ')code = get_verification_code()encrypted_pwd = get_encrypted_password(username, password, code)login(username, encrypted_pwd, code)if __name__ == '__main__':main()總結
以上是生活随笔為你收集整理的【JS 逆向百例】DOM 事件断点调试,某商盟登录逆向的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 韩国猴痘预警级别上调:其境内已现首例确诊
- 下一篇: gradle idea java ssm