ronin-sql 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 (40) hide show
  1. data/History.txt +9 -0
  2. data/Manifest.txt +7 -2
  3. data/README.txt +6 -3
  4. data/Rakefile +8 -8
  5. data/lib/ronin/code/sql/alter_table.rb +6 -6
  6. data/lib/ronin/code/sql/common_dialect.rb +1 -1
  7. data/lib/ronin/code/sql/create.rb +10 -2
  8. data/lib/ronin/code/sql/create_index.rb +3 -3
  9. data/lib/ronin/code/sql/create_table.rb +3 -3
  10. data/lib/ronin/code/sql/create_view.rb +3 -3
  11. data/lib/ronin/code/sql/delete.rb +7 -2
  12. data/lib/ronin/code/sql/dialect.rb +3 -1
  13. data/lib/ronin/code/sql/drop_index.rb +3 -3
  14. data/lib/ronin/code/sql/drop_table.rb +3 -3
  15. data/lib/ronin/code/sql/drop_view.rb +3 -3
  16. data/lib/ronin/code/sql/insert.rb +5 -5
  17. data/lib/ronin/code/sql/program.rb +2 -1
  18. data/lib/ronin/code/sql/select.rb +18 -5
  19. data/lib/ronin/code/sql/update.rb +3 -3
  20. data/lib/ronin/formatting/extensions/sql/string.rb +69 -0
  21. data/lib/ronin/formatting/extensions/sql.rb +24 -0
  22. data/lib/ronin/formatting/sql.rb +24 -0
  23. data/lib/ronin/sql/{extensions → error/extensions}/string.rb +3 -46
  24. data/lib/ronin/sql/error/extensions.rb +24 -0
  25. data/lib/ronin/sql/error/patterns.rb +1 -0
  26. data/lib/ronin/sql/error.rb +1 -0
  27. data/lib/ronin/sql/extensions/uri/http.rb +13 -28
  28. data/lib/ronin/sql/extensions.rb +0 -1
  29. data/lib/ronin/sql/injection.rb +2 -0
  30. data/lib/ronin/sql/version.rb +1 -1
  31. data/lib/ronin/sql.rb +0 -1
  32. data/spec/code/sql/common_dialect_spec.rb +205 -0
  33. data/spec/code/sql/create_examples.rb +4 -4
  34. data/spec/code/sql/select_spec.rb +4 -4
  35. data/spec/spec_helper.rb +3 -1
  36. data/spec/sql/extensions/uri/http_spec.rb +34 -0
  37. data.tar.gz.sig +1 -0
  38. metadata +45 -11
  39. metadata.gz.sig +4 -0
  40. data/spec/sql/extensions/string_spec.rb +0 -28
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 0.2.3 / 2009-07-02
2
+
3
+ * Use Hoe >= 2.0.0.
4
+ * Require ronin >= 0.2.4.
5
+ * Require ronin-web >= 0.1.3.
6
+ * Use Ronin::Scanners::Scanner to define the scanner for finding
7
+ Ronin::SQL::Injection objects for URI::HTTP urls.
8
+ * Added more specs.
9
+
1
10
  === 0.2.2 / 2009-01-22
2
11
 
3
12
  * Depend on the new ronin-web library.
data/Manifest.txt CHANGED
@@ -63,11 +63,15 @@ lib/ronin/code/sql/union_clause.rb
63
63
  lib/ronin/code/sql/update.rb
64
64
  lib/ronin/code/sql/values_clause.rb
65
65
  lib/ronin/code/sql/where_clause.rb
66
+ lib/ronin/formatting/sql.rb
67
+ lib/ronin/formatting/extensions/sql.rb
68
+ lib/ronin/formatting/extensions/sql/string.rb
66
69
  lib/ronin/sql/extensions.rb
67
- lib/ronin/sql/extensions/string.rb
68
70
  lib/ronin/sql/extensions/uri.rb
69
71
  lib/ronin/sql/extensions/uri/http.rb
70
72
  lib/ronin/sql/error.rb
73
+ lib/ronin/sql/error/extensions.rb
74
+ lib/ronin/sql/error/extensions/string.rb
71
75
  lib/ronin/sql/error/message.rb
72
76
  lib/ronin/sql/error/pattern.rb
73
77
  lib/ronin/sql/error/error.rb
@@ -97,5 +101,6 @@ spec/code/sql/select_spec.rb
97
101
  spec/code/sql/update_spec.rb
98
102
  spec/code/sql/replace_spec.rb
99
103
  spec/code/sql/delete_spec.rb
104
+ spec/code/sql/common_dialect_spec.rb
100
105
  spec/sql/error_spec.rb
101
- spec/sql/extensions/string_spec.rb
106
+ spec/sql/extensions/uri/http_spec.rb
data/README.txt CHANGED
@@ -45,12 +45,15 @@ of Ronin.
45
45
 
46
46
  == REQUIREMENTS:
47
47
 
