ronin-sql 0.1.1 → 0.2.0

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 (101) hide show
  1. data/History.txt +43 -0
  2. data/Manifest.txt +76 -23
  3. data/README.txt +31 -6
  4. data/Rakefile +2 -2
  5. data/lib/ronin/code/sql/{keyword.rb → add_column_clause.rb} +9 -13
  6. data/lib/ronin/code/sql/as.rb +47 -0
  7. data/lib/ronin/code/sql/asc.rb +38 -0
  8. data/lib/ronin/code/sql/between.rb +18 -12
  9. data/lib/ronin/code/sql/binary_expr.rb +12 -5
  10. data/lib/ronin/code/sql/clause.rb +37 -0
  11. data/lib/ronin/code/sql/code.rb +1 -1
  12. data/lib/ronin/code/sql/common_dialect.rb +16 -10
  13. data/lib/ronin/code/sql/create.rb +68 -0
  14. data/lib/ronin/code/sql/create_index.rb +9 -39
  15. data/lib/ronin/code/sql/create_table.rb +9 -56
  16. data/lib/ronin/code/sql/create_view.rb +7 -29
  17. data/lib/ronin/code/sql/default_values_clause.rb +38 -0
  18. data/lib/ronin/code/sql/delete.rb +10 -25
  19. data/lib/ronin/code/sql/desc.rb +38 -0
  20. data/lib/ronin/code/sql/dialect.rb +172 -52
  21. data/lib/ronin/code/sql/{builder.rb → drop.rb} +16 -20
  22. data/lib/ronin/code/sql/drop_index.rb +43 -0
  23. data/lib/ronin/code/sql/drop_table.rb +8 -16
  24. data/lib/ronin/code/sql/drop_view.rb +43 -0
  25. data/lib/ronin/code/sql/emittable.rb +102 -0
  26. data/lib/ronin/code/sql/exceptions/unknown_clause.rb +31 -0
  27. data/lib/ronin/code/sql/exceptions/unknown_dialect.rb +2 -2
  28. data/lib/ronin/code/sql/exceptions/unknown_statement.rb +31 -0
  29. data/lib/ronin/code/sql/exceptions.rb +3 -1
  30. data/lib/ronin/code/sql/expr.rb +7 -96
  31. data/lib/ronin/code/sql/field.rb +40 -23
  32. data/lib/ronin/code/sql/fields_clause.rb +48 -0
  33. data/lib/ronin/code/sql/from_clause.rb +44 -0
  34. data/lib/ronin/code/sql/function.rb +15 -12
  35. data/lib/ronin/code/sql/group_by_clause.rb +48 -0
  36. data/lib/ronin/code/sql/having_clause.rb +48 -0
  37. data/lib/ronin/code/sql/in.rb +9 -9
  38. data/lib/ronin/code/sql/injected_statement.rb +102 -0
  39. data/lib/ronin/code/sql/injection.rb +171 -5
  40. data/lib/ronin/code/sql/insert.rb +15 -45
  41. data/lib/ronin/code/sql/intersect_clause.rb +44 -0
  42. data/lib/ronin/code/sql/join_clause.rb +125 -0
  43. data/lib/ronin/code/sql/{like_expr.rb → like.rb} +19 -31
  44. data/lib/ronin/code/sql/limit_clause.rb +44 -0
  45. data/lib/ronin/code/sql/modifier.rb +50 -0
  46. data/lib/ronin/code/sql/offset_clause.rb +44 -0
  47. data/lib/ronin/code/sql/on_clause.rb +57 -0
  48. data/lib/ronin/code/sql/order_by_clause.rb +44 -0
  49. data/lib/ronin/code/sql/program.rb +170 -23
  50. data/lib/ronin/code/sql/rename_to_clause.rb +44 -0
  51. data/lib/ronin/code/sql/replace.rb +15 -17
  52. data/lib/ronin/code/sql/select.rb +46 -141
  53. data/lib/ronin/code/sql/set_clause.rb +44 -0
  54. data/lib/ronin/code/sql/statement.rb +117 -47
  55. data/lib/ronin/code/sql/token.rb +64 -0
  56. data/lib/ronin/code/sql/unary_expr.rb +9 -5
  57. data/lib/ronin/code/sql/union_all_clause.rb +44 -0
  58. data/lib/ronin/code/sql/union_clause.rb +44 -0
  59. data/lib/ronin/code/sql/update.rb +10 -31
  60. data/lib/ronin/code/sql/values_clause.rb +48 -0
  61. data/lib/ronin/code/sql/where_clause.rb +44 -0
  62. data/lib/ronin/code/sql.rb +1 -1
  63. data/lib/ronin/sql/error/error.rb +64 -0
  64. data/lib/ronin/sql/error/message.rb +64 -0
  65. data/lib/ronin/sql/error/pattern.rb +106 -0
  66. data/lib/ronin/sql/error/patterns.rb +100 -0
  67. data/lib/ronin/sql/error.rb +5 -30
  68. data/lib/ronin/sql/extensions/uri/http.rb +76 -21
  69. data/lib/ronin/sql/extensions/uri.rb +1 -1
  70. data/lib/ronin/sql/extensions.rb +2 -1
  71. data/lib/ronin/sql/injection.rb +213 -0
  72. data/lib/ronin/sql/version.rb +2 -2
  73. data/lib/ronin/sql.rb +7 -2
  74. data/spec/code/sql/create_examples.rb +19 -0
  75. data/spec/code/sql/create_index_spec.rb +25 -0
  76. data/spec/code/sql/create_table_spec.rb +27 -0
  77. data/spec/code/sql/create_view_spec.rb +16 -0
  78. data/spec/code/sql/delete_spec.rb +14 -0
  79. data/spec/code/sql/drop_examples.rb +10 -0
  80. data/spec/code/sql/drop_index_spec.rb +16 -0
  81. data/spec/code/sql/drop_table_spec.rb +16 -0
  82. data/spec/code/sql/drop_view_spec.rb +16 -0
  83. data/spec/code/sql/has_default_values_clause_examples.rb +10 -0
  84. data/spec/code/sql/has_fields_clause_examples.rb +15 -0
  85. data/spec/code/sql/has_from_clause_examples.rb +13 -0
  86. data/spec/code/sql/has_values_clause_examples.rb +15 -0
  87. data/spec/code/sql/has_where_clause_examples.rb +15 -0
  88. data/spec/code/sql/insert_spec.rb +21 -0
  89. data/spec/code/sql/replace_spec.rb +21 -0
  90. data/spec/code/sql/select_spec.rb +105 -0
  91. data/spec/code/sql/update_spec.rb +26 -0
  92. data/spec/helpers/code.rb +14 -0
  93. data/spec/sql/error_spec.rb +24 -0
  94. data/spec/sql/extensions/string_spec.rb +28 -0
  95. data/spec/sql_spec.rb +9 -0
  96. data/tasks/spec.rb +2 -0
  97. metadata +82 -29
  98. data/lib/ronin/code/sql/injection_builder.rb +0 -137
  99. data/lib/ronin/code/sql/injection_style.rb +0 -79
  100. data/lib/ronin/code/sql/style.rb +0 -170
  101. data/lib/ronin/sql/sql.rb +0 -83
