关注这个靶场的其它相关笔记:Authentication Lab —— 靶场笔记合集-CSDN博客
0x01:Client Side Auth 前情提要
有些时候,开发人员会将身份验证的逻辑写于前端,这样写是十分不安全的,因为前端的代码几乎全部都是可见的,在一个能够逆向 JS 的攻击者面前,所有基于前端的防御,都是纸老虎。
0x02:Client Side Auth Write UP
进入靶场,是一个登录框,并且写着 JS Login,基本可以判断,该靶场的身份验证逻辑是基于前端的:
随便写一个 Username 和 Password,点击登录,页面通过弹窗提示 “Invalid credentials”:
如果你比较细心,还可以通过浏览器的 “开发者工具” 发现,当我们点击 Login 按钮时,页面并没有向后端发送请求包,这意味着,所有的身份验证逻辑都是基于前端的:
刷新页面,进行抓包,开始分析 JS 文件。站点只有一个 JS 文件,且登录逻辑很好找到:
下面开始分析 JS 的登录逻辑:
function login() {// 获取用户输入的 用户名 和 密码var username = document.getElementById("username").value;var password = document.getElementById("password").value;// 将用户名和密码进行拼接,赋值给 concatvar concat = username+":"+password;var encrypted = "\u0000\u000c\u0007H1\u001c\u0002\u00160\u0000)\u000c\u001c\u0002'\u000e\u0006\u000c\u0001\u00003\u0013\u0016\u0007\u001c\n\u000b\u0017";var secret = "secretkey";// 如果 xorString (concat, 'secretkey') 的结果等于 encryptedif (xorString (concat, secret) == encrypted) {// 就给 /ClientSide 传递 hash 参数,该参数的值为 md5 后的 passwordurl="/ClientSide?hash=" + md5(password);// 进行跳转document.location=url;} else {// 如果计算后的结果不匹配,弹出警告框alert ("Invalid credentials");}}
用户输入的用户名和密码经过拼接后,与 secretkey
进行 xorString
运算,如果该值与 encrypted
的值相等,就完成登录,否则弹出警告框。这里需要提两点:
-
xorString
是一个基于异或的加密函数,而异或操作具有对称性,即使用相同的密钥对加密后的字符串再次进行加密会返回原始文本。 -
encrypted
的内容是 Unicode 编码。
根据异或操作的对称性,我们先获取正确的 username
与 password
的值,直接使用浏览器的控制台就可以完成:
var encrypted = "\u0000\u000c\u0007H1\u001c\u0002\u00160\u0000)\u000c\u001c\u0002'\u000e\u0006\u000c\u0001\u00003\u0013\u0016\u0007\u001c\n\u000b\u0017"; var secret = "secretkey"; xorString (encrypted, secret)
成功获取到了明文的用户名和密码,此时使用该用户名和密码,就可以完成登录:
sid:ThisIsLongSecurePassword