本仓库包含 2 个针对 CVE-2022-30600 的概念验证实现。
CVE-2022-30600 是一个安全漏洞,允许攻击者绕过 moodle webapp 中的账户锁定阈值。
根据 NVD 数据库中以下条目的概述 https://nvd.nist.gov/vuln/detail/CVE-2022-30600,以下版本已知容易受此漏洞影响。
3.9 - 3.9.13
3.10 - 3.10.10
3.11 - 3.11.6
如用于修补此漏洞的提交中所概述,问题在于访问和增加数据库中 login_failed_count 值所使用的逻辑。
如果发生超过 1 个并发登录请求,那么 moodle webapp 可能无法正确检查和更新应用程序内的登录值。这导致 2 次或更多登录失败仅被计为 1 次登录失败。
为了更好地理解这一点,下图是从客户端、webapp 和数据库角度对失败登录请求的高级分解。
sequenceDiagram
participant C as Client
participant W as Webapp
participant D as Database
C->>W: Login Request
W->>D: Requests failed_login_attempt
D->>W: failed_login_attempt = 0
W->>W: local failed_login_attempt = 0
W->>W: local failed_login_attempt = 1
W->>D: failed_login_attempt = 1
W->>C: Login Failed结果是数据库中的 failed_login_attempt 值是正确的,后续的登录尝试将正确更新该值。
如果攻击者发送多个并发登录请求,则会出现以下问题。
sequenceDiagram
participant C as Client
participant W as Webapp
participant D as Database
C->>W: Login Request (session 1)
C->>W: Login Request (session 2)
W->>D: Requests failed_login_attempt (session 1)
W->>D: Requests failed_login_attempt (session 2)
D->>W: failed_login_attempt = 0 (session 1)
D->>W: failed_login_attempt = 0 (session 2)
W->>W: local failed_login_attempt = 0 (session 1)
W->>W: local failed_login_attempt = 0 (session 2)
W->>W: local failed_login_attempt = 1 (session 1)
W->>W: local failed_login_attempt = 1 (session 2)
W->>D: failed_login_attempt = 1 (session 1)
W->>D: failed_login_attempt = 1 (session 2)
W->>C: Login Failed (session 1)
W->>C: Login Failed (session 2)此交互的结果是,尽管发生了 2 次失败的登录请求,但数据库中的 failed_login_attempt 值仅增加了 1。这可以扩展到数百个请求,其限制是客户端可以发出的并发请求数以及 Web 服务器可以同时处理的请求数。
此外,如果攻击者可以访问多个客户端(例如僵尸网络),并且能够同步发出这些请求的时间,那么攻击者可以克服使用单个客户端的限制,使得攻击更难以缓解。
poc.py 是此攻击的 Python3 实现。它使用线程来执行并发请求。虽然此概念验证有效,但 Python3 中存在的全局解释器锁会在此情况下削弱使用多线程的好处。我强烈建议使用 C++ 实现,因为在单个客户端上执行攻击时它的效果更好。
poc.py [-h] -u USERNAME -url TARGET -w WORDLIST -t THREADS [-a ATTEMPTS] [-d DELAY]
options:
-h, --help
显示此帮助信息
-u USERNAME, --username USERNAME
目标账户的用户名
-url TARGET, --target TARGET
目标 moodle webapp 的基础 URL
-w WORDLIST, --wordlist WORDLIST
使用的字典文件路径
-t THREADS, --threads THREADS
每次尝试创建的线程数
-a ATTEMPTS, --attempts ATTEMPTS
您希望进行的尝试次数。默认为 1
-d DELAY, --delay DELAY
每次尝试之间的秒数。默认值为 2
python3 poc.py -u admin -url https://moodle/ -w /usr/share/wordlists/rockyou.txt -t 15 -a 8
目标:https://moodle/
账户用户名:admin
字典:/usr/share/wordlists/rockyou.txt
线程:每次尝试将发出 15 个登录请求
尝试次数:攻击将重复 8 次。
在此示例中,总共将发出 120(8 * 15)个登录请求。每次尝试之间将有 2 秒的延迟。
poc.cpp 是此攻击的 C++ 实现,它使用 curl 库来执行攻击。因此,它需要一些编译器标志才能编译。总体而言,此实现比 Python3 版本功能更好,因为线程能够使用客户端设备的所有核心,在更短的时间内允许更多的并发连接。这意味着利用能够更一致地工作。
g++ poc.cpp -o poc -lcurl
用法:
poc [OPTION...]
-a, --attempts
执行攻击的次数。
-t, --threads
每次尝试使用的线程数。
-n, --username
目标账户的用户
-u, --URL
moodle webapp 的基础 URL
-d, --delay
尝试之间的时间延迟。默认为 5
-v, --version
显示版本
-h, --help
显示帮助信息
-w, --wordlist arg
密码字典。
./poc -w /usr/share/wordlists/rockyou.txt -u https://moodle/ -n admin -a 3 -t 5 -d 2
字典:/usr/share/wordlists/rockyou.txt
URL:https://moodle/
账户用户名:admin
尝试次数:将进行 3 次尝试
线程:每次尝试将使用 5 个线程
延迟:每次尝试之间将有 2 秒延迟
为了开发、测试和调试这些脚本,我创建了一台虚拟机。该虚拟机使用了以下软件和版本。
Moodle 3.9.0 PHP 7.2.34 MySQL 8.0.30 Ubuntu 5.15.0-41-generic Apache 2.4.52
我不支持将我的源代码用于非法活动。