信息安全技术大赛——Console

时间:2013-05-24 | 分类:个人日志,学习园地 | 浏览:3065 | 评论:3 | 发表评论

题目标题:Console
题目描述:
题目入口:http://code2.myclover.org/

这道题没有描述,打开网页,只看到一个人在不停地走动:

网页源码里只提示要用Chrome打开网页,就没其它提示了,唯一可疑的就是题目Console。
打开Chrome的开发人员工具,重新打开网页,切换到Console标签,看到了提示信息:

按照提示输入syc,然后回车,出现了以下内容:

"你尝试过F5了么?如果没有,试试看!"
"注意到URL了么?好像很有趣"
"尝试着点击浏览器的后退看看,你什么时候访问的这些地址呀?"
"看看你的浏览器历史记录"
"试着访问这些地址,你会找到线索"

这时浏览器的地址栏里的地址是:http://code2.myclover.org/Sunday。
点击浏览器的后退按钮,地址栏里的地址变成:http://code2.myclover.org/Saturday。
于是我打开浏览器的历史记录看了一下:

可以看到,浏览器产生了7个访问历史,从Monday到Sunday。
但是这是怎么产生的呢?我查看了开发人员工具的Network标签,发现了一个名为msg的js文件:

再打开这个js文件,里面有一段代码:

var a = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
for (var b = 0; b < 7; b++) {
    history.pushState(null, null, a[b])
};

history.pushState是HTML5里的API,作用是将指定的URL添加到浏览器历史记录里。

再根据提示访问历史记录里的地址,出现了提示:

一开始以为网页里有陷阱,但查看源码并没发现什么奇怪的地方。
于是继续访问其它地址,当访问到了星期三时,提示变了:

每周三都是 [三叶草] 集会的日子,每次集会都可以得到三个字符。
据说收集到所有的字符,就可以找到神龙,神龙就会告诉你key。
搜集到所有的字符,将这些字符按照 [大写字母+小写字母+数字] 的顺序排列起来,
再访问这个序列构造的URL就可以找到神龙。
例如:ABFGJbcdzy456,则访问 http://[你懂的]/ABFGJbcdzy456。
不过传说所有的字符大概有四十多个。

获取字符的地址为:http://code2.myclover.org/randomstr。
下面为获取所有字符并排序的python代码:

#!/usr/bin/python
# -*- coding : utf8 -*-
import urllib2

# 返回网页源码的3个字符
def get_three_chars():
    try:
        url = 'http://code2.myclover.org/randomstr'
        page = urllib2.urlopen(url, timeout=10)
        return page.read()
    except:
        return ''

if __name__ == '__main__':
    # 循环100次,获取300个字符拼成字符串
    chars = ''.join([get_three_chars() for i in range(100)])
    # words是用于排序的字符串
    words = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    # 去掉重复字符后排序
    print ''.join(sorted(set(chars), key=lambda x:words.index(x)))

因为提示说字符大概有40多个,那么获取100次得到300个字符应该覆盖了全部字符了。
执行后得到了传说中的字符:ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678。
(好吧,居然有48个字符,也算是40多个吧!!!)
打开网址后又看到了提示:
http://code2.myclover.org/ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678

神龙说:
({}+[])[!![]-~!![]-~!![]]+(!![]+[])[-~!![]]+([][[]]+[])[!![]-~!![]-~!![]]+(!![]+[])[+[]]+(![]+[])[!![]-~!![]]+'y'+({}+[])[!![]-~!![]-~!![]]

是一段精心构造的js代码,可以参考这篇文章:一段有趣的Javascript代码及分析

 js代码中的加号是连接字符串的操作符,所以代码可以写成:

({}+[])[!![]-~!![]-~!![]]    //1
+
(!![]+[])[-~!![]]    //2
+
([][[]]+[])[!![]-~!![]-~!![]]    //3
+
(!![]+[])[+[]]    //4
+
(![]+[])[!![]-~!![]]    //5
+
'y'    //6
+
({}+[])[!![]-~!![]-~!![]]    //7

1、({}+[])[!![]-~!![]-~!![]]。
可以拆分成两个部分:({}+[]) 和 [!![]-~!![]-~!![]]。
({}+[])在计算{}+[]时,由于对象无法相加,所以在加法之前会先做一个toString的转换,
即({}.toString()+[].toString()) = "[object Object]",是一个字符串。
[!![]-~!![]-~!![]]里面都包含有!![],因为[]是一个object,为非Null值,
!是逻辑取反,所以![]的结果是false,因此!![] = true。
也就是说[!![]-~!![]-~!![]]可转化为[true - ~true - ~true]。

在计算~true时,~是按位取反操作,需要一个数字操作数,所以true当作数字1处理。
1在计算机的原码是00000001,按位取反后~1 = 11111110,是一个负数。
因为负数在计算机里是以补码显示的,转成原码的方法是非符号位减1再取反,
即11111110 => 11111101 => 10000010,结果为-2,因此~true = ~1 = -2。 
简单的计算方法是操作数取负数再减1,~1 = -1-1 = -2。
所以[true - ~true - ~true] = [1 - (-2) - (-2)] = [5]。
"[object Object]"[5] 表示取字符串第5个元素的值,所以"[object Object]"[5] = 'c'。

2、(!![]+[])[-~!![]]。
同上,可以拆分成两个部分:(!![]+[]) 和 [-~!![]]。
(!![]+[]) = (true + []) = (true + "") = "true"。
[-~!![]] = [-~1] = [-(-2)] = [2]。
(!![]+[])[-~!![]] = "true"[2] = 'u'。

3、([][[]]+[])[!![]-~!![]-~!![]]。
同上,可以拆分成两个部分:([][[]]+[]) 和 [!![]-~!![]-~!![]]。
[][[]]可拆分为[] 和 [[]],[]是空数组,[[]]里面的[]是一个object,
而取空数组元素时下标只能用数字,不能用object,所以返回未定义undefined,
因此([][[]]+[]) = (undefined + []) = "undefined"。
[!![]-~!![]-~!![]] = [true - ~true - ~true] = [1-(-2)-(-2)] = [5]。
([][[]]+[])[!![]-~!![]-~!![]] = "undefined"[5] = 'i'。

4、(!![]+[])[+[]] = (true+[])[+0] = "true"[0] = 't'。

5、(![]+[])[!![]-~!![]] = (false+[])[true-~true] = "false"[3] = 's'。

6、'y' = 'y'。

7、和1相同。

把上面7个字符拼起来就得到了过关的key:"cuitsyc"。

最简单的方法是把js代码复制到开发人员工具的Console里执行:

标签: , ,
本文链接: 信息安全技术大赛——Console
版权所有: 破博客, 转载请注明本文出处。

3个评论

  1. 好长啊
    2013/12/19 13:39:27

    好长啊


  2. 2013/06/04 19:33:04

    这道题有点意思.这是今年的吗???..成都信息工程学院的人还真是闲啊..

发表评论

您的昵称: *

您的邮箱: * (显示gravatar头像)

联系方式: