GoogleCTF2018-beginners-js_safe_1
最近听群里师傅提起GoogleCTF,正好我没有做这个比赛,于是打算近期将题目复现一下。
题目环境地址:https://github.com/google/google-ctf
这一题是一道 JS 代码审计、调试的题目,代码很简单,只有一个HTML文件,主要的功能就是输入一个字符串,运行 JS 代码之后告诉你这个字符串是否正确,一般来说这个字符串就是 flag 了。
因为主要代码不多,所以我就直接贴上来了
1 |
|
其中code变量是generate.py生成的一个1000+长度的字符串,而keyhole.value即我们的输入字符串。
简单审计一下代码,首先我们要输入一个CTF{xxxxxxx}格式的字符串,而字符串中间的xxxxxx则会储存在env[g]中,然后 javascript 代码遍历code字符串,不停地给env[lhs]赋予新值,最后如果env[h]为0,就会返回”granted”,flag就是这个时候我们输入的那个字符串。
因为一共进行了几百次循环,所以为了减少工作量,我们可以找到env[g]首次出现的地方(因为前面的处理都跟我们的输入无关,是每次都相同的),然后从那里开始,这里我使用CTF{Twings}作为测试。
1 |
|
一个简单的正则表达式,得到的 i 为876,于是:
1 |
|
把处理的过程都打印出来看看都是些什么东西。我们可以看到 i=884 的时候对我们的输入做了一些处理:
1 |
|
后面那一串数字即我们输入的 Twings 字符串的ASCII值,看起来似乎是进行了SHA256加密,我们打印一下结果看一下:
1 |
|
而生成结果中正好存放着它的SHA256哈希,看来这个猜想没有错,我们继续往下看。
我们可以看到,从 i=960 开始,代码会遍历这个哈希,并将它的各个字符跟一个固定字符串的各个字符轮流进行异或,再将异或结果与env[h]进行或运算,并将或运算的结果存入env[h]中。而env[h]的初始值为0,也就是说,如果我们要最后env[h]的值为0,我们就需要输入一个SHA256哈希值跟这个固定字符串相同的字符串,来让异或的结果一直为0。
我们先将这个字符串提取出来:
1 |
|
结果是:[230, 104, 96, 84, 111, 24, 205, 187, 205, 134, 179, 94, 24, 181, 37, 191, 252, 103, 247, 114, 198, 80, 206, 223, 227, 255, 122, 0, 38, 250, 29, 238],转化为十六进制即e66860546f18cdbbcd86b35e18b525bffc67f772c650cedfe3ff7a0026fa1dee,谷歌这个哈希即可得到正确的flag:CTF{Passw0rd!}