librex 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -0
- data/lib/rex/exploitation/cmdstager.rb +9 -133
- data/lib/rex/exploitation/cmdstager/base.rb +170 -0
- data/lib/rex/exploitation/cmdstager/debug_asm.rb +142 -0
- data/lib/rex/exploitation/cmdstager/debug_write.rb +136 -0
- data/lib/rex/exploitation/cmdstager/tftp.rb +63 -0
- data/lib/rex/exploitation/cmdstager/vbs.rb +128 -0
- data/lib/rex/io/stream.rb +2 -2
- data/lib/rex/io/stream_server.rb +1 -1
- data/lib/rex/job_container.rb +7 -6
- data/lib/rex/mime/header.rb +12 -10
- data/lib/rex/mime/message.rb +57 -26
- data/lib/rex/ole/directory.rb +5 -4
- data/lib/rex/ole/samples/create_ole.rb +0 -0
- data/lib/rex/ole/samples/dir.rb +0 -0
- data/lib/rex/ole/samples/dump_stream.rb +1 -1
- data/lib/rex/ole/samples/ole_info.rb +0 -0
- data/lib/rex/parser/nexpose_xml.rb +131 -0
- data/lib/rex/parser/nmap_xml.rb +1 -0
- data/lib/rex/peparsey/pe.rb +21 -3
- data/lib/rex/post/meterpreter/client.rb +6 -1
- data/lib/rex/post/meterpreter/client_core.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +19 -18
- data/lib/rex/post/meterpreter/packet.rb +68 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +2 -2
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +5 -5
- data/lib/rex/post/meterpreter/ui/console.rb +2 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +5 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +2 -2
- data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -0
- data/lib/rex/proto/http/client.rb +8 -3
- data/lib/rex/proto/http/packet.rb +11 -1
- data/lib/rex/proto/smb/client.rb +1 -1
- data/lib/rex/proto/smb/utils.rb +72 -24
- data/lib/rex/proto/tftp.rb +3 -0
- data/lib/rex/proto/tftp/constants.rb +37 -0
- data/lib/rex/proto/tftp/server.rb +249 -0
- data/lib/rex/proto/tftp/server.rb.ut.rb +28 -0
- data/lib/rex/script/meterpreter.rb +6 -0
- data/lib/rex/services/local_relay.rb +2 -2
- data/lib/rex/socket/ip.rb +9 -8
- data/lib/rex/socket/range_walker.rb +43 -5
- data/lib/rex/socket/udp.rb +11 -4
- data/lib/rex/text.rb +42 -19
- data/lib/rex/ui/interactive.rb +24 -22
- data/lib/rex/ui/text/irb_shell.rb +4 -2
- data/lib/rex/ui/text/output/file.rb +6 -0
- data/lib/rex/ui/text/shell.rb +14 -18
- data/lib/rex/zip/samples/comment.rb +0 -0
- data/lib/rex/zip/samples/mkwar.rb +0 -0
- data/lib/rex/zip/samples/mkzip.rb +0 -0
- data/lib/rex/zip/samples/recursive.rb +0 -0
- metadata +20 -5
data/lib/rex/mime/message.rb
CHANGED
@@ -4,47 +4,72 @@ class Message
|
|
4
4
|
|
5
5
|
require 'rex/mime/header'
|
6
6
|
require 'rex/mime/part'
|
7
|
-
require 'rex/text'
|
7
|
+
require 'rex/text'
|
8
8
|
|
9
9
|
attr_accessor :header, :parts, :bound, :content
|
10
10
|
|
11
|
-
def initialize
|
11
|
+
def initialize(data=nil)
|
12
12
|
self.header = Rex::MIME::Header.new
|
13
13
|
self.parts = []
|
14
14
|
self.bound = "_Part_#{rand(1024)}_#{rand(0xffffffff)}_#{rand(0xffffffff)}"
|
15
15
|
self.content = ''
|
16
|
+
if data
|
17
|
+
head,body = data.split(/\r?\n\r?\n/, 2)
|
18
|
+
|
19
|
+
self.header.parse(head)
|
20
|
+
ctype = self.header.find('Content-Type')
|
21
|
+
|
22
|
+
if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary=([^\s]+)/
|
23
|
+
self.bound = $1
|
24
|
+
|
25
|
+
chunks = body.to_s.split(/--#{self.bound}(--)?\r?\n/)
|
26
|
+
self.content = chunks.shift.to_s.gsub(/\s+$/, '')
|
27
|
+
self.content << "\r\n" if not self.content.empty?
|
28
|
+
|
29
|
+
chunks.each do |chunk|
|
30
|
+
break if chunk == "--"
|
31
|
+
head,body = chunk.split(/\r?\n\r?\n/, 2)
|
32
|
+
part = Rex::MIME::Part.new
|
33
|
+
part.header.parse(head)
|
34
|
+
part.content = body.gsub(/\s+$/, '')
|
35
|
+
self.parts << part
|
36
|
+
end
|
37
|
+
else
|
38
|
+
self.content = body.to_s.gsub(/\s+$/, '') + "\r\n"
|
39
|
+
end
|
40
|
+
end
|
16
41
|
end
|
17
42
|
|
18
43
|
def to
|
19
44
|
(self.header.find('To') || [nil, nil])[1]
|
20
45
|
end
|
21
|
-
|
46
|
+
|
22
47
|
def to=(val)
|
23
48
|
self.header.set("To", val)
|
24
49
|
end
|
25
|
-
|
50
|
+
|
26
51
|
def from=(val)
|
27
|
-
self.header.set("From", val)
|
52
|
+
self.header.set("From", val)
|
28
53
|
end
|
29
|
-
|
54
|
+
|
30
55
|
def from
|
31
56
|
(self.header.find('From') || [nil, nil])[1]
|
32
57
|
end
|
33
|
-
|
58
|
+
|
34
59
|
def subject=(val)
|
35
|
-
self.header.set("Subject", val)
|
60
|
+
self.header.set("Subject", val)
|
36
61
|
end
|
37
|
-
|
62
|
+
|
38
63
|
def subject
|
39
64
|
(self.header.find('Subject') || [nil, nil])[1]
|
40
65
|
end
|
41
|
-
|
66
|
+
|
42
67
|
def mime_defaults
|
43
68
|
self.header.set("MIME-Version", "1.0")
|
44
69
|
self.header.set("Content-Type", "multipart/mixed; boundary=\"#{self.bound}\"")
|
45
70
|
self.header.set("Subject", '') # placeholder
|
46
71
|
self.header.set("Date", Time.now.strftime("%a,%e %b %Y %H:%M:%S %z"))
|
47
|
-
self.header.set("Message-ID",
|
72
|
+
self.header.set("Message-ID",
|
48
73
|
"<"+
|
49
74
|
Rex::Text.rand_text_alphanumeric(rand(20)+40)+
|
50
75
|
"@"+
|
@@ -55,24 +80,24 @@ class Message
|
|
55
80
|
self.header.set("To", '') # placeholder
|
56
81
|
end
|
57
82
|
|
58
|
-
|
83
|
+
|
59
84
|
def add_part(data='', content_type='text/plain', transfer_encoding="8bit", content_disposition=nil)
|
60
85
|
part = Rex::MIME::Part.new
|
61
86
|
part.header.set("Content-Type", content_type)
|
62
|
-
|
87
|
+
|
63
88
|
if (transfer_encoding)
|
64
89
|
part.header.set("Content-Transfer-Encoding", transfer_encoding)
|
65
90
|
end
|
66
|
-
|
91
|
+
|
67
92
|
if (content_disposition)
|
68
93
|
part.header.set("Content-Disposition", content_disposition)
|
69
94
|
end
|
70
|
-
|
95
|
+
|
71
96
|
part.content = data
|
72
97
|
self.parts << part
|
73
98
|
part
|
74
99
|
end
|
75
|
-
|
100
|
+
|
76
101
|
def add_part_attachment(data, name)
|
77
102
|
self.add_part(
|
78
103
|
Rex::Text.encode_base64(data, "\r\n"),
|
@@ -81,7 +106,7 @@ class Message
|
|
81
106
|
"attachment; filename=\"#{name}\""
|
82
107
|
)
|
83
108
|
end
|
84
|
-
|
109
|
+
|
85
110
|
|
86
111
|
def add_part_inline_attachment(data, name)
|
87
112
|
self.add_part(
|
@@ -91,22 +116,28 @@ class Message
|
|
91
116
|
"inline; filename=\"#{name}\""
|
92
117
|
)
|
93
118
|
end
|
94
|
-
|
119
|
+
|
95
120
|
def to_s
|
96
121
|
msg = self.header.to_s + "\r\n"
|
97
|
-
|
98
|
-
|
99
|
-
|
122
|
+
|
123
|
+
if self.content and not self.content.empty?
|
124
|
+
msg << self.content + "\r\n"
|
125
|
+
end
|
126
|
+
|
100
127
|
self.parts.each do |part|
|
101
128
|
msg << "--" + self.bound + "\r\n"
|
102
|
-
msg << part.to_s
|
129
|
+
msg << part.to_s + "\r\n"
|
130
|
+
end
|
131
|
+
|
132
|
+
if self.parts.length > 0
|
133
|
+
msg << "--" + self.bound + "--\r\n"
|
103
134
|
end
|
104
135
|
|
105
|
-
|
106
|
-
|
107
|
-
msg
|
136
|
+
# Force CRLF for SMTP compatibility
|
137
|
+
msg.gsub("\r", '').gsub("\n", "\r\n")
|
108
138
|
end
|
109
139
|
|
110
140
|
end
|
111
141
|
end
|
112
|
-
end
|
142
|
+
end
|
143
|
+
|
data/lib/rex/ole/directory.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
##
|
2
|
-
# $Id: directory.rb
|
3
|
-
# Version: $Revision:
|
2
|
+
# $Id: directory.rb 9287 2010-05-12 05:33:35Z jduck $
|
3
|
+
# Version: $Revision: 9287 $
|
4
4
|
##
|
5
5
|
|
6
6
|
##
|
@@ -51,7 +51,6 @@ class Directory < DirEntry
|
|
51
51
|
child.sid = @num_entries
|
52
52
|
@num_entries += 1
|
53
53
|
|
54
|
-
|
55
54
|
# link item to siblings and/or parent
|
56
55
|
if (parent._sidChild == DIR_NOSTREAM)
|
57
56
|
parent._sidChild = child.sid
|
@@ -72,7 +71,9 @@ class Directory < DirEntry
|
|
72
71
|
break
|
73
72
|
end
|
74
73
|
}
|
75
|
-
|
74
|
+
if (not sib)
|
75
|
+
raise RuntimeError, 'Unable to find a sibling to link to in the directory'
|
76
|
+
end
|
76
77
|
end
|
77
78
|
parent << child
|
78
79
|
end
|
File without changes
|
data/lib/rex/ole/samples/dir.rb
CHANGED
File without changes
|
@@ -23,7 +23,7 @@ if (stg = Rex::OLE::Storage.new(document))
|
|
23
23
|
data = stm.read(stm.length)
|
24
24
|
data ||= ""
|
25
25
|
$stderr.puts "Successfully opened the \"%s\" stream (%u bytes)" % [stream, data.length]
|
26
|
-
$stdout.
|
26
|
+
$stdout.print data
|
27
27
|
stm.close
|
28
28
|
else
|
29
29
|
$stderr.puts "Unable to open stream: #{stream}"
|
File without changes
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Rex
|
2
|
+
module Parser
|
3
|
+
|
4
|
+
# XXX doesn't tie services to vulns
|
5
|
+
class NexposeXMLStreamParser
|
6
|
+
|
7
|
+
attr_accessor :callback
|
8
|
+
|
9
|
+
def initialize(callback = nil)
|
10
|
+
reset_state
|
11
|
+
self.callback = callback if callback
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset_state
|
15
|
+
@state = :generic_state
|
16
|
+
@host = { "status" => nil, "endpoints" => [], "names" => [], "vulns" => {} }
|
17
|
+
@vuln = { "refs" => [] }
|
18
|
+
end
|
19
|
+
|
20
|
+
def tag_start(name, attributes)
|
21
|
+
case name
|
22
|
+
when "node"
|
23
|
+
@host["hardware-address"] = attributes["hardware-address"]
|
24
|
+
@host["addr"] = attributes["address"]
|
25
|
+
@host["status"] = attributes["status"]
|
26
|
+
when "os"
|
27
|
+
# Take only the highest certainty
|
28
|
+
if not @host["os_certainty"] or (@host["os_certainty"].to_f < attributes["certainty"].to_f)
|
29
|
+
@host["os_vendor"] = attributes["vendor"]
|
30
|
+
@host["os_family"] = attributes["family"]
|
31
|
+
@host["os_product"] = attributes["product"]
|
32
|
+
@host["arch"] = attributes["arch"]
|
33
|
+
@host["os_certainty"] = attributes["certainty"]
|
34
|
+
end
|
35
|
+
when "name"
|
36
|
+
#@host["names"].push attributes["name"]
|
37
|
+
@state = :in_name
|
38
|
+
when "endpoint"
|
39
|
+
# This is a port in NeXpose parlance
|
40
|
+
@host["endpoints"].push(attributes)
|
41
|
+
when "service"
|
42
|
+
@state = :in_service
|
43
|
+
# Store any service info with the associated port. There shouldn't
|
44
|
+
# be any collisions on attribute names here, so just merge them.
|
45
|
+
@host["endpoints"].last.merge!(attributes)
|
46
|
+
when "fingerprint"
|
47
|
+
if @state == :in_service
|
48
|
+
@host["endpoints"].last.merge!(attributes)
|
49
|
+
end
|
50
|
+
when "test"
|
51
|
+
if attributes["status"] == "vulnerable-exploited" or attributes["status"] == "vulnerable-version"
|
52
|
+
@host["vulns"][attributes["id"]] = attributes.dup
|
53
|
+
end
|
54
|
+
when "vulnerability"
|
55
|
+
@vuln.merge! attributes
|
56
|
+
when "reference"
|
57
|
+
@state = :in_reference
|
58
|
+
@vuln["refs"].push attributes
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def text(str)
|
63
|
+
case @state
|
64
|
+
when :in_name
|
65
|
+
@host["names"].push str
|
66
|
+
when :in_reference
|
67
|
+
@vuln["refs"].last["value"] = str
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def tag_end(name)
|
72
|
+
case name
|
73
|
+
when "node"
|
74
|
+
callback.call(:host, @host) if callback
|
75
|
+
reset_state
|
76
|
+
when "vulnerability"
|
77
|
+
callback.call(:vuln, @vuln) if callback
|
78
|
+
reset_state
|
79
|
+
when "service","reference"
|
80
|
+
@state = :generic_state
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# We don't need these methods, but they're necessary to keep REXML happy
|
85
|
+
def xmldecl(version, encoding, standalone); end
|
86
|
+
def cdata; end
|
87
|
+
def comment(str); end
|
88
|
+
def instruction(name, instruction); end
|
89
|
+
def attlist; end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
__END__
|
95
|
+
|
96
|
+
<node address="10.1.1.10" status="alive" hardware-address="0007371F3BE8">
|
97
|
+
<names>
|
98
|
+
<name>NETBIOSNAME</name>
|
99
|
+
<name>hostname.example.com</name>
|
100
|
+
</names>
|
101
|
+
<fingerprints>
|
102
|
+
<os certainty="1.00" device-class="Domain controller" vendor="Microsoft" family="Windows" product="Windows Server 2003, Standard Edition" version="SP2" arch="x86"/>
|
103
|
+
<os certainty="0.85" device-class="General" vendor="Microsoft" family="Windows" product="Windows Server 2003"/>
|
104
|
+
<os certainty="0.70" vendor="Microsoft" family="Windows" product="Windows Server 2003"/>
|
105
|
+
</fingerprints>
|
106
|
+
<software>
|
107
|
+
<fingerprint certainty="1.00" vendor="Acronis" product="Acronis True Image Echo Server" version="9.5.8163"/>
|
108
|
+
<fingerprint certainty="1.00" vendor="Acronis" product="Acronis Universal Restore for Acronis True Image Echo Server" version="9.5.8076"/>
|
109
|
+
<fingerprint certainty="1.00" software-class="Internet Client" vendor="Microsoft" family="Internet Explorer" product="Internet Explorer" version="7.0.5730.11"/>
|
110
|
+
<fingerprint certainty="1.00" software-class="Database Client" vendor="Microsoft" family="MDAC" product="MDAC" version="2.8"/>
|
111
|
+
<fingerprint certainty="1.00" software-class="Media Client" vendor="Microsoft" family="Windows Media Player" product="Windows Media Player" version="10.0.0.3997"/>
|
112
|
+
<fingerprint certainty="1.00" vendor="MySolutions NORDIC" product="NSClient++ (Win32)" version="0.3.4.0"/>
|
113
|
+
<fingerprint certainty="1.00" vendor="Symantec Corporation" product="LiveUpdate 3.1 (Symantec Corporation)" version="3.1.0.99"/>
|
114
|
+
<fingerprint certainty="1.00" vendor="Symantec Corporation" product="Symantec AntiVirus" version="10.1.5000.5"/>
|
115
|
+
</software>
|
116
|
+
<tests>
|
117
|
+
<test status="not-vulnerable" id="backdoor-ckb.cfaae1e6">
|
118
|
+
|
119
|
+
<endpoint protocol="tcp" port="139" status="open">
|
120
|
+
<services>
|
121
|
+
<service name="CIFS">
|
122
|
+
<fingerprints>
|
123
|
+
<fingerprint certainty="1.00" product="Windows Server 2003 R2 5.2"/>
|
124
|
+
</fingerprints>
|
125
|
+
<tests>
|
126
|
+
</tests>
|
127
|
+
</service>
|
128
|
+
</services>
|
129
|
+
</endpoint>
|
130
|
+
</node>
|
131
|
+
|
data/lib/rex/parser/nmap_xml.rb
CHANGED
@@ -77,6 +77,7 @@ class NmapXMLStreamParser
|
|
77
77
|
when "status"
|
78
78
|
# <status> refers to the liveness of the host; values are "up" or "down"
|
79
79
|
@host["status"] = attributes["state"]
|
80
|
+
@host["status_reason"] = attributes["reason"]
|
80
81
|
when "port"
|
81
82
|
@host["ports"].push(attributes)
|
82
83
|
when "state"
|
data/lib/rex/peparsey/pe.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
# $Id: pe.rb
|
3
|
+
# $Id: pe.rb 9272 2010-05-10 16:18:19Z jduck $
|
4
4
|
|
5
5
|
require 'rex/image_source'
|
6
6
|
require 'rex/peparsey/exceptions'
|
@@ -143,7 +143,7 @@ class Pe < PeBase
|
|
143
143
|
self.hdr.config = self._config_header
|
144
144
|
self.hdr.tls = self._tls_header
|
145
145
|
self.hdr.exceptions = self._exception_header
|
146
|
-
|
146
|
+
|
147
147
|
# We load the exception directory last as it relies on hdr.file to be created above.
|
148
148
|
self._exception_header = _load_exception_directory()
|
149
149
|
end
|
@@ -184,5 +184,23 @@ class Pe < PeBase
|
|
184
184
|
(ptr_32?) ? ("0x%.8x" % va) : ("0x%.16x" % va)
|
185
185
|
end
|
186
186
|
|
187
|
-
|
187
|
+
#
|
188
|
+
# Converts a file offset into a virtual address
|
189
|
+
#
|
190
|
+
def file_offset_to_va(offset)
|
191
|
+
image_base + file_offset_to_rva(offset)
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Read raw bytes from the specified offset in the underlying file
|
196
|
+
#
|
197
|
+
# NOTE: You should pass raw file offsets into this, not offsets from
|
198
|
+
# the beginning of the section. If you need to read from within a
|
199
|
+
# section, add section.file_offset prior to passing the offset in.
|
200
|
+
#
|
201
|
+
def read(offset, len)
|
202
|
+
_isource.read(offset, len)
|
203
|
+
end
|
204
|
+
|
188
205
|
|
206
|
+
end end end
|
@@ -81,13 +81,14 @@ class Client
|
|
81
81
|
self.ext_aliases = ObjectAliases.new
|
82
82
|
self.alive = true
|
83
83
|
self.target_id = opts[:target_id]
|
84
|
+
self.capabilities= opts[:capabilities] || {}
|
84
85
|
|
85
86
|
self.response_timeout = opts[:timeout] || self.class.default_timeout
|
86
87
|
self.send_keepalives = true
|
87
88
|
|
88
89
|
|
89
90
|
# Switch the socket to SSL mode and receive the hello if needed
|
90
|
-
if not opts[:skip_ssl]
|
91
|
+
if capabilities[:ssl] and not opts[:skip_ssl]
|
91
92
|
swap_sock_plain_to_ssl()
|
92
93
|
end
|
93
94
|
|
@@ -325,6 +326,10 @@ class Client
|
|
325
326
|
# The unique target identifier for this payload
|
326
327
|
#
|
327
328
|
attr_accessor :target_id
|
329
|
+
#
|
330
|
+
# The libraries available to this meterpreter server
|
331
|
+
#
|
332
|
+
attr_accessor :capabilities
|
328
333
|
|
329
334
|
protected
|
330
335
|
attr_accessor :parser, :ext_aliases # :nodoc:
|
@@ -89,7 +89,7 @@ class ClientCore < Extension
|
|
89
89
|
}
|
90
90
|
|
91
91
|
if (image != nil)
|
92
|
-
request.add_tlv(TLV_TYPE_DATA, image, false,
|
92
|
+
request.add_tlv(TLV_TYPE_DATA, image, false, client.capabilities[:zlib])
|
93
93
|
else
|
94
94
|
raise RuntimeError, "Failed to serialize library #{library_path}.", caller
|
95
95
|
end
|
@@ -222,7 +222,7 @@ class ClientCore < Extension
|
|
222
222
|
request = Packet.create_request( 'core_migrate' )
|
223
223
|
request.add_tlv( TLV_TYPE_MIGRATE_PID, pid )
|
224
224
|
request.add_tlv( TLV_TYPE_MIGRATE_LEN, payload.length )
|
225
|
-
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD, payload, false,
|
225
|
+
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD, payload, false, client.capabilities[:zlib])
|
226
226
|
if( process['arch'] == ARCH_X86_64 )
|
227
227
|
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 2 ) # PROCESS_ARCH_X64
|
228
228
|
else
|
@@ -24,10 +24,10 @@ class Priv < Extension
|
|
24
24
|
#
|
25
25
|
def initialize(client)
|
26
26
|
super(client, 'priv')
|
27
|
-
|
27
|
+
|
28
28
|
client.register_extension_aliases(
|
29
29
|
[
|
30
|
-
{
|
30
|
+
{
|
31
31
|
'name' => 'priv',
|
32
32
|
'ext' => self
|
33
33
|
},
|
@@ -36,25 +36,25 @@ class Priv < Extension
|
|
36
36
|
# Initialize sub-classes
|
37
37
|
self.fs = Fs.new(client)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
#
|
41
41
|
# Attempt to elevate the meterpreter to Local SYSTEM
|
42
42
|
#
|
43
43
|
def getsystem( technique=0 )
|
44
44
|
request = Packet.create_request( 'priv_elevate_getsystem' )
|
45
|
-
|
46
|
-
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
|
47
|
-
|
45
|
+
|
46
|
+
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
|
47
|
+
|
48
48
|
if( client.platform == 'x64/win64' )
|
49
49
|
elevator_path = ::File.join( Msf::Config.install_root, "data", "meterpreter", "elevator.x64.dll" )
|
50
50
|
else
|
51
51
|
elevator_path = ::File.join( Msf::Config.install_root, "data", "meterpreter", "elevator.dll" )
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
elevator_path = ::File.expand_path( elevator_path )
|
55
|
-
|
55
|
+
|
56
56
|
elevator_data = ""
|
57
|
-
|
57
|
+
|
58
58
|
::File.open( elevator_path, "rb" ) { |f|
|
59
59
|
elevator_data += f.read( f.stat.size )
|
60
60
|
}
|
@@ -63,29 +63,29 @@ class Priv < Extension
|
|
63
63
|
request.add_tlv( TLV_TYPE_ELEVATE_SERVICE_NAME, elevator_name )
|
64
64
|
request.add_tlv( TLV_TYPE_ELEVATE_SERVICE_DLL, elevator_data )
|
65
65
|
request.add_tlv( TLV_TYPE_ELEVATE_SERVICE_LENGTH, elevator_data.length )
|
66
|
-
|
66
|
+
|
67
67
|
# as some service routines can be slow we bump up the timeout to 90 seconds
|
68
68
|
response = client.send_request( request, 90 )
|
69
|
-
|
69
|
+
|
70
70
|
technique = response.get_tlv_value( TLV_TYPE_ELEVATE_TECHNIQUE )
|
71
|
-
|
71
|
+
|
72
72
|
if( response.result == 0 and technique != nil )
|
73
73
|
client.core.use( "stdapi" ) if not client.ext.aliases.include?( "stdapi" )
|
74
74
|
client.sys.config.getprivs
|
75
75
|
return [ true, technique ]
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
return [ false, 0 ]
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
#
|
82
82
|
# Returns an array of SAM hashes from the remote machine.
|
83
83
|
#
|
84
84
|
def sam_hashes
|
85
|
-
|
86
|
-
|
85
|
+
# This can take a long long time for large domain controls, bump the timeout to one hour
|
86
|
+
response = client.send_request(Packet.create_request('priv_passwd_get_sam_hashes'), 3600)
|
87
87
|
|
88
|
-
response.get_tlv_value(TLV_TYPE_SAM_HASHES).split(/\n/).map { |hash|
|
88
|
+
response.get_tlv_value(TLV_TYPE_SAM_HASHES).split(/\n/).map { |hash|
|
89
89
|
SamUser.new(hash)
|
90
90
|
}
|
91
91
|
end
|
@@ -101,4 +101,5 @@ protected
|
|
101
101
|
|
102
102
|
end
|
103
103
|
|
104
|
-
end; end; end; end; end
|
104
|
+
end; end; end; end; end
|
105
|
+
|