HackThisSite - JavaScript Mission 1
Challenge
Idiot Test. The page is a single password box and a button; the check runs entirely in the browser.第一关 Idiot Test:页面只有一个密码输入框和一个提交按钮,点按钮时在浏览器里执行页内 JS 校验。
页面结构是 input#pass 加一个
<button onclick="javascript:check(document.getElementById('pass').value)">。按钮不提交任何表单,点击只是把输入框的值交给页内函数
check()。
Solution
用带登录态的会话取关卡页源码(HackThisSite
是短期凭据,这里写成占位符):
1 | $ curl -s -b 'HackThisSite=<mission-cookie>' \ |
页面里负责校验的函数:
1 | function check(x) { |
为什么这段 JS 能被绕过
check()把输入和字面量"cookies"直接比较,密码就硬编码在客户端 JavaScript 里。浏览器拿到的源码就是全部逻辑,查看源码或 devtools 即可读出,不需要任何猜测。- 真正决定通关的动作是成功分支里的
window.location += "?lvl_password=" + x。它把密码追加到当前 URL 上,再作为一个普通 GET 回跳给服务端。也就是说,客户端 JS 只决定是否发起这次跳转;跳转本身可以手工构造,无需运行页面。 - 用 Node 把这段逻辑提取出来运行一遍,即可确认比较结果:
1 | $ node -e 'function check(x){ return x == "cookies"; } console.log(check("cookies"))' |
Submit
把 cookies
填进输入框点按钮,等价于对关卡页发起这次请求:
1 | $ curl -s -b 'HackThisSite=<mission-cookie>' \ |
服务端靠 Referer 判断请求来自关卡页:同一 URL 不带
Referer 时不计完成,补上 -e
指向的关卡页地址后即计入完成。提交后 profile 的 Javascript
列表出现本关完成标记,账号积分 6501 → 6669(七关合计)。