编写加密传输爆破插件jsEncrypter

我曾经听某大牛所过两句话:

1
2
3
1. 我们能入侵最先进的系统,却不能阻止用户使用弱口令。

2. 当一个系统的用户超过1000+,那么弱口令一定存在!

不管这两句话是否属实,但都说明了一个问题,弱口令虽然简单,但是很难完全消除。因为它的问题不是出现在技术层面,而是在人性!所以每次渗透测试我都比较注重弱口令的检测。

当一个系统没有对登录次数进行限制时,我们就可以考虑进行爆破了。在我经验中,爆破遇到了以下三个难点:

序号 情况 解决
1 验证码 验证码有的可以绕过,无法绕开也已经存在识别验证码的插件。
2 token token问题,使用burp Suite完全可以解决。
3 加密传输 目前解决方案比较少,对应的工具基本没有找到。

今天特地对第三种情况进行解决,所以有了此文!

针对加密传输问题,freeBuf上的《对登录中账号密码进行加密之后再传输的爆破的思路和方式》写的挺好,作者提供了4种思路去解决,比我思考的全面。我最初的解决方案类似文章中的第四种思路,今天的解决方案是写一个Burp插件,和文章中的第一种思路类似但又有点区别。

0x01 流程

上一个流程图,给大家捋一捋插件运行的整个流程。

图1-流程图

0x02 开发

插件核心代码

我们的插件实现对payload的处理,所以一定要实现Burp Suite APIs的IIntruderPayloadProcessor接口的processPayload方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public byte[] processPayload(byte[] currentPayload, byte[] originalPayload, byte[] baseValue) {
byte[] newpayload ="".getBytes();
String payload = new String(currentPayload); //获取当前paylaod
CloseableHttpClient client = HttpClients.createDefault(); //新建一个HttpClient
HttpPost httpPost = new HttpPost(gui.getURL()); //新建一个post请求
try {
List nameValuePairs = new ArrayList(1);
nameValuePairs.add(new BasicNameValuePair("payload",payload)); //添加payload参数
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); //设置HttpPost实体
CloseableHttpResponse response = client.execute(httpPost); //发送带有payload的请求
//获取phantomJS处理好的结果
String responseAsString = EntityUtils.toString(response.getEntity());
newpayload = helpers.stringToBytes(responseAsString);

} catch (Exception e) {
stderr.println(e.getMessage());
newpayload = "JsEncrypter cannot connect phantomJS!".getBytes();
}
return newpayload; //返回处理好的payload给Burp Suite
}

phantomJS脚本编写

phantomJS是一个没有界面的浏览器,除了不能浏览,其他的和正常浏览器一样。使用它来执行我们编写好的脚本。

phantomJS下载地址:http://phantomjs.org/download.html

由于每个网站前端加密传输的算法一样,所以每次引入的js都不同,调用加密函数的代码也不仅相同。鉴于以上情况,为了每次不用重复写一些固定的代码,我们写一个模板代码。每次使用时,只要填写好引入js的文件名,以及实现好在js_encrypt()函数体调用加密算法对payload进行加密处理即可。

phatomJS脚本模板代码
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
/**
* author: c0ny1
* date: 2017-12-16
*/

var webserver = require('webserver');
server = webserver.create();

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

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

// 处理函数
function js_encrypt(payload){
var newpayload;
/**********在这里编写调用加密函数进行加密的代码************/

/**********************************************************/
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){
if(request.method == 'POST'){
var payload = request.post['payload'];
var encrypt_payload = js_encrypt(payload);
console.log('[+] ' + payload + ':' + encrypt_payload); //显示原始payload和加密处理好的payload
response.statusCode = 200;
response.write(encrypt_payload.toString()); //返回处理好的payload
response.close();
}else{
response.statusCode = 200;
response.write("^_^\n\rhello jsEncrypter!");
response.close();
}
});

0x03演示

完整的代码请移步github: http://github.com/c0ny1/jsEncrypter

大家自行下载,编译好,最后加载到Burp Suite中!

图2-插件界面

(1) 靶机搭建

项目jsEncrytper/server目录下提供一个php编写的靶机,我们用phpStudy把他运行起来。靶机目前支持的加密算法有7中:

  • base64 (PS:严格来说base64是一种编码,不是一种加密算法)
  • md5
  • sha1
  • sha254
  • sha384
  • sha512
  • RSA

我们选择sha1来进行演示。

图3-靶机

(2) 编写phantomJS脚本

  1. 通过查看靶机页面的js代码,我们知道实现sha1加密的是sha1.js这个文件,我们将它下载下来。

  2. 复制phantomJS模板代码jsEncrypter/js/jsEncrypter_base.js文件,改名为jsEncrypter_sha1.js。

  3. 在脚本中加载sha1.js,然后在js_encrypt函数中实现调用加密函数对传入的payload进行加密处理,即可。

完整代码如下:
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
var webserver = require('webserver');
server = webserver.create();

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

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

// 处理函数
function js_encrypt(payload){
var newpayload;
/**********在这里编写调用加密函数进行加密的代码************/
newpayload = hex_sha1(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){
if(request.method == 'POST'){
var payload = request.post['payload'];
var encrypt_payload = js_encrypt(payload);
console.log('[+] ' + payload + ':' + encrypt_payload);
response.statusCode = 200;
response.write(encrypt_payload.toString());
response.close();
}else{
response.statusCode = 200;
response.write("^_^\n\rhello jsEncrypt!");
response.close();
}
});

(3) 运行phantomJS脚本

1
2
3
4
5
λ phantomjs.exe jsEncrypter_sha1.js
[*] load js successful
[!] ^_^
[*] jsEncrypterJS start!
[+] address: http://127.0.0.1:1664

(4) 测试是否能成功加密

图4-测试

(5) 抓包爆破

图5-抓包爆破

0x04最后的话

各位如果有更好的解决方案,请留言互相交流。发现项目有bug或者有更好的修改建议,欢迎在github提交issuse,期待我们一起进步!

项目地址:https://github.com/c0ny1/jsEncrypter