librex 0.0.51 → 0.0.52
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.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
|