arachni 0.2.2.1

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 (262) hide show
  1. data/ACKNOWLEDGMENTS.md +14 -0
  2. data/AUTHORS.md +6 -0
  3. data/CHANGELOG.md +162 -0
  4. data/CONTRIBUTORS.md +10 -0
  5. data/EXPLOITATION.md +429 -0
  6. data/HACKING.md +101 -0
  7. data/LICENSE.md +341 -0
  8. data/README.md +350 -0
  9. data/Rakefile +86 -0
  10. data/bin/arachni +22 -0
  11. data/bin/arachni_web +77 -0
  12. data/bin/arachni_xmlrpc +21 -0
  13. data/bin/arachni_xmlrpcd +82 -0
  14. data/bin/arachni_xmlrpcd_monitor +74 -0
  15. data/conf/README.webui.yaml.txt +44 -0
  16. data/conf/webui.yaml +11 -0
  17. data/external/metasploit/LICENSE +24 -0
  18. data/external/metasploit/modules/exploits/unix/webapp/arachni_exec.rb +142 -0
  19. data/external/metasploit/modules/exploits/unix/webapp/arachni_path_traversal.rb +113 -0
  20. data/external/metasploit/modules/exploits/unix/webapp/arachni_php_eval.rb +150 -0
  21. data/external/metasploit/modules/exploits/unix/webapp/arachni_php_include.rb +141 -0
  22. data/external/metasploit/modules/exploits/unix/webapp/arachni_sqlmap.rb +92 -0
  23. data/external/metasploit/plugins/arachni.rb +536 -0
  24. data/getoptslong.rb +241 -0
  25. data/lib/anemone.rb +2 -0
  26. data/lib/anemone/cookie_store.rb +35 -0
  27. data/lib/anemone/core.rb +371 -0
  28. data/lib/anemone/exceptions.rb +5 -0
  29. data/lib/anemone/http.rb +144 -0
  30. data/lib/anemone/page.rb +337 -0
  31. data/lib/anemone/page_store.rb +160 -0
  32. data/lib/anemone/storage.rb +34 -0
  33. data/lib/anemone/storage/base.rb +75 -0
  34. data/lib/anemone/storage/exceptions.rb +15 -0
  35. data/lib/anemone/storage/mongodb.rb +89 -0
  36. data/lib/anemone/storage/pstore.rb +50 -0
  37. data/lib/anemone/storage/redis.rb +90 -0
  38. data/lib/anemone/storage/tokyo_cabinet.rb +57 -0
  39. data/lib/anemone/tentacle.rb +40 -0
  40. data/lib/arachni.rb +16 -0
  41. data/lib/audit_store.rb +346 -0
  42. data/lib/component_manager.rb +293 -0
  43. data/lib/component_options.rb +395 -0
  44. data/lib/exceptions.rb +76 -0
  45. data/lib/framework.rb +637 -0
  46. data/lib/http.rb +809 -0
  47. data/lib/issue.rb +302 -0
  48. data/lib/module.rb +4 -0
  49. data/lib/module/auditor.rb +455 -0
  50. data/lib/module/base.rb +188 -0
  51. data/lib/module/element_db.rb +158 -0
  52. data/lib/module/key_filler.rb +87 -0
  53. data/lib/module/manager.rb +87 -0
  54. data/lib/module/output.rb +68 -0
  55. data/lib/module/trainer.rb +240 -0
  56. data/lib/module/utilities.rb +110 -0
  57. data/lib/options.rb +547 -0
  58. data/lib/parser.rb +2 -0
  59. data/lib/parser/auditable.rb +522 -0
  60. data/lib/parser/elements.rb +296 -0
  61. data/lib/parser/page.rb +149 -0
  62. data/lib/parser/parser.rb +717 -0
  63. data/lib/plugin.rb +4 -0
  64. data/lib/plugin/base.rb +110 -0
  65. data/lib/plugin/manager.rb +162 -0
  66. data/lib/report.rb +4 -0
  67. data/lib/report/base.rb +119 -0
  68. data/lib/report/manager.rb +92 -0
  69. data/lib/rpc/xml/client/base.rb +71 -0
  70. data/lib/rpc/xml/client/dispatcher.rb +49 -0
  71. data/lib/rpc/xml/client/instance.rb +88 -0
  72. data/lib/rpc/xml/server/base.rb +90 -0
  73. data/lib/rpc/xml/server/dispatcher.rb +357 -0
  74. data/lib/rpc/xml/server/framework.rb +206 -0
  75. data/lib/rpc/xml/server/instance.rb +191 -0
  76. data/lib/rpc/xml/server/module/manager.rb +46 -0
  77. data/lib/rpc/xml/server/options.rb +124 -0
  78. data/lib/rpc/xml/server/output.rb +299 -0
  79. data/lib/rpc/xml/server/plugin/manager.rb +58 -0
  80. data/lib/ruby.rb +5 -0
  81. data/lib/ruby/object.rb +32 -0
  82. data/lib/ruby/string.rb +74 -0
  83. data/lib/ruby/xmlrpc/server.rb +27 -0
  84. data/lib/spider.rb +200 -0
  85. data/lib/typhoeus/request.rb +91 -0
  86. data/lib/typhoeus/response.rb +34 -0
  87. data/lib/ui/cli/cli.rb +744 -0
  88. data/lib/ui/cli/output.rb +279 -0
  89. data/lib/ui/web/log.rb +82 -0
  90. data/lib/ui/web/output_stream.rb +94 -0
  91. data/lib/ui/web/report_manager.rb +222 -0
  92. data/lib/ui/web/server.rb +903 -0
  93. data/lib/ui/web/server/db/placeholder +0 -0
  94. data/lib/ui/web/server/public/banner.png +0 -0
  95. data/lib/ui/web/server/public/bodybg-small.png +0 -0
  96. data/lib/ui/web/server/public/bodybg.png +0 -0
  97. data/lib/ui/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
  98. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  99. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  100. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  101. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  102. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  103. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  104. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  105. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  106. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  107. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  108. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  109. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  110. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  111. data/lib/ui/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +573 -0
  112. data/lib/ui/web/server/public/favicon.ico +0 -0
  113. data/lib/ui/web/server/public/footer.jpg +0 -0
  114. data/lib/ui/web/server/public/icons/error.png +0 -0
  115. data/lib/ui/web/server/public/icons/info.png +0 -0
  116. data/lib/ui/web/server/public/icons/ok.png +0 -0
  117. data/lib/ui/web/server/public/icons/status.png +0 -0
  118. data/lib/ui/web/server/public/js/jquery-1.4.4.min.js +167 -0
  119. data/lib/ui/web/server/public/js/jquery-ui-1.8.9.custom.min.js +781 -0
  120. data/lib/ui/web/server/public/logo.png +0 -0
  121. data/lib/ui/web/server/public/nav-left.jpg +0 -0
  122. data/lib/ui/web/server/public/nav-right.jpg +0 -0
  123. data/lib/ui/web/server/public/nav-selected-left.jpg +0 -0
  124. data/lib/ui/web/server/public/nav-selected-right.jpg +0 -0
  125. data/lib/ui/web/server/public/reports/placeholder +1 -0
  126. data/lib/ui/web/server/public/sidebar-bottom.jpg +0 -0
  127. data/lib/ui/web/server/public/sidebar-h4.jpg +0 -0
  128. data/lib/ui/web/server/public/sidebar-top.jpg +0 -0
  129. data/lib/ui/web/server/public/spider.png +0 -0
  130. data/lib/ui/web/server/public/style.css +604 -0
  131. data/lib/ui/web/server/tmp/placeholder +0 -0
  132. data/lib/ui/web/server/views/dispatcher.erb +85 -0
  133. data/lib/ui/web/server/views/dispatcher_error.erb +14 -0
  134. data/lib/ui/web/server/views/error.erb +1 -0
  135. data/lib/ui/web/server/views/flash.erb +18 -0
  136. data/lib/ui/web/server/views/home.erb +14 -0
  137. data/lib/ui/web/server/views/instance.erb +213 -0
  138. data/lib/ui/web/server/views/layout.erb +95 -0
  139. data/lib/ui/web/server/views/log.erb +40 -0
  140. data/lib/ui/web/server/views/modules.erb +71 -0
  141. data/lib/ui/web/server/views/options.erb +23 -0
  142. data/lib/ui/web/server/views/output_results.erb +51 -0
  143. data/lib/ui/web/server/views/plugins.erb +42 -0
  144. data/lib/ui/web/server/views/report_formats.erb +30 -0
  145. data/lib/ui/web/server/views/reports.erb +55 -0
  146. data/lib/ui/web/server/views/settings.erb +120 -0
  147. data/lib/ui/web/server/views/welcome.erb +38 -0
  148. data/lib/ui/xmlrpc/dispatcher_monitor.rb +204 -0
  149. data/lib/ui/xmlrpc/xmlrpc.rb +843 -0
  150. data/logs/placeholder +0 -0
  151. data/metamodules/autothrottle.rb +74 -0
  152. data/metamodules/timeout_notice.rb +118 -0
  153. data/metamodules/uniformity.rb +98 -0
  154. data/modules/audit/code_injection.rb +136 -0
  155. data/modules/audit/code_injection_timing.rb +115 -0
  156. data/modules/audit/code_injection_timing/payloads.txt +4 -0
  157. data/modules/audit/csrf.rb +301 -0
  158. data/modules/audit/ldapi.rb +103 -0
  159. data/modules/audit/ldapi/errors.txt +26 -0
  160. data/modules/audit/os_cmd_injection.rb +103 -0
  161. data/modules/audit/os_cmd_injection/payloads.txt +2 -0
  162. data/modules/audit/os_cmd_injection_timing.rb +104 -0
  163. data/modules/audit/os_cmd_injection_timing/payloads.txt +3 -0
  164. data/modules/audit/path_traversal.rb +141 -0
  165. data/modules/audit/response_splitting.rb +105 -0
  166. data/modules/audit/rfi.rb +193 -0
  167. data/modules/audit/sqli.rb +120 -0
  168. data/modules/audit/sqli/regexp_ids.txt +90 -0
  169. data/modules/audit/sqli_blind_rdiff.rb +321 -0
  170. data/modules/audit/sqli_blind_timing.rb +103 -0
  171. data/modules/audit/sqli_blind_timing/payloads.txt +51 -0
  172. data/modules/audit/trainer.rb +89 -0
  173. data/modules/audit/unvalidated_redirect.rb +90 -0
  174. data/modules/audit/xpath.rb +104 -0
  175. data/modules/audit/xpath/errors.txt +26 -0
  176. data/modules/audit/xss.rb +99 -0
  177. data/modules/audit/xss_event.rb +134 -0
  178. data/modules/audit/xss_path.rb +125 -0
  179. data/modules/audit/xss_script_tag.rb +112 -0
  180. data/modules/audit/xss_tag.rb +112 -0
  181. data/modules/audit/xss_uri.rb +125 -0
  182. data/modules/recon/allowed_methods.rb +104 -0
  183. data/modules/recon/backdoors.rb +131 -0
  184. data/modules/recon/backdoors/filenames.txt +16 -0
  185. data/modules/recon/backup_files.rb +177 -0
  186. data/modules/recon/backup_files/extensions.txt +28 -0
  187. data/modules/recon/common_directories.rb +138 -0
  188. data/modules/recon/common_directories/directories.txt +265 -0
  189. data/modules/recon/common_files.rb +138 -0
  190. data/modules/recon/common_files/filenames.txt +17 -0
  191. data/modules/recon/directory_listing.rb +171 -0
  192. data/modules/recon/grep/captcha.rb +62 -0
  193. data/modules/recon/grep/credit_card.rb +85 -0
  194. data/modules/recon/grep/cvs_svn_users.rb +73 -0
  195. data/modules/recon/grep/emails.rb +59 -0
  196. data/modules/recon/grep/html_objects.rb +53 -0
  197. data/modules/recon/grep/private_ip.rb +54 -0
  198. data/modules/recon/grep/ssn.rb +53 -0
  199. data/modules/recon/htaccess_limit.rb +82 -0
  200. data/modules/recon/http_put.rb +95 -0
  201. data/modules/recon/interesting_responses.rb +118 -0
  202. data/modules/recon/unencrypted_password_forms.rb +119 -0
  203. data/modules/recon/webdav.rb +126 -0
  204. data/modules/recon/xst.rb +107 -0
  205. data/path_extractors/anchors.rb +35 -0
  206. data/path_extractors/forms.rb +35 -0
  207. data/path_extractors/frames.rb +38 -0
  208. data/path_extractors/generic.rb +39 -0
  209. data/path_extractors/links.rb +35 -0
  210. data/path_extractors/meta_refresh.rb +39 -0
  211. data/path_extractors/scripts.rb +37 -0
  212. data/path_extractors/sitemap.rb +31 -0
  213. data/plugins/autologin.rb +137 -0
  214. data/plugins/content_types.rb +90 -0
  215. data/plugins/cookie_collector.rb +99 -0
  216. data/plugins/form_dicattack.rb +185 -0
  217. data/plugins/healthmap.rb +94 -0
  218. data/plugins/http_dicattack.rb +133 -0
  219. data/plugins/metamodules.rb +118 -0
  220. data/plugins/proxy.rb +248 -0
  221. data/plugins/proxy/server.rb +66 -0
  222. data/plugins/waf_detector.rb +184 -0
  223. data/profiles/comprehensive.afp +74 -0
  224. data/profiles/full.afp +75 -0
  225. data/reports/afr.rb +59 -0
  226. data/reports/ap.rb +55 -0
  227. data/reports/html.rb +179 -0
  228. data/reports/html/default.erb +967 -0
  229. data/reports/metareport.rb +139 -0
  230. data/reports/metareport/arachni_metareport.rb +174 -0
  231. data/reports/plugin_formatters/html/content_types.rb +82 -0
  232. data/reports/plugin_formatters/html/cookie_collector.rb +66 -0
  233. data/reports/plugin_formatters/html/form_dicattack.rb +54 -0
  234. data/reports/plugin_formatters/html/healthmap.rb +76 -0
  235. data/reports/plugin_formatters/html/http_dicattack.rb +54 -0
  236. data/reports/plugin_formatters/html/metaformatters/timeout_notice.rb +65 -0
  237. data/reports/plugin_formatters/html/metaformatters/uniformity.rb +71 -0
  238. data/reports/plugin_formatters/html/metamodules.rb +93 -0
  239. data/reports/plugin_formatters/html/waf_detector.rb +54 -0
  240. data/reports/plugin_formatters/stdout/content_types.rb +73 -0
  241. data/reports/plugin_formatters/stdout/cookie_collector.rb +61 -0
  242. data/reports/plugin_formatters/stdout/form_dicattack.rb +52 -0
  243. data/reports/plugin_formatters/stdout/healthmap.rb +72 -0
  244. data/reports/plugin_formatters/stdout/http_dicattack.rb +53 -0
  245. data/reports/plugin_formatters/stdout/metaformatters/timeout_notice.rb +55 -0
  246. data/reports/plugin_formatters/stdout/metaformatters/uniformity.rb +68 -0
  247. data/reports/plugin_formatters/stdout/metamodules.rb +89 -0
  248. data/reports/plugin_formatters/stdout/waf_detector.rb +48 -0
  249. data/reports/plugin_formatters/xml/content_types.rb +91 -0
  250. data/reports/plugin_formatters/xml/cookie_collector.rb +70 -0
  251. data/reports/plugin_formatters/xml/form_dicattack.rb +57 -0
  252. data/reports/plugin_formatters/xml/healthmap.rb +82 -0
  253. data/reports/plugin_formatters/xml/http_dicattack.rb +57 -0
  254. data/reports/plugin_formatters/xml/metaformatters/timeout_notice.rb +67 -0
  255. data/reports/plugin_formatters/xml/metaformatters/uniformity.rb +82 -0
  256. data/reports/plugin_formatters/xml/metamodules.rb +91 -0
  257. data/reports/plugin_formatters/xml/waf_detector.rb +58 -0
  258. data/reports/stdout.rb +182 -0
  259. data/reports/txt.rb +77 -0
  260. data/reports/xml.rb +231 -0
  261. data/reports/xml/buffer.rb +98 -0
  262. metadata +516 -0
