ronin 0.2.2 → 0.2.3

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.
Files changed (98) hide show
  1. data/History.txt +53 -0
  2. data/Manifest.txt +26 -18
  3. data/README.txt +12 -19
  4. data/Rakefile +9 -9
  5. data/TODO.txt +5 -5
  6. data/lib/ronin/cacheable.rb +246 -0
  7. data/lib/ronin/database/database.rb +21 -3
  8. data/lib/ronin/database/exceptions/invalid_config.rb +1 -1
  9. data/lib/ronin/environment.rb +5 -2
  10. data/lib/ronin/extensions.rb +2 -0
  11. data/lib/ronin/{models.rb → extensions/array.rb} +19 -6
  12. data/lib/ronin/extensions/ip_addr.rb +127 -0
  13. data/lib/ronin/{objectify/exceptions/object_context_not_found.rb → extensions/kernel.rb} +14 -3
  14. data/lib/ronin/extensions/uri/query_params.rb +4 -2
  15. data/lib/ronin/formatting/extensions/binary/integer.rb +6 -0
  16. data/lib/ronin/formatting/extensions/binary/string.rb +14 -12
  17. data/lib/ronin/formatting/extensions/text/string.rb +37 -19
  18. data/lib/ronin/has_license.rb +4 -2
  19. data/lib/ronin/model.rb +0 -1
  20. data/lib/ronin/network/extensions/http/net.rb +30 -3
  21. data/lib/ronin/network/extensions/telnet/net.rb +0 -18
  22. data/lib/ronin/network/http/exceptions/unknown_request.rb +1 -1
  23. data/lib/ronin/platform/exceptions/extension_not_found.rb +1 -1
  24. data/lib/ronin/platform/exceptions/overlay_cached.rb +1 -1
  25. data/lib/ronin/platform/exceptions/overlay_not_found.rb +1 -1
  26. data/lib/ronin/platform/extension.rb +18 -3
  27. data/lib/ronin/platform/extension_cache.rb +7 -1
  28. data/lib/ronin/platform/object_cache.rb +13 -12
  29. data/lib/ronin/platform/overlay.rb +14 -6
  30. data/lib/ronin/platform/overlay_cache.rb +11 -5
  31. data/lib/ronin/product.rb +20 -3
  32. data/lib/ronin/ronin.rb +0 -15
  33. data/lib/ronin/rpc/exceptions/response_missing.rb +1 -1
  34. data/lib/ronin/sessions/esmtp.rb +1 -10
  35. data/lib/ronin/{objectify.rb → sessions/exceptions.rb} +3 -3
  36. data/lib/ronin/{objectify/exceptions/unknown_object_context.rb → sessions/exceptions/variable_missing.rb} +4 -4
  37. data/lib/ronin/sessions/http.rb +3 -10
  38. data/lib/ronin/sessions/imap.rb +1 -10
  39. data/lib/ronin/sessions/pop3.rb +1 -9
  40. data/lib/ronin/sessions/session.rb +11 -21
  41. data/lib/ronin/sessions/smtp.rb +1 -10
  42. data/lib/ronin/sessions/tcp.rb +10 -13
  43. data/lib/ronin/sessions/telnet.rb +2 -17
  44. data/lib/ronin/sessions/udp.rb +6 -11
  45. data/lib/ronin/static/finders.rb +24 -0
  46. data/lib/ronin/ui/command_line/command_line.rb +41 -21
  47. data/lib/ronin/ui/command_line/commands/help.rb +7 -3
  48. data/lib/ronin/ui/command_line/commands/ls.rb +1 -1
  49. data/lib/ronin/ui/command_line/commands/rm.rb +1 -1
  50. data/lib/ronin/ui/command_line/exceptions/unknown_command.rb +1 -1
  51. data/lib/ronin/ui/diagnostics.rb +12 -5
  52. data/lib/ronin/ui/hexdump/extensions/file.rb +3 -1
  53. data/lib/ronin/ui/hexdump/hexdump.rb +1 -1
  54. data/lib/ronin/ui/verbose.rb +14 -0
  55. data/lib/ronin/version.rb +1 -1
  56. data/spec/cacheable_spec.rb +150 -0
  57. data/spec/classes/cacheable_model.rb +15 -0
  58. data/spec/classes/licensed_model.rb +12 -0
  59. data/spec/code/classes/thing.rb +13 -0
  60. data/spec/code/reference_spec.rb +1 -14
  61. data/spec/extensions/array_spec.rb +34 -0
  62. data/spec/extensions/ip_addr_spec.rb +44 -0
  63. data/spec/extensions/kernel_spec.rb +19 -0
  64. data/spec/extensions/uri/query_params_spec.rb +8 -0
  65. data/spec/formatting/binary/string_spec.rb +1 -1
  66. data/spec/formatting/digest/string_spec.rb +84 -0
  67. data/spec/formatting/http/string_spec.rb +84 -0
  68. data/spec/formatting/text/string_spec.rb +51 -0
  69. data/spec/has_license_spec.rb +29 -0
  70. data/spec/helpers/cacheable.rb +7 -0
  71. data/spec/helpers/contexts/ronin_cacheable_model.rb +13 -0
  72. data/spec/helpers/database.rb +5 -0
  73. data/spec/platform/helpers/overlays/hello/lib/init.rb +1 -0
  74. data/spec/platform/helpers/overlays/hello/lib/stuff/another_test.rb +6 -0
  75. data/spec/platform/helpers/overlays/hello/lib/stuff/test.rb +4 -0
  76. data/spec/platform/overlay_cache_spec.rb +1 -1
  77. data/spec/platform/overlay_spec.rb +28 -0
  78. data/spec/product_spec.rb +7 -0
  79. data/spec/sessions/classes/test_session.rb +11 -0
  80. data/spec/sessions/classes/uses_test_session.rb +10 -0
  81. data/spec/sessions/session_spec.rb +13 -44
  82. data/spec/spec_helper.rb +0 -5
  83. data/spec/static/{helpers → classes}/static_class.rb +0 -0
  84. data/spec/static/helpers/static.rb +0 -1
  85. data/spec/static/static_spec.rb +1 -0
  86. metadata +44 -35
  87. data/lib/ronin/objectify/exceptions.rb +0 -25
  88. data/lib/ronin/objectify/objectify.rb +0 -240
  89. data/lib/ronin/target.rb +0 -44
  90. data/lib/ronin/ui/command_line/param_parser.rb +0 -93
  91. data/spec/formatting/digest_spec.rb +0 -54
  92. data/spec/formatting/http_spec.rb +0 -53
  93. data/spec/formatting/text_spec.rb +0 -40
  94. data/spec/helpers.rb +0 -0
  95. data/spec/objectify/objectify_spec.rb +0 -31
  96. data/spec/target_spec.rb +0 -16
  97. data/spec/ui/command_line/helpers/example_command.rb +0 -21
  98. data/spec/ui/command_line/param_parser_spec.rb +0 -49