@@ -0,0 +1,64 @@
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
+ module Ronin
25
+ module SQL
26
+ module Error
27
+ class Message
28
+
29
+ # The URL which is vulnerable
30
+ attr_reader :url
31
+
32
+ # The vulnerable query param
33
+ attr_accessor :param
34
+
35
+ # SQL error type
36
+ attr_reader :type
37
+
38
+ # SQL Dialect
39
+ attr_reader :dialect
40
+
41
+ # SQL error message
42
+ attr_reader :message
43
+
44
+ #
45
+ # Creates a new SQL Error object with the specified _type_,
46
+ # _dialect_ and _message_.
47
+ #
48
+ def initialize(type,dialect,message)
49
+ @type = type
50
+ @dialect = dialect
51
+ @message = message
52
+ end
53
+
54
+ #
55
+ # Returns the message in String form.
56
+ #
57
+ def to_s
58
+ @message.to_s
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,106 @@
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/message'
25
+
26
+ module Ronin
27
+ module SQL
28
+ module Error
29
+ class Pattern
30
+
31
+ # Name of the pattern
32
+ attr_reader :name
33
+
34
+ # Name of the SQL dialect
35
+ attr_accessor :dialect
36
+
37
+ # Patterns to use for matching SQL errors
38
+ attr_reader :patterns
39
+
40
+ #
41
+ # Creates a new Pattern object with the specified _name_. If a
42
+ # _block_ is given, it will be passed the newly created Pattern
43
+ # object.
44
+ #
45
+ def initialize(name,&block)
46
+ @dialect = :common
47
+ @name = name.to_sym
48
+ @patterns = []
49
+
50
+ block.call(self) if block
51
+ end
52
+
53
+ #
54
+ # Add the specified _pattern_ to be used to recognize SQL error
55
+ # messages.
56
+ #
57
+ def recognize(pattern)
58
+ @patterns << pattern
59
+ return self
60
+ end
61
+
62
+ #
63
+ # Returns the first match between the error pattern and the
64
+ # specified _data_. If no matches were found +nil+ will be
65
+ # returned.
66
+ #
67
+ def match(data)
68
+ data = data.to_s
69
+
70
+ @patterns.each do |pattern|
71
+ match = data.match(pattern)
72
+
73
+ return Message.new(@name,@dialect,match[0]) if match
74
+ end
75
+
76
+ return nil
77
+ end
78
+
79
+ #
80
+ # Returns the match index within the specified _data_ where a SQL
81
+ # error Pattern occurs. If no SQL error Pattern can be found within
82
+ # _data_, +nil+ will be returned.
83
+ #
84
+ def =~(data)
85
+ data = data.to_s
86
+
87
+ @patterns.each do |pattern|
88
+ if (index = (pattern =~ data))
89
+ return index
90
+ end
91
+ end
92
+
93
+ return nil
94
+ end
95
+
96
+ #
97
+ # Returns the name of the error pattern.
98
+ #
99
+ def to_s
100
+ @name.to_s
101
+ end
102
+
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,100 @@
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/pattern'
25
+
26
+ module Ronin
27
+ module SQL
28
+ module Error
29
+ Error.pattern :ms_sql do |p|
30
+ p.dialect = :ms
31
+ p.recognize /Microsoft OLE DB Provider for SQL Server/
32
+ p.recognize /Microsoft OLE DB Provider for ODBC Drivers.*\[Microsoft\]\[ODBC SQL Server Driver\]/
33
+ end
34
+
35
+ Error.pattern :ms_access do |p|
36
+ p.dialect = :ms
37
+ p.recognize /Microsoft OLE DB Provider for ODBC Drivers.*\[Microsoft\]\[ODBC Access Driver\]/
38
+ p.recognize /\[Microsoft\]\[ODBC Microsoft Access Driver\] Syntax error/
39
+ end
40
+
41
+ Error.pattern :ms_jetdb do |p|
42
+ p.dialect = :ms
43
+ p.recognize /Microsoft JET Database Engine/
44
+ end
45
+
46
+ Error.pattern :ms_adodb do |p|
47
+ p.dialect = :ms
48
+ p.recognize /ADODB.Command.*error/
49
+ end
50
+
51
+ Error.pattern :asp_net do |p|
52
+ p.dialect = :common
53
+ p.recognize /Server Error.*System\.Data\.OleDb\.OleDbException/
54
+ end
55
+
56
+ Error.pattern :mysql do |p|
57
+ p.dialect = :mysql
58
+ p.recognize /Warning.*supplied argument is not a valid MySQL result/
59
+ p.recognize /Warning.*mysql_.*\(\)/
60
+ p.recognize /You have an error in your SQL syntax.*(on|at) line/
61
+ end
62
+
63
+ Error.pattern :php do |p|
64
+ p.dialect = :common
65
+ p.recognize /Warning.*failed to open stream/
66
+ p.recognize /Fatal Error.*(on|at) line/
67
+ end
68
+
69
+ Error.pattern :oracle do |p|
70
+ p.dialect = :oracle
71
+ p.recognize /ORA-[0-9][0-9][0-9][0-9]/
72
+ end
73
+
74
+ Error.pattern :jdbc do |p|
75
+ p.dialect = :common
76
+ p.recognize /Invalid SQL statement or JDBC/
77
+ end
78
+
79
+ Error.pattern :java_servlet do |p|
80
+ p.dialect = :common
81
+ p.recognize /javax\.servlet\.ServletException/
82
+ end
83
+
84
+ Error.pattern :apache_tomcat do |p|
85
+ p.dialect = :common
86
+ p.recognize /org\.apache\.jasper\.JasperException/
87
+ end
88
+
89
+ Error.pattern :vb_runtime do |p|
90
+ p.dialect = :common
91
+ p.recognize /Microsoft VBScript runtime/
92
+ end
93
+
94
+ Error.pattern :vb_asp do |p|
95
+ p.dialect = :common
96
+ p.recognize /Type mismatch/
97
+ end
98
+ end
99
+ end
100
+ end
@@ -3,7 +3,7 @@
3
3
  # Ronin SQL - A Ronin library providing support for SQL related security
