题目描述

小宁发现了一个网页,但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} )

Solution

进入场景,可以看到一个弹窗,输入密码后会检验密码正确性。

  1. function dechiffre(pass_enc) {
  2. var pass = '70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65';
  3. var tab = pass_enc.split(',');
  4. var tab2 = pass.split(',');
  5. var i, j, k, l = 0, m, n, o, p = '';
  6. i = 0;
  7. j = tab.length;
  8. k = j + (l) + (n = 0);
  9. n = tab2.length;
  10. for (i = (o = 0); i < (k = j = n); i++) {
  11. o = tab[i - l];
  12. p += String.fromCharCode((o = tab2[i]));
  13. if (i == 5) break;
  14. }
  15. for (i = (o = 0); i < (k = j = n); i++) {
  16. o = tab[i - l];
  17. if (i > 5 && i < k - 1) p += String.fromCharCode((o = tab2[i]));
  18. }
  19. p += String.fromCharCode(tab2[17]);
  20. pass = p;
  21. return pass;
  22. }
  23. String['fromCharCode'](dechiffre(
  24. '\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'));
  25. h = window.prompt('Enter password');
  26. alert(dechiffre(h));

这段代码我们可以在dechiffre()函数返回前加几个console.log()去打印调试。调试几遍后你会发现,无论你参数传了什么字符串进去,它返回的结果都是固定的FAUX PASSWORD HAH

现在线索只剩下String['fromCharCode']后面的几个神秘字符了。我们编写一段 Perl 脚本打印这些十六进制数:

$str = "\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($str);

输出结果是:

55,56,54,79,115,69,114,116,107,49,50

这很有可能是一串 ASCII 字符,我们再修改上面的 Perl 脚本:

$str = "\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($str);
printf("\n");

# 55,56,54,79,115,69,114,116,107,49,50
@list = (55,56,54,79,115,69,114,116,107,49,50);
foreach $c (@list) {
    printf("%c", $c);
}

这时候结果输出是:

55,56,54,79,115,69,114,116,107,49,50
786OsErtk12

我们修改一下格式尝试提交,可以通过测试。