<input id="eiiko"></input>
<menu id="eiiko"><blockquote id="eiiko"></blockquote></menu>
  • <bdo id="eiiko"><samp id="eiiko"></samp></bdo>
  • Tar解压漏洞的验证方法及其临时修复方案

    2019-03-21 396202人围观 ,发现 10 个不明物体 漏洞

    *本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

    之前WinRAR出现的漏洞,没几天网上就出现了各种利用这种漏洞的攻击了,想到这,我突然想起来Linux下也有这么一款解压软件也是有漏洞的。今天给大家说一说吧 !

    我们在Linux下使用最多的压缩和解压工具就是tar了。如果说这款工具出现了漏洞,那么危害还是很大的。不过还真的出现了一个解压路径的漏洞:这个漏洞出现在tar解压命令上,如果恶意者提前构造好这种有害的压缩包。当我们在使用tar命令解压的时候导致压缩包解压到不是我们指定的目录下面,导致了文件覆盖,更有甚者进行远程的代码执行!

    影响范围

    GNU tar :1.14 ~1.29 (包含1.29)

    影响系统包括所以使用GNU tar命令的linux系统

    实验环境

    操作机 : Kali Linux

    实验工具

    tar-poc.tar :这个文件是本次漏洞试验的POC,我们将使用本文件验证漏洞

    tar-1.26.tar.gz :1.26版本的tar源码

    实验步骤

    步骤1:漏洞分析

    在实现漏洞复现之前我们得了解一下,这个漏洞的是什么原因导致的。那我们就得对源码进行分析,在进行源码的分析过程中发现了paxnames.c这个文件是有问题的,那我们废?#23433;?#22810;?#21040;?#20837;源码存放文件夹,盘它:

    cd /root/Desktop/ // 进入桌面

    cat tar-1.26/lib/paxnames.c // 预览paxnames.c文件

    在tar1.26的源码包中,lib文件夹下存放着函数库和一些配置文件,其中paxnames.c文件里面存放着检测文件名和路径安全性的相关函数和配置。就是检测程序考虑的不够完美导致了漏洞的出现。

    打开后,可以看到如下代码:

    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

     &quot;..&quot;, and leading slashes.  */

                 size_tprefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);

     

         for (p = file_name + prefix_len; *p; )

     {

             if (p[0] == '.' &amp;&amp; p[1] == '.' &amp;&amp;(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 (&amp;prefix_table[link_target],file_name,

         prefix_len, &amp;prefix))

        {

          static char const *const diagnostic[] =

          {

     N_(&quot;Removing leading `%s' from member names&quot;),

     N_(&quot;Removing leading `%s' from hard link targets&quot;)

          };

          WARN ((0, 0, _(diagnostic[link_target]), prefix));

        }

     }

       }

    在研究了一段时间之后发现,这?#26410;?#30721;里面有个safer_name_suffix函数,他的任务就是检测文件名是否合法,文件后缀是否合法。

    absolute_names 是一个变量,它用来获得文件的名称,如果absolute_names变?#35838;?,那么就将文件名中文件系统的前缀给去掉。

    在之前比较老的版本,如果压缩文件中存在 .. 字符串,系统会跳过不去处理这些文件。

    而在后来的版本中,safer_name_suffix不再跳过文件名中包含 ../ 字符串的恶意字符,强制?#22659;?#25152;有存在可能被恶意访问的字符,如 ../ ,把 ../ 之前的所有字符都?#22659;?#21482;会留下其后面的字符。

    使其与解压目标路径变?#19978;嘍月?#24452;,而压缩包中的内容就会覆盖恶意访问者指定的路径文件,漏洞就这样产生了。

    例如:test.tar压缩包中有一个文件夹,其文件?#26032;?#24452;?#26469;?#20026; etc/motd../etc/shadow ,然后在执行命令 tar -C / -xvf test.taretc/motd ,意思是将test.tar里面的内容解压到etc/motd目录下。

    但是在safer_name_suffix函数中经过一系列操作,已经将 ../ 之前的内容都去掉了,路径名只剩下 etc/shdow ,这时候, etc/shdow 就被覆盖了。

    步骤2:使用POC验证漏洞

    本步将使用POC验证漏洞.

    现在我们使用POC来验证漏洞,因为此POC是覆盖 etc/shadow ,所以我们首先先查看一下原始的shadow文件有什么内容。

    使用命令:

    cat /etc/shadow // 预览shadow文件的内容

    可以看到,里面记录了各个账户的?#27809;?#21517;、?#29992;?#36807;的密码、上次更改密码的日期等。

    接下来我们来解压POC,将他解压到 etc 目录下,使用命令:

    cd /root/Desktop

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

    其中,X的意思是从归档文件中?#22836;?#25991;件。v的意思是输出tar处理文件的信息到屏幕。f的意思是使用归档文件,一般情况下f这个选项是必选的。

    这时,再次查看 etc/shadow 文件,发现已经被替换。已经不是之前的内容。

    我们明明是解压到etc/motd的目录下,它却解压到etc的根目录下,覆盖了shadow文件,因此到这里,我们就成功的验证了漏洞。

    实验结果分析与总结

    漏洞修复

    自己琢磨了一段时间之后,发现在safer_name_suffix中添加判断,如果检测到 ../ 字符串,直接报错,然后退出程序,如下:

    --- lib/paxnames.c.orig    2016-04-06 00:04:47.314860045 +0300

    +++ lib/paxnames.c      2016-04-06 02:08:44.962297881 +0300

    @@ -18,6 +18,7 @@

    #include &lt;system.h&gt;

    #include &lt;hash.h&gt;

    #include &lt;paxlib.h&gt;

    +#include &lt;quotearg.h&gt;

    /* Hash tables of strings.  */

    @@ -114,7 +115,15 @@

         for (p = file_name + prefix_len; *p; )

           {

             if (p[0] == '.' &amp;&amp; p[1] == '.' &amp;&amp;(ISSLASH (p[2]) || !p[2]))

    -          prefix_len = p + 2 - file_name;

    +            {

    +            static char const *constdiagnostic[] =

    +            {

    +              N_(&quot;%s: Member namecontains '..'&quot;),

    +              N_(&quot;%s: Hard link targetcontains '..'&quot;)

    +            };

    +            FATAL_ERROR ((0, 0,_(diagnostic[link_target]),

    +                          quotearg_colon(file_name)));

    +          }

    这种方法的确可以修复漏洞,但还有一点不足,?#27809;?#22312;配置文件或者操作文件时,如果遇到 ../ 这种情况,到一半就强行停止下来,这样的话?#27809;?#20307;验度很差。

    *本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

    发表评论

    已有 10 条评论

    取消
    Loading...
    css.php 天津11选5开奖
    <input id="eiiko"></input>
    <menu id="eiiko"><blockquote id="eiiko"></blockquote></menu>
  • <bdo id="eiiko"><samp id="eiiko"></samp></bdo>
  • <input id="eiiko"></input>
    <menu id="eiiko"><blockquote id="eiiko"></blockquote></menu>
  • <bdo id="eiiko"><samp id="eiiko"></samp></bdo>