小宁发现了一个网页,但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} )
该题来自攻防世界新手练习区的 GFSJ0480。
访问靶场,输入任意密码,弹出错误窗口并加载空页面,使用检查器查看对应源代码,使用 JavaScript 脚本编写判断逻辑:
//将一个逗号分隔的字符编码字符串解密为明文字符串
function dechiffre (pass_enc) {
var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65";
var tab = pass_enc.split(',');
var tab2 = pass.split(',');
var i, j, k, l = 0, m, n, o, p = "";
i = 0;
j = tab.length;
k = j + (l) + (n = 0);
n = tab2.length;
for (i = (o = 0); i < (k = j = n); i++) {
o = tab[i - l];
p += String.fromCharCode((o = tab2[i]));
if (i == 5) break;
}
for (i = (o = 0); i < (k = j = n); i++) {
o = tab[i - l];
if (i > 5 && i < k-1) p += String.fromCharCode((o = tab2[i]));
}
p += String.fromCharCode(tab2[17]);
pass = p;
return pass;
}
//相当于 String.fromCharCode 方法,但方括号表示法可以在运行时动态改变
String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"));
h = window.prompt('Enter password');
alert(dechiffre(h));
根据代码逻辑,可以知道,不论循环执行情况如何,错误窗口都会弹出,由这两个循环中的 String.fromCharCode
可知我们需要进行 Unicode 字符串转码来获取 flag;而循环外部定义的十六进制编码字符串很有可能是最终的 flag。对此,我们编写 Python 脚本来实现对该密钥的破译:
s = ("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31"
"\x30\x37\x2c\x34\x39\x2c\x35\x30")
print(s) # 转换为 ASCII 码
# ASCII values of characters in the string: 55,56,54,79,115,69,114,116,116,107,49,
s = s.split(",") # 分割字符串
flag = ""
for i in s:
flag += chr(int(i)) # Unicode 码转换为字符
print(flag)
执行脚本,输出 786OsErtk12
,按题目给出的 flag 形式包裹起来,即 Cyberpeace{786OsErtk12}
,直接提交即可。