文章总结: 本文描述了如何利用空字节注入绕过邮箱唯一性校验。攻击者在注册请求中添加空字符,使后端认为邮箱不同而放行,但实际存储时剥离空字符导致新账户覆盖原账户。这导致原用户无法登录,从而实现删除任意用户账户的效果。 综合评分: 85 文章分类: 渗透测试,WEB安全,漏洞分析
我是如何删除应用中任意我想要的用户账户的
haidragon
安全狗的自我修养
2026年1月12日 16:22 湖南
官网:http://securitytech.cc/
#
嗨,
今天我将讲述我是如何发现一个漏洞,它允许我删除应用中任何我想删除的用户。这个想法本身很简单,但它的影响力一点都不简单 🙂
顺便说一句,我是在大学 DSP 期末考试前 5 个小时发现这个漏洞的(我真的恨 DSP -_-)。所以,是的,期末前的夜晚才是我的巅峰时刻(GOAT)。
我们的目标是 Bugcrowd 上的一个公开 BBP 项目,而且已经存在很长时间了。很多人总觉得在公开 BBP 上找漏洞很难,因为已经被很多黑客测试过了——我也同意这一点。但思维方式永远比环境更重要。 别完全听我的,也别一上来就去黑 Google 😂。
当你测试一个网站时,你必须从 三个角度 思考:
- 系统期望用户做什么,不期望用户做什么 —— 那如果我做了“不期望的事情”会怎样?关键永远是 what if…
- 尝试用一种“不应该发生的方式”去完成同一件事
- 先像普通用户一样理解目标,再像黑客一样理解它。你越了解它,就越容易破坏它。
给应用开发者多加点“任务”吧 😈
一开始,当我选择目标时,我总是优先测试高影响漏洞,而危害用户账户和数据永远排在最前面。
在测试应用的注册和登录功能时,我发现: 👉 注册后并不需要验证邮箱 这本身就是一个糟糕的实现。
我创建了一个新账号,然后退出登录,开始思考下一步我能做什么。
我想到的第一个问题是:
是否允许用同一个邮箱创建多个账户?
答案是:不允许
他们期望: 👉 一个邮箱只能注册一个账号
那么问题来了:
如果我找到一种方式,用同一个邮箱再创建一个账户呢?
当然,他们一定有防护机制来避免这种情况。但问题是:
如果这个“异常情况”真的发生了,他们是否正确处理了?
我们来看看怎么做到的
其实这种场景可以测试的技巧有很多。 我通常先从**响应篡改(Response Manipulation)**开始,看看限制是不是只存在于前端 UI。 结果失败了。
测试了一会儿后,Null Byte(空字节)注入出现在我脑海中。
我们先来想象一下: 后端是如何校验邮箱唯一性的?
假设后端逻辑是这样的(简化版)
db_query = "SELECT * FROM users WHERE email=@input_email;"
if len(q) > 0:
print("user already exists!")
else:
create a new account
这当然不是现实世界中的真实代码,只是为了方便理解。
在我们“破坏”它之前,先看看数据库是如何处理不同值的。
数据库的对比行为
SELECT'a'='a'ASresult;
这个查询一定会返回 true,因为 'a' == 'a'。
t 表示返回 true。
如果我们希望返回 false:
因为 'a' != 'b',返回 f。
那如果是 Null Byte 呢?
非常棒的行为——至少对我这种人来说是这样 🙂
回到后端逻辑
db_query = "SELECT * FROM users WHERE email=@input_email;"
if len(q) > 0:
print("user already exists!")
else:
create a new account
假设数据库中已经存在:
[email protected]
正常情况
- 输入:
[email protected] - 查询命中
if条件为 true- 返回:
user already exists
但如果我们输入的是:
[email protected]\0
逻辑就变成了:
db_email = "[email protected]"
input_email = "[email protected]\0"
if len(q) is true: # 实际为 false
print("user already exists!") # 被跳过
else:
create a new account # 执行
也就是说:
👉 通过注入 Null Byte,绕过了数据库唯一性检查
👉 进入 else 分支创建新账户
👉 在写入数据库时,Null Byte 被剥离
👉 最终创建了一个真实的 [email protected] 账户
希望我解释清楚了。
回到目标应用的注册请求
注册表单是通过 JSON 提交的。
在 JSON 中,Null Byte 表示为:
\u0000
开始利用
然后……
我们成功注册进去了。
现在:
- 同一个邮箱
- 两个不同的密码
- 两个不同的账户
我迫不及待想看看: 👉 如果我用同一个邮箱登录,会发生什么?
结果非常有意思
- 用攻击者密码登录 → 成功
- 用受害者原密码登录 → 👀
返回了 404
提示:
“实体不存在(the entity does not exists)”
这说明:
👉 受害者账户被删除了 👉 攻击者账户在数据库中覆盖了它
密码重置:致命一击
普通用户遇到登录失败,第一反应一定是:
“我是不是忘记密码了?”
于是我用 受害者邮箱 发起了密码重置请求:
结果是:
- 受害者确实收到了重置邮件
- 但这个重置链接属于攻击者账户
- 受害者账户已经被彻底从数据库中移除
如果用户联系支持团队?
👉 他们也帮不了 👉 数据已经不存在 👉 除非他们有数据库备份
你以为我会停在这里吗?😈
我想到了:
如果攻击者针对的是公司员工账号呢? 比如:admin、support 等?
这些账号太容易猜了。
老实说,我没有真的测试这个场景 😂 因为如果我真的删了他们的管理员或支持账号,再报告这个漏洞—— 我可能不是拿奖金,而是去坐牢。
不过,我在报告中明确说明了所有可能的利用场景。
时间不允许了
我本来还想测试更多东西,但当时已经 11:30 了, 我只剩 30 分钟去考试。
希望你喜欢这个故事。
- 公众号:安全狗的自我修养
- vx:2207344074
- http://gitee.com/haidragon
- http://github.com/haidragon
- bilibili:haidragonx
#
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全狗的自我修养 haidragon《我是如何删除应用中任意我想要的用户账户的》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论