4
4
  # tasks.
5
5
  #
6
- # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of the GNU General Public License as published by
@@ -21,32 +21,7 @@
21
21
  #++
22
22
  #
23
23
 
24
- module Ronin
25
- module SQL
26
- class Error
27
-
28
- # SQL error type
29
- attr_reader :type
30
-
31
- # SQL error message
32
- attr_reader :message
33
-
34
- #
35
- # Creates a new SQL Error object with the specified _type_ and
36
- # _message_.
37
- #
38
- def initialize(type,message)
39
- @type = type
40
- @message = message
41
- end
42
-
43
- #
44
- # Returns the message in String form.
45
- #
46
- def to_s
47
- @message.to_s
48
- end
49
-
50
- end
51
- end
52
- end
24
+ require 'ronin/sql/error/message'
25
+ require 'ronin/sql/error/pattern'
26
+ require 'ronin/sql/error/error'
27
+ require 'ronin/sql/error/patterns'
@@ -3,7 +3,7 @@
3
3
  # Ronin SQL - A Ronin library providing support for SQL related security
4
4
  # tasks.
5
5
  #
6
- # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of the GNU General Public License as published by
@@ -21,10 +21,9 @@
21
21
  #++
22
22
  #
23
23
 
24
- require 'ronin/sql/sql'
25
- require 'ronin/network/http'
26
-
27
- require 'uri'
24
+ require 'ronin/sql/injection'
25
+ require 'ronin/extensions/uri/http'
26
+ require 'ronin/chars'
28
27
 