@@ -22,6 +22,7 @@
22
22
  #
23
23
 
24
24
  require 'ronin/database/exceptions/invalid_config'
25
+ require 'ronin/model'
25
26
  require 'ronin/arch'
26
27
  require 'ronin/os'
27
28
  require 'ronin/author'
@@ -103,6 +104,25 @@ module Ronin
103
104
  return @@ronin_database_log = DataMapper::Logger.new(stream,level)
104
105
  end
105
106
 
107
+ #
108
+ # Returns +true+ if the Database is setup, returns +false+ otherwise.
109
+ #
110
+ def Database.setup?
111
+ repository = DataMapper.repository(Model::REPOSITORY_NAME)
112
+
113
+ return repository.class.adapters.has_key?(repository.name)
114
+ end
115
+
116
+ #
117
+ # Call the given _block_ then run auto-upgrades on the Database.
118
+ #
119
+ def Database.update!(&block)
120
+ block.call if block
121
+
122
+ DataMapper.auto_upgrade!(Model::REPOSITORY_NAME) if Database.setup?
123
+ return nil
124
+ end
125
+
106
126
  #
107
127
  # Sets up the Database with the given _configuration_. If
108
128
  # _configuration is not given, +DEFAULT_CONFIG+ will be used to setup
@@ -115,9 +135,7 @@ module Ronin
115
135
  # setup the database repository
