ronin-vulns 0.1.0.beta1

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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.github/workflows/ruby.yml +31 -0
  4. data/.gitignore +13 -0
  5. data/.rspec +1 -0
  6. data/.ruby-version +1 -0
  7. data/.yardopts +1 -0
  8. data/COPYING.txt +165 -0
  9. data/ChangeLog.md +22 -0
  10. data/Gemfile +34 -0
  11. data/README.md +328 -0
  12. data/Rakefile +34 -0
  13. data/bin/ronin-vulns +19 -0
  14. data/data/rfi_test.asp +21 -0
  15. data/data/rfi_test.aspx +25 -0
  16. data/data/rfi_test.cfm +27 -0
  17. data/data/rfi_test.jsp +19 -0
  18. data/data/rfi_test.php +24 -0
  19. data/data/rfi_test.pl +25 -0
  20. data/gemspec.yml +41 -0
  21. data/lib/ronin/vulns/cli/command.rb +39 -0
  22. data/lib/ronin/vulns/cli/commands/lfi.rb +145 -0
  23. data/lib/ronin/vulns/cli/commands/open_redirect.rb +119 -0
  24. data/lib/ronin/vulns/cli/commands/reflected_xss.rb +99 -0
  25. data/lib/ronin/vulns/cli/commands/rfi.rb +156 -0
  26. data/lib/ronin/vulns/cli/commands/scan.rb +316 -0
  27. data/lib/ronin/vulns/cli/commands/sqli.rb +133 -0
  28. data/lib/ronin/vulns/cli/commands/ssti.rb +126 -0
  29. data/lib/ronin/vulns/cli/logging.rb +78 -0
  30. data/lib/ronin/vulns/cli/web_vuln_command.rb +347 -0
  31. data/lib/ronin/vulns/cli.rb +45 -0
  32. data/lib/ronin/vulns/lfi/test_file.rb +91 -0
  33. data/lib/ronin/vulns/lfi.rb +266 -0
  34. data/lib/ronin/vulns/open_redirect.rb +118 -0
  35. data/lib/ronin/vulns/reflected_xss/context.rb +224 -0
  36. data/lib/ronin/vulns/reflected_xss/test_string.rb +149 -0
  37. data/lib/ronin/vulns/reflected_xss.rb +184 -0
  38. data/lib/ronin/vulns/rfi.rb +224 -0
  39. data/lib/ronin/vulns/root.rb +28 -0
  40. data/lib/ronin/vulns/sqli/error_pattern.rb +89 -0
  41. data/lib/ronin/vulns/sqli.rb +397 -0
  42. data/lib/ronin/vulns/ssti/test_expression.rb +104 -0
  43. data/lib/ronin/vulns/ssti.rb +203 -0
  44. data/lib/ronin/vulns/url_scanner.rb +218 -0
  45. data/lib/ronin/vulns/version.rb +26 -0
  46. data/lib/ronin/vulns/vuln.rb +49 -0
  47. data/lib/ronin/vulns/web_vuln/http_request.rb +223 -0
  48. data/lib/ronin/vulns/web_vuln.rb +774 -0
  49. data/man/ronin-vulns-lfi.1 +107 -0
  50. data/man/ronin-vulns-lfi.1.md +80 -0
  51. data/man/ronin-vulns-open-redirect.1 +98 -0
  52. data/man/ronin-vulns-open-redirect.1.md +73 -0
  53. data/man/ronin-vulns-reflected-xss.1 +95 -0
  54. data/man/ronin-vulns-reflected-xss.1.md +71 -0
  55. data/man/ronin-vulns-rfi.1 +107 -0
  56. data/man/ronin-vulns-rfi.1.md +80 -0
  57. data/man/ronin-vulns-scan.1 +138 -0
  58. data/man/ronin-vulns-scan.1.md +103 -0
  59. data/man/ronin-vulns-sqli.1 +107 -0
  60. data/man/ronin-vulns-sqli.1.md +80 -0
  61. data/man/ronin-vulns-ssti.1 +99 -0
  62. data/man/ronin-vulns-ssti.1.md +74 -0
  63. data/ronin-vulns.gemspec +60 -0
  64. metadata +161 -0
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+ # frozen_string_literal: true
3
+ #
4
+ # ronin-vulns - A Ruby library for blind vulnerability testing.
5
+ #
6
+ # Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # ronin-vulns is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Lesser General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # ronin-vulns 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 Lesser General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Lesser General Public License
19
+ # along with ronin-vulns. If not, see <https://www.gnu.org/licenses/>.
20
+ #
21
+
22
+ require 'ronin/vulns/web_vuln'
23
+
24
+ module Ronin
25
+ module Vulns
26
+ class ReflectedXSS < WebVuln
27
+ #
28
+ # A test string of characters to determine which special characters are
29
+ # escaped/filtered and which are passed through.
30
+ #
31
+ # @api private
32
+ #
33
+ class TestString
34
+
35
+ # The test string.
36
+ #
37
+ # @return [String]
38
+ attr_reader :string
39
+
40
+ # The test regexp to determine which special characters were
41
+ # escaped/filtered and which were passed through unescaped.
42
+ #
43
+ # @return [Regexp]
44
+ attr_reader :regexp
45
+
46
+ #
47
+ # Initializes the test string.
48
+ #
49
+ # @param [String] string
50
+ # The test string.
51
+ #
52
+ # @param [Regexp] regexp
53
+ # The test regexp to determine which special characters were
54
+ # escaped/filtered and which were passed through unescaped.
55
+ #
56
+ def initialize(string,regexp)
57
+ @string = string
58
+ @regexp = regexp
59
+ end
60
+
61
+ # Special characters and their common escaped equivalents.
62
+ ESCAPED_CHARS = {
63
+ "'" => ['%27', '&#39;', "\\'"],
64
+ '"' => ['%22', '&quot;', "\\\""],
65
+ ' ' => ['+', '%20', '&nbsp;'],
66
+ '=' => ['%3D'],
67
+ '/' => ['%2F'],
68
+ '<' => ['%3C', '&lt;'],
69
+ '>' => ['%3E', '&gt;'],
70
+ '&' => ['%26', '&amp;'],
71
+ }
72
+
73
+ #
74
+ # Builds a test string from a mapping of characters and their HTML
75
+ # escaped equivalents.
76
+ #
77
+ # @param [String] chars
78
+ # The characters for the test string.
79
+ #
80
+ # @return [TestString]
81
+ # The built test string.
82
+ #
83
+ def self.build(chars)
84
+ string = String.new
85
+ regexp = String.new
86
+
87
+ chars.each_char do |char|
88
+ string << char
89
+
90
+ regexp << "(?:(#{Regexp.escape(char)})"
91
+
92
+ if (escaped_chars = ESCAPED_CHARS[char])
93
+ escaped_chars.each do |string|
94
+ regexp << "|#{Regexp.escape(string)}"
95
+ end
96
+ end
97
+
98
+ regexp << ')?'
99
+ end
100
+
101
+ return new(string,Regexp.new(regexp))
102
+ end
103
+
104
+ #
105
+ # Wraps the test string with a prefix and suffix.
106
+ #
107
+ # @param [String] prefix
108
+ # The prefix string to prepend to the test string.
109
+ #
110
+ # @param [String] suffix
111
+ # The suffix string to append to the test string.
112
+ #
113
+ # @return [TestString]
114
+ # The new test string with the prefix and suffix.
115
+ #
116
+ def wrap(prefix,suffix)
117
+ self.class.new(
118
+ "#{prefix}#{@string}#{suffix}",
119
+ /#{Regexp.escape(prefix)}#{@regexp}#{Regexp.escape(suffix)}/
120
+ )
121
+ end
122
+
123
+ #
124
+ # Matches the response body against {#regexp}.
125
+ #
126
+ # @param [String] body
127
+ # The response body to try matching.
128
+ #
129
+ # @return [MatchData, nil]
130
+ # The match data or `nil` if the body did not match {#regexp}.
131
+ #
132
+ def match(body)
133
+ body.match(@regexp)
134
+ end
135
+
136
+ #
137
+ # Converts the test string to a String.
138
+ #
139
+ # @return [String]
140
+ # The {#string}.
141
+ #
142
+ def to_s
143
+ @string
144
+ end
145
+
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+ # frozen_string_literal: true
3
+ #
4
+ # ronin-vulns - A Ruby library for blind vulnerability testing.
5
+ #
6
+ # Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # ronin-vulns is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Lesser General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # ronin-vulns 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 Lesser General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Lesser General Public License
19
+ # along with ronin-vulns. If not, see <https://www.gnu.org/licenses/>.
20
+ #
21
+
22
+ require 'ronin/vulns/web_vuln'
23
+ require 'ronin/vulns/reflected_xss/test_string'
24
+ require 'ronin/vulns/reflected_xss/context'
25
+
26
+ require 'set'
27
+
28
+ module Ronin
29
+ module Vulns
30
+ #
31
+ # Represents a (Reflected) Cross Site Scripting (XSS) vulnerability.
32
+ #
33
+ # ## Features
34
+ #
35
+ # * Tests a URL with just one HTTP request (per param).
36
+ # * Tests which HTML special characters are allowed.
37
+ # * Identifies the context, tag name, and/or attribute name of the XSS.
38
+ # * Determines viability of XSS based on the context.
39
+ # * Includes random data in the test values.
40
+ #
41
+ class ReflectedXSS < WebVuln
42
+
43
+ # The characters that are allowed and will not be escaped or filtered.
44
+ #
45
+ # @return [Set<String>, nil]
46
+ attr_reader :allowed_chars
47
+
48
+ # The context the XSS occurred in.
49
+ #
50
+ # @return [Context, nil]
51
+ attr_reader :context
52
+
53
+ #
54
+ # Tests the test string by sending an HTTP request with the test string
55
+ # embedded.
56
+ #
57
+ # @param [TestString] test_string
58
+ #
59
+ # @yield [body, match]
60
+ # If the response was `text/html` and the test string appears (at least
61
+ # partially) in the response body, the response body and match data will
62
+ # be yielded.
63
+ #
64
+ # @yieldparam [String] body
65
+ # The response body.
66
+ #
67
+ # @yieldparam [MatchData] match
68
+ # The matched data for the test string.
69
+ #
70
+ # @api private
71
+ #
72
+ def test_string(test_string)
73
+ test_string = test_string.wrap(random_value,random_value)
74
+
75
+ response = exploit("#{original_value}#{test_string}")
76
+ content_type = response.content_type
77
+ body = response.body
78
+
79
+ if content_type && content_type.include?('text/html')
80
+ if (match = test_string.match(body))
81
+ yield body, match
82
+ end
83
+ end
84
+ end
85
+
86
+ #
87
+ # Tests whether characters in the test string will be escaped/filtered or
88
+ # passed through and updates {#allowed_chars}.
89
+ #
90
+ # @param [TestString] test_string
91
+ # The test string to send.
92
+ #
93
+ # @yield [body, match]
94
+ # If a block is given, it will be passed the response body and the
95
+ # regular expression match data, if the response contains the test
96
+ # string.
97
+ #
98
+ # @yieldparam [String] body
99
+ # The response body.
100
+ #
101
+ # @yieldparam [MatchData] match
102
+ # The matched data for the test string.
103
+ #
104
+ # @api private
105
+ #
106
+ def test_chars(test_string)
107
+ test_string(test_string) do |body,match|
108
+ @allowed_chars ||= Set.new
109
+ @allowed_chars.merge(match.captures.compact)
110
+
111
+ yield body, match if block_given?
112
+ end
113
+ end
114
+
115
+ # HTML special characters to test.
116
+ HTML_TEST_STRING = TestString.build("'\"= /><")
117
+
118
+ #
119
+ # Tests which HTML characters are accepted or escaped/filtered.
120
+ #
121
+ # @yield [body, match]
122
+ # If a block is given, it will be passed the response body and the
123
+ # regular expression match data, if the response contains the test
124
+ # string.
125
+ #
126
+ # @yieldparam [String] body
127
+ # The response body.
128
+ #
129
+ # @yieldparam [MatchData] match
130
+ # The matched data for the test string.
131
+ #
132
+ # @api private
133
+ #
134
+ def test_html_chars(&block)
135
+ test_chars(HTML_TEST_STRING,&block)
136
+ end
137
+
138
+ #
139
+ # Tests whether the URL is vulnerable to (Reflected) Cross Site Scripting
140
+ # (XSS).
141
+ #
142
+ # @return [Boolean]
143
+ # Indicates whether the URL is vulnerable to (Reflected) Cross Site
144
+ # Scripting (XSS).
145
+ #
146
+ # @note
147
+ # If the URL is vulnerable, {#allowed_chars} and {#context} will be set.
148
+ #
149
+ def vulnerable?
150
+ # test HTML special characters
151
+ test_html_chars do |body,match|
152
+ xss_index = match.begin(0)
153
+
154
+ # determine the contents which the XSS occurs
155
+ if (@context = Context.identify(body,xss_index))
156
+ # determine whether enough special HTML characters are allowed to
157
+ # escape the context which the XSS occurs.
158
+ return @context.viable?(@allowed_chars)
159
+ end
160
+ end
161
+
162
+ return false
163
+ end
164
+
165
+ #
166
+ # Returns the type or kind of vulnerability.
167
+ #
168
+ # @return [Symbol]
169
+ #
170
+ # @note
171
+ # This is used internally to map an vulnerability class to a printable
172
+ # type.
173
+ #
174
+ # @api private
175
+ #
176
+ # @abstract
177
+ #
178
+ def self.vuln_type
179
+ :reflected_xss
180
+ end
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-vulns - A Ruby library for blind vulnerability testing.
4
+ #
5
+ # Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-vulns is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-vulns is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-vulns. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/vulns/web_vuln'
22
+ require 'ronin/vulns/version'
23
+
24
+ require 'ronin/support/network/http'
25
+ require 'uri/query_params'
26
+
27
+ module Ronin
28
+ module Vulns
29
+ #
30
+ # Represents a Remote File Inclusion (RFI) vulnerability.
31
+ #
32
+ class RFI < WebVuln
33
+
34
+ # The script extensions and their languages
35
+ URL_EXTS = {
36
+ '.asp' => :asp,
37
+ '.aspx' => :asp_net,
38
+ '.cfm' => :cold_fusion,
39
+ '.cfml' => :cold_fusion,
40
+ '.jsp' => :jsp,
41
+ '.php' => :php,
42
+ '.pl' => :perl
43
+ }
44
+
45
+ # The github.com base URL for all RFI test scripts.
46
+ GITHUB_BASE_URL = "https://raw.githubusercontent.com/ronin-rb/ronin-vulns/#{VERSION}/data"
47
+
48
+ # Mapping of scripting languages to RFI test scripts.
49
+ TEST_SCRIPT_URLS = {
50
+ asp: "#{GITHUB_BASE_URL}/rfi_test.asp",
51
+ asp_net: "#{GITHUB_BASE_URL}/rfi_test.aspx",
52
+ cold_fusion: "#{GITHUB_BASE_URL}/rfi_test.cfm",
53
+ jsp: "#{GITHUB_BASE_URL}/rfi_test.jsp",
54
+ php: "#{GITHUB_BASE_URL}/rfi_test.php",
55
+ perl: "#{GITHUB_BASE_URL}/rfi_test.pl"
56
+ }
57
+
58
+ # The string that will be returned if the Remote File Inclusion (RFI)
59
+ # script is executed.
60
+ VULN_RESPONSE_STRING = "Security Alert: Remote File Inclusion Detected!"
61
+
62
+ # The filter bypass technique to use.
63
+ #
64
+ # @return [nil, :double_encode, :suffix_escape, :null_byte]
65
+ attr_reader :filter_bypass
66
+
67
+ # URL of the Remote File Inclusion (RFI) Test script
68
+ #
69
+ # @return [URI::HTTP, String]
70
+ attr_reader :test_script_url
71
+
72
+ #
73
+ # Creates a new Remote File Inclusion (RFI) object.
74
+ #
75
+ # @param [String, URI::HTTP] url
76
+ # The URL to attempt to exploit.
77
+ #
78
+ # @param [:null_byte, :double_encode, nil] filter_bypass
79
+ # Specifies which filter bypass technique to use.
80
+ # * `:double_encode` - will cause the inclusion URL to be URI escaped
81
+ # twice.
82
+ # * `:suffix_escape` - escape any appended suffix (ex: `param + ".php"`)
83
+ # by adding a URI fragment character (`#`) to the end of the RFI
84
+ # script URL. The fragment component of the URI is not sent to the
85
+ # web server.
86
+ # * `:null_byte` - will cause the inclusion URL to be appended with a
87
+ # `%00` character. **Note:* this technique only works on PHP < 5.3.
88
+ #
89
+ # @param [:asp, :asp_net, :cold_fusion, :jsp, :php, :perl, nil] script_lang
90
+ # Explicitly specifies the scripting language that the URL uses.
91
+ #
92
+ # @param [String, URI::HTTP, nil] test_script_url
93
+ # The URL of the RFI test script. If not specified, it will default to
94
+ # {test_script_for}.
95
+ #
96
+ def initialize(url, script_lang: nil, test_script_url: nil, filter_bypass: nil, **kwargs)
97
+ super(url,**kwargs)
98
+
99
+ @test_script_url = if test_script_url
100
+ test_script_url
101
+ elsif script_lang
102
+ self.class.test_script_url_for(script_lang)
103
+ else
104
+ self.class.test_script_for(@url)
105
+ end
106
+
107
+ @filter_bypass = filter_bypass
108
+ end
109
+
110
+ #
111
+ # Returns the test script URL for the given scripting language.
112
+ #
113
+ # @param [:asp, :asp_net, :cold_fusion, :jsp, :php, :perl] script_lang
114
+ # The scripting language.
115
+ #
116
+ # @return [String]
117
+ # The test script URL for the given scripting language.
118
+ #
119
+ # @raise [ArgumentError]
120
+ # An unknown scripting language value was given.
121
+ #
122
+ def self.test_script_url_for(script_lang)
123
+ TEST_SCRIPT_URLS.fetch(script_lang) do
124
+ raise(ArgumentError,"unknown scripting language: #{script_lang.inspect}")
125
+ end
126
+ end
127
+
128
+ #
129
+ # Attempts to infer the programming language used for the web page at the
130
+ # given URL.
131
+ #
132
+ # @param [String, URI::HTTP] url
133
+ # The URL to infer from.
134
+ #
135
+ # @return [:asp, :cold_fusion, :jsp, :php, :perl, nil]
136
+ # The programming language inferred from the URL.
137
+ #
138
+ def self.infer_script_lang(url)
139
+ url = URI(url)
140
+
141
+ return URL_EXTS[File.extname(url.path)]
142
+ end
143
+
144
+ #
145
+ # Selects the RFI test script for the scripting language used by the given
146
+ # URL.
147
+ #
148
+ # @param [String, URI::HTTP] url
149
+ # The URL to test.
150
+ #
151
+ # @return [String, nil]
152
+ # The RFI test script URL or `nil` if the scripting language could not
153
+ # be inferred from the URL.
154
+ #
155
+ def self.test_script_for(url)
156
+ if (lang = infer_script_lang(url))
157
+ TEST_SCRIPT_URLS.fetch(lang)
158
+ end
159
+ end
160
+
161
+ #
162
+ # Optionally applies a filter bypass technique to the RFI URL.
163
+ #
164
+ # @param [URI::HTTP, String] url
165
+ # The RFI URL to optionall encode before it will be injected into a
166
+ # HTTP request.
167
+ #
168
+ # @return [String]
169
+ # The optionally encoded RFI URL.
170
+ #
171
+ def encode_payload(url)
172
+ url = url.to_s
173
+
174
+ case @filter_bypass
175
+ when :double_encode
176
+ # Optionally double URI encodes the script URL
177
+ url = URI::QueryParams.escape(url)
178
+ when :suffix_escape
179
+ # Optionally append a '#' character to escape any appended suffixes
180
+ # (ex: `param + ".php"`).
181
+ url = "#{url}#"
182
+ when :null_byte
183
+ # Optionally append a null-byte
184
+ # NOTE: uri-query_params will automatically URI encode the null byte
185
+ url = "#{url}\0"
186
+ end
187
+
188
+ return url
189
+ end
190
+
191
+ #
192
+ # Tests whether the URL and query parameter are vulnerable to Remote File
193
+ # Inclusion (RFI).
194
+ #
195
+ # @return [Boolean]
196
+ # Specifies whether the URL and query parameter are vulnerable to RFI.
197
+ #
198
+ def vulnerable?
199
+ response = exploit(@test_script_url)
200
+ body = response.body
201
+
202
+ return body.include?(VULN_RESPONSE_STRING)
203
+ end
204
+
205
+ #
206
+ # Returns the type or kind of vulnerability.
207
+ #
208
+ # @return [Symbol]
209
+ #
210
+ # @note
211
+ # This is used internally to map an vulnerability class to a printable
212
+ # type.
213
+ #
214
+ # @api private
215
+ #
216
+ # @abstract
217
+ #
218
+ def self.vuln_type
219
+ :rfi
220
+ end
221
+
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-vulns - A Ruby library for blind vulnerability testing.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-vulns is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-vulns is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-vulns. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ module Ronin
22
+ module Vulns
23
+ # Path to `ronin-vulns` root directory.
24
+ #
25
+ # @api private
26
+ ROOT = File.expand_path(File.join(__dir__,'..','..','..'))
27
+ end
28
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-vulns - A Ruby library for blind vulnerability testing.
4
+ #
5
+ # Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-vulns is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-vulns is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-vulns. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/vulns/web_vuln'
22
+
23
+ module Ronin
24
+ module Vulns
25
+ class SQLI < WebVuln
26
+ #
27
+ # Represents a collection of patterns for SQL error messages for a
28
+ # particular database.
29
+ #
30
+ # @api private
31
+ #
32
+ class ErrorPattern
33
+
34
+ # The combined error message regexp.
35
+ #
36
+ # @return [Regexp]
37
+ attr_reader :regexp
38
+
39
+ #
40
+ # Initializes the error pattern.
41
+ #
42
+ # @param [Regexp] regexp
43
+ # The combined of regular expression.
44
+ #
45
+ def initialize(regexp)
46
+ @regexp = regexp
47
+ end
48
+
49
+ #
50
+ # Creates an error pattern from multiple different regexps.
51
+ #
52
+ # @param [Array<Regexp>] regexps
53
+ # The collection of regular expressions.
54
+ #
55
+ def self.[](*regexps)
56
+ new(Regexp.union(regexps))
57
+ end
58
+
59
+ #
60
+ # Tests whether the respones body contains a SQL error.
61
+ #
62
+ # @param [String] response_body
63
+ # The HTTP response body.
64
+ #
65
+ # @return [MatchData, nil]
66
+ # The match data if the {#regexp} is found within the response body.
67
+ #
68
+ def match(response_body)
69
+ @regexp.match(response_body)
70
+ end
71
+
72
+ #
73
+ # Tests whether the file was successfully included into the response
74
+ # body.
75
+ #
76
+ # @param [String] response_body
77
+ # The HTTP response body.
78
+ #
79
+ # @return [Integer, nil]
80
+ # Indicates whether the {#regexp} was found in the response body.
81
+ #
82
+ def =~(response_body)
83
+ response_body =~ @regexp
84
+ end
85
+
86
+ end
87
+ end
88
+ end
89
+ end