29
28
  module URI
30
29
  class HTTP < Generic
@@ -34,36 +33,92 @@ module URI
34
33
  # SQL errors.
35
34
  #
36
35
  # _options_ may contain the following keys:
37
- # <tt>:injection</tt>:: The SQL injection to use. Defaults to
38
- # <tt>"'"</tt>.
39
- # <tt>:types</tt>:: A list of error types to test for. If not specified
40
- # all the error patterns in ERROR_PATTERNS will be
41
- # tested.
36
+ # <tt>:sql</tt>:: The SQL injection to use. Defaults to <tt>"'"</tt>.
42
37
  #
43
38
  def sql_errors(options={})
44
- injection = (options[:injection] || "'")
39
+ errors = {}
45
40
 
46
- return test_query_params(injection,options) do |param,injection_url|
47
- body = Net.http_get_body(options.merge(:url => injection_url))
41
+ return each_query_param do |param,value|
42
+ error = SQL::Injection.new(self,param).error(options)
48
43
 
49
- Ronin::SQL.error(body,options)
44
+ errors[param] = error if error
50
45
  end
46
+
47
+ return errors
48
+ end
49
+
50
+ def sql_error(options={})
51
+ sql_errors(options).values.first
51
52
  end
52
53
 
53
54
  #
54
- # Tests each +query_params+ of the HTTP URI with the given _options_ for
55
- # SQL errors.
55
+ # Returns +true+ if any of the +query_params+ of the HTTP URI return
56
+ # SQL errors using the given _options_, returns +false+ otherwise.
56
57
  #
57
58
  # _options_ may contain the following keys:
58
- # <tt>:injection</tt>:: The SQL injection to use. Defaults to
59
- # <tt>"'"</tt>.
60
- # <tt>:types</tt>:: A list of error types to test for. If not specified
61
- # all the error patterns in ERROR_PATTERNS will be
62
- # tested.
59
+ # <tt>:sql</tt>:: The SQL injection to use. Defaults to <tt>"'"</tt>.
63
60
  #