116
136
  DataMapper.setup(Model::REPOSITORY_NAME, configuration)
117
137
 
118
- block.call if block
119
-
120
- DataMapper.auto_upgrade!(Model::REPOSITORY_NAME)
138
+ Database.update!(&block)
121
139
  return nil
122
140
  end
123
141
  end
@@ -23,7 +23,7 @@
23
23
 
24
24
  module Ronin
25
25
  module Database
26
- class InvalidConfig < RuntimeError
26
+ class InvalidConfig < StandardError
27
27
  end
28
28
  end
29
29
  end
@@ -26,11 +26,14 @@ require 'ronin/extensions'
26
26
  require 'ronin/formatting'
27
27
  require 'ronin/path'
28
28
  require 'ronin/network'
29
- require 'ronin/models'
29
+ require 'ronin/database'
30
30
  require 'ronin/ui'
31
31
  require 'ronin/ronin'
32
32
 
33
33
  require 'chars'
34
34
  require 'pp'
35
35
 
36
- Ronin::Config.load
36
+ module Ronin
37
+ Config.load
38
+ Database.setup
39
+ end
@@ -22,7 +22,9 @@
22
22
  #
23
23
 
24
24
  require 'ronin/extensions/meta'
25
+ require 'ronin/extensions/kernel'
25
26
  require 'ronin/extensions/hash'
26
27
  require 'ronin/extensions/uri'
27
28
  require 'ronin/extensions/string'
28
29
  require 'ronin/extensions/file'
30
+ require 'ronin/extensions/ip_addr'
@@ -21,13 +21,26 @@
21
21
  #++
22
22
  #
23
23
 
24
- require 'ronin/database'
25
- require 'ronin/model'
24
+ class Array
26
25
 
27
- require 'reverse_require'
26
+ #
27
+ # Returns the power set of the array. Shamelessly borrowed from
28
+ # http://johncarrino.net/blog/2006/08/11/powerset-in-ruby/.
29
+ #
30
+ # [1,2,3].power_set
31
+ # # => [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
32
+ #
33
+ def power_set
34
+ inject([[]]) do |power_set,element|
35
+ sub_set = []
28
36
 
29
- module Ronin
30
- Database.setup do
31
- require_for 'ronin', 'ronin/models'
37
+ power_set.each do |i|
38
+ sub_set << i
39
+ sub_set << i + [element]
40
+ end
41
+
42
+ sub_set
43
+ end
32
44
  end
45
+
33
46
  end
