Web_XCTF_WriteUp | simple_js

发布时间 2023-11-30 08:04:10作者: Guanz

题目

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

题目

分析

F12 打开查看器找到一串 JS 代码:


分析一下大致意思:

function dechiffre(pass_enc){
    var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65";  // 变量pass赋值
    var tab  = pass_enc.split(',');                                      // 变量tab接受pass_enc参数按“,”拆分返回的新数组
            // 变量tab2接受pass参数按“,”返回的新数组
            // 定义变量 i、j、k、l(初始化为0)、m、n、o、p(初始化为空字符串
            // i初始化为0
            // j初始化为tab中拆分数组的个数(即pass_enc被拆分的个数)
            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赋值为0,计算j+l+n的值赋给k
                    n = tab2.length;                                     // n赋值为tab2中拆分数组的个数(即pass被拆分的个数)
                    // 变量o赋值为0,变量j接收变量n的赋值,变量k接收变量j的赋值。循环n次
                    // tab第i-l个元素赋给o
                    // tab2第i个元素赋值给o,p尾部拼接o创建的字符串
                    for(i = (o=0); i < (k = j = n); i++ ){o = tab[i-l];p += String.fromCharCode((o = tab2[i]));
                            // 当i等于5时跳出循环
                            if(i == 5)break;}
                    // 变量o赋值为0,变量j接收变量n的赋值,变量k接收变量j的赋值。循环n次
                    for(i = (o=0); i < (k = j = n); i++ ){
                    // tab第i-l个元素赋给o
                    o = tab[i-l];
                            // 如果i大于5且小于k-1
                            if(i > 5 && i < k-1)
                                    // tab2第i个元素赋值给o,p尾部拼接o创建的字符串
                                    p += String.fromCharCode((o = tab2[i]));
                    }
    p += String.fromCharCode(tab2[17]);  // p尾部拼接tab2第17个元素
    pass = p;return pass;                // p赋值给pass。返回pass
}
// 调用dechiffre,将返回值转为字符
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');  // 打开显示提示文本为“Enter password”的提示窗口
alert( dechiffre(h) );                // h作为参数调用函数dechiffre,弹窗显示

这个排版真是…(吸气)


整体看下来,dechiffre 函数里有两个字符串,分别是输入的 pass_enc 和原有的 pass。运行过程中,pass_enc 和 pass 按 “,” 被拆分,分别放在 tab 和 tab2 两个变量中。
在两个 for 循环中,变量 p 不断拼接 o 的字符串形式,并最终作为返回值传递。
变量 o 在被赋值为 tab 的第 i-l 个元素后没有进行任何操作,很快被赋值为 tab2 的第 i 个元素。
也就是说,我们输入的 pass_enc 值其实并没有参与运行,即输入的 Enter password 对输出结果不造成影响,而浏览器实际输出的是将 70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65 转化为字符串的结果。


同时,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")); 似乎只是调用了 dechiffre 函数,结果并没有作为输出显示,很奇怪。


综上,我们需要将 tab2 和 tab 的地位进行替换,即将代码第 3 行的 tab 改为 tab2,第 8 行的 tab2 改为 tab,第 10 行的循环次数 n 的由 tab2.length 改为 tab.length。


但更改后的代码依旧需要在弹窗中输入密码,我们手头仅有的可能就是调用了 dechiffre 但没有输出的那串字符。尝试将这串字符作为输入直接填入代码。


一番摸索后,我们找到了将更改后的代码运行在浏览器上的方式,更改后的代码内容如下:

<html><body><script>
    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 tab2  = pass_enc.split(',');
                var tab = pass.split(',');var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;
                        k = j + (l) + (n=0);
                        n = tab.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;
    }

    h = window.prompt('Enter password');
    alert(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") );

</script></body></html>

将代码保存为 html 文件,用浏览器打开,点击确定后得到一串十位字符:


看字符串内容不像某种类型的编码,尝试作为 flag 提交,确定为 flag 内容。

Flag

Cyberpeace{786OsErtk12}

参考

JavaScript 教程-菜鸟教程
js中的连续赋值-瓶盖的盖-CSDN博客
JavaScript中字符串连接/拼接的四种方式-Colbyzn-CSDN
JavaScript String 对象-菜鸟教程
HTML(.htm或.html)文件怎么打开?-柚子-知乎.html
html基本格式-yzyggu-CSDN博客
HTML<script>标签-菜鸟教程