我的解题过程
-
下载文件web100,由于无文件后缀名,故使用Hex Editor打开目标文件进行分析
- 大体可以看出文件内容为JavaScript代码
- 由于文件一开始的内容为”<script>“,由于JavaScript文件中是不会出现标签的,所以该文件为HTML文件,JavaScript通过script标签内嵌在HTML文档中
-
将文件名更改为web100.html,使用浏览器打开,进行进一步分析
-
网页内容为一个输入框和一个按钮
-
虽然有大量不可读代码,通过Chrome的JavaScript代码高亮可以看出,JavaScript代码中先定义了一个名为’_‘的字符串,之后执行了一个for循环对’_‘代码进行了处理,之后使用eval将’_‘字符串作为JavaScript代码进行了执行
-
-
使用Hex Editor的Insert Mode对web100.js进行编辑,将eval函数修改为console.log,使用浏览器打开,从F12的console中获取真正执行的JavaScript代码
function $() { var e = document.getElementById("c").value; if (e.length == 16) if (e.match(/^be0f23/) != null) if (e.match(/233ac/) != null) if (e.match(/e98aa$/) != null) if (e.match(/c7be9/) != null) { var t = ["fl", "s_a", "i", "e}"]; var n = ["a", "_h0l", "n"]; var r = ["g{", "e", "_0"]; var i = ["it'", "_", "n"]; var s = [t, n, r, i]; for (var o = 0; o < 13; ++o) { document.write(s[o % 4][0]); s[o % 4].splice(0, 1) } } } document.write('<input id="c"><button onclick=$()>Ok</button>'); delete _
-
可以看出进行了四个正则匹配,如果匹配成功,则从四个数组轮流读取首元素中拼接出真正的flag并写到document中
- 字符串长度为16
- 字符串以be0f23开头
- 字符串中有233ac
- 字符串以e98aa结尾
- 字符串中有c7be9
Result:be0f233ac7be98aa
-
所以当输入框内容为”be0f233ac7be98aa”,网页将打印flag
-
发现flag,flag{it’s_a_h0le_in_0ne}
-
提交,答案正确
独立思考
1. 本题中的JavaScript代码有哪些特殊的?
-
eval(string),是全局函数,将字符串当作脚本执行
-
with,是关键字,使用with语句关联对象,在with代码块内每个变量首先被认为是一个局部变量,如果局部变量和关联对象的某个属性同名,则这个局部变量会指向关联对象的属性
-
var obj ={a:1,b:2,c:3}
-
一般的修改方式:
obj.a=233; obj.b=666; obj.c=888;
-
通过with的修改方式:
with(obj){ a=233; b=666; c=888; }
-
-
pop(),不是处理栈的函数,而是处理数组的函数,该方法将删除array的最后一个元素,并将该元素返回,如果数组为空,则返回undefined。
-
join(separater),处理数组的函数,将所有数组的元素以separater为分隔符进行拼接成一个字符串
-
splice(index,howmany,new……),处理数组的函数,删除index位置的howmany个元素,第三个及以后的参数是可选的,用于指定替换删除掉的元素的元素
-
split(separater,howmany),处理字符串的函数,是join()的逆过程,用于将一个字符串分割为字符串数组
2. 本题中新学会了哪些正则语法?
- [^ABC],匹配除了[]中字符的字符
- ^,匹配字符串的开始位置
- $,匹配字符串的结束位置
3. 本题中JavaScript字符串经过了哪些处理被解密出来的?
for(Y in $='....')
with(_.split($[Y]))
_=join(pop())
-
for/in循环会遍历对象的属性
var person={name:"mon",age:233} var x; for(x in person){ document.write(person[x]); }
通过使用浏览器调试发现,for/in会把字符串当作char[],Y是数组索引号,$[Y]
-
每次循环中
- 会把”_“字符串使用$[Y]分割为数组
- 接下来是与with关键字相关的极具迷惑的一段代码
- 对”_“分割出来的数组执行pop(),此时删除了最后一个元素,并返回了一个最后一个元素
- join()将pop()出来的值作为参数,即separater分隔符,对”_“字符串的”分割后且删除最后一个元素的”数组进行拼接为字符串,填充就是删除前的最后一个元素
- 将操作后的字符串赋值给”_“参数
以第一个循环为例,$变量为13B的字符串
- Y的值为0
- $[Y]为0x0f
- 对”_“字符串以0x0f进行分割为数组
- pop()出来的最后一个元素为”ment”
- join(“ment”),将ment插入到数组的元素之间
- 完成了对”_“字符串的一次解密
以此类推,一共进行13次循环,完成对”_“的解密,重新恢复出真正的字符串
产生过的疑问
- 本题中的JavaScript代码有哪些特殊的?
- 本题中新学会了哪些正则语法?
- 本题中JavaScript字符串经过了哪些处理被解密出来的?