@@ -0,0 +1,120 @@
1
+ =begin
2
+ $Id$
3
+
4
+ Arachni
5
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
6
+
7
+ This is free software; you can copy and distribute and modify
8
+ this program under the term of the GPL v2.0 License
9
+ (See LICENSE file for details)
10
+
11
+ =end
12
+
13
+ module Arachni
14
+
15
+ module Modules
16
+
17
+ #
18
+ # SQL Injection audit module.<br/>
19
+ # It audits links, forms and cookies.
20
+ #
21
+ #
22
+ # @author: Tasos "Zapotek" Laskos
23
+ # <tasos.laskos@gmail.com>
24
+ # <zapotek@segfault.gr>
25
+ # @version: 0.1.4
26
+ #
27
+ # @see http://cwe.mitre.org/data/definitions/89.html
28
+ # @see http://unixwiz.net/techtips/sql-injection.html
29
+ # @see http://en.wikipedia.org/wiki/SQL_injection
30
+ # @see http://www.securiteam.com/securityreviews/5DP0N1P76E.html
31
+ # @see http://www.owasp.org/index.php/SQL_Injection
32
+ #
33
+ class SQLInjection < Arachni::Module::Base
34
+
35
+ include Arachni::Module::Utilities
36
+
37
+ def initialize( page )
38
+ super( page )
39
+ end
40
+
41
+ def prepare( )
42
+
43
+ #
44
+ # it's better to save big arrays to a file
45
+ # a big array is ugly, messy and can't be updated as easily
46
+ #
47
+ # but don't open the file yourself, use get_data_file( filename )
48
+ # with a block and read each line
49
+ #
50
+ # keep your files under modules/<modtype>/<modname>/
51
+ #
52
+
53
+ #
54
+ # we make this a class variable and populate it only once
55
+ # to reduce file IO
56
+ #
57
+ @@__regexps ||= []
58
+
59
+ if @@__regexps.empty?
60
+ read_file( 'regexp_ids.txt' ) { |regexp| @@__regexps << regexp }
61
+ end
62
+
63
+ # prepare the string that will hopefully cause the webapp
64
+ # to output SQL error messages
65
+ @__injection_str = [
66
+ '\'`--',
67
+ ')'
68
+ ]
69
+
70
+ @__opts = {
71
+ :format => [ Format::APPEND ],
72
+ :regexp => @@__regexps,
73
+ :param_flip => true
74
+ }
75
+
76
+ end
77
+
78
+ def run( )
79
+ @__injection_str.each { |str| audit( str, @__opts ) }
80
+ end
81
+
82
+
83
+ def self.info
84
+ {
85
+ :name => 'SQLInjection',
86
+ :description => %q{SQL injection recon module},
87
+ :elements => [
88
+ Issue::Element::FORM,
89
+ Issue::Element::LINK,
90
+ Issue::Element::COOKIE,
91
+ Issue::Element::HEADER
92
+ ],
93
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com> ',
94
+ :version => '0.1.4',
95
+ :references => {
96
+ 'UnixWiz' => 'http://unixwiz.net/techtips/sql-injection.html',
97
+ 'Wikipedia' => 'http://en.wikipedia.org/wiki/SQL_injection',
98
+ 'SecuriTeam' => 'http://www.securiteam.com/securityreviews/5DP0N1P76E.html',
99
+ 'OWASP' => 'http://www.owasp.org/index.php/SQL_Injection'
100
+ },
101
+ :targets => { 'Generic' => 'all' },
102
+ :issue => {
103
+ :name => %q{SQL Injection},
104
+ :description => %q{SQL code can be injected into the web application.},
105
+ :tags => [ 'sql','injection', 'regexp', 'database', 'error' ],
106
+ :cwe => '89',
107
+ :severity => Issue::Severity::HIGH,
108
+ :cvssv2 => '9.0',
109
+ :remedy_guidance => 'User inputs must be validated and filtered
110
+ before being included in database queries.',
111
+ :remedy_code => '',
112
+ :metasploitable => 'unix/webapp/arachni_sqlmap'
113
+ }
114
+
115
+ }
116
+ end
117
+
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,90 @@
1
+ System\.Data\.OleDb\.OleDbException
2
+ \[SQL Server\]
3
+ \[Microsoft\]\[ODBC SQL Server Driver\]
4
+ \[SQLServer JDBC Driver\]
5
+ \[SqlException
6
+ System\.Data\.SqlClient\.SqlException
7
+ Unclosed quotation mark after the character string
8
+ '80040e14'
9
+ mssql_query\(\)
10
+ odbc_exec\(\)
11
+ Microsoft OLE DB Provider for ODBC Drivers
12
+ Microsoft OLE DB Provider for SQL Server
13
+ Incorrect syntax near
14
+ Sintaxis incorrecta cerca de
15
+ Syntax error in string in query expression
16
+ ADODB\.Field \(0x800A0BCD\)<br>
17
+ Procedure '[^']+' requires parameter '[^']+'
18
+ ADODB\.Recordset\'
19
+ Unclosed quotation mark before the character string
20
+ SQLCODE
21
+ DB2 SQL error:
22
+ SQLSTATE
23
+ \[IBM\]\[CLI Driver\]\[DB26000\]
24
+ \[CLI Driver\]
25
+ \[DB26000\]
26
+ Sybase message:
27
+ Syntax error in query expression
28
+ Data type mismatch in criteria expression\.
29
+ Microsoft JET Database Engine
30
+ \[Microsoft\]\[ODBC Microsoft Access Driver\]
31
+ (PLS|ORA)-[0-9][0-9][0-9][0-9]
32
+ PostgreSQL query failed:
33
+ supplied argument is not a valid PostgreSQL result
34
+ pg_query\(\) \[:
35
+ pg_exec\(\) \[:
36
+ supplied argument is not a valid MySQL
37
+ Column count doesn't match value count at row
38
+ mysql_fetch_array\(\)
39
+ on MySQL result index
40
+ You have an error in your SQL syntax;
41
+ You have an error in your SQL syntax near
42
+ MySQL server version for the right syntax to use
43
+ \[MySQL\]\[ODBC
44
+ Column count doesn't match
45
+ the used select statements have different number of columns
46
+ Table '[^']+' doesn't exist
47
+ com\.informix\.jdbc
48
+ Dynamic Page Generation Error:
49
+ An illegal character has been found in the statement
50
+ <b>Warning<b>: ibase_
51
+ Dynamic SQL Error
52
+ \[DM_QUERY_E_SYNTAX\]
53
+ has occurred in the vicinity of:
54
+ A Parser Error \(syntax error\)
55
+ java\.sql\.SQLException
56
+ Unexpected end of command in statement
57
+ \[Macromedia\]\[SQLServer JDBC Driver\]
58
+ SELECT .*? FROM .*?
59
+ UPDATE .*? SET .*?
60
+ INSERT INTO .*?
61
+ Unknown column
62
+ where clause
63
+ SQL syntax.*MySQL
64
+ Warning.*mysql_.*
65
+ valid MySQL result
66
+ PostgreSQL.*ERROR
67
+ Warning.*pg_.*
68
+ valid PostgreSQL result
69
+ Driver.*SQL[\-\_\ ]*Server
70
+ OLE DB.*SQL Server
71
+ SQL Server.*Driver
72
+ Warning.*mssql_.*
73
+ Access.*Driver
74
+ Driver.*Access
75
+ JET Database Engine
76
+ Access Database Engine
77
+ ORA-[0-9][0-9][0-9][0-9]
78
+ Oracle error
79
+ Oracle.*Driver
80
+ Warning.*oci_.*
81
+ Warning.*ora_.*
82
+ CLI Driver.*DB2
83
+ DB2 SQL error
84
+ Exception.*Informix
85
+ Sybase message
86
+ Dynamic SQL Error
87
+ Warning.*sqlite_.*
88
+ SQLite/JDBCDriver
89
+ SQLite\.Exception
90
+ System\.Data\.SQLite\.SQLiteException
@@ -0,0 +1,321 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+
13
+ module Modules
14
+
15
+ #
16
+ # Blind SQL injection audit module
17
+ #
18
+ # It uses reverse-diff analysis of HTML code in order to determine successful
19
+ # blind SQL injections.
20
+ #
21
+ # @author: Tasos "Zapotek" Laskos
22
+ # <tasos.laskos@gmail.com>
23
+ # <zapotek@segfault.gr>
24
+ # @version: 0.3
25
+ #
26
+ # @see http://cwe.mitre.org/data/definitions/89.html
27
+ # @see http://capec.mitre.org/data/definitions/7.html
28
+ # @see http://www.owasp.org/index.php/Blind_SQL_Injection
29
+ #
30
+ class BlindrDiffSQLInjection < Arachni::Module::Base
31
+
32
+ include Arachni::Module::Utilities
33
+
34
+ def initialize( page )
35
+ super( page )
36
+ end
37
+
38
+ def prepare( )
39
+
40
+ # possible quote characters used in SQL statements
41
+ @__quotes = [
42
+ '\'',
43
+ '"',
44
+ ''
45
+ ]
46
+
47
+ # this will cause a silent error if there's a blind SQL injection
48
+ @__bad_chars =[
49
+ '\'"`',
50
+ # we need 2 requests thus we change the second one a little bit to
51
+ # fool the Auditor's redundancy filter
52
+ '\'"``'
53
+ ]
54
+
55
+ # %q% will be replaced by a character in @__quotes
56
+ @__injection = '%q% and %q%1'
57
+
58
+ @__opts = {
59
+ :format => [ Format::APPEND ],
60
+ # we need to do our own redundancy checks
61
+ :redundant => true
62
+ }
63
+
64
+ # used for redundancy checks
65
+ @@__audited ||= Set.new
66
+
67
+ # this is the structure of the responses
68
+ @responses = {
69
+ :orig => '',
70
+
71
+ :good => {
72
+
73
+ },
74
+ :bad => {
75
+ }
76
+ }
77
+
78
+ end
79
+
80
+ def run( )
81
+
82
+ return if( __audited? )
83
+
84
+ if( !@page.query_vars || @page.query_vars.empty? )
85
+ print_status( 'Nothing to audit on current page, skipping...' )
86
+ return
87
+ end
88
+
89
+ # get the link object that fits the URL of the page
90
+ # this will be the one to audit
91
+ @page.links.each {
92
+ |link|
93
+ @__candidate = link if link.action == @page.url
94
+ }
95
+
96
+ return if !@__candidate
97
+
98
+ # let's get a fresh rendering of the page to assist us with
99
+ # irrelevant dynamic content elimination (banners, ads, etc...)
100
+ @http.get( @page.url, :params => @page.query_vars ).on_complete {
101
+ |res|
102
+
103
+ # eliminate dynamic content that's context-irrelevant
104
+ # ie. changing with every refresh
105
+ @responses[:orig] = @page.html.rdiff( res.body )
106
+ }
107
+
108
+ # force the webapp to return an error page
109
+ prep_bad_responses( )
110
+
111
+ # start injecting 'good' SQL queries
112
+ prep_good_responses( )
113
+
114
+ @http.after_run {
115
+ # analyze the HTML code of the responses in order to determine
116
+ # which injections were succesfull
117
+ analyze( )
118
+ }
119
+ end
120
+
121
+ # Audits page with 'bad' SQL characters and gathers error pages
122
+ def prep_bad_responses( )
123
+
124
+ @__bad_chars.each {
125
+ |str|
126
+
127
+ # get injection variations that will hopefully cause an internal/silent
128
+ # SQL error
129
+ variations = @__candidate.injection_sets( str, @__opts )
130
+
131
+ @responses[:bad_total] = variations.size
132
+
133
+ variations.each {
134
+ |link|
135
+
136
+ # the altered link variable
137
+ altered = link.altered
138
+
139
+ print_status( @__candidate.get_status_str( altered ) )
140
+
141
+ # register us as the auditor
142
+ link.auditor( self )
143
+ # submit the link and get the response
144
+ link.submit( @__opts ).on_complete {
145
+ |res|
146
+
147
+ @responses[:bad][altered] ||= res.body.clone
148
+
149
+ # remove context-irrelevant dynamic content like banners and such
150
+ # from the error page
151
+ @responses[:bad][altered] = @responses[:bad][altered].rdiff( res.body.clone )
152
+ }
153
+ }
154
+ }
155
+ end
156
+
157
+ # Injects SQL code that doesn't affect the flow of execution nor presentation
158
+ def prep_good_responses( )
159
+
160
+ @__quotes.each {
161
+ |quote|
162
+
163
+ # prepare the statement with combinations of quote characters
164
+ str = @__injection.gsub( '%q%', quote )
165
+
166
+ variations = @__candidate.injection_sets( str, @__opts )
167
+
168
+ @responses[:good_total] = variations.size
169
+
170
+ variations.each {
171
+ |link|
172
+
173
+ # the altered link variable
174
+ altered = link.altered
175
+
176
+ # register us as the auditor
177
+ link.auditor( self )
178
+
179
+ # submit the link and get the response
180
+ link.submit( @__opts ).on_complete {
181
+ |res|
182
+
183
+ @responses[:good][altered] ||= []
184
+
185
+ # save the response for later analysis
186
+ @responses[:good][altered] << {
187
+ 'str' => str,
188
+ 'res' => res
189
+ }
190
+ }
191
+
192
+ }
193
+ }
194
+
195
+ end
196
+
197
+ # Goes through the responses induced by {#prep_good_responses} and {#__check} their code
198
+ def analyze( )
199
+ @responses[:good].keys.each {
200
+ |key|
201
+ @responses[:good][key].each {
202
+ |res|
203
+ __check( res['str'], res['res'], key )
204
+ }
205
+ }
206
+ end
207
+
208
+ #
209
+ # Compares HTML responses in order to identify successful blind sql injections
210
+ #
211
+ # @param [String] str the string that unveiled the vulnerability
212
+ # @param [Typhoeus::Response]
213
+ # @param [String] var the vulnerable variable
214
+ #
215
+ def __check( str, res, var )
216
+
217
+ # if one of the injections gives the same results as the
218
+ # original page then a blind SQL injection exists
219
+ check = res.body.rdiff( @page.html )
220
+
221
+ if( check == @responses[:orig] && @responses[:bad][var] != check &&
222
+ !@http.custom_404?( res ) && res.code == 200 )
223
+ __log_results( var, res, str )
224
+ end
225
+
226
+ end
227
+
228
+ def clean_up
229
+ @@__audited << __audit_id( )
230
+ end
231
+
232
+ def __audit_id
233
+ "#{URI( normalize_url( @page.url ) ).path}::#{@page.query_vars.keys}"
234
+ end
235
+
236
+ def __audited?
237
+ @@__audited.include?( __audit_id( ) )
238
+ end
239
+
240
+
241
+ def self.info
242
+ {
243
+ :name => 'Blind (rDiff) SQL Injection',
244
+ :description => %q{It uses rDiff analysis to decide how different inputs affect
245
+ the behavior of the the web pages.
246
+ Using that as a basis it extrapolates about what inputs are vulnerable to blind SQL injection.
247
+ (Note: This module may get confused by certain types of XSS vulnerabilities.
248
+ If this module returns a positive result you should investigate nonetheless.)},
249
+ :elements => [
250
+ Issue::Element::LINK
251
+ ],
252
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com> ',
253
+ :version => '0.2.2',
254
+ :references => {
255
+ 'OWASP' => 'http://www.owasp.org/index.php/Blind_SQL_Injection',
256
+ 'MITRE - CAPEC' => 'http://capec.mitre.org/data/definitions/7.html'
257
+ },
258
+ :targets => { 'Generic' => 'all' },
259
+
260
+ :issue => {
261
+ :name => %q{Blind SQL Injection},
262
+ :description => %q{SQL code can be injected into the web application
263
+ even though it may not be obvious due to suppression of error messages.},
264
+ :tags => [ 'sql', 'blind', 'rdiff', 'injection', 'database' ],
265
+ :cwe => '89',
266
+ :severity => Issue::Severity::HIGH,
267
+ :cvssv2 => '9.0',
268
+ :remedy_guidance => %q{Suppression of error messages leads to
269
+ security through obscurity which is not a good practise.
270
+ The web application needs to enforce stronger validation
271
+ on user inputs.},
272
+ :remedy_code => '',
273
+ :metasploitable => 'unix/webapp/arachni_sqlmap'
274
+ }
275
+
276
+ }
277
+ end
278
+
279
+ private
280
+
281
+ def __log_results( var, res, str )
282
+
283
+ url = res.effective_url
284
+
285
+ # since we bypassed the auditor completely we need to create
286
+ # our own opts hash and pass it to the Vulnerability class.
287
+ #
288
+ # this is only required for Metasploitable vulnerabilities
289
+ opts = {
290
+ :injected_orig => URI( @page.url ).query,
291
+ :combo => @__candidate.auditable
292
+ }
293
+
294
+ issue = Issue.new( {
295
+ :var => var,
296
+ :url => url,
297
+ :method => res.request.method.to_s,
298
+ :opts => opts,
299
+ :injected => str,
300
+ :id => str,
301
+ :regexp => 'n/a',
302
+ :regexp_match => 'n/a',
303
+ :elem => Issue::Element::LINK,
304
+ :response => res.body,
305
+ :verification => true,
306
+ :headers => {
307
+ :request => res.request.headers,
308
+ :response => res.headers,
309
+ }
310
+ }.merge( self.class.info )
311
+ )
312
+
313
+ print_ok( "In #{Issue::Element::LINK} var '#{var}' ( #{url} )" )
314
+
315
+ # register our results with the system
316
+ register_results( [ issue ] )
317
+ end
318
+
319
+ end
320
+ end
321
+ end