librex 0.0.51 → 0.0.52
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +1 -1
- data/lib/rex/exploitation/jsobfu.rb +1 -2
- data/lib/rex/parser/acunetix_nokogiri.rb +12 -1
- data/lib/rex/pescan/analyze.rb +60 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +2 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +1 -1
- data/lib/rex/proto/dhcp/server.rb +4 -2
- data/lib/rex/ropbuilder/rop.rb +15 -3
- data/lib/rex/socket.rb +14 -15
- data/lib/rex/text.rb +1 -1
- metadata +3 -3
data/README.markdown
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
A non-official re-packaging of the Rex library as a gem for easy of usage of the Metasploit REX framework in a non Metasploit application. I received permission from HDM to create this package.
|
4
4
|
|
5
5
|
Currently based on:
|
6
|
-
SVN Revision:
|
6
|
+
SVN Revision: 13798
|
7
7
|
|
8
8
|
# Credits
|
9
9
|
The Metasploit development team <http://www.metasploit.com>
|
@@ -190,7 +190,7 @@ module Rex
|
|
190
190
|
return unless @state[:fullurl].kind_of? URI
|
191
191
|
return unless @state[:form_variables].kind_of? Array
|
192
192
|
return if @state[:form_variables].empty?
|
193
|
-
method = @state[:form_variables].first[1]
|
193
|
+
method = parse_method(@state[:form_variables].first[1])
|
194
194
|
vars = @state[:form_variables].map {|x| x[0]}
|
195
195
|
form_info = {}
|
196
196
|
form_info[:web_site] = @state[:web_site]
|
@@ -276,6 +276,17 @@ module Rex
|
|
276
276
|
parsed
|
277
277
|
end
|
278
278
|
|
279
|
+
# Don't cause the web report to die just because we can't tell
|
280
|
+
# what method was used -- default to GET. Sometimes it's just "POST," and
|
281
|
+
# sometimes it's "URL encoded POST," and sometimes it might be something
|
282
|
+
# else.
|
283
|
+
def parse_method(meth)
|
284
|
+
verbs = "(GET|POST|PATH)"
|
285
|
+
real_method = meth.match(/^\s*#{verbs}/)
|
286
|
+
real_method ||= meth.match(/\s*#{verbs}\s*$/)
|
287
|
+
( real_method && real_method[1] ) ? real_method[1] : "GET"
|
288
|
+
end
|
289
|
+
|
279
290
|
def report_host(&block)
|
280
291
|
return unless @report_data[:host]
|
281
292
|
return unless in_tag("Scan")
|
data/lib/rex/pescan/analyze.rb
CHANGED
@@ -134,9 +134,50 @@ module Analyze
|
|
134
134
|
LoaderFlags
|
135
135
|
NumberOfRvaAndSizes
|
136
136
|
})
|
137
|
+
|
137
138
|
$stdout.puts tbl.to_s
|
138
139
|
$stdout.puts "\n\n"
|
139
140
|
|
141
|
+
# Get DllCharacteristics (in Integer)
|
142
|
+
dllcharacteristics = pe.hdr.opt.struct[23].value
|
143
|
+
|
144
|
+
if (dllcharacteristics > 0)
|
145
|
+
tbl = table("DllCharacteristics", ['Flag', 'Value'])
|
146
|
+
|
147
|
+
# http://msdn.microsoft.com/en-us/library/ms680339(v=vs.85).aspx
|
148
|
+
traits = {
|
149
|
+
:ASLR => 'False', #IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
150
|
+
:Integrity => 'False', #IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
|
151
|
+
:NX => 'False', #IMAGE_DLLCHARACTERISTICS_NX_COMPAT
|
152
|
+
:Isolation => 'False', #IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
|
153
|
+
:SEH => 'False', #IMAGE_DLLCHARACTERISTICS_NO_SEH
|
154
|
+
:Bind => 'False', #IMAGE_DLLCHARACTERISTICS_NO_BIND
|
155
|
+
:WDM => 'False', #IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
|
156
|
+
:Terminal => 'False' #IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
|
157
|
+
}
|
158
|
+
|
159
|
+
# Convert integer to an bit array
|
160
|
+
c_bits = ("%32d" %dllcharacteristics.to_s(2)).split('').map { |e| e.to_i }.reverse
|
161
|
+
|
162
|
+
# Check characteristics
|
163
|
+
traits[:ASLR] = 'True' if c_bits[6] == 1 #0x0040
|
164
|
+
traits[:Integrity] = 'True' if c_bits[7] == 1 #0x0080
|
165
|
+
traits[:NX] = 'True' if c_bits[8] == 1 #0x0100
|
166
|
+
traits[:Isolation] = 'True' if c_bits[9] == 1 #0x0200
|
167
|
+
traits[:SEH] = 'True' if c_bits[10] == 1 #0x0400
|
168
|
+
traits[:Bind] = 'True' if c_bits[11] == 1 #0x0800
|
169
|
+
traits[:WDM] = 'True' if c_bits[13] == 1 #2000
|
170
|
+
traits[:Terminal] = 'True' if c_bits[15] == 1 #0x8000
|
171
|
+
|
172
|
+
# Putting results to table
|
173
|
+
traits.each do |trait_name, trait_value|
|
174
|
+
tbl << [trait_name, trait_value]
|
175
|
+
end
|
176
|
+
|
177
|
+
$stdout.puts tbl.to_s
|
178
|
+
$stdout.puts "\n\n"
|
179
|
+
end
|
180
|
+
|
140
181
|
if (pe.exports)
|
141
182
|
tbl = table("Exported Functions", ['Ordinal', 'Name', 'Address'])
|
142
183
|
pe.exports.entries.each do |ent|
|
@@ -146,13 +187,28 @@ module Analyze
|
|
146
187
|
$stdout.puts "\n\n"
|
147
188
|
end
|
148
189
|
|
190
|
+
# Rex::PeParsey::Pe doesn't seem to give us any offset information for each function,
|
191
|
+
# which makes it difficult to calculate the actual addresses for them. So instead we
|
192
|
+
# are using Metasm::COFF::ImportDirectory to do this task. The ability to see
|
193
|
+
# addresses is mainly for ROP.
|
149
194
|
if (pe.imports)
|
150
|
-
tbl = table("Imported Functions", ['Library', 'Ordinal', 'Name'])
|
151
|
-
|
152
|
-
|
153
|
-
|
195
|
+
tbl = table("Imported Functions", ['Library', 'Address', 'Ordinal', 'Name'])
|
196
|
+
exefmt = Metasm::AutoExe.orshellcode{ Metasm.const_get('x86_64').new }
|
197
|
+
exe = exefmt.decode_file(pe._isource.file.path)
|
198
|
+
ibase = pe.image_base
|
199
|
+
exe_imports = exe.imports
|
200
|
+
exe_imports.each do |lib|
|
201
|
+
lib_name = lib.libname
|
202
|
+
ini_offset = lib.iat_p
|
203
|
+
func_table = lib.imports
|
204
|
+
offset = 0
|
205
|
+
func_table.each do |func|
|
206
|
+
func_addr = "0x%08x" %(ibase + ini_offset + offset)
|
207
|
+
tbl << [lib_name, func_addr, func.hint, func.name]
|
208
|
+
offset += 4
|
154
209
|
end
|
155
210
|
end
|
211
|
+
|
156
212
|
$stdout.puts tbl.to_s
|
157
213
|
$stdout.puts "\n\n"
|
158
214
|
end
|
@@ -73,7 +73,7 @@ class Console::CommandDispatcher::Priv::Timestomp
|
|
73
73
|
when "-e"
|
74
74
|
emodified = str_to_time(val)
|
75
75
|
when "-z"
|
76
|
-
|
76
|
+
print_line("#{val}")
|
77
77
|
modified = str_to_time(val)
|
78
78
|
accessed = str_to_time(val)
|
79
79
|
creation = str_to_time(val)
|
@@ -129,4 +129,4 @@ end
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end
|
132
|
-
end
|
132
|
+
end
|
@@ -91,7 +91,7 @@ class Console::CommandDispatcher::Sniffer
|
|
91
91
|
stats = client.sniffer.capture_stats(intf)
|
92
92
|
print_status("Capture statistics for interface #{intf}")
|
93
93
|
stats.each_key do |k|
|
94
|
-
|
94
|
+
print_line("\t#{k}: #{stats[k]}")
|
95
95
|
end
|
96
96
|
|
97
97
|
return true
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: server.rb
|
1
|
+
# $Id: server.rb 13779 2011-09-23 15:12:19Z scriptjunkie $
|
2
2
|
|
3
3
|
require 'rex/socket'
|
4
4
|
require 'rex/proto/dhcp'
|
@@ -275,7 +275,6 @@ protected
|
|
275
275
|
return
|
276
276
|
end
|
277
277
|
elsif messageType == DHCPRequest #DHCP Request - send DHCP ACK
|
278
|
-
self.served[buf[28..43]][1] = true # mark as requested
|
279
278
|
pkt << [DHCPAck].pack('C')
|
280
279
|
# now we ignore their discovers (but we'll respond to requests in case a packet was lost)
|
281
280
|
if ( self.served_over != 0 )
|
@@ -322,6 +321,9 @@ protected
|
|
322
321
|
|
323
322
|
pkt << ("\x00" * 32) #padding
|
324
323
|
|
324
|
+
# And now we mark as requested
|
325
|
+
self.served[buf[28..43]][1] = true if messageType == DHCPRequest
|
326
|
+
|
325
327
|
send_packet(nil, pkt)
|
326
328
|
end
|
327
329
|
|
data/lib/rex/ropbuilder/rop.rb
CHANGED
@@ -15,7 +15,7 @@ class RopBase
|
|
15
15
|
|
16
16
|
def to_csv(gadgets = [])
|
17
17
|
if gadgets.empty? and @gadgets.nil? or @gadgets.empty?
|
18
|
-
print_error("No gadgets collected to convert to CSV format.")
|
18
|
+
@stdio.print_error("No gadgets collected to convert to CSV format.")
|
19
19
|
return
|
20
20
|
end
|
21
21
|
|
@@ -45,14 +45,25 @@ class RopBase
|
|
45
45
|
begin
|
46
46
|
data = File.new(file, 'r').read
|
47
47
|
rescue
|
48
|
-
print_error("Error reading #{file}")
|
48
|
+
@stdio.print_error("Error reading #{file}")
|
49
|
+
return []
|
50
|
+
end
|
51
|
+
|
52
|
+
if data.empty? or data.nil?
|
53
|
+
return []
|
49
54
|
end
|
50
55
|
|
51
56
|
data.gsub!(/\"/, '')
|
52
57
|
data.gsub!("Address,Raw,Disassembly\n", '')
|
58
|
+
|
53
59
|
@gadgets = []
|
60
|
+
|
54
61
|
data.each_line do |line|
|
55
62
|
addr, raw, disasm = line.split(',', 3)
|
63
|
+
if addr.nil? or raw.nil? or disasm.nil?
|
64
|
+
@stdio.print_error("Import file format corrupted")
|
65
|
+
return []
|
66
|
+
end
|
56
67
|
disasm.gsub!(/: /, ":\t")
|
57
68
|
disasm.gsub!(' | ', "\n")
|
58
69
|
raw = [raw].pack('H*')
|
@@ -77,6 +88,7 @@ end
|
|
77
88
|
|
78
89
|
class RopCollect < RopBase
|
79
90
|
def initialize(file="")
|
91
|
+
@stdio = Rex::Ui::Text::Output::Stdio.new
|
80
92
|
@file = file if not file.empty?
|
81
93
|
@bin = Metasm::AutoExe.decode_file(file) if not file.empty?
|
82
94
|
@disassembler = @bin.disassembler if not @bin.nil?
|
@@ -254,4 +266,4 @@ class RopCollect < RopBase
|
|
254
266
|
end
|
255
267
|
end
|
256
268
|
end
|
257
|
-
end
|
269
|
+
end
|
data/lib/rex/socket.rb
CHANGED
@@ -152,27 +152,26 @@ module Socket
|
|
152
152
|
#
|
153
153
|
def self.getaddress(addr, accept_ipv6 = true)
|
154
154
|
begin
|
155
|
-
|
156
155
|
if dotted_ip?(addr)
|
157
156
|
return addr
|
158
157
|
end
|
159
|
-
|
158
|
+
|
160
159
|
res = ::Socket.gethostbyname(addr)
|
161
160
|
return nil if not res
|
162
|
-
|
161
|
+
|
163
162
|
# Shift the first three elements out
|
164
163
|
rname = res.shift
|
165
164
|
ralias = res.shift
|
166
165
|
rtype = res.shift
|
167
|
-
|
168
|
-
# Reject IPv6 addresses if we don't accept them
|
166
|
+
|
167
|
+
# Reject IPv6 addresses if we don't accept them
|
169
168
|
if not accept_ipv6
|
170
169
|
res.reject!{|nbo| nbo.length != 4}
|
171
170
|
end
|
172
|
-
|
171
|
+
|
173
172
|
# Make sure we have at least one name
|
174
|
-
return nil if res.length == 0
|
175
|
-
|
173
|
+
return nil if res.length == 0
|
174
|
+
|
176
175
|
# Return the first address of the result
|
177
176
|
self.addr_ntoa( res[0] )
|
178
177
|
rescue ::ArgumentError # Win32 bug
|
@@ -236,10 +235,10 @@ module Socket
|
|
236
235
|
addr_ntoi(resolv_nbo(host))
|
237
236
|
end
|
238
237
|
|
239
|
-
#
|
238
|
+
#
|
240
239
|
# Converts an ASCII IP address to a CIDR mask. Returns
|
241
240
|
# nil if it's not convertable.
|
242
|
-
#
|
241
|
+
#
|
243
242
|
def self.addr_atoc(mask)
|
244
243
|
mask_i = resolv_nbo_i(mask)
|
245
244
|
cidr = nil
|
@@ -476,7 +475,7 @@ module Socket
|
|
476
475
|
##
|
477
476
|
|
478
477
|
#
|
479
|
-
# This method does NOT send any traffic to the destination, instead, it uses a
|
478
|
+
# This method does NOT send any traffic to the destination, instead, it uses a
|
480
479
|
# "bound" UDP socket to determine what source address we would use to
|
481
480
|
# communicate with the specified destination. The destination defaults to
|
482
481
|
# Google's DNS server to make the standard behavior determine which IP
|
@@ -491,14 +490,14 @@ module Socket
|
|
491
490
|
)
|
492
491
|
r = s.getsockname[1]
|
493
492
|
s.close
|
494
|
-
|
493
|
+
|
495
494
|
# Trim off the trailing interface ID for link-local IPv6
|
496
495
|
return r.split('%').first
|
497
496
|
rescue ::Exception
|
498
497
|
return '127.0.0.1'
|
499
498
|
end
|
500
499
|
end
|
501
|
-
|
500
|
+
|
502
501
|
#
|
503
502
|
# Identifies the link-local address of a given interface (if IPv6 is enabled)
|
504
503
|
#
|
@@ -507,10 +506,10 @@ module Socket
|
|
507
506
|
return if not (r and r =~ /^fe80/i)
|
508
507
|
r
|
509
508
|
end
|
510
|
-
|
509
|
+
|
511
510
|
#
|
512
511
|
# Identifies the mac address of a given interface (if IPv6 is enabled)
|
513
|
-
#
|
512
|
+
#
|
514
513
|
def self.ipv6_mac(intf)
|
515
514
|
r = ipv6_link_address(intf)
|
516
515
|
return if not r
|
data/lib/rex/text.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: librex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.52
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,10 +10,10 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-09-
|
13
|
+
date: 2011-09-27 00:00:00.000000000Z
|
14
14
|
dependencies: []
|
15
15
|
description: Rex provides a variety of classes useful for security testing and exploit
|
16
|
-
development. Based on SVN Revision
|
16
|
+
development. Based on SVN Revision 13798
|
17
17
|
email:
|
18
18
|
- hdm@metasploit.com
|
19
19
|
- jacob.hammack@hammackj.com
|