ronin-sql 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +43 -0
- data/Manifest.txt +76 -23
- data/README.txt +31 -6
- data/Rakefile +2 -2
- data/lib/ronin/code/sql/{keyword.rb → add_column_clause.rb} +9 -13
- data/lib/ronin/code/sql/as.rb +47 -0
- data/lib/ronin/code/sql/asc.rb +38 -0
- data/lib/ronin/code/sql/between.rb +18 -12
- data/lib/ronin/code/sql/binary_expr.rb +12 -5
- data/lib/ronin/code/sql/clause.rb +37 -0
- data/lib/ronin/code/sql/code.rb +1 -1
- data/lib/ronin/code/sql/common_dialect.rb +16 -10
- data/lib/ronin/code/sql/create.rb +68 -0
- data/lib/ronin/code/sql/create_index.rb +9 -39
- data/lib/ronin/code/sql/create_table.rb +9 -56
- data/lib/ronin/code/sql/create_view.rb +7 -29
- data/lib/ronin/code/sql/default_values_clause.rb +38 -0
- data/lib/ronin/code/sql/delete.rb +10 -25
- data/lib/ronin/code/sql/desc.rb +38 -0
- data/lib/ronin/code/sql/dialect.rb +172 -52
- data/lib/ronin/code/sql/{builder.rb → drop.rb} +16 -20
- data/lib/ronin/code/sql/drop_index.rb +43 -0
- data/lib/ronin/code/sql/drop_table.rb +8 -16
- data/lib/ronin/code/sql/drop_view.rb +43 -0
- data/lib/ronin/code/sql/emittable.rb +102 -0
- data/lib/ronin/code/sql/exceptions/unknown_clause.rb +31 -0
- data/lib/ronin/code/sql/exceptions/unknown_dialect.rb +2 -2
- data/lib/ronin/code/sql/exceptions/unknown_statement.rb +31 -0
- data/lib/ronin/code/sql/exceptions.rb +3 -1
- data/lib/ronin/code/sql/expr.rb +7 -96
- data/lib/ronin/code/sql/field.rb +40 -23
- data/lib/ronin/code/sql/fields_clause.rb +48 -0
- data/lib/ronin/code/sql/from_clause.rb +44 -0
- data/lib/ronin/code/sql/function.rb +15 -12
- data/lib/ronin/code/sql/group_by_clause.rb +48 -0
- data/lib/ronin/code/sql/having_clause.rb +48 -0
- data/lib/ronin/code/sql/in.rb +9 -9
- data/lib/ronin/code/sql/injected_statement.rb +102 -0
- data/lib/ronin/code/sql/injection.rb +171 -5
- data/lib/ronin/code/sql/insert.rb +15 -45
- data/lib/ronin/code/sql/intersect_clause.rb +44 -0
- data/lib/ronin/code/sql/join_clause.rb +125 -0
- data/lib/ronin/code/sql/{like_expr.rb → like.rb} +19 -31
- data/lib/ronin/code/sql/limit_clause.rb +44 -0
- data/lib/ronin/code/sql/modifier.rb +50 -0
- data/lib/ronin/code/sql/offset_clause.rb +44 -0
- data/lib/ronin/code/sql/on_clause.rb +57 -0
- data/lib/ronin/code/sql/order_by_clause.rb +44 -0
- data/lib/ronin/code/sql/program.rb +170 -23
- data/lib/ronin/code/sql/rename_to_clause.rb +44 -0
- data/lib/ronin/code/sql/replace.rb +15 -17
- data/lib/ronin/code/sql/select.rb +46 -141
- data/lib/ronin/code/sql/set_clause.rb +44 -0
- data/lib/ronin/code/sql/statement.rb +117 -47
- data/lib/ronin/code/sql/token.rb +64 -0
- data/lib/ronin/code/sql/unary_expr.rb +9 -5
- data/lib/ronin/code/sql/union_all_clause.rb +44 -0
- data/lib/ronin/code/sql/union_clause.rb +44 -0
- data/lib/ronin/code/sql/update.rb +10 -31
- data/lib/ronin/code/sql/values_clause.rb +48 -0
- data/lib/ronin/code/sql/where_clause.rb +44 -0
- data/lib/ronin/code/sql.rb +1 -1
- data/lib/ronin/sql/error/error.rb +64 -0
- data/lib/ronin/sql/error/message.rb +64 -0
- data/lib/ronin/sql/error/pattern.rb +106 -0
- data/lib/ronin/sql/error/patterns.rb +100 -0
- data/lib/ronin/sql/error.rb +5 -30
- data/lib/ronin/sql/extensions/uri/http.rb +76 -21
- data/lib/ronin/sql/extensions/uri.rb +1 -1
- data/lib/ronin/sql/extensions.rb +2 -1
- data/lib/ronin/sql/injection.rb +213 -0
- data/lib/ronin/sql/version.rb +2 -2
- data/lib/ronin/sql.rb +7 -2
- data/spec/code/sql/create_examples.rb +19 -0
- data/spec/code/sql/create_index_spec.rb +25 -0
- data/spec/code/sql/create_table_spec.rb +27 -0
- data/spec/code/sql/create_view_spec.rb +16 -0
- data/spec/code/sql/delete_spec.rb +14 -0
- data/spec/code/sql/drop_examples.rb +10 -0
- data/spec/code/sql/drop_index_spec.rb +16 -0
- data/spec/code/sql/drop_table_spec.rb +16 -0
- data/spec/code/sql/drop_view_spec.rb +16 -0
- data/spec/code/sql/has_default_values_clause_examples.rb +10 -0
- data/spec/code/sql/has_fields_clause_examples.rb +15 -0
- data/spec/code/sql/has_from_clause_examples.rb +13 -0
- data/spec/code/sql/has_values_clause_examples.rb +15 -0
- data/spec/code/sql/has_where_clause_examples.rb +15 -0
- data/spec/code/sql/insert_spec.rb +21 -0
- data/spec/code/sql/replace_spec.rb +21 -0
- data/spec/code/sql/select_spec.rb +105 -0
- data/spec/code/sql/update_spec.rb +26 -0
- data/spec/helpers/code.rb +14 -0
- data/spec/sql/error_spec.rb +24 -0
- data/spec/sql/extensions/string_spec.rb +28 -0
- data/spec/sql_spec.rb +9 -0
- data/tasks/spec.rb +2 -0
- metadata +82 -29
- data/lib/ronin/code/sql/injection_builder.rb +0 -137
- data/lib/ronin/code/sql/injection_style.rb +0 -79
- data/lib/ronin/code/sql/style.rb +0 -170
- 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
|
data/lib/ronin/sql/error.rb
CHANGED
@@ -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-
|
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
|
-
|
25
|
-
|
26
|
-
|
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-
|
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/
|
25
|
-
require 'ronin/
|
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>:
|
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
|
-
|
39
|
+
errors = {}
|
45
40
|
|
46
|
-
return
|
47
|
-
|
41
|
+
return each_query_param do |param,value|
|
42
|
+
error = SQL::Injection.new(self,param).error(options)
|
48
43
|
|
49
|
-
|
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
|
-
#
|
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>:
|
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-
|
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
|
data/lib/ronin/sql/extensions.rb
CHANGED
@@ -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-
|
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
|
data/lib/ronin/sql/version.rb
CHANGED
@@ -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-
|
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.
|
27
|
+
VERSION = '0.2.0'
|
28
28
|
end
|
29
29
|
end
|