librex 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -1
- data/Rakefile +13 -0
- data/lib/rex.rb +4 -1
- data/lib/rex/assembly/nasm.rb +4 -0
- data/lib/rex/compat.rb +31 -1
- data/lib/rex/encoder/alpha2/generic.rb +11 -10
- data/lib/rex/exceptions.rb +1 -1
- data/lib/rex/exploitation/egghunter.rb +27 -0
- data/lib/rex/file.rb +13 -0
- data/lib/rex/io/stream.rb +9 -1
- data/lib/rex/io/stream_abstraction.rb +18 -7
- data/lib/rex/io/stream_server.rb +2 -2
- data/lib/rex/job_container.rb +1 -1
- data/lib/rex/mime/message.rb +5 -4
- data/lib/rex/ole.rb +83 -6
- data/lib/rex/ole/propset.rb +144 -0
- data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
- data/lib/rex/parser/ip360_xml.rb +93 -0
- data/lib/rex/parser/nessus_xml.rb +118 -0
- data/lib/rex/parser/netsparker_xml.rb +94 -0
- data/lib/rex/parser/retina_xml.rb +109 -0
- data/lib/rex/post/meterpreter/channel.rb +15 -8
- data/lib/rex/post/meterpreter/client.rb +32 -3
- data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +14 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +5 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +16 -8
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -7
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +15 -4
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +13 -7
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +20 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +18 -7
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +10 -17
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +16 -6
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +4 -5
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +2 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +4 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
- data/lib/rex/proto/dhcp/server.rb +8 -4
- data/lib/rex/proto/http/client.rb +19 -45
- data/lib/rex/proto/http/packet.rb +8 -5
- data/lib/rex/proto/http/response.rb +8 -3
- data/lib/rex/proto/http/server.rb +1 -1
- data/lib/rex/proto/proxy/socks4a.rb +4 -4
- data/lib/rex/proto/rfb.rb +19 -0
- data/lib/rex/proto/rfb.rb.ut.rb +37 -0
- data/lib/rex/proto/rfb/cipher.rb +78 -0
- data/lib/rex/proto/rfb/client.rb +207 -0
- data/lib/rex/proto/rfb/constants.rb +52 -0
- data/lib/rex/proto/tftp/server.rb +20 -17
- data/lib/rex/services/local_relay.rb +1 -1
- data/lib/rex/socket.rb +69 -10
- data/lib/rex/socket/comm/local.rb +7 -4
- data/lib/rex/socket/range_walker.rb +14 -1
- data/lib/rex/text.rb +28 -3
- data/lib/rex/text.rb.ut.rb +14 -0
- data/lib/rex/thread_factory.rb +42 -0
- data/lib/rex/ui/text/input/buffer.rb +1 -1
- data/lib/rex/zip/archive.rb +74 -9
- data/lib/rex/zip/entry.rb +6 -1
- metadata +22 -7
@@ -0,0 +1,94 @@
|
|
1
|
+
module Rex
|
2
|
+
module Parser
|
3
|
+
|
4
|
+
|
5
|
+
class NetSparkerXMLStreamParser
|
6
|
+
|
7
|
+
attr_accessor :on_found_vuln
|
8
|
+
|
9
|
+
def initialize(on_found_vuln = nil)
|
10
|
+
self.on_found_vuln = on_found_vuln if on_found_vuln
|
11
|
+
reset_state
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset_state
|
15
|
+
@state = :generic_state
|
16
|
+
@vuln = {'info' => []}
|
17
|
+
@attr = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def tag_start(name, attributes)
|
21
|
+
@state = "in_#{name.downcase}".intern
|
22
|
+
@attr = attributes
|
23
|
+
|
24
|
+
case name
|
25
|
+
when "vulnerability"
|
26
|
+
@vuln['confirmed'] = attributes['confirmed']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def text(str)
|
31
|
+
case @state
|
32
|
+
when :in_url
|
33
|
+
@vuln['url'] ||= ""
|
34
|
+
@vuln['url'] += str
|
35
|
+
when :in_type
|
36
|
+
@vuln['type'] ||= ""
|
37
|
+
@vuln['type'] += str
|
38
|
+
when :in_severity
|
39
|
+
@vuln['severity'] ||= ""
|
40
|
+
@vuln['severity'] += str
|
41
|
+
when :in_vulnerableparametertype
|
42
|
+
@vuln["vparam_type"] ||= ""
|
43
|
+
@vuln["vparam_type"] += str
|
44
|
+
when :in_vulnerableparameter
|
45
|
+
@vuln["vparam_name"] ||= ""
|
46
|
+
@vuln["vparam_name"] += str
|
47
|
+
when :in_vulnerableparametervalue
|
48
|
+
@vuln["vparam_value"] ||= ""
|
49
|
+
@vuln["vparam_value"] += str
|
50
|
+
when :in_rawrequest
|
51
|
+
@vuln["request"] ||= ""
|
52
|
+
@vuln["request"] += str
|
53
|
+
when :in_rawresponse
|
54
|
+
@vuln["response"] ||= ""
|
55
|
+
@vuln["response"] += str
|
56
|
+
when :in_info
|
57
|
+
# <info name="Identified Internal Path(s)">C:\AppServ\www\test-apps\dokeos\main\inc\banner.inc.php</info>
|
58
|
+
if not str.to_s.strip.empty?
|
59
|
+
@vuln['info'] << [@attr['name'] || "Information", str]
|
60
|
+
end
|
61
|
+
when :in_netsparker
|
62
|
+
when :in_target
|
63
|
+
when :in_scantime
|
64
|
+
when :generic_state
|
65
|
+
when :in_vulnerability
|
66
|
+
when :in_extrainformation
|
67
|
+
else
|
68
|
+
# $stderr.puts "unknown state: #{@state}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def tag_end(name)
|
73
|
+
case name
|
74
|
+
when "vulnerability"
|
75
|
+
@vuln.keys.each do |k|
|
76
|
+
@vuln[k] = @vuln[k].strip if @vuln[k].kind_of?(::String)
|
77
|
+
end
|
78
|
+
on_found_vuln.call(@vuln) if on_found_vuln
|
79
|
+
reset_state
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# We don't need these methods, but they're necessary to keep REXML happy
|
84
|
+
def xmldecl(version, encoding, standalone); end
|
85
|
+
def cdata; end
|
86
|
+
def comment(str); end
|
87
|
+
def instruction(name, instruction); end
|
88
|
+
def attlist; end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
__END__
|
94
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Rex
|
2
|
+
module Parser
|
3
|
+
|
4
|
+
# XXX - Retina XML does not include ANY service/port information export
|
5
|
+
class RetinaXMLStreamParser
|
6
|
+
|
7
|
+
attr_accessor :on_found_host
|
8
|
+
|
9
|
+
def initialize(on_found_host = nil)
|
10
|
+
reset_state
|
11
|
+
self.on_found_host = on_found_host if on_found_host
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset_state
|
15
|
+
@state = :generic_state
|
16
|
+
@host = { 'vulns' => [] }
|
17
|
+
reset_audit_state
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset_audit_state
|
21
|
+
@audit = { 'refs' => [] }
|
22
|
+
end
|
23
|
+
|
24
|
+
def tag_start(name, attributes)
|
25
|
+
@state = "in_#{name.downcase}".intern
|
26
|
+
end
|
27
|
+
|
28
|
+
def text(str)
|
29
|
+
case @state
|
30
|
+
when :in_ip
|
31
|
+
@host["address"] = str
|
32
|
+
when :in_dnsname
|
33
|
+
@host["hostname"] = str.split(/\s+/).first
|
34
|
+
when :in_netbiosname
|
35
|
+
@host["netbios"] = str
|
36
|
+
when :in_mac
|
37
|
+
@host["mac"] = str
|
38
|
+
when :in_os
|
39
|
+
@host["os"] = str
|
40
|
+
when :in_rthid
|
41
|
+
@audit['refs'].push(['RETINA', str])
|
42
|
+
when :in_cve
|
43
|
+
str.split(",").each do |cve|
|
44
|
+
cve = cve.to_s.strip
|
45
|
+
next if cve.empty?
|
46
|
+
pre,val = cve.split('-', 2)
|
47
|
+
next if not val
|
48
|
+
next if pre != "CVE"
|
49
|
+
@audit['refs'].push( ['CVE', val] )
|
50
|
+
end
|
51
|
+
when :in_name
|
52
|
+
@audit['name'] = str
|
53
|
+
when :in_description
|
54
|
+
@audit['description'] = str
|
55
|
+
when :in_risk
|
56
|
+
@audit['risk'] = str
|
57
|
+
when :in_cce
|
58
|
+
@audit['cce'] = str
|
59
|
+
when :in_date
|
60
|
+
@audit['data'] = str
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def tag_end(name)
|
65
|
+
case name
|
66
|
+
when "host"
|
67
|
+
on_found_host.call(@host) if on_found_host
|
68
|
+
reset_state
|
69
|
+
when "audit"
|
70
|
+
@host['vulns'].push @audit
|
71
|
+
reset_audit_state
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# We don't need these methods, but they're necessary to keep REXML happy
|
76
|
+
def xmldecl(version, encoding, standalone); end
|
77
|
+
def cdata; end
|
78
|
+
def comment(str); end
|
79
|
+
def instruction(name, instruction); end
|
80
|
+
def attlist; end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
__END__
|
86
|
+
<scanJob>
|
87
|
+
<hosts>
|
88
|
+
<host>
|
89
|
+
<ip>10.2.79.98</ip>
|
90
|
+
<netBIOSName>bsmith-10156B07C</netBIOSName>
|
91
|
+
<dnsName>bsmith-10156b07c.core.testcorp.com random.testcorp.com</dnsName>
|
92
|
+
<mac>00:02:29:0E:38:2B</mac>
|
93
|
+
<os>Windows Server 2003 (X64), Service Pack 2</os>
|
94
|
+
<audit>
|
95
|
+
<rthID>7851</rthID>
|
96
|
+
<cve>CVE-2009-0089,CVE-2009-0550,CVE-2009-0086</cve>
|
97
|
+
<cce>N/A</cce>
|
98
|
+
<name>Microsoft Windows HTTP Services Multiple Vulnerabilities (960803)</name>
|
99
|
+
<description>Microsoft Windows HTTP Services contains multiple vulnerabilities when handling ..</description>
|
100
|
+
<date>09/15/2010</date>
|
101
|
+
<risk>Low</risk>
|
102
|
+
<pciLevel>5 (Urgent)</pciLevel>
|
103
|
+
<cvssScore>10 [AV:N/AC:L/Au:N/C:C/I:C/A:C]</cvssScore>
|
104
|
+
<fixInformation>....</fixInformation>
|
105
|
+
</audit>
|
106
|
+
</host>
|
107
|
+
</hosts>
|
108
|
+
</scanJob>
|
109
|
+
|
@@ -141,6 +141,11 @@ class Channel
|
|
141
141
|
if (cid and client)
|
142
142
|
client.add_channel(self)
|
143
143
|
end
|
144
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.cid) )
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.finalize(client,cid)
|
148
|
+
proc { self._close(client,cid) }
|
144
149
|
end
|
145
150
|
|
146
151
|
##
|
@@ -262,27 +267,29 @@ class Channel
|
|
262
267
|
#
|
263
268
|
# Closes the channel.
|
264
269
|
#
|
265
|
-
def _close(addends
|
266
|
-
if (
|
270
|
+
def self._close(client, cid, addends=nil)
|
271
|
+
if (cid == nil)
|
267
272
|
raise IOError, "Channel has been closed.", caller
|
268
273
|
end
|
269
274
|
|
270
275
|
request = Packet.create_request('core_channel_close')
|
271
276
|
|
272
277
|
# Populate the request
|
273
|
-
request.add_tlv(TLV_TYPE_CHANNEL_ID,
|
278
|
+
request.add_tlv(TLV_TYPE_CHANNEL_ID, cid)
|
274
279
|
request.add_tlvs(addends)
|
275
280
|
|
276
|
-
|
281
|
+
client.send_request(request, nil)
|
277
282
|
|
278
283
|
# Disassociate this channel instance
|
279
|
-
|
280
|
-
|
281
|
-
self.cid = nil
|
284
|
+
client.remove_channel(cid)
|
282
285
|
|
283
286
|
return true
|
284
287
|
end
|
285
|
-
|
288
|
+
|
289
|
+
def _close(addends = nil)
|
290
|
+
self.class._close(self.client, self.cid, addends)
|
291
|
+
self.cid = nil
|
292
|
+
end
|
286
293
|
#
|
287
294
|
# Enables or disables interactive mode.
|
288
295
|
#
|
@@ -41,6 +41,23 @@ class Client
|
|
41
41
|
#
|
42
42
|
@@ext_hash = {}
|
43
43
|
|
44
|
+
#
|
45
|
+
# Cached SSL certificate (required to scale)
|
46
|
+
#
|
47
|
+
@@ssl_ctx = nil
|
48
|
+
|
49
|
+
#
|
50
|
+
# Mutex to synchronize class-wide operations
|
51
|
+
#
|
52
|
+
@@ssl_mutex = ::Mutex.new
|
53
|
+
|
54
|
+
#
|
55
|
+
# Lookup the error that occurred
|
56
|
+
#
|
57
|
+
def self.lookup_error(code)
|
58
|
+
code
|
59
|
+
end
|
60
|
+
|
44
61
|
#
|
45
62
|
# Checks the extension hash to see if a class has already been associated
|
46
63
|
# with the supplied extension name.
|
@@ -133,6 +150,11 @@ class Client
|
|
133
150
|
end
|
134
151
|
|
135
152
|
def generate_ssl_context
|
153
|
+
@@ssl_mutex.synchronize do
|
154
|
+
if not @@ssl_ctx
|
155
|
+
|
156
|
+
wlog("Generating SSL certificate for Meterpreter sessions")
|
157
|
+
|
136
158
|
key = OpenSSL::PKey::RSA.new(1024){ }
|
137
159
|
cert = OpenSSL::X509::Certificate.new
|
138
160
|
cert.version = 2
|
@@ -175,7 +197,14 @@ class Client
|
|
175
197
|
|
176
198
|
ctx.session_id_context = Rex::Text.rand_text(16)
|
177
199
|
|
178
|
-
|
200
|
+
wlog("Generated SSL certificate for Meterpreter sessions")
|
201
|
+
|
202
|
+
@@ssl_ctx = ctx
|
203
|
+
|
204
|
+
end # End of if not @ssl_ctx
|
205
|
+
end # End of mutex.synchronize
|
206
|
+
|
207
|
+
@@ssl_ctx
|
179
208
|
end
|
180
209
|
|
181
210
|
#
|
@@ -197,7 +226,7 @@ class Client
|
|
197
226
|
# waiting for a response.
|
198
227
|
#
|
199
228
|
def Client.default_timeout
|
200
|
-
return
|
229
|
+
return 300
|
201
230
|
end
|
202
231
|
|
203
232
|
##
|
@@ -233,7 +262,7 @@ class Client
|
|
233
262
|
|
234
263
|
# No new constants added?
|
235
264
|
if ((diff = new - old).empty?)
|
236
|
-
|
265
|
+
diff = [ name.capitalize ]
|
237
266
|
end
|
238
267
|
|
239
268
|
klass = Rex::Post::Meterpreter::Extensions.const_get(diff[0]).const_get(diff[0])
|
@@ -51,7 +51,7 @@ class Sniffer < Extension
|
|
51
51
|
request = Packet.create_request('sniffer_capture_start')
|
52
52
|
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
53
53
|
request.add_tlv(TLV_TYPE_SNIFFER_PACKET_COUNT, maxp.to_i)
|
54
|
-
request.add_tlv(TLV_TYPE_SNIFFER_ADDITIONAL_FILTER, filter) if filter.length
|
54
|
+
request.add_tlv(TLV_TYPE_SNIFFER_ADDITIONAL_FILTER, filter) if filter.length > 0
|
55
55
|
response = client.send_request(request)
|
56
56
|
end
|
57
57
|
|
@@ -18,7 +18,7 @@ module Fs
|
|
18
18
|
###
|
19
19
|
class Dir < Rex::Post::Dir
|
20
20
|
|
21
|
-
class <<self
|
21
|
+
class << self
|
22
22
|
attr_accessor :client
|
23
23
|
end
|
24
24
|
|
@@ -192,7 +192,7 @@ class Dir < Rex::Post::Dir
|
|
192
192
|
# Downloads the contents of a remote directory a
|
193
193
|
# local directory, optionally in a recursive fashion.
|
194
194
|
#
|
195
|
-
def Dir.download(dst, src, recursive = false, &stat)
|
195
|
+
def Dir.download(dst, src, recursive = false, force = true, &stat)
|
196
196
|
self.entries(src).each { |src_sub|
|
197
197
|
dst_item = dst + ::File::SEPARATOR + src_sub
|
198
198
|
src_item = src + File::SEPARATOR + src_sub
|
@@ -205,8 +205,17 @@ class Dir < Rex::Post::Dir
|
|
205
205
|
|
206
206
|
if (src_stat.file?)
|
207
207
|
stat.call('downloading', src_item, dst_item) if (stat)
|
208
|
-
|
209
|
-
|
208
|
+
begin
|
209
|
+
client.fs.file.download(dst_item, src_item)
|
210
|
+
stat.call('downloaded', src_item, dst_item) if (stat)
|
211
|
+
rescue ::Rex::Post::Meterpreter::RequestError => e
|
212
|
+
if force
|
213
|
+
stat.call('failed', src_item, dst_item) if (stat)
|
214
|
+
else
|
215
|
+
raise e
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
210
219
|
elsif (src_stat.directory?)
|
211
220
|
if (recursive == false)
|
212
221
|
next
|
@@ -218,7 +227,7 @@ class Dir < Rex::Post::Dir
|
|
218
227
|
end
|
219
228
|
|
220
229
|
stat.call('mirroring', src_item, dst_item) if (stat)
|
221
|
-
download(dst_item, src_item, recursive, &stat)
|
230
|
+
download(dst_item, src_item, recursive, force, &stat)
|
222
231
|
stat.call('mirrored', src_item, dst_item) if (stat)
|
223
232
|
end
|
224
233
|
}
|
@@ -84,7 +84,7 @@ class Socket
|
|
84
84
|
begin
|
85
85
|
return SocketSubsystem::TcpServerChannel.open(client, params)
|
86
86
|
rescue ::Rex::Post::Meterpreter::RequestError => e
|
87
|
-
case e.
|
87
|
+
case e.code
|
88
88
|
when 10000 .. 10100
|
89
89
|
raise ::Rex::ConnectionError.new
|
90
90
|
end
|
@@ -103,7 +103,7 @@ class Socket
|
|
103
103
|
end
|
104
104
|
return nil
|
105
105
|
rescue ::Rex::Post::Meterpreter::RequestError => e
|
106
|
-
case e.
|
106
|
+
case e.code
|
107
107
|
when 10000 .. 10100
|
108
108
|
raise ::Rex::ConnectionError.new
|
109
109
|
end
|
@@ -118,7 +118,7 @@ class Socket
|
|
118
118
|
begin
|
119
119
|
return SocketSubsystem::UdpChannel.open(client, params)
|
120
120
|
rescue ::Rex::Post::Meterpreter::RequestError => e
|
121
|
-
case e.
|
121
|
+
case e.code
|
122
122
|
when 10000 .. 10100
|
123
123
|
raise ::Rex::ConnectionError.new
|
124
124
|
end
|
@@ -16,6 +16,7 @@ require 'rex/post/meterpreter/extensions/stdapi/sys/event_log'
|
|
16
16
|
require 'rex/post/meterpreter/extensions/stdapi/sys/power'
|
17
17
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/railgun'
|
18
18
|
require 'rex/post/meterpreter/extensions/stdapi/ui'
|
19
|
+
require 'rex/post/meterpreter/extensions/stdapi/webcam/webcam'
|
19
20
|
|
20
21
|
module Rex
|
21
22
|
module Post
|
@@ -74,6 +75,10 @@ class Stdapi < Extension
|
|
74
75
|
'name' => 'railgun',
|
75
76
|
'ext' => Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun.new(client)
|
76
77
|
},
|
78
|
+
{
|
79
|
+
'name' => 'webcam',
|
80
|
+
'ext' => Rex::Post::Meterpreter::Extensions::Stdapi::Webcam::Webcam.new(client)
|
81
|
+
},
|
77
82
|
{
|
78
83
|
'name' => 'ui',
|
79
84
|
'ext' => UI.new(client)
|