关注这个靶场的其它相关笔记: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;
// 将用户名和密码进行拼接,赋值给 concat
var 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') 的结果等于 encrypted
if (xorString (concat, secret) == encrypted) {
// 就给 /ClientSide 传递 hash 参数,该参数的值为 md5 后的 password
url="/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