48
- * ronin >= 0.1.2
49
- * ronin-web >= 0.1.0
48
+ * {ronin}[http://ronin.rubyforge.org/] >= 0.1.2
49
+ * {ronin-web}[http://ronin.rubyforge.org/web/] >= 0.1.0
50
50
 
51
51
  == INSTALL:
52
52
 
53
- $ sudo gem install ronin-sql
53
+ $ sudo gem install --no-rdoc ronin-sql
54
+
55
+ * Due to a bug in RDoc ronin-sql must be installed with RDoc documentation
56
+ disabled.
54
57
 
55
58
  == EXAMPLES:
56
59
 
data/Rakefile CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
+ require 'hoe/signing'
5
6
  require './tasks/spec.rb'
6
- require './lib/ronin/sql/version.rb'
7
7
 
8
- Hoe.new('ronin-sql', Ronin::SQL::VERSION) do |p|
9
- p.rubyforge_name = 'ronin'
10
- p.developer('Postmodern','postmodern.mod3@gmail.com')
11
- p.remote_rdoc_dir = 'docs/ronin-sql'
12
- p.extra_deps = [
13
- ['ronin', '>=0.1.4'],
14
- ['ronin-web', '>=0.1.0']
8
+ Hoe.spec('ronin-sql') do
9
+ self.rubyforge_name = 'ronin'
10
+ self.developer('Postmodern','postmodern.mod3@gmail.com')
11
+ self.remote_rdoc_dir = 'docs/ronin-sql'
12
+ self.extra_deps = [
13
+ ['ronin', '>=0.2.4'],
14
+ ['ronin-web', '>=0.1.3']
15
15
  ]
16
16
  end
17
17
 
@@ -33,15 +33,15 @@ module Ronin
33
33
  clause :rename_to, RenameToClause
34
34
  clause :add_column, AddColumnClause
35
35
 
36
- def initialize(options={},&block)
37
- @table = options[:table]
36
+ def initialize(dialect,table=nil,options={},&block)
37
+ @table = table
38
38
 
39
- super(options,&block)
39
+ super(dialect,options,&block)
40
40
  end
41
41
 
42
- def table(name)
43
- @table = name
44
- return self
42
+ def table(name=nil)
43
+ @table = name if name
44
+ return @table
45
45
  end
46
46
 
47
47
  def emit
@@ -50,7 +50,7 @@ module Ronin
50
50
 
51
51
  aggregators :avg, :count, :group_concat, :min, :max, :sum, :total
52
52
 
53
- statement :create_type, CreateTable
53
+ statement :create_table, CreateTable
54
54
  statement :create_index, CreateIndex
55
55
  statement :create_view, CreateView
56
56
  statement :alter_table, AlterTable
@@ -40,16 +40,24 @@ module Ronin
40
40
  super(dialect,options,&block)
41
41
  end
42
42
 
43
- def temp
43
+ def temp!
44
44
  @temp = true
45
45
  return self
46
46
  end
47
47
 
48
- def if_not_exists
48
+ def temp?
49
+ @temp == true
50
+ end
51
+
52
+ def if_not_exists!
49
53
  @if_not_exists = true
50
54
  return self
51
55
  end
52
56
 
57
+ def if_not_exists?
58
+ @if_not_exists == true
59
+ end
60
+
53
61
  def emit
54
62
  tokens = emit_token('CREATE')
55
63
  tokens += emit_token('TEMP') if @temp
@@ -35,9 +35,9 @@ module Ronin
35
35
  super(dialect,'INDEX',index,options,&block)
36
36
  end
37
37
 
38
- def index(name)
39
- @name = name
40
- return self
38
+ def index(name=nil)
39
+ @name = name if name
40
+ return @name
41
41
  end
42
42
 
43
43
  end
@@ -35,9 +35,9 @@ module Ronin
35
35
  super(dialect,'TABLE',table,options,&block)
36
36
  end
37
37
 
38
- def table(name)
39
- @name = name
40
- return self
38
+ def table(name=nil)
39
+ @name = name if name
40
+ return @name
41
41
  end
42
42
 
43
43
  end
@@ -32,9 +32,9 @@ module Ronin
32
32
  super(dialect,'VIEW',view,options,&block)
33
33
  end
34
34
 
35
- def view(name)
36
- @name = name
37
- return self
35
+ def view(name=nil)
36
+ @name = name if name
37
+ return @name
38
38
  end
39
39
 
40
40
  end
@@ -33,12 +33,17 @@ module Ronin
33
33
  clause :from, FromClause
34
34
  clause :where, WhereClause
35
35
 
36
- def initialize(dialect,options={},&block)
37
- @table = options[:table]
36
+ def initialize(dialect,table=nil,options={},&block)
37
+ @table = table
38
38
 
39
39
  super(dialect,options,&block)
40
40
  end
41
41
 
42
+ def table(name=nil)
43
+ @table = name if name
44
+ return @table
45
+ end
46
+
42
47
  def emit
43
48
  emit_token('DELETE FROM') + emit_value(@table)
44
49
  end
@@ -212,7 +212,9 @@ module Ronin
212
212
  type_name = name.upcase
213
213
  supports_length = options[:length]
214
214
 
215
- class_def(name) do |length|
215
+ class_def(name) do |*arguments|
216
+ length = arguments.first
217
+
216
218
  if (supports_length && length)
217
219
  Token.new("#{type_name}(#{length})")
218
220
  else
@@ -32,9 +32,9 @@ module Ronin
32
32
  super(dialect,'INDEX',index,options,&block)
33
33
  end
34
34
 
35
- def index(name)
36
- @name = name
37
- return self
35
+ def index(name=nil)
36
+ @name = name if name
37
+ return @name
38
38
  end
39
39
 
40
40
  end
@@ -32,9 +32,9 @@ module Ronin
32
32
  super(dialect,'TABLE',table,options,&block)
33
33
  end
34
34
 
35
- def table(name)
36
- @name = name
37
- return self
35
+ def table(name=nil)
36
+ @name = name if name
37
+ return @name
38
38
  end
39
39
 
40
40
  end
@@ -32,9 +32,9 @@ module Ronin
32
32
  super(dialect,'VIEW',view,options,&block)
33
33
  end
34
34
 
35
- def view(name)
36
- @name = name
37
- return self
35
+ def view(name=nil)
36
+ @name = name if name
37
+ return @name
38
38
  end
39
39
 
40
40
  end
@@ -35,15 +35,15 @@ module Ronin
35
35
  clause :default_values, DefaultValuesClause
36
36
  clause :values, ValuesClause
37
37
 
38
- def initialize(dialect,options={},&block)
39
- @table = options[:table]
38
+ def initialize(dialect,table=nil,options={},&block)
39
+ @table = table
40
40
 
41
41
  super(dialect,options,&block)
42
42
  end
43
43
 
44
- def table(name)
45
- @table = name
46
- return value
44
+ def table(name=nil)
45
+ @table = name if name
46
+ return @table
47
47
  end
48
48
 
49
49
  def emit
@@ -23,7 +23,8 @@
23
23
 
24
24
  require 'ronin/code/sql/dialect'
25
25
  require 'ronin/code/sql/common_dialect'
26
- require 'ronin/chars/char_set'
26
+
27
+ require 'chars/char_set'
27
28
 
28
29
  module Ronin
29
30
  module Code
@@ -52,11 +52,16 @@ module Ronin
52
52
  clause :union_all, UnionAllClause
53
53
 
54
54
  def initialize(dialect,options={},&block)
55
- @distinct_rows = options[:distinct_rows]
56
- @all_rows = options[:all_rows]
57
-
58
55
  super(dialect,options)
59
56
 
57
+ if options[:distinct_rows]
58
+ self.distinct_rows!
59
+ end
60
+
61
+ if options[:all_rows]
62
+ self.all_rows!
63
+ end
64
+
60
65
  unless options[:fields]
61
66
  fields(all)
62
67
  end
@@ -64,16 +69,24 @@ module Ronin
64
69
  instance_eval(&block) if block
65
70
  end
66
71
 
67
- def all_rows
72
+ def all_rows!
68
73
  @all_rows = true
69
74
  return self
70
75
  end
71
76
 
72
- def distinct_rows
77
+ def all_rows?
78
+ @all_rows == true
79
+ end
80
+
81
+ def distinct_rows!
73
82
  @distinct_rows = true
74
83
  return self
75
84
  end
76
85
 
86
+ def distinct_rows?
87
+ @distinct_rows == true
88
+ end
89
+
77
90
  def emit
78
91
  tokens = emit_token('SELECT')
79
92
 
@@ -39,9 +39,9 @@ module Ronin
39
39
  super(dialect,options,&block)
40
40
  end
41
41
 
42
- def table(value)
43
- @table = value
44
- return self
42
+ def table(name=nil)
43
+ @table = name if name
44
+ return @table
45
45
  end
46
46
 
47
47
  def emit
@@ -0,0 +1,69 @@
1
+ #
2
+ #--
3
+ # Ronin SQL - A Ronin library providing support for SQL related security
4
+ # tasks.
5
+ #
6
+ # Copyright (c) 2007-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
+ class String
25
+
26
+ #
27
+ # Returns the SQL hex-string encoded form of the String.
28
+ #
29
+ # "/etc/passwd".sql_encode
30
+ # # => "0x2f6574632f706173737764"
31
+ #
32
+ def sql_encode
33
+ return '' if empty?
34
+
35
+ hex_string = '0x'
36
+
37
+ each_byte do |b|
38
+ hex_string << ('%.2x' % b)
39
+ end
40
+
41
+ return hex_string
42
+ end
43
+
44
+ #
45
+ # Returns the SQL decoded form of the String.
46
+ #
47
+ # "'Conan O''Brian'".sql_decode
48
+ # # => "Conan O'Brian"
49
+ #
50
+ # "0x2f6574632f706173737764".sql_decode
51
+ # # => "/etc/passwd"
52
+ #
53
+ def sql_decode
54
+ if ((self[0...2] == '0x') && (length % 2 == 0))
55
+ raw = ''
56
+
57
+ self[2..-1].scan(/[0-9a-fA-F]{2}/).each do |hex_char|
58
+ raw << hex_char.hex.chr
59
+ end
60
+
61
+ return raw
62
+ elsif (self[0..0] == "'" && self[-1..-1] == "'")
63
+ self[1..-2].gsub(/\\'/,"'").gsub(/''/,"'")
64
+ else
65
+ return self
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ #--
3
+ # Ronin SQL - A Ronin library providing support for SQL related security
4
+ # tasks.
5
+ #
6
+ # Copyright (c) 2007-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 'ronin/formatting/extensions/sql/string'
@@ -0,0 +1,24 @@
1
+ #
2
+ #--
3
+ # Ronin SQL - A Ronin library providing support for SQL related security
4
+ # tasks.
5
+ #
6
+ # Copyright (c) 2007-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 'ronin/formatting/extensions/sql'
@@ -62,11 +62,11 @@ class String
62
62
  #
63
63
  def sql_error?(options={})
64
64
  if options[:dialect]
65
- patterns = Error.patterns_for_dialect(options[:dialect])
65
+ patterns = Ronin::SQL::Error.patterns_for_dialect(options[:dialect])
66
66
  elsif options[:types]
67
- patterns = Error.patterns_for(*options[:types])
67
+ patterns = Ronin::SQL::Error.patterns_for(*options[:types])
68
68
  else
69
- patterns = Error.patterns.values
69
+ patterns = Ronin::SQL::Error.patterns.values
70
70
  end
71
71
 
72
72
  patterns.each do |pattern|
@@ -76,47 +76,4 @@ class String
76
76
  return false
77
77
  end
78
78
 
79
- #
80
- # Returns the SQL hex-string encoded form of the String.
81
- #
82
- # "/etc/passwd".sql_encode
83
- # # => "0x2f6574632f706173737764"
84
- #
85
- def sql_encode
86
- return '' if empty?
87
-
88
- hex_string = '0x'
89
-
90
- each_byte do |b|
91
- hex_string << ('%.2x' % b)
92
- end
93
-
94
- return hex_string
95
- end
96
-
97
- #
98
- # Returns the SQL decoded form of the String.
99
- #
100
- # "'Conan O''Brian'".sql_decode
101
- # # => "Conan O'Brian"
102
- #
103
- # "0x2f6574632f706173737764".sql_decode
104
- # # => "/etc/passwd"
105
- #
106
- def sql_decode
107
- if ((self[0...2] == '0x') && (length % 2 == 0))
108
- raw = ''
109
-
110
- self[2..-1].scan(/[0-9a-fA-F]{2}/).each do |hex_char|
111
- raw << hex_char.hex.chr
112
- end
113
-
114
- return raw
115
- elsif (self[0..0] == "'" && self[-1..-1] == "'")
116
- self[1..-2].gsub(/\\'/,"'").gsub(/''/,"'")
117
- else
118
- return self
119
- end
120
- end
121
-
122
79
  end
@@ -0,0 +1,24 @@
1
+ #
2
+ #--
3
+ # Ronin SQL - A Ronin library providing support for SQL related security
4
+ # tasks.
5
+ #
6
+ # Copyright (c) 2007-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 'ronin/sql/error/extensions/string'
@@ -28,6 +28,7 @@ module Ronin
28
28
  module Error
29
29
  Error.pattern :ms_sql do |p|
30
30
  p.dialect = :ms
31
+ p.recognize /Microsoft SQL Native Client/
31
32
  p.recognize /Microsoft OLE DB Provider for SQL Server/
32
33
  p.recognize /Microsoft OLE DB Provider for ODBC Drivers.*\[Microsoft\]\[ODBC SQL Server Driver\]/
33
34
  end
@@ -25,3 +25,4 @@ require 'ronin/sql/error/message'
25
25
  require 'ronin/sql/error/pattern'
26
26
  require 'ronin/sql/error/error'
27
27
  require 'ronin/sql/error/patterns'
28
+ require 'ronin/sql/error/extensions'
@@ -22,12 +22,14 @@
22
22
  #
23
23
 
24
24
  require 'ronin/sql/injection'
25
+ require 'ronin/scanners/scanner'
25
26
  require 'ronin/extensions/uri/http'
26
- require 'ronin/chars'
27
27
 
28
28
  module URI
29
29
  class HTTP < Generic
30
30
 
31
+ include Ronin::Scanners::Scanner
32
+
31
33
  #
32
34
  # Tests the +query_params+ of the HTTP URL with the given _options_ for
33
35
  # SQL errors.
@@ -39,9 +41,9 @@ module URI
39
41
  errors = {}
40
42
 
41
43
  return each_query_param do |param,value|
42
- error = SQL::Injection.new(self,param).error(options)
44
+ mesg = Ronin::SQL::Injection.new(self,param).error(options)
43
45
 
44
- errors[param] = error if error
46
+ errors[param] = mesg if mesg
45
47
  end
46
48
 
47
49
  return errors
@@ -66,10 +68,8 @@ module URI
66
68
  # Tests the +query_params+ of the HTTP URL with the given _options_ for
67
69
  # blind SQL injections.
68
70
  #
69
- def sql_injections(options={})
70
- injectable = []
71
-
72
- each_query_param do |param,value|
71
+ scanner(:sqli) do |url,results,options|
72
+ url.each_query_param do |param,value|
73
73
  integer_tests = [
74
74
  {:escape => value},
75
75
  {:escape => value, :close_parenthesis => true}
@@ -80,7 +80,7 @@ module URI
80
80
  {:escape => value, :close_string => true, :close_parenthesis => true}
81
81
  ]
82
82
 
83
- if (value && Chars.numeric =~ value)
83
+ if (value && value =~ /^[0-9]+$/)
84
84
  # if the param value is numeric, we should try escaping a
85
85
  # numeric value first.
86
86
  tests = integer_tests + string_tests
@@ -91,34 +91,19 @@ module URI
91
91
  end
92
92
 
93
93
  tests.each do |test|
94
- inj = Ronin::SQL::Injection.new(self,param,options.merge(test))
94
+ inj = Ronin::SQL::Injection.new(url,param,options.merge(test))
95
95
 
96
96
  if inj.vulnerable?(options)
97
- injectable << inj
97
+ results.call(inj)
98
98
  break
99
99
  end
100
100
  end
101
101
  end
102
-
103
- return injectable
104
- end
105
-
106
- #
107
- # Returns the first vulnerable SQL injection object found in the
108
- # HTTP URL.
109
- #
110
- def sql_injection(options={})
111
- sql_injections(options).first
112
102
  end
113
103
 
114
- #
115
- # Returns +true+ if any of the +query_params+ of the HTTP URL are
116
- # vulnerable to blind SQL injection using the given _options_, returns
117
- # +false+ otherwise.
118
- #
119
- def has_sql_injections?(options={})
120
- !(sql_injections(options).empty?)
121
- end
104
+ alias sql_injections sqli_scan
105
+ alias sql_injection first_sqli
106
+ alias has_sql_injections? has_sqli?
122
107
 
123
108
  end
124
109
  end
@@ -21,5 +21,4 @@
21
21
  #++
22
22
  #
23
23
 
24
- require 'ronin/sql/extensions/string'
25
24
  require 'ronin/sql/extensions/uri'
@@ -28,12 +28,14 @@ require 'ronin/extensions/uri'
28
28
  require 'ronin/web/extensions/nokogiri'
29
29
  require 'ronin/web/spider'
30
30
 
31
+ require 'parameters'
31
32
  require 'nokogiri'
32
33
 
33
34
  module Ronin
34
35
  module SQL
35
36
  class Injection
36
37
 
38
+ include Parameters
37
39
  include Sessions::HTTP
38
40
 
39
41
  # The URL to inject upon
@@ -24,6 +24,6 @@
24
24
  module Ronin
25
25
  module SQL
26
26
  # Ronin SQL version
27
- VERSION = '0.2.2'
27
+ VERSION = '0.2.3'
28
28
  end
29
29
  end
data/lib/ronin/sql.rb CHANGED
@@ -21,7 +21,6 @@
21
21
  #++
22
22
  #
23
23
 
24
- require 'ronin/code/sql'
25
24
  require 'ronin/sql/extensions'
26
25
  require 'ronin/sql/error'
27
26
  require 'ronin/sql/injection'
@@ -0,0 +1,205 @@
1
+ require 'ronin/code/sql/common_dialect'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Code::SQL::CommonDialect do
6
+ before(:all) do
7
+ @dialect = Code::SQL::CommonDialect.new
8
+ end
9
+
10
+ it "should provide the 'yes' primitive" do
11
+ token = @dialect.yes
12
+
13
+ token.class.should == Code::SQL::Token
14
+ token.to_s.should == 'yes'
15
+ end
16
+
17
+ it "should provide the 'no' primitive" do
18
+ token = @dialect.no
19
+
20
+ token.class.should == Code::SQL::Token
21
+ token.to_s.should == 'no'
22
+ end
23
+
24
+ it "should provide the 'on' primitive" do
25
+ token = @dialect.on
26
+
27
+ token.class.should == Code::SQL::Token
28
+ token.to_s.should == 'on'
29
+ end
30
+
31
+ it "should provide the 'off' primitive" do
32
+ token = @dialect.off
33
+
34
+ token.class.should == Code::SQL::Token
35
+ token.to_s.should == 'off'
36
+ end
37
+
38
+ it "should provide the 'null' primitive" do
39
+ token = @dialect.null
40
+
41
+ token.class.should == Code::SQL::Token
42
+ token.to_s.should == 'null'
43
+ end
44
+
45
+ it "should provide the 'int' data-type" do
46
+ token = @dialect.int
47
+
48
+ token.class.should == Code::SQL::Token
49
+ token.to_s.should == 'INT'
50
+ end
51
+
52
+ it "should provide the 'varchar' data-type" do
53
+ token = @dialect.varchar
54
+
55
+ token.class.should == Code::SQL::Token
56
+ token.to_s.should == 'VARCHAR'
57
+ end
58
+
59
+ it "should provide the 'varchar' data-type with specific length" do
60
+ token = @dialect.varchar(15)
61
+
62
+ token.class.should == Code::SQL::Token
63
+ token.to_s.should == 'VARCHAR(15)'
64
+ end
65
+
66
+ it "should provide the 'text' data-type" do
67
+ token = @dialect.text
68
+
69
+ token.class.should == Code::SQL::Token
70
+ token.to_s.should == 'TEXT'
71
+ end
72
+
73
+ it "should provide the 'record' data-type" do
74
+ token = @dialect.record
75
+
76
+ token.class.should == Code::SQL::Token
77
+ token.to_s.should == 'RECORD'
78
+ end
79
+
80
+ it "should provide the 'avg' function" do
81
+ func = @dialect.avg(:salary)
82
+
83
+ func.name.should == :avg
84
+ func.fields.should == [:salary]
85
+ end
86
+
87
+ it "should provide the 'count' function" do
88
+ func = @dialect.count(:id)
89
+
90
+ func.name.should == :count
91
+ func.fields.should == [:id]
92
+ end
93
+
94
+ it "should provide the 'group_concat' function" do
95
+ func = @dialect.group_concat(:id)
96
+
97
+ func.name.should == :group_concat
98
+ func.fields.should == [:id]
99
+ end
100
+
101
+ it "should provide the 'min' function" do
102
+ func = @dialect.min(:salary)
103
+
104
+ func.name.should == :min
105
+ func.fields.should == [:salary]
106
+ end
107
+
108
+ it "should provide the 'max' function" do
109
+ func = @dialect.max(:salary)
110
+
111
+ func.name.should == :max
112
+ func.fields.should == [:salary]
113
+ end
114
+
115
+ it "should provide the 'sum' function" do
116
+ func = @dialect.sum(:salary)
117
+
118
+ func.name.should == :sum
119
+ func.fields.should == [:salary]
120
+ end
121
+
122
+ it "should provide the 'total' function" do
123
+ func = @dialect.total(:salary)
124
+
125
+ func.name.should == :total
126
+ func.fields.should == [:salary]
127
+ end
128
+
129
+ it "should provide the 'create table' statement" do
130
+ stmt = @dialect.create_table(:users)
131
+
132
+ stmt.class.should == Code::SQL::CreateTable
133
+ stmt.table.should == :users
134
+ end
135
+
136
+ it "should provide the 'create index' statement" do
137
+ stmt = @dialect.create_index(:users_index)
138
+
139
+ stmt.class.should == Code::SQL::CreateIndex
140
+ stmt.index.should == :users_index
141
+ end
142
+
143
+ it "should provide the 'create view' statement" do
144
+ stmt = @dialect.create_view(:users_view)
145
+
146
+ stmt.class.should == Code::SQL::CreateView
147
+ stmt.view.should == :users_view
148
+ end
149
+
150
+ it "should provide the 'alter table' statement" do
151
+ stmt = @dialect.alter_table(:users)
152
+
153
+ stmt.class.should == Code::SQL::AlterTable
154
+ stmt.table.should == :users
155
+ end
156
+
157
+ it "should provide the 'insert' statement" do
158
+ stmt = @dialect.insert(:users)
159
+
160
+ stmt.class.should == Code::SQL::Insert
161
+ stmt.table.should == :users
162
+ end
163
+
164
+ it "should provide the 'select' statement" do
165
+ stmt = @dialect.select(:from => :users)
166
+
167
+ stmt.class.should == Code::SQL::Select
168
+ stmt.from.table.should == :users
169
+ end
170
+
171
+ it "should provide the 'update' statement" do
172
+ stmt = @dialect.update(:users)
173
+
174
+ stmt.class.should == Code::SQL::Update
175
+ stmt.table.should == :users
176
+ end
177
+
178
+ it "should provide the 'delete' statement" do
179
+ stmt = @dialect.delete(:users)
180
+
181
+ stmt.class.should == Code::SQL::Delete
182
+ stmt.table.should == :users
183
+ end
184
+
185
+ it "should provide the 'drop table' statement" do
186
+ stmt = @dialect.drop_table(:users)
187
+
188
+ stmt.class.should == Code::SQL::DropTable
189
+ stmt.table.should == :users
190
+ end
191
+
192
+ it "should provide the 'drop index' statement" do
193
+ stmt = @dialect.drop_index(:users_index)
194
+
195
+ stmt.class.should == Code::SQL::DropIndex
196
+ stmt.index.should == :users_index
197
+ end
198
+
199
+ it "should provide the 'drop view' statement" do
200
+ stmt = @dialect.drop_view(:users_view)
201
+
202
+ stmt.class.should == Code::SQL::DropView
203
+ stmt.view.should == :users_view
204
+ end
205
+ end
@@ -8,12 +8,12 @@ shared_examples_for "Create" do
8
8
  it_should_behave_like "has a fields clause"
9
9
 
10
10
  it "should have a temp option" do
11
- @sql.temp
12
- @sql.instance_variable_get('@temp').should == true
11
+ @sql.temp!
12
+ @sql.should be_temp
13
13
  end
14
14
 
15
15
  it "should have a if_not_exists option" do
16
- @sql.if_not_exists
17
- @sql.instance_variable_get('@if_not_exists').should == true
16
+ @sql.if_not_exists!
17
+ @sql.should be_if_not_exists
18
18
  end
19
19
  end
@@ -94,12 +94,12 @@ describe Select do
94
94
  end
95
95
 
96
96
  it "should have an all rows option" do
97
- @sql.all_rows
98
- @sql.instance_variable_get('@all_rows').should == true
97
+ @sql.all_rows!
98
+ @sql.should be_all_rows
99
99
  end
100
100
 
101
101
  it "should have an distinct rows option" do
102
- @sql.distinct_rows
103
- @sql.instance_variable_get('@distinct_rows').should == true
102
+ @sql.distinct_rows!
103
+ @sql.should be_distinct_rows
104
104
  end
105
105
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'rubygems'
2
- gem 'rspec', '>=1.1.3'
2
+ gem 'rspec', '>=1.1.12'
3
3
  require 'spec'
4
4
 
5
+ require 'ronin/sql/version'
6
+
5
7
  include Ronin
@@ -0,0 +1,34 @@
1
+ require 'ronin/sql/extensions/uri/http'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe URI::HTTP do
6
+ before(:all) do
7
+ @url = URI('http://testasp.acunetix.com/showthread.asp?id=2')
8
+ end
9
+
10
+ it "should determine which query params have SQL errors" do
11
+ @url.sql_errors.should == {'id' => '2'}
12
+ end
13
+
14
+ it "should find all SQL injections" do
15
+ injections = @url.sql_injections
16
+ injection = injections.first
17
+
18
+ injections.length.should == 1
19
+
20
+ injection.param.should == 'id'
21
+ injection.sql_options[:escape].should == '2'
22
+ end
23
+
24
+ it "should find the first working SQL injection" do
25
+ injection = @url.sql_injection
26
+
27
+ injection.param.should == 'id'
28
+ injection.sql_options[:escape].should == '2'
29
+ end
30
+
31
+ it "should determine if a URL is vulnerable to SQL injection" do
32
+ @url.has_sql_injections?.should == true
33
+ end
34
+ end
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ Ȩ�f�^U��78�pF��Xg��lȘ&��"�[���"�����h���t�5oa~@x���Q�F�l�x��&� ͻó*��5>�Y�_:䭕����p��o�0xe4�U����(�d��T����4й��� �a�ɱ��Kd�1�D�k\0�^��c� �W�"��:`��^e�,�ی���c[�����*W)��8l|���J��E-,�Kt�n__W5��c���s�����u@ �M)���1c�#6��`��
metadata CHANGED
@@ -1,15 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ronin-sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDQDCCAiigAwIBAgIBADANBgkqhkiG9w0BAQUFADBGMRgwFgYDVQQDDA9wb3N0
14
+ bW9kZXJuLm1vZDMxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
15
+ ARkWA2NvbTAeFw0wOTA2MDMwNDU5MDNaFw0xMDA2MDMwNDU5MDNaMEYxGDAWBgNV
16
+ BAMMD3Bvc3Rtb2Rlcm4ubW9kMzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYK
17
+ CZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
18
+ 1wvANkTDHFgVih5XLjuTwTZjgBq1lBGybXJiH6Id1lY2JOMqM5FB1DDHVvvij94i
19
+ mJabN0zkzu6VKWC70y0IwOxY7CPokr0eFdK/D0y7mCq1P8QITv76i2YqAl0eYqIt
20
+ W+IhIkANQ7E6uMZIZcdnfadC6lPAtlKkqtd9crvRbFgr6e3kyflmohbRnTEJHoRd
21
+ 7SHHsybE6DSn7oTDs6XBTNrNIn5VfZA0z01eeos/+zBm1zKJOK2+/7xtLLDuDU9G
22
+ +Rd+ltUBbvxUrMNZmDG29pnmN2xTRH+Q8HxD2AxlvM5SRpK6OeZaHV7PaCCAVZ4L
23
+ T9BFl1sfMvRlABeGEkSyuQIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
24
+ sDAdBgNVHQ4EFgQUKwsd+PqEYmBvyaTyoL+uRuk+PhEwDQYJKoZIhvcNAQEFBQAD
25
+ ggEBAB4TvHsrlbcXcKg6gX5BIb9tI+zGkpzo0Z7jnxMEcNO7NGGwmzafDBI/xZYv
26
+ xkRH3/HXbGGYDOi6Q6gWt5GujSx0bOImDtYTJTH8jnzN92HzEK5WdScm1QpZKF1e
27
+ cezArMbxbSPaosxTCtG6LQTkE28lFQsmFZ5xzouugS4h5+LVJiVMmiP+l3EfkjFa
28
+ GOURU+rNEMPWo8MCWivGW7jes6BMzWHcW7DQ0scNVmIcCIgdyMmpscuAEOSeghy9
29
+ /fFs57Ey2OXBL55nDOyvN/ZQ2Vab05UH4t+GCxjAPeirzL/29FBtePT6VD44c38j
30
+ pDj+ws7QjtH/Qcrr1l9jfN0ehDs=
31
+ -----END CERTIFICATE-----
11
32
 
12
- date: 2009-01-22 00:00:00 -08:00
33
+ date: 2009-07-08 00:00:00 -07:00
13
34
  default_executable:
14
35
  dependencies:
15
36
  - !ruby/object:Gem::Dependency
@@ -20,7 +41,7 @@ dependencies:
20
41
  requirements:
21
42
  - - ">="
22
43
  - !ruby/object:Gem::Version
23
- version: 0.1.4
44
+ version: 0.2.4
24
45
  version:
25
46
  - !ruby/object:Gem::Dependency
26
47
  name: ronin-web
@@ -30,7 +51,7 @@ dependencies:
30
51
  requirements:
31
52
  - - ">="
32
53
  - !ruby/object:Gem::Version
33
- version: 0.1.0
54
+ version: 0.1.3
34
55
  version:
35
56
  - !ruby/object:Gem::Dependency
36
57
  name: hoe
@@ -40,9 +61,15 @@ dependencies:
40
61
  requirements:
41
62
  - - ">="
42
63
  - !ruby/object:Gem::Version
43
- version: 1.8.3
64
+ version: 2.3.2
44
65
  version:
45
- description: Ronin SQL is a Ruby library for Ronin that provids support for SQL related security tasks. Ronin is a Ruby platform designed for information security and data exploration tasks. Ronin allows for the rapid development and distribution of code over many of the common Source-Code-Management (SCM) systems.
66
+ description: |-
67
+ Ronin SQL is a Ruby library for Ronin that provids support for SQL related
68
+ security tasks.
69
+
70
+ Ronin is a Ruby platform designed for information security and data
71
+ exploration tasks. Ronin allows for the rapid development and distribution
72
+ of code over many of the common Source-Code-Management (SCM) systems.
46
73
  email:
47
74
  - postmodern.mod3@gmail.com
48
75
  executables: []
@@ -119,11 +146,15 @@ files:
119
146
  - lib/ronin/code/sql/update.rb
120
147
  - lib/ronin/code/sql/values_clause.rb
121
148
  - lib/ronin/code/sql/where_clause.rb
149
+ - lib/ronin/formatting/sql.rb
150
+ - lib/ronin/formatting/extensions/sql.rb
151
+ - lib/ronin/formatting/extensions/sql/string.rb
122
152
  - lib/ronin/sql/extensions.rb
123
- - lib/ronin/sql/extensions/string.rb
124
153
  - lib/ronin/sql/extensions/uri.rb
125
154
  - lib/ronin/sql/extensions/uri/http.rb
126
155
  - lib/ronin/sql/error.rb
156
+ - lib/ronin/sql/error/extensions.rb
157
+ - lib/ronin/sql/error/extensions/string.rb
127
158
  - lib/ronin/sql/error/message.rb
128
159
  - lib/ronin/sql/error/pattern.rb
129
160
  - lib/ronin/sql/error/error.rb
@@ -153,10 +184,13 @@ files:
153
184
  - spec/code/sql/update_spec.rb
154
185
  - spec/code/sql/replace_spec.rb
155
186
  - spec/code/sql/delete_spec.rb
187
+ - spec/code/sql/common_dialect_spec.rb
156
188
  - spec/sql/error_spec.rb
157
- - spec/sql/extensions/string_spec.rb
189
+ - spec/sql/extensions/uri/http_spec.rb
158
190
  has_rdoc: true
159
191
  homepage: http://ronin.rubyforge.org/sql/
192
+ licenses: []
193
+
160
194
  post_install_message:
161
195
  rdoc_options:
162
196
  - --main
@@ -178,9 +212,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
212
  requirements: []
179
213
 
180
214
  rubyforge_project: ronin
181
- rubygems_version: 1.3.1
215
+ rubygems_version: 1.3.4
182
216
  signing_key:
183
- specification_version: 2
217
+ specification_version: 3
184
218
  summary: Ronin SQL is a Ruby library for Ronin that provids support for SQL related security tasks
185
219
  test_files: []
186
220
 
metadata.gz.sig ADDED
@@ -0,0 +1,4 @@
1
+ �Z� ��d�L�u�dT�H�1�QP�A��U���]��E�w߸K��&a�t����AL��@�{�`����v�~�”Y{` ���$9i��\$�C�S�'������O�/�۔ka�e�\U3��&O�E��p�X���L�a_ �����Q��>�l*=����������E����c��`�T/$���1�:
2
+ OB&��S*���_T>�.�
3
+ �&���eX����v�k����2KC�6'_��e�
4
+ ��
@@ -1,28 +0,0 @@
1
- require 'ronin/sql/extensions/string'
2
-
3
- require 'spec_helper'
4
-
5
- describe String do
6
- describe "SQL-hex encoding" do
7
- it "should be able to be SQL-hex encoded" do
8
- '/etc/passwd'.sql_encode.should == '0x2f6574632f706173737764'
9
- end
10
-
11
- it "should return an empty String if empty" do
12
- ''.sql_encode.should == ''
13
- end
14
- end
15
-
16
- describe "SQL-hex decoding" do
17
- it "should be able to be SQL-hex decoded" do
18
- encoded = '/etc/passwd'.sql_encode
19
-
20
- encoded.should == '0x2f6574632f706173737764'
21
- encoded.sql_decode.should == '/etc/passwd'
22
- end
23
-
24
- it "should be able to decode SQL comma-escaping" do
25
- "'Conan O''Brian'".sql_decode.should == "Conan O'Brian"
26
- end
27
- end
28
- end