IDF实验室-简单的js解密

Posted by pzque on 2015-05-05     

原题:

[简单的js解密]
这里写图片描述


writeup:

直接看代码,页面内有一段script:

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
/**
* Pseudo md5 hash function
* @param {string} string
* @param {string} method The function method, can be 'ENCRYPT' or 'DECRYPT'
* @return {string}
*/
function pseudoHash(string, method) {
// Default method is encryption
if (!('ENCRYPT' == method || 'DECRYPT' == method)) {
method = 'ENCRYPT';
}
// Run algorithm with the right method
if ('ENCRYPT' == method) {
// Variable for output string
var output = '';
// Algorithm to encrypt
for (var x = 0, y = string.length, charCode, hexCode; x < y; ++x) {
charCode = string.charCodeAt(x);
if (128 > charCode) {
charCode += 128;
} else if (127 < charCode) {
charCode -= 128;
}
charCode = 255 - charCode;
hexCode = charCode.toString(16);
if (2 > hexCode.length) {
hexCode = '0' + hexCode;
}

output += hexCode;
}
// Return output
return output;
} else if ('DECRYPT' == method) {
// DECODE MISS
// Return ASCII value of character
return string;
}
}
document.getElementById('password').value = pseudoHash('4e1e4c4d1b19474c1e1c491d1a484a1d49464f48191a47474a4b494a1d481e46', 'DECRYPT');

输入框中的内容是由js插进去的,内容为字符串:

4e1e4c4d1b19474c1e1c491d1a484a1d49464f48191a47474a4b494a1d481e46

pseudoHash()函数实现加解密功能,这里仅仅实现了加密,观察加密算法,逐位地对字符串包含的字符进行了以下操作:

  1. 得到字符的unicode码值charCode
  2. charCode < 128,charCode += 128
    charCode > 127,charCode -= 127
  3. charCode = 255 - charCode
  4. charCode转为16进制

最后得到的是将所有的16进制字符拼接起来的结果,由此不难编写解密算法,使用python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
s = '4b481a4c4c471d4c1c4f474d464b4a1a19194f4b1b1a491b494a464e4a1e1b1a'
def decode(s):
charcode = []
i = 0
while i<len(s):
charcode.append(int(s[i:i+2],16))
i = i + 2
charcode = [255-i for i in charcode]

chars = []
for i in charcode:
if 127<i+128<255:
chars.append(i+128)
elif 0<i-128<128:
chars.append(i-128)
else: chars.append(i)
result = [unichr(i) for i in chars]
return ''.join(result)

t = decode(s)

运行后得到结果

47e338b3c082945eff04de6d65915ade

直接当作flag提交,错误,继续分析:

解密后得到的字符串长32位,全16进制,可尝试再次使用解密算法

1
decode(t)

得到结果

8œGÌ¿ýë!€{¡î%¡

一堆乱码,应该不对,但还是尝试提交,果然错了。

另考虑此字符串为32位md5码

拖入在线网站解密,得到

5083

继续提交,仍然不对。
遂变换各种顺序,反复解密加密,都没有结果。

直接搜答案

竟然要在做题的页面提交…
[简单的js解密]
这里写图片描述
提交

47e338b3c082945eff04de6d65915ade

得到答案

wctf{jS_decRypt__Eaaasy}

flag:

wctf{jS_decRypt__Eaaasy}

知识点

  1. js字符串处理
    • string.charCodeAt(x),x为位置索引,得到string[x]字符的unicode码(0~65535)
    • int.toString(16),将整数int转换为16进制字符串
  2. python字符串处理相关
  • ord(char/unichr) 返回一个字符的码值
  • chr(num) 返回一个码值代表的ascii字符
  • unichr(0-65535) 返回一个码值代表的unicode字符
  • int('string', base) 将一个基数为base的字符串转化为一个十进制整数