64
61
  def has_sql_errors?(options={})
65
62
  !(sql_errors(options).empty?)
66
63
  end
67
64
 
65
+ #
66
+ # Tests the +query_params+ of the HTTP URL with the given _options_ for
67
+ # blind SQL injections.
68
+ #
69
+ def sql_injections(options={})
70
+ injectable = []
71
+
72
+ each_query_param do |param,value|
73
+ integer_tests = [
74
+ {:escape => value},
75
+ {:escape => value, :close_parenthesis => true}
76
+ ]
77
+
78
+ string_tests = [
79
+ {:escape => value, :close_string => true},
80
+ {:escape => value, :close_string => true, :close_parenthesis => true}
81
+ ]
82
+
83
+ if (value && Chars.numeric =~ value)
84
+ # if the param value is numeric, we should try escaping a
85
+ # numeric value first.
86
+ tests = integer_tests + string_tests
87
+ else
88
+ # if the param value is a string, we should try escaping a
89
+ # string value first.
90
+ tests = string_tests + integer_tests
91
+ end
92
+
93
+ tests.each do |test|
94
+ inj = Ronin::SQL::Injection.new(self,param,options.merge(test))
95
+
96
+ if inj.vulnerable?(options)
97
+ injectable << inj
98
+ break
99
+ end
100
+ end
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
+ end
113
+
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
122
+
68
123
  end
69
124
  end
@@ -3,7 +3,7 @@
3
3
  # Ronin SQL - A Ronin library providing support for SQL related security
4
4
  # tasks.
5
5
  #
6
- # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of the GNU General Public License as published by
@@ -3,7 +3,7 @@
3
3
  # Ronin SQL - A Ronin library providing support for SQL related security
4
4
  # tasks.
5
5
  #
6
- # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of the GNU General Public License as published by
@@ -21,4 +21,5 @@
21
21
  #++
22
22
  #
23
23
 
24
+ require 'ronin/sql/extensions/string'
24
25
  require 'ronin/sql/extensions/uri'
