我是如何删除应用中任意我想要的用户账户的

admin 2026-01-13 14:43:48 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文描述了如何利用空字节注入绕过邮箱唯一性校验。攻击者在注册请求中添加空字符,使后端认为邮箱不同而放行,但实际存储时剥离空字符导致新账户覆盖原账户。这导致原用户无法登录,从而实现删除任意用户账户的效果。 综合评分: 85 文章分类: 渗透测试,WEB安全,漏洞分析


cover_image

我是如何删除应用中任意我想要的用户账户的

haidragon

安全狗的自我修养

2026年1月12日 16:22 湖南

官网:http://securitytech.cc/

#


嗨,

今天我将讲述我是如何发现一个漏洞,它允许我删除应用中任何我想删除的用户。这个想法本身很简单,但它的影响力一点都不简单 🙂

顺便说一句,我是在大学 DSP 期末考试前 5 个小时发现这个漏洞的(我真的恨 DSP -_-)。所以,是的,期末前的夜晚才是我的巅峰时刻(GOAT)。

我们的目标是 Bugcrowd 上的一个公开 BBP 项目,而且已经存在很长时间了。很多人总觉得在公开 BBP 上找漏洞很难,因为已经被很多黑客测试过了——我也同意这一点。但思维方式永远比环境更重要。 别完全听我的,也别一上来就去黑 Google 😂。

当你测试一个网站时,你必须从 三个角度 思考:

  1. 系统期望用户做什么,不期望用户做什么 —— 那如果我做了“不期望的事情”会怎样?关键永远是 what if…
  2. 尝试用一种“不应该发生的方式”去完成同一件事
  3. 先像普通用户一样理解目标,再像黑客一样理解它。你越了解它,就越容易破坏它。

给应用开发者多加点“任务”吧 😈

一开始,当我选择目标时,我总是优先测试高影响漏洞,而危害用户账户和数据永远排在最前面。

在测试应用的注册和登录功能时,我发现: 👉 注册后并不需要验证邮箱 这本身就是一个糟糕的实现。

我创建了一个新账号,然后退出登录,开始思考下一步我能做什么。

我想到的第一个问题是:

是否允许用同一个邮箱创建多个账户?

答案是:不允许

他们期望: 👉 一个邮箱只能注册一个账号

那么问题来了:

如果我找到一种方式,用同一个邮箱再创建一个账户呢?

当然,他们一定有防护机制来避免这种情况。但问题是:

如果这个“异常情况”真的发生了,他们是否正确处理了?


我们来看看怎么做到的

其实这种场景可以测试的技巧有很多。 我通常先从**响应篡改(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《我是如何删除应用中任意我想要的用户账户的》

Nu1LTeam×阿里CTF2026 网络安全文章

Nu1LTeam×阿里CTF2026

文章总结: 阿里CTF2026将于1月31日开赛,Nu1LTeam担任唯一技术支持并与阿里云共同打造。声明强调赛事公平,出题方不参赛,队内非出题成员可代表原单位
评论:0   参与:  0