最近實在太忙,更新速度也慢了,今天得空網上衝浪一會,心血來潮開啟了童年遊戲大話西遊官網,本想看看有什麼變化,發個帖抱怨一下為啥還不開懷舊服,就在登入之際又忍不住按下了F12,跟我想的一樣,的確是把密碼加密了,那好吧,等我把JS程式碼扣完再去發帖吧,覺得有幫助關注一下知識圖譜與大資料公眾號吧,當然不關注也無所謂。
前言
依然有完整JS程式碼,原文連結,點選文末閱讀更多即可,還是熟悉的rsa加密,有興趣的可以跟著東扣扣西扣扣,鍛鍊一下,整個過程不難。登入地址請跳到執行章節,在python程式碼裡有。。
直入正題
開啟登入介面,輸入錯誤的賬號密碼(圖中的賬號均為虛構)。
目的當然是檢視提交的資料裡有沒有加密的,找到其提交url
,如下所示:
右側往下拉一點即可看到提交的引數,這次有點不一樣,提交的引數並不是FormData
形式,不過也不影響,如下:
仔細看一下,大概可以知道pw
是密碼加密結果,un
是賬號,其它幾個引數暫時可以看成是固定的(一樣也可以通過除錯得到),今天主要是pw
即密碼解密,接下來可以通過呼叫棧進去,呼叫棧進去也可以稍微利用一點技巧,比如可以檢視方法名,我們現在是在解密登入,那我們就可以通過方法名裡有類似login
的進去。如下圖所示:
進去以後你可能會迫不及待的像往常一樣查詢pw
關鍵字,其實通過關鍵字也能猜到這樣查詢是能找到,當時要耗費不少精力,畢竟pw
只有兩個字母太容易與其它單詞匹配了:
是不是,一下子匹配了113
個地方,你當然可以一下一下點了,這樣細心點也能找到,只不過費點時間而已,還有一個方法,現在我們已經知道密碼是被加密了,那我們就搜尋關於加密的單詞,類似encrypt
,這是一個經驗,大家可以掌握,試著搜一下encrypt
:
一共搜到16
處,這可比113
少多了吧,手再也不酸了,,因為以後還會遇到很多引數名只有一個字母或者兩個的情況,這算是一個比較有意思的方法吧。接下來我們在幾個比較懷疑的encrypt
打上斷點,一共有三處,為什麼這麼說,看下面程式碼,是不是都很像要找的(截圖麻煩,我直接把程式碼放下面了):
n.pw = MP.encrypt2(this.__password);//第一處
t.pw = MP.encrypt2(this.$refs.mpinput._$getValue() || "0");//第二處
t.pw = MP.encrypt2(n);//第三處
進入除錯
在前面我們已經在幾個可以點打上了斷點,接下來就可以除錯了,啟用斷點(即輸入賬號密碼,點選登入),果不其然,跳到了其中一個斷點:
那就是這裡嘍,單步執行下去,進入加密函式encrypt2
:
其中encrypt2
的引數e
為你輸入的密碼,除錯了幾次發現這裡getPublicKey
引數p
其實也是個固定值,一共需要摳的主函式也就兩個,一個encrypt
和getPublicKey
,p
值請看下圖:
繼續執行,進入設定getPublicKey
函式:
getPublicKey: function(e) {
if (e.length < 50)
return !1;
if ("-----BEGIN PUBLIC KEY-----" != e.substr(0, 26))
return !1;
e = e.substr(26);
if ("-----END PUBLIC KEY-----" != e.substr(e.length - 24))
return !1;
e = e.substr(0, e.length - 24);
e = new ASN1Data(Base64.decode(e));
if (e.error)
return !1;
e = e.data;
if ("1.2.840.113549.1.1.1" == e[0][0][0])
return new RSAPublicKey(e[0][1][0][0],e[0][1][0][1]);
else
return !1
}
encrypt
函式:
encrypt: function(e, t) {
if (!t)
return !1;
var i = t.modulus.bitLength() + 7 >> 3;
e = this.pkcs1pad2(e, i);
if (!e)
return !1;
e = e.modPowInt(t.encryptionExponent, t.modulus);
if (!e)
return !1;
e = e.toString(16);
for (; e.length < 2 * i; )
e = "0" + e;
return Base64.encode(Hex.decode(e))
}
到這裡大家應該都知道要扣哪些了吧,對,就是getPublicKey
和encrypt
裡面使用到的一些小函式,比如Base64.decode(e)
、Hex.decode(e)
等等這些,難點是這些方法裡面還巢狀了其它方法,容易的地方是這些方法基本都在一起,再提一個摳程式碼的小技巧,摳的時候可以找到你想要的函式,點一下函式的大括號,括號下面會有橫線,這時候你就可以確定摳到哪裡了,因為結尾的大括號下面也會有橫線,聽不明白沒關係,看一下下圖就理解了:
我這裡就不列出所有程式碼了,大家有興趣的可以關注知識圖譜與大資料公眾號,找到這篇文章,點選文末的閱讀原文即可看到完整JS
程式碼。
執行
相信大家都能摳出來,摳完就可以通過python
執行,上盤古時期程式碼:
import execjs
#url = http://xy2.netease.com/member.php?mod=logging&action=login
with open('..//js//dahuaxiyou.js', encoding='utf-8') as f:
dahuaxiyou = f.read()
js = execjs.compile(dahuaxiyou)
logid = js.call('get_pwd', "qwerqwrqrq")
print(logid)
執行結果如下:
結束
摳rsa
的程式碼的確要比md5
要費點時間,不過只要細心都能摳出來,摳不出來的點即文末閱讀原文即可。覺得有幫助關注一下知識圖譜與大資料公眾號吧,有大量摳JS
程式碼的文章,當然不關注也無所謂。