@@ -0,0 +1,213 @@
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'
25
+ require 'ronin/code/sql/injection'
26
+ require 'ronin/sessions/http'
27
+ require 'ronin/extensions/uri'
28
+ require 'ronin/web/extensions/hpricot'
29
+ require 'ronin/web/web'
30
+
31
+ module Ronin
32
+ module SQL
33
+ class Injection
34
+
35
+ include Sessions::HTTP
36
+
37
+ # The URL to inject upon
38
+ attr_reader :url
39
+
40
+ # The URL query param to inject into
41
+ attr_reader :param
42
+
43
+ # Options for crafting SQL injections
44
+ attr_reader :sql_options
45
+
46
+ # HTTP request method (either :get or :post)
47
+ parameter :http_method,
48
+ :default => :get,
49
+ :description => 'HTTP request method to use'
50
+
51
+ #
52
+ # Creates a new Injection object with the specified _url_, _param_
53
+ # to inject upon and the given _options_ which will be used
54
+ # for crafting SQL injections.
55
+ #
56
+ def initialize(url,param,options={})
57
+ super()
58
+
59
+ @url = url
60
+ @param = param
61
+ @sql_options = options
62
+ end
63
+
64
+ #
65
+ # Spider a site starting at the specified _url_ using the given
66
+ # _options_ and return an Array of URLs which are vulnerable to SQL
67
+ # Injection. If a _block_ is given, it will be passed vulnerable SQL
68
+ # Injection objects as they are found.
69
+ #
70
+ # Injection.spider('http://www.target.com/contact/')
71
+ # # => [...]
72
+ #
73
+ # Injection.spider('http://www.target.com/') do |injection|
74
+ # ...
75
+ # end
76
+ #
77
+ def Injection.spider(url,options={},&block)
78
+ injections = []
79
+
80
+ Web.spider_site(url,options) do |spider|
81
+ spider.every_url_like(/\?[a-zA-Z0-9_]/) do |vuln_url|
82
+ found = vuln_url.sql_injections
83
+
84
+ found.each(&block) if block
85
+ injections += found
86
+ end
87
+ end
88
+
89
+ return injections
90
+ end
91
+
92
+ #
93
+ # Creates a new Code::SQL::Injection object using the given _options_
94
+ # and _block_. The given _options_ will be merged with the injections
95
+ # sql_options, to create a tailored Code::SQL::Injection object.
96
+ #
97
+ def sql(options={},&block)
98
+ Code::SQL::Injection.new(@sql_options.merge(options),&block)
99
+ end
100
+
101
+ def inject(options={},&block)
102
+ injection = (options[:sql] || sql(options,&block))
103
+
104
+ injection_url = URI(@url.to_s)
105
+ injection_url.query_params[@param.to_s] = injection
106
+
107
+ request_method = (options[:method] || @http_method)
108
+ options = options.merge(:url => injection_url)
109
+
110
+ if request_method == :post
111
+ return http_post_body(options)
112
+ else
113
+ return http_get_body(options)
114
+ end
115
+ end
116
+
117
+ def inject_error(options={})
118
+ inject({:sql => "'"}.merge(options))
119
+ end
120
+
121
+ def error(options={})
122
+ inject_error(options).sql_error
123
+ end
124
+
125
+ def has_error?(options={})
126
+ Error.has_message?(inject_error(options))
127
+ end
128
+
129
+ def vulnerable?(options={})
130
+ body1 = inject(options) { no_rows }
131
+ body2 = inject(options) { all_rows }
132
+
133
+ if (body1.sql_error? || body2.sql_error?)
134
+ return false
135
+ end
136
+
137
+ body1 = Hpricot(body1)
138
+ body2 = Hpricot(body2)
139
+
140
+ return body1 < body2
141
+ end
142
+
143
+ def has_column?(column,options={})
144
+ body1 = inject(options)
145
+ body2 = inject(options.merge(:symbols => {:column => column})) do
146
+ has_column?(column)
147
+ end
148
+
149
+ if (body1.sql_error? || body2.sql_error?)
150
+ return false
151
+ end
152
+
153
+ body1 = Hpricot(body1)
154
+ body2 = Hpricot(body2)
155
+
156
+ return body1 == body2
157
+ end
158
+
159
+ def has_table?(table,options={})
160
+ body1 = inject(options)
161
+ body2 = inject(options.merge(:symbols => {:table => table})) do
162
+ has_table?(table)
163
+ end
164
+
165
+ if (body1.sql_error? || body2.sql_error?)
166
+ return false
167
+ end
168
+
169
+ body1 = Hpricot(body1)
170
+ body2 = Hpricot(body2)
171
+
172
+ return body1 == body2
173
+ end
174
+
175
+ def uses_column?(column,options={})
176
+ body1 = inject(options)
177
+ body2 = inject(options.merge(:symbols => {:column => column})) do
178
+ uses_column?(table)
179
+ end
180
+
181
+ if (body1.sql_error? || body2.sql_error?)
182
+ return false
183
+ end
184
+
185
+ body1 = Hpricot(body1)
186
+ body2 = Hpricot(body2)
187
+
188
+ return body1 == body2
189
+ end
190
+
191
+ def uses_table?(table,options={})
192
+ body1 = inject(options)
193
+ body2 = inject(options.merge(:symbols => {:table => table})) do
194
+ uses_table?(table)
195
+ end
196
+
197
+ if (body1.sql_error? || body2.sql_error?)
198
+ return false
199
+ end
200
+
201
+ body1 = Hpricot(body1)
202
+ body2 = Hpricot(body2)
203
+
204
+ return body1 == body2
205
+ end
206
+
207
+ def to_s
208
+ @url.to_s
209
+ end
210
+
211
+ end
212
+ end
213
+ end
@@ -3,7 +3,7 @@
3
3
  # Ronin SQL - A Ronin library providing support for SQL related security
4
4
  # tasks.
5
5
  #
6
- # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of the GNU General Public License as published by
@@ -24,6 +24,6 @@
24
24
  module Ronin
25
25
  module SQL
26
26
  # Ronin SQL version
27
- VERSION = '0.1.1'
27
+ VERSION = '0.2.0'
28
28
  end
29
29
  end