@@ -0,0 +1,127 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ipaddr'
25
+
26
+ class IPAddr
27
+
28
+ include Enumerable
29
+
30
+ #
31
+ # Iterates over the CIDR or globbed address range, passing each
32
+ # address in the range to the specified _block_. Supports both
33
+ # IPv4 and IPv6 address ranges.
34
+ #
35
+ # IPAddr.each('10.1.1.1/24') do |ip|
36
+ # ...
37
+ # end
38
+ #
39
+ # IPAddr.each('10.1.1-5.*') do |ip|
40
+ # ...
41
+ # end
42
+ #
43
+ # IPAddr.each('::ff::02-0a::c3') do |ip|
44
+ # ...
45
+ # end
46
+ #
47
+ def IPAddr.each(cidr_or_glob,&block)
48
+ unless (cidr_or_glob.include?('*') || cidr_or_glob.include?('-'))
49
+ IPAddr.new(cidr_or_glob).each(&block)
50
+ return nil
51
+ end
52
+
53
+ if cidr_or_glob.include?('::')
54
+ prefix = if cidr_or_glob =~ /^::/
55
+ '::'
56
+ else
57
+ ''
58
+ end
59
+
60
+ separator = '::'
61
+ base = 16
62
+
63
+ format = lambda { |address|
64
+ prefix + address.map { |i| '%.2x' % i }.join('::')
65
+ }
66
+ else
67
+ separator = '.'
68
+ base = 10
69
+
70
+ format = lambda { |address| address.join('.') }
71
+ end
72
+
73
+ ranges = cidr_or_glob.split(separator).map { |segment|
74
+ if segment == '*'
75
+ (1..254)
76
+ elsif segment.include?('-')
77
+ start, stop = segment.split('-',2).map { |i| i.to_i(base) }
78
+
79
+ (start..stop)
80
+ elsif !(segment.empty?)
81
+ segment.to_i(base)
82
+ end
83
+ }.compact
84
+
85
+ expand_range = lambda { |address,remaining|
86
+ if remaining.empty?
87
+ block.call(format.call(address))
88
+ else
89
+ n = remaining.first
90
+ remaining = remaining[1..-1]
91
+
92
+ if n.kind_of?(Range)
93
+ n.each { |i| expand_range.call(address + [i], remaining) }
94
+ else
95
+ expand_range.call(address + [n], remaining)
96
+ end
97
+ end
98
+ }
99
+
100
+ expand_range.call([], ranges)
101
+ return nil
102
+ end
103
+
104
+ #
105
+ # Iterates over each IP address that is included in the addresses mask,
106
+ # passing each address to the specified _block_.
107
+ #
108
+ # IPAddr.new('10.1.1.1/24').each do |ip|
109
+ # puts ip
110
+ # end
111
+ #
112
+ def each(&block)
113
+ case @family
114
+ when Socket::AF_INET
115
+ family_mask = IN4MASK
116
+ when Socket::AF_INET6
117
+ family_mask = IN6MASK
118
+ end
119
+
120
+ (0..((~@mask_addr) & family_mask)).each do |i|
121
+ block.call(_to_string(@addr | i))
122
+ end
123
+
124
+ return self
125
+ end
126
+
127
+ end
@@ -21,9 +21,20 @@
21
21
  #++
22
22
  #
23
23
 
24
- module Ronin
25
- module Objectify
26
- class ObjectContextNotFound < RuntimeError
24
+ module Kernel
25
+ #
26
+ # Calls the given _block_ and ignores any raised exceptions.
27
+ # If an exception is raised, +nil+ will be returned.
28
+ #
29
+ # try do
30
+ # Resolv.getaddress('might.not.exist.com')
31
+ # end
32
+ #
33
+ def try(&block)
34
+ begin
35
+ block.call if block
36
+ rescue
37
+ return nil
27
38
  end
28
39
  end
29
40
  end
@@ -21,6 +21,8 @@
21
21
  #++
22
22
  #
23
23
 
24
+ require 'cgi'
25
+
24
26
  module URI
25
27
  module QueryParams
26
28
  # Query parameters
@@ -89,9 +91,9 @@ module URI
89
91
  "#{name}=active"
90
92
  elsif value
91
93
  if value.kind_of?(Array)
92
- "#{name}=#{URI.encode(value.join(' '))}"
94
+ "#{name}=#{CGI.escape(value.join(' '))}"
93
95
  else
94
- "#{name}=#{URI.encode(value.to_s)}"
96
+ "#{name}=#{CGI.escape(value.to_s)}"
95
97
  end
96
98
  else
97
99
  "#{name}="
@@ -32,6 +32,12 @@ class Integer
32
32
  # _endian_ must be either <tt>:little</tt>, <tt>:big</tt> or
33
33
  # <tt>:net</tt>.
34
34
  #
35
+ # 0xff41.bytes(2)
36
+ # # => [65, 255]
37
+ #
38
+ # 0xff41.bytes(4, :big)
39
+ # # => [0, 0, 255, 65]
40
+ #
35
41
  def bytes(address_length,endian=:little)
36
42
  endian = endian.to_s
37
43
  buffer = []
@@ -40,19 +40,21 @@ class String
40
40
  #
41
41
  def depack(arch,address_length=arch.address_length)
42
42
  integer = 0x0
43
+ byte_index = 0
43
44
 
