原题: [简单的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 function pseudoHash (string, method ) { if (!('ENCRYPT' == method || 'DECRYPT' == method)) { method = 'ENCRYPT' ; } if ('ENCRYPT' == method) { var output = '' ; 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; } else if ('DECRYPT' == method) { return string; } } document .getElementById('password' ).value = pseudoHash('4e1e4c4d1b19474c1e1c491d1a484a1d49464f48191a47474a4b494a1d481e46' , 'DECRYPT' );
输入框中的内容是由js插进去的,内容为字符串:
4e1e4c4d1b19474c1e1c491d1a484a1d49464f48191a47474a4b494a1d481e46
pseudoHash()函数实现加解密功能,这里仅仅实现了加密,观察加密算法,逐位地对字符串包含的字符进行了以下操作:
得到字符的unicode码值charCode
若charCode < 128,charCode += 128 若charCode > 127,charCode -= 127
charCode = 255 - charCode
将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进制,可尝试再次使用解密算法
得到结果
8GÌ¿ýë!{¡î%¡
一堆乱码,应该不对,但还是尝试提交,果然错了。
另考虑此字符串为32位md5码 拖入在线网站解密,得到
5083
继续提交,仍然不对。 遂变换各种顺序,反复解密加密,都没有结果。
直接搜答案 竟然要在做题的页面提交…[简单的js解密] 提交
47e338b3c082945eff04de6d65915ade
得到答案
wctf{jS_decRypt__Eaaasy}
flag:
wctf{jS_decRypt__Eaaasy}
知识点
js字符串处理
string.charCodeAt(x)
,x为位置索引,得到string[x]字符的unicode码(0~65535)
int.toString(16)
,将整数int转换为16进制字符串
python字符串处理相关
ord(char/unichr)
返回一个字符的码值
chr(num)
返回一个码值代表的ascii字符
unichr(0-65535)
返回一个码值代表的unicode字符
int('string', base)
将一个基数为base的字符串转化为一个十进制整数
为正常使用来必力评论功能请激活JavaScript