librex 0.0.51 → 0.0.52

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: 13694
6
+ SVN Revision: 13798
7
7
 
8
8
  # Credits
9
9
  The Metasploit development team <http://www.metasploit.com>
@@ -1,8 +1,7 @@
1
1
  ##
2
- # $Id: jsobfu.rb 12843 2011-06-03 17:52:34Z egypt $
2
+ # $Id: jsobfu.rb 13761 2011-09-19 23:01:26Z jduck $
3
3
  ##
4
4
 
5
- $:.unshift("lib")
6
5
  require 'rex/text'
7
6
  require 'rkelly'
8
7
 
@@ -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")
@@ -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
- pe.imports.each do |lib|
152
- lib.entries.each do |ent|
153
- tbl << [lib.name, ent.ordinal, ent.name]
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
- puts "#{val}"
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
- puts "\t#{k}: #{stats[k]}"
94
+ print_line("\t#{k}: #{stats[k]}")
95
95
  end
96
96
 
97
97
  return true
@@ -1,4 +1,4 @@
1
- # $Id: server.rb 13639 2011-08-25 22:48:33Z scriptjunkie $
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
 
@@ -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
@@ -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
@@ -862,7 +862,7 @@ module Text
862
862
  0.upto(len-1) do |i|
863
863
  setnum = i % sets.size
864
864
 
865
- puts counter.inspect
865
+ #puts counter.inspect
866
866
  end
867
867
 
868
868
  return buf
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.51
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-05 00:00:00.000000000Z
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 13694
16
+ development. Based on SVN Revision 13798
17
17
  email:
18
18
  - hdm@metasploit.com
19
19
  - jacob.hammack@hammackj.com