JavaScript 反混淆

前言

感觉 HTB 这章没讲啥东西啊,之前基本都学过了,都是些最简单的混淆和反混淆,用在线工具基本就能解决。还有一些很基本的加密解密, base64hex 啥的。

练习

Task1

Try to study the HTML code of the webpage, and identify used JavaScript code within it. What is the name of the JavaScript file being used?

太简单了,直接 <C-f> 搜一下 .js 就行了。

Task2

Once you find the JavaScript code, try to run it to see if it does any interesting functions. Did you get something in return?

这一问让我们看看上一问的那个 js 文件:

1
eval(function (p, a, c, k, e, d) { e = function (c) { return c.toString(36) }; if (!''.replace(/^/, String)) { while (c--) { d[c.toString(a)] = k[c] || c.toString(a) } k = [function (e) { return d[e] }]; e = function () { return '\\w+' }; c = 1 }; while (c--) { if (k[c]) { p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]) } } return p }('t 5(){6 7=\'1{n\'+\'8\'+\'9\'+\'a\'+\'b\'+\'c!\'+\'}\',0=d e(),2=\'/4\'+\'.g\';0[\'f\'](\'i\',2,!![]),0[\'k\'](l)}m[\'o\'](\'1{j\'+\'p\'+\'q\'+\'r\'+\'s\'+\'h\'+\'3}\');', 30, 30, 'xhr|HTB|_0x437f8b|k3y|keys|apiKeys|var|flag|3v3r_|run_0|bfu5c|473d_|c0d3|new|XMLHttpRequest|open|php|n_15_|POST||send|null|console||log|4v45c|r1p7_|3num3|r4710|function'.split('|'), 0, {}))

我们一看就知道是用 packer 混淆了,所以我们先用 UnPacker 反混淆:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function apiKeys()
{
var flag='HTB
{
n'+'3v3r_'+'run_0'+'bfu5c'+'473d_'+'c0d3!'+'
}
',xhr=new XMLHttpRequest(),_0x437f8b='/keys'+'.php';
xhr['open']('POST',_0x437f8b,!![]),xhr['send'](null)
}
console['log']('HTB
{
j'+'4v45c'+'r1p7_'+'3num3'+'r4710'+'n_15_'+'k3y
}
');

我们看到有个 flag,还有个输出,我们要的是返回值,好像不用反混淆也行,拿到控制台里去跑一下:

1
Uncaught SyntaxError: Invalid or unexpected tokenUnderstand this error

可恶,报错了,那我们手动拼接吧,用 vim 处理,很快的 :s/'\+'//g 就行了。

Task3

As you may have noticed, the JavaScript code is obfuscated. Try applying the skills you learned in this module to deobfuscate the code, and retrieve the ‘flag’ variable.

这一问又问我们刚才那个代码里的 flag 是什么,我们还是直接 vim 处理一下就行了。

Task4

Try to Analyze the deobfuscated JavaScript code, and understand its main functionality. Once you do, try to replicate what it’s doing to get a secret key. What is the key?

这一问要我们去分析刚才的 js 代码,找到里面的一个 key。

因为后面的部分是一个 console 的输出,所以我们只需要看这些就行了:

1
2
3
4
5
6
7
8
9
function apiKeys()
{
var flag='HTB
{
n'+'3v3r_'+'run_0'+'bfu5c'+'473d_'+'c0d3!'+'
}
',xhr=new XMLHttpRequest(),_0x437f8b='/keys'+'.php';
xhr['open']('POST',_0x437f8b,!![]),xhr['send'](null)
}

反混淆之后还是有点丑,我们格式化一下:

1
2
3
4
5
function apiKeys(){
var flag='HTB{n'+'3v3r_'+'run_0'+'bfu5c'+'473d_'+'c0d3!'+'}',
xhr=new XMLHttpRequest(),_0x437f8b='/keys'+'.php';
xhr['open']('POST',_0x437f8b,!![]),xhr['send'](null)
}

这样看着舒服多了,flag 没啥用,刚才已经用过了,跟这个函数的功能没啥关系,xhr 是一个 http 请求,_0x437f8b 是我们请求的一个目标,所以这个函数的功能就是对 http://SERVER_IP:PORT/keys.php 发送一个 POST 请求,我们用 curl 发一个看看:

1
2
$ curl http://$SERVER/keys.php -X POST
4150495f70336e5f37333537316e365f31355f66756e

这里的 $SERVER 就是 SERVER_IP:PORT

我们也是成功的获取到了响应。

Task5

Once you have the secret key, try to decide it’s encoding method, and decode it. Then send a ‘POST’ request to the same previous page with the decoded key as “key=DECODED_KEY”. What is the flag you got?

上一问获取到的那个响应是一个密文,这一问要我们解密,那个密文长度是 4 的倍数,我们猜测是 base64 加密的,所以我们先试一下:

1
2
$ echo 4150495f70336e5f37333537316e365f31355f66756e | base64 -d
�^t��_�M���_߽�ߝ��^�߮_�]����

出来一坨乱七八糟的东西,可能是猜错了,那我们用菜刀试试,打开 CyberChef,直接搞进去,用 Magic 试一下,发现是 hex,明文是 API_p3n_73571n6_15_fun,然后我们发一个请求:

1
2
$ curl http://$SERVER/keys.php -X POST -d 'key=API_p3n_73571n6_15_fun'
HTB{r34dy_70_h4ck_my_w4y_1n_2_HTB}

就解决了。

其实命令行解密 hex 前面也有讲,但是我没记住,并且有合适的在线工具,那就这么过去了。