【2021春节】解题领红包之番外篇分析

2021年3月3日 528点热度 0人点赞 0条评论

作者坛账号:周易


【2021春节】解题领红包之番外篇分析

番外篇一

解压文件,得到番外篇.js。打开文件,如图所示。由题目描述或de4js易得此为JSFuck处理过的。

图片

番外篇一很简单,直接使用de4js或利用控制台即可还原。
还原后代码如下:

 复制代码 隐藏代码
function _52pojie_MMXXI_(t) {
    let e = [];
    for (let f of t) {
        let t = f.codePointAt(0),
            h = 0;
        t -= 0x1d4 << 0x1c8, "bkd0egfw002whccadqf6gm0q3mi2".match(/../g).forEach(f => {
            f = parseInt(f, 0x24), t >= f && t < f + 0x1A && e.push(h % 7), h++
        })
    }
    let f = [];
    for (; e.length >= 3;) {
        let t = 0x31 * e.shift();
        if (t += 7 * e.shift(), (t += e.shift()) > 0xff) break;
        f.push(t)
    }
    return new Uint8Array(f);
    const flag1 = 'n0w_wh3r3_1s_th3_c1ph3rt3xt?'
}

容易看出flag1为n0w_wh3r3_1s_th3_c1ph3rt3xt?

番外篇二

我们分析函数_52pojie_MMXXI_,不难发现上半部分使用到了Unicode字符。不妨改造代码将其打印,结果如下:

 复制代码 隐藏代码
t = 0x1d4 << 0x1c8, "bkd0egfw002whccadqf6gm0q3mi2".match(/../g).forEach(f => {
    f = parseInt(f, 0x24);
    for (let i = 0; i < 26; i++) {
        document.write(String.fromCodePoint(t + f + i))
    }
    document.write('<br>')
})
 复制代码 隐藏代码
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????

很明显,我们应该找到一段Unicode原文作为参数,才能得到flag2。但是参数在哪里?这里感谢逍遥一仙给了思路。
在JavaScript中,有一个函数负责将Unicode转为ANSI。这就是String.prototype.normalize()。
因此不妨重载该函数,得到参数。

 复制代码 隐藏代码
(function() {
    var oldString_prototype_normalize = String.prototype.normalize;
    String.prototype.normalize = function() {
        console.log(this.toString() + '\n');
        for (let a of arguments) {
            console.log(a.toString() + '\n');
        }
        return oldString_prototype_normalize.apply(this, arguments);
    }
})();

首先在控制台中运行如上代码,然后再次运行题目,得到结果如下。

图片

 复制代码 隐藏代码
?????? ???????? _52?????_?????_(?){??? ?=[];???(??? ? ?? ?){??? ?=?.???????????(0),?=0;?-=0?1?4<<0?1?8,"???0????002????????6??0?3??2".?????(/../?).???????(?=>{?=????????(?,0?24),?>=?&&?<?+0?1?&&?.????(?%7),?++})}??? ?=[];???(;?.??????>=3;){??? ?=0?31*?.?????();??(?+=7*?.?????(),(?+=?.?????())>0???)?????;?.????(?)}?????? ??? ????8?????(?);????? ????1='?0?_??3?3_1?_??3_?1??3??3???'}

这就是我们期待已久的参数了。
重新利用原来的_52pojie_MMXXI_函数,得到数组。我们将其写入文件,不难发现又是JavaScript代码。

 复制代码 隐藏代码
"?ⁱ???ₙᵁ?ⅈᶜ??ⅇ".normalize('NFKD')

在控制台中运行即可得到flag2为HideInUnicode

图片

后记

此题考查Unicode编码在JavaScript中的应用。

  • 关于乱码的问题
    原始函数返回的是数组。当然也可以进行修改使其打印到控制台中,但有可能出现乱码。解题过程中使用了C写入到文件,并使用文本编辑器打开,没有出现乱码。若使用JavaScript直接打印,则需要使用String.fromCodePoint()

     复制代码 隐藏代码
    #include<stdio.h>
    unsigned char a[] = {
    /* JavaScript中返回的数组 */
    };
    int main() {
    FILE * fp = fopen("out.js", "wb");
    fwrite(a, sizeof(a), 1, fp);
    }
  • 关于如何想出重载
    在JavaScript中,重载一些函数可以使分析更为便捷。常用的重载有eval()Function构造函数等。
    在此题中,重载eval()也能得到结果。

--

www.52pojie.cn


--

pojie_52

32840【2021春节】解题领红包之番外篇分析

这个人很懒,什么都没留下

文章评论