开源验证码库导致的 jumpserver 账户接管漏洞

admin 2024年4月24日05:59:51评论3 views字数 2169阅读7分13秒阅读模式
 

前言

jumpserver 前不久出了一个密码重置漏洞 CVE-2023-42820

在当天我就复现了这个漏洞 这个随机数的案例非常有趣 这个漏洞出现在了一个很难想到的位置 是一个由第三方依赖库引起的问题

漏洞分析

验证码库中的一个问题

分析一下修复后的版本差异 发现了一个有趣的commit

生成随机字符串的时候增加重置了随机数种子的步骤

https://github.com/jumpserver/jumpserver/commit/ce645b1710c5821119f313e1b3d801470565aac0

开源验证码库导致的 jumpserver 账户接管漏洞

我原本以为这个漏洞可能是 攻击者可以收集到足够随机数导致伪随机数预测的问题

但是我发现了同commit账号下的这个给第三方验证码库django-simple-captcha的PR

https://github.com/mbi/django-simple-captcha/pull/221

在这个pr里同样也有一处设置种子的步骤

继续审计 发现了这个验证码库的奇葩逻辑

下面是我画的一张django-simple-captcha 库的流程图

开源验证码库导致的 jumpserver 账户接管漏洞

完整的的验证码流程有3个请求

  • 第一个请求 生成验证码

服务器会生成随机challenge 和一个随机字符串key 储存到数据库 把包含key的验证码url返回

  • 第二个请求 访问验证码url 获取 验证码图片/语音

服务器会将key 设置为随机数seed 之后根据key从数据库查找challenge 根据配置文件随机生成噪点和干扰线 渲染成验证码图片

  • 第三个请求 验证验证码

之后服务器会根据key从数据库查找challenge 进行eval后与提交的答案比较 返回比较结果

开源验证码库导致的 jumpserver 账户接管漏洞

在这里很容易看到一个不对劲的步骤

这个库居然把作为随机数seed 的key直接返回给用户 作为验证码的索引

开源验证码库导致的 jumpserver 账户接管漏洞

:::info/captcha/image/{key}/:::

也就是说访问一次验证码图片 当前进程的全局seed 就会被设置为key 同时我们也拿到了这个key

现在 我们就可以利用这个key预测之后生成的随机数

重置用户密码

现在我们可以控制随机数的生成 那么怎么利用这个特性呢?

jumpserver的密码重置功能默认是开启的

开源验证码库导致的 jumpserver 账户接管漏洞

jumpserver重置验证码时会向邮箱发送包含随机字符串验证码的一封邮件 (因为代码上的问题 没有正确配置邮件服务器时也能正常生成验证码)

在这里我们可以通过拿到的key预测这个验证码

构造EXP

在利用过程中 我们需要知道当设置种子后又生成了多少个随机数

分析验证码生成部分的代码 找到验证码生成的过程

开源验证码库导致的 jumpserver 账户接管漏洞

把随机数生成的部分抽出 之后放入之后的EXP中

开源验证码库导致的 jumpserver 账户接管漏洞

这里有几点需要注意

  • 在验证码字符的旋转过程 会导致随机数生成的次数变化 有一个随机数生成循环会随验证码的长度而变化
  • 因为jumpserver使用的验证码类型为数学计算验证码 所以生成的验证码位数在 4-5位
  • 另外出现在CAPTCHA_PUNCTUATION内的验证码字符不会当做单独的一个字符

开源验证码库导致的 jumpserver 账户接管漏洞

也就是说如果验证码为 5-1=时 5- 会被认为是一个字符

开源验证码库导致的 jumpserver 账户接管漏洞

所以 实际上循环范围应该是3-5

之后按照jumpserver中的实现生成验证码字符串

开源验证码库导致的 jumpserver 账户接管漏洞

成功重置了密码

开源验证码库导致的 jumpserver 账户接管漏洞

自动化EXP

手工利用这个漏洞还是有点麻烦 所以我们要实现一个自动化利用的exp

EXP暂时不公开

这里就交给读者自己实现EXP了 内容涉及CSRF 和 表单处理的内容 自己实现一遍应该会学到很多

下面给出一点点提示

自动化利用我们得绕过图片验证码

在重置密码的时候需要完成一个图片验证码

我们通过之前的漏洞来固定seed 时生成的图片验证码也可预测

(这一步中的随机数生成次数与之前的有些差异 通过调试分析代码可以简单解决)

最终 我实现了一个高成功率的自动化利用脚本 可以在3s内完成 包括图片验证码绕过的 自动密码重置脚本

开源验证码库导致的 jumpserver 账户接管漏洞

详细步骤:

  1. 进入重置密码流程
  2. 访问 /core/auth/password/forget/previewing/ 生成图片验证码url1
  3. 多次访问验证码url1 让seed污染大部分的 workers 提高成功概率 让seed固定
  4. 访问 /core/auth/password/forget/previewing/ 生成新图片验证码url2
  5. 根据seed 预测图片验证码 解决验证码
  6. 多次访问验证码url1 让seed污染大部分的 workers 提高成功概率 让seed固定
  7. 发送邮箱验证码
  8. 根据seed 预测验证码 尝试验证 获取重置链接
  9. 重置密码

漏洞修复

django-simple-captcha 发布了 0.5.19版本 通过重置种子 修复了这个问题

https://github.com/mbi/django-simple-captcha/blob/master/CHANGES

jumpserver >= v2.28.19, >= v3.6.5 临时修复了这个问题

https://github.com/jumpserver/jumpserver/security/advisories/GHSA-7prv-g565-82qp

django-simple-captcha vulnerability

本文作者:白帽酱永久链接:https://rce.moe/2023/10/03/jumpserver-CVE-2023-42820/版权声明:本文首发于白帽酱的博客,转载请注明出处!
 

原文始发于微信公众号(Ots安全):图片验证码引起的惨案 一个开源验证码库导致的 jumpserver 账户接管漏洞

 

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月24日05:59:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   开源验证码库导致的 jumpserver 账户接管漏洞http://cn-sec.com/archives/2084796.html

发表评论

匿名网友 填写信息