js断点调试及配合burpsuit技巧

js逆向常见断点调试方法为以下三种

代码全局搜索
文件流程断点
代码标签断点
XHR提交断点

JS逆向-流程&全局搜索-登录算法

流程断点:审查元素抓网络请求包发起程序
全局搜索:通过抓包参数名进行代码全局搜索

JS逆向-标签&XHR断点-登录算法

标签断点:审查元素对应标签按钮加入断点
XHR断点:审查元素源代码加入XHR断点配置

实战案例(XHR断点法)

准备工作

目标网址:https://account.hpc.sjtu.edu.cn/#/login

测试账号:xigua

测试密码:123

查看数据包

请求内容:

1
2
userName: xigua
password: QnEO1gmtAxaN1rj7H4ksZQDu+WD1MjUKHkWuwG8xkLgNTjq+WieX+a1pUeCTIXl02TYb75rSfj3MejR7XLDG4g==

响应内容:

1
{code: 11013, msg: "user name is not exist"}

观察响应器中的请求调用堆栈:

点开value跳转至代码,可看到附近代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
key: "handleSubmit",
value: function(e) {
var t = this;
e.preventDefault();
var n = this.refs
, i = n.emailInput.value
, a = n.pwdInput.value;
if (this.validateLoginForm(i, a)) {
this.setState({
loading: !0
});
var r = new JSEncrypt
, o = C.RSACODE;
r.setPublicKey(o);
var s = r.encrypt(a)
, l = this.props.actions;
l.login(i, s).then(function() {
localStorage.setItem("login_password", a),
localStorage.setItem("firstLogin", "1"),
t.setState({
loading: !1
})
}).catch(function(e) {
11033 == e.code ? (t.props.confirm("该用户未绑定集群,请联系管理员绑定集群。"),
t.setState({
loading: !1
})) : 11015 == e.code ? ("username error" == e.msg ? t.setState({
emailValid: "用户名不存在。"
}) : "password error" == e.msg ? t.setState({
pwdValid: "密码不正确。"
}) : "user is inactive" == e.msg ? t.props.confirm("用户未激活") : t.setState({
emailValid: "用户名或密码错误。",
pwdValid: "用户名或密码错误。"
}),
t.setState({
loading: !1
})) : (t.setState({
emailValid: "用户名或密码错误。",
pwdValid: "用户名或密码错误。"
}),
t.setState({
loading: !1
}))
})

可以看到密码加密的相关代码为:

1
2
3
var r = new JSEncrypt, o = C.RSACODE;
r.setPublicKey(o);
var s = r.encrypt(a)

在JSEncrypt对象可找到该对象所在文件,将该文件与该处代码合并可得加密代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var KJUR = {};
!function(e, t) {
"object" == typeof module && "object" == typeof module.exports ? module.exports = e.document ? t(e, !0) : function(e) {
if (!e.document)
throw new Error("jQuery requires a window with a document");
return t(e)
}
: t(e)
}
// 此处省略约7000行代码
,
ze.prototype.getPublicKeyB64 = function() {
return this.getKey().getPublicBaseKeyB64()
}
,
t.JSEncrypt = ze
}(JSEncryptExports);
var JSEncrypt = JSEncryptExports.JSEncrypt;

var r = new JSEncrypt,o = '305c300d06092a864886f70d0101010500034b003048024100959684a0076fd2a8fc1589469cf8c95f16ef67490c519f4d274373f29cee64cf6a0db8ad8953122c5b3664e4a48acd34d9b95c0ae62a31be612632e1c49154db0203010001';
r.setPublicKey(o);
var s = r.encrypt('xigua')
console.log(s)

输出结果为:

cCrh1+o1KqvGzWhjCVU2cR9Ry0dGyQ7/MNOlkY8LUJr1zmqmmTd3jYgrksHiX7xpngmdHj3YSNluvEnKfteZow==

成功

burpsuit中使用

环境配置

1、下载phantomjs并设置环境变量
https://phantomjs.org/download.html

2、BurpSuite加载jsEncrypter插件
https://github.com/c0ny1/jsEncrypter/releases

测试

打开jsEncrypter下的phantomjs_server.js文件,将代码修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* author: c0ny1
* date: 2017-12-16
* last update: 2019-5-30 11:16
*/
var fs = require('fs');
var logfile = 'jsEncrypter.log';
var webserver = require('webserver');
server = webserver.create();

var host = '127.0.0.1';
var port = '1664';

// 加载实现加密算法的js脚本
var wasSuccessful = phantom.injectJs('JSEncrypt.js');/*引入实现加密的js文件*/

// 处理函数
function js_encrypt(payload){
var newpayload;
/**********在这里编写调用加密函数进行加密的代码************/
var r = new JSEncrypt,o = '305c300d06092a864886f70d0101010500034b003048024100959684a0076fd2a8fc1589469cf8c95f16ef67490c519f4d274373f29cee64cf6a0db8ad8953122c5b3664e4a48acd34d9b95c0ae62a31be612632e1c49154db0203010001';
r.setPublicKey(o);
newpayload = r.encrypt(payload)

/**********************************************************/
return newpayload;
}

if(wasSuccessful){
console.log("[*] load js successful");
console.log("[!] ^_^");
console.log("[*] jsEncrypterJS start!");
console.log("[+] address: http://"+host+":"+port);
}else{
console.log('[*] load js fail!');
}

var service = server.listen(host+':'+port,function(request, response){
try{
if(request.method == 'POST'){
var payload = request.post['payload'];
var encrypt_payload = js_encrypt(payload);
var log = payload + ':' + encrypt_payload;
console.log('[+] ' + log);
fs.write(logfile,log + '\n', 'w+');
response.statusCode = 200;
response.write(encrypt_payload.toString());
response.close();
}else{
response.statusCode = 200;
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('---------------------------------------------')
console.log('[*] phantomJS exit!')
phantom.exit();
}
});

并将网站文件中的JSEncrypt.js保存至同名文件,在此cmd运行phantomjs phantomjs_server.js

在burp中intruder中payload处理选择调用burp扩展,选择JSEncrypt

即可开始测试