Challenge
Faith is trying to trick you.... The checker has a dead
comparison that looks like the answer; the real password is a one-line
variable.
第四关页面开头写着
Faith is trying to trick you...(Faith
意在误导)。校验函数里有一行看似答案的废弃比较,真正的密码只是一个变量。
Solution
用带登录态的会话取关卡页:
1 2
| $ curl -s -b 'HackThisSite=<mission-cookie>' \ 'https://www.hackthissite.org/missions/javascript/4/'
|
页面里的校验函数:
1 2 3 4 5 6 7 8 9 10
| RawrRawr = "moo"; function check(x) { "" + RawrRawr + "" == "hack_this_site"; if (x == "" + RawrRawr + "") { alert("Rawr! win!"); window.location = "../../../missions/javascript/4/?lvl_password=" + x; } else { alert("Rawr, fail."); } }
|
RawrRawr = "moo" 是全局赋值,值就写在源码里。
""+RawrRawr+"" == "hack_this_site";
是干扰语句。它确实计算了一个字符串拼接("" + "moo" + ""
得到 "moo"),也确实拿它和 "hack_this_site"
做了比较,但这个比较的布尔结果被直接丢弃、没有赋给任何变量、也没有参与后面的
if。用 Node 单独跑这一行就能看到它恒为
false:
1 2
| $ node -e 'var RawrRawr = "moo"; console.log(""+RawrRawr+"" == "hack_this_site")' false
|
- 真正生效的条件是下一行的
if (x == ""+RawrRawr+"")。"" + RawrRawr + ""
只是把变量转成字符串,结果还是 "moo",所以比较等价于
x == "moo"。与空串拼接不会改变值:这是题目用来混淆视觉的,不是用来加密的。
1 2
| $ node -e 'var RawrRawr = "moo"; function check(x){ return x == ""+RawrRawr+""; } console.log(check("moo"))' true
|
- 放行动作是把
x 拼进 URL
回跳:window.location = "../../../missions/javascript/4/?lvl_password="+x。和前面几关一样,客户端只负责拼
URL,拼接结果完全可以手工构造。
Verify
1 2 3
| $ curl -s -b 'HackThisSite=<mission-cookie>' \ -e 'https://www.hackthissite.org/missions/javascript/4/' \ 'https://www.hackthissite.org/missions/javascript/4/?lvl_password=moo'
|