44
- if arch.endian=='little'
45
- address_length.times do |i|
46
- if self[i]
47
- integer = (integer | (self[i] << (i*8)))
48
- end
49
- end
50
- elsif arch.endian=='big'
51
- address_length.times do |i|
52
- if self[i]
53
- integer = (integer | (self[i] << ((address_length-i-1)*8)))
54
- end
55
- end
45
+ if arch.endian == 'little'
46
+ mask = lambda { |b| b << (byte_index * 8) }
47
+ elsif arch.endian == 'big'
48
+ mask = lambda { |b|
49
+ b << ((address_length - byte_index - 1) * 8)
50
+ }
51
+ end
52
+
53
+ self.each_byte do |b|
54
+ break if byte_index >= address_length
55
+
56
+ integer |= mask.call(b)
57
+ byte_index += 1
56
58
  end
57
59
 
58
60
  return integer
@@ -26,7 +26,7 @@ require 'chars'
26
26
  class String
27
27
 
28
28
  #
29
- # Creates a new String by passing each character to the specified _block_
29
+ # Creates a new String by passing each byte to the specified _block_
30
30
  # using the given _options_.
31
31
  #
32
32
  # _options_ may include the following keys:
@@ -34,7 +34,7 @@ class String
34
34
  # defaults to <tt>Chars.all</tt>.
35
35
  # <tt>:excluded</tt>:: The characters not to format.
36
36
  #
37
- def format_chars(options={},&block)
37
+ def format_bytes(options={},&block)
38
38
  included = (options[:included] || Chars.all)
39
39
  excluded = (options[:excluded] || [])
40
40
 
@@ -42,12 +42,10 @@ class String
42
42
  formatted = ''
43
43
 
44
44
  self.each_byte do |b|
45
- c = b.chr
46
-
47
45
  if targeted.include_byte?(b)
48
- formatted << block.call(c)
46
+ formatted << block.call(b)
49
47
  else
50
- formatted << c
48
+ formatted << b
51
49
  end
52
50
  end
53
51
 
@@ -55,7 +53,7 @@ class String
55
53
  end
56
54
 
57
55
  #
58
- # Creates a new String by passing each byte to the specified _block_
56
+ # Creates a new String by passing each character to the specified _block_
59
57
  # using the given _options_.
60
58
  #
61
59
  # _options_ may include the following keys:
@@ -63,15 +61,9 @@ class String
63
61
  # defaults to <tt>Chars.all</tt>.
64
62
  # <tt>:excluded</tt>:: The characters not to format.
65
63
  #
66
- def format_bytes(options={},&block)
67
- format_chars(options) do |c|
68
- i = block.call(c[0])
69
-
70
- if i.kind_of?(Integer)
71
- i.chr
72
- else
73
- i.to_s
74
- end
64
+ def format_chars(options={},&block)
65
+ format_bytes(options) do |b|
66
+ block.call(b.chr)
75
67
  end
76
68
  end
77
69
 
@@ -83,14 +75,14 @@ class String
83
75
  # <tt>:probability</tt>:: The probability that a character will have it's
84
76
  # case changed; defaults to 0.5.
85
77
  #
86
- # "get out your checkbook".rand_case
87
- # # => "gEt Out YOur CHEckbook"
78
+ # "get out your checkbook".random_case
79
+ # # => "gEt Out YOur CHEckbook"
88
80
  #
89
81
  def random_case(options={})
90
82
  prob = (options[:probability] || 0.5)
91
83
 
92
84
  format_chars(options) do |c|
93
- if rand < prob
85
+ if rand <= prob
94
86
  c.swapcase
95
87
  else
96
88
  c
@@ -98,4 +90,30 @@ class String
98
90
  end
99
91
  end
100
92
 
93
+ #
94
+ # Pads the string using the specified _padding_ out to the given
95
+ # _max_length_. _max_length_ will default to the strings own length,
96
+ # if not given.
97
+ #
98
+ # "hello".pad('A',50)
99
+ # # => "helloAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
100
+ #
101
+ def pad(padding,max_length=self.length)
102
+ padding = padding.to_s
103
+
104
+ if max_length >= self.length
105
+ max_length -= self.length
106
+ else
107
+ max_length = 0
108
+ end
109
+
110
+ padded = self + (padding * (max_length / padding.length))
111
+
112
+ unless (remaining = max_length % padding.length) == 0
113
+ padded += padding[0...remaining]
114
+ end
115
+
116
+ return padded
117
+ end
118
+
101
119
  end