參考文章
前言
最近學習挖洞以來,碰到資料做了加密基本上也就放棄了。但是發現越來越多的網站都開始做前端加密了,不論是金融行業還是其他。所以趁此機會來搗鼓一下。
從上圖可以看到,網站在前端對我的賬號密碼做了加密處理。前端加密的好處在於防止資料被劫持後直接洩露使用者資訊,增加攻擊者成本。雖然有https,但是也有被破解的風險。再者國內很多網站都沒有設定https,所以前端加密會進一步提高使用者資料的安全性
但對於我這樣一個菜雞,就算是洞放在我面前我也不一定能找到,更何況是加了密。太難了。
工具
phantomJS:https://phantomjs.org/download.html
,使用方法: phantomJS.exe decrypt.js
jsEncrypter :https://github.com/c0ny1/jsEncrypter
簡便方法:
1)下載打包好的 jar 檔案:連結:https://pan.baidu.com/s/1gDqmTVdYRD6nH5CfoqxavA 提取碼:go8h
2)新增到 BURP 擴充套件
3)在 jsEncrypter 下載地址裡下載模板檔案,即https://github.com/c0ny1/jsEncrypter/tree/master/script
裡的 phantomjs_server.js
一般流程:
1)尋找加密函式
2) 編寫 phantomJS 執行指令碼,只需要將實現加密演算法的 js 檔案引入模板指令碼,並在模板指令碼的 js_encrypt 函式體中完成對加密函式的呼叫。當然也可以不引入實現加密演算法的 js 檔案,直接在 js_encrypt 函式體中實現加密演算法,並呼叫
如下是 phantomjs_server.js 裡的部分內容:
/* 1.在這引入實現加密所有 js 檔案,注意引入順序和網頁一致 */
loadScript("script-1.js");
loadScript("script-2.js");
loadScript("script-n.js");
/**********************************************/
...
function jsEncrypt(burp_payload){
var new_payload;
/* 2.在這裡編寫呼叫加密函式進行加密的程式碼,並把結果賦值給new_payload */
/*********************************************************/
return new_payload;
}
3)在終端中輸入 phantomJS.exe phantomjs_server.js
,然後在 burp 裡操作就行了
步驟演示
在 phantomjs_server.js 檔案中匯入網頁中實現加密演算法的 js 檔案(差不多就是依賴檔案),方便之後直接呼叫加密函式
/* 1.在這引入實現加密所有 js 檔案,注意引入順序和網頁一致 */
loadScript("script-1.js");
loadScript("script-2.js");
loadScript("script-n.js");
/**********************************************/
通常來說,如果一個網站的 js 檔案沒有做混淆,並能輕鬆找到加密函式,且加密演算法比較簡單的話,其實是不需要匯入 js 檔案的
可以直接將加密函式複製或者自己編寫即可,但是往往加密演算法的實現比較複雜,需要引入許多依賴,所以還是匯入較好,後續編寫加密演算法再呼叫其中的依賴
此時可能有人就會問了,我要是知道實現加密演算法的 js 檔案是那個,我還看個 JB 文章呢!
確實,說的不錯。以下提供兩個解決辦法
- 匯入所有 js 檔案
嗯,是個好辦法。
不多哈,也就億個。 - 通過關鍵字尋找 js 檔案
通過ctrl+shift+f
全域性搜尋encrypt、aes、des、md5、key、iv、rsa
等關鍵字過濾一波再匯入
不錯不錯,少了 3 個?
在瀏覽器控制檯裡尋找實現對應資料加密的加密函式
Tips:在這一步,可能會碰到找不到加密函式的問題,以下有幾個解決辦法
-
瀏覽器的事件監聽
firefox:
chrome:
-
搜尋關鍵詞 encrypt crypt aes rsa des key iv 等等跟加密相關的
-
結合各種引數、提示字元定位加密函式
引數:source、key
提示字元:
- 根據 url 來定位
網站登陸常常是向某一個 api 介面傳送賬號密碼資訊,因此點選提交時,用 js 發起請求就需要提供 api 地址
如下是全域性搜尋得到的結果:
然後就找到了加密函式
進一步跟進檢視實現演算法
可以看到通過了 aes 和 rsa 加密,因此後續也需要找到 aes 的 key、iv 以及 rsa 的 public_key
aes 的 key 生成函式:
iv:
rsa 的 public_key:
在 phantomjs_server.js 中的 jsEncrypt 函式內呼叫找到的或自己編寫的加密函式
一般來說,該函式是需要自己重新編寫的
最終結果:
/**
* author: c0ny1
* date: 2017-12-16
* last update: 2020-03-03
*/
var fs = require('fs');
var webserver = require('webserver');
server = webserver.create();
var logfile = 'jsEncrypter.log';
var host = '127.0.0.1';
var port = '1664';
/* 1.在這引入實現加密所有js檔案,注意引入順序和網頁一致 */
loadScript("aes.js");
loadScript("zero.js");
loadScript("rsa.js");
// loadScript("script-n.js");
/**********************************************/
function loadScript(scriptName) {
var isSuccess = phantom.injectJs(scriptName);
if(isSuccess){
console.log("[*] load " + scriptName + " successful")
}else{
console.log("[!] load " + scriptName + " fail")
console.log("[*] phantomjs server exit");
phantom.exit();
}
}
// 定義 des 加密函式
function encryptByDES(message, key){
var keyHex = CryptoJS.enc.Utf8.parse(key);
var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString();
}
//定義 aes 加密函式
function encryptByAES(data, key, iv){
var key = CryptoJS.enc.Latin1.parse(key);
var iv = CryptoJS.enc.Latin1.parse(iv);
var encrypted = CryptoJS.AES.encrypt(data,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding});
return encrypted.ciphertext.toString();
}
// 定義 rsa 加密函式
function encryptByRSA(data, pub_key){
var encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + pub_key + '-----END PUBLIC KEY-----');
var encrypted = encrypt.encrypt(data);
return encrypted;
}
// 定義 aeskey 生成函式
function createAesKey() {
var expect = 16;
var key = Math.random().toString(36).substr(2);
while (key.length < expect) {
key += Math.random().toString(36).substr(2);
}
key = key.substr(0, 16);
this.aesKey = key;
return key;
};
var PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIivtXleN3uU5AnqidOAsD/96s\nADl1RU8g8eeRfBvovhpFvTxqdjP4/aicrSLE/tP4+nctocHclxK2tCqS6758g2bk\nDrlyxcfVdFV8l9wLxciNf2eBrraKoNf85RBh8bcOT96TTpYF0dSgmJVPwMR5u8am\n+trZ5y3jtTGQ/Ht4lQIDAQAB\n-----END PUBLIC KEY-----";
function jsEncrypt(burp_payload){
/* 2.在這裡編寫呼叫加密函式進行加密的程式碼,並把結果賦值給new_payload */
var aeskey = createAesKey();
var key = CryptoJS.enc.Utf8.parse(aesKey)
//console.log(this.aesKey);
/*********************************************************/
result = {
source: encryptByAES(burp_payload,aeskey,key),
key: encryptByRSA(aeskey,PUBLIC_KEY)
};
return [result.source,aeskey,key];
// return burp_payload;
}
console.log("[*] Phantomjs server for jsEncrypter started successfully!");
console.log("[*] address: http://"+host+":"+port);
console.log("[!] ^_^");
var service = server.listen(host+':'+port,function(request, response){
try{
if(request.method == 'POST'){
var payload = request.post['payload'];
var encrypt_payload = jsEncrypt(payload);
var log = payload + ':' + encrypt_payload;
console.log('[+] ' + log);
fs.write(logfile,log + '\n', 'w+');
response.statusCode = 200;
response.setEncoding('UTF-8');
response.write(encrypt_payload.toString());
response.close();
}else{
response.statusCode = 200;
response.setEncoding('UTF-8');
response.write("^_^\n\rhello jsEncrypter!");
response.close();
}
}catch(e){
//console.log('[Error]'+e.message+' happen '+e.line+'line');
console.log('\n-----------------Error Info--------------------');
var fullMessage = "Message: "+e.toString() + ':'+ e.line;
for (var p in e) {
fullMessage += "\n" + p.toUpperCase() + ": " + e[p];
}
console.log(fullMessage);
console.log('---------------------------------------------');
response.statusCode = 200;
response.setEncoding('UTF-8');
response.write(fullMessage);
response.close();
console.log('[*] phantomJS exit!');
phantom.exit();
}
});
一般網站都是 aes des ras 等方式進行加密,其依賴檔案都是開源的,所以可以直接引入,因此可以省略第一步,直接自己編寫函式。需要用到依賴檔案如下:
對加密函式的實現不懂的話,可以看我前一篇文章
因為加密方式都差不多,所以引入檔案可以統一寫成:
/* 1.在這引入實現加密所有 js 檔案,注意引入順序和網頁一致 */
loadScript("des.js");
loadScript("aes.js");
loadScript("aes填充方式.js");
loadScript("rsa.js");
/**********************************************/
然後再定義各種加密函式的實現,再呼叫就行了