watobo 0.9.8.677

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 (260) hide show
  1. data/bin/watobo_gui.rb +39 -0
  2. data/certificates/cert.pem +19 -0
  3. data/certificates/privkey.pem +15 -0
  4. data/certificates/watobo_dh.key +5 -0
  5. data/config/datastore.yml +5 -0
  6. data/config/forwarding_proxy.yml +12 -0
  7. data/config/general.yml +4 -0
  8. data/config/gui.yml +23 -0
  9. data/config/interceptor.yml +16 -0
  10. data/config/scan_policy.yml +13 -0
  11. data/config/scanner.yml +34 -0
  12. data/icons/Add.ico +0 -0
  13. data/icons/Add_24x24.ico +0 -0
  14. data/icons/Bandwidth.ico +0 -0
  15. data/icons/Bandwidth_24x24.ico +0 -0
  16. data/icons/Mr. Bomb.ico +0 -0
  17. data/icons/Mr. Bomb_16x16.ico +0 -0
  18. data/icons/Mr. Bomb_24x24.ico +0 -0
  19. data/icons/Orange Ball.ico +0 -0
  20. data/icons/Orange Ball_16x16.ico +0 -0
  21. data/icons/Orange Ball_24x24.ico +0 -0
  22. data/icons/Pause.ico +0 -0
  23. data/icons/Play.ico +0 -0
  24. data/icons/Play_24x24.ico +0 -0
  25. data/icons/Red Ball.ico +0 -0
  26. data/icons/Red Ball_16x16.ico +0 -0
  27. data/icons/Red Ball_24x24.ico +0 -0
  28. data/icons/Run.ico +0 -0
  29. data/icons/Stop.ico +0 -0
  30. data/icons/Stop_24x24.ico +0 -0
  31. data/icons/Terminal.ico +0 -0
  32. data/icons/Transfer.ico +0 -0
  33. data/icons/Transfer_16x16.ico +0 -0
  34. data/icons/User.ico +0 -0
  35. data/icons/User_16x16.ico +0 -0
  36. data/icons/User_24x24.ico +0 -0
  37. data/icons/Web Browser.ico +0 -0
  38. data/icons/Web Browser_16x16.ico +0 -0
  39. data/icons/Write Document.ico +0 -0
  40. data/icons/Yellow Ball.ico +0 -0
  41. data/icons/Yellow Ball_16x16.ico +0 -0
  42. data/icons/Yellow Ball_24x24.ico +0 -0
  43. data/icons/advanced.ico +0 -0
  44. data/icons/advanced_16x16.ico +0 -0
  45. data/icons/advanced_24x24.ico +0 -0
  46. data/icons/applications.ico +0 -0
  47. data/icons/applications_16x16.ico +0 -0
  48. data/icons/applications_24x24.ico +0 -0
  49. data/icons/browser_16x16.ico +0 -0
  50. data/icons/browser_24x24.ico +0 -0
  51. data/icons/burn.ico +0 -0
  52. data/icons/burn_16x16.ico +0 -0
  53. data/icons/burn_24x24.ico +0 -0
  54. data/icons/calculator.ico +0 -0
  55. data/icons/calculator_24x24.ico +0 -0
  56. data/icons/cb_checked.ico +0 -0
  57. data/icons/cb_checked_orange.ico +0 -0
  58. data/icons/cb_unchecked.ico +0 -0
  59. data/icons/coin_24x24.ico +0 -0
  60. data/icons/conversation.ico +0 -0
  61. data/icons/conversation_24x24.ico +0 -0
  62. data/icons/engine.ico +0 -0
  63. data/icons/filter.ico +0 -0
  64. data/icons/folder.ico +0 -0
  65. data/icons/folder_16x16.ico +0 -0
  66. data/icons/fuzzer_16x16.ico +0 -0
  67. data/icons/fuzzer_24x24.ico +0 -0
  68. data/icons/go-down_16x16.png +0 -0
  69. data/icons/go-up_16x16.png +0 -0
  70. data/icons/help.ico +0 -0
  71. data/icons/help_16x16.ico +0 -0
  72. data/icons/help_24x24.ico +0 -0
  73. data/icons/iChat.ico +0 -0
  74. data/icons/iChat_16x16.ico +0 -0
  75. data/icons/iChat_24x24.ico +0 -0
  76. data/icons/icons.txt +3 -0
  77. data/icons/info.ico +0 -0
  78. data/icons/info_16x16.ico +0 -0
  79. data/icons/info_24x24.ico +0 -0
  80. data/icons/interceptor_24x24.ico +0 -0
  81. data/icons/lock.ico +0 -0
  82. data/icons/lock_12x12.ico +0 -0
  83. data/icons/lock_16x16.ico +0 -0
  84. data/icons/monitor.ico +0 -0
  85. data/icons/plugin.ico +0 -0
  86. data/icons/plugin_24x24.ico +0 -0
  87. data/icons/scan_16x16.png +0 -0
  88. data/icons/send.ico +0 -0
  89. data/icons/server.ico +0 -0
  90. data/icons/server_16x16.ico +0 -0
  91. data/icons/siberas_logo_x24.gif +0 -0
  92. data/icons/tag_blue_32x32.ico +0 -0
  93. data/icons/watobo-48x48.png +0 -0
  94. data/icons/watobo-logo.png +0 -0
  95. data/icons/watobo.ico +0 -0
  96. data/lib/watobo/adapters/data_store.rb +38 -0
  97. data/lib/watobo/adapters/file/file_store.rb +211 -0
  98. data/lib/watobo/adapters/session_store.rb +27 -0
  99. data/lib/watobo/adapters.rb +26 -0
  100. data/lib/watobo/config.rb +143 -0
  101. data/lib/watobo/constants.rb +92 -0
  102. data/lib/watobo/core/active_check.rb +404 -0
  103. data/lib/watobo/core/cookie.rb +69 -0
  104. data/lib/watobo/core/fuzz_gen.rb +160 -0
  105. data/lib/watobo/core/http_socket.rb +142 -0
  106. data/lib/watobo/core/interceptor.rb +729 -0
  107. data/lib/watobo/core/passive_check.rb +141 -0
  108. data/lib/watobo/core/project.rb +1058 -0
  109. data/lib/watobo/core/scanner.rb +396 -0
  110. data/lib/watobo/core/session.rb +1320 -0
  111. data/lib/watobo/core/simple_ca.rb +393 -0
  112. data/lib/watobo/core.rb +34 -0
  113. data/lib/watobo/defaults.rb +40 -0
  114. data/lib/watobo/external/diff/lcs/array.rb +42 -0
  115. data/lib/watobo/external/diff/lcs/block.rb +72 -0
  116. data/lib/watobo/external/diff/lcs/callbacks.rb +343 -0
  117. data/lib/watobo/external/diff/lcs/change.rb +190 -0
  118. data/lib/watobo/external/diff/lcs/hunk.rb +279 -0
  119. data/lib/watobo/external/diff/lcs/ldiff.rb +247 -0
  120. data/lib/watobo/external/diff/lcs/string.rb +40 -0
  121. data/lib/watobo/external/diff/lcs.rb +1124 -0
  122. data/lib/watobo/external/ntlm/ntlm.rb +797 -0
  123. data/lib/watobo/externals.rb +28 -0
  124. data/lib/watobo/framework/create_project.rb +55 -0
  125. data/lib/watobo/framework/init.rb +149 -0
  126. data/lib/watobo/framework/init_modules.rb +116 -0
  127. data/lib/watobo/framework/license_text.rb +50 -0
  128. data/lib/watobo/framework.rb +26 -0
  129. data/lib/watobo/gui/about_watobo.rb +68 -0
  130. data/lib/watobo/gui/browser_preview.rb +460 -0
  131. data/lib/watobo/gui/certificate_dialog.rb +132 -0
  132. data/lib/watobo/gui/chat_diff.rb +415 -0
  133. data/lib/watobo/gui/chatviewer_frame.rb +427 -0
  134. data/lib/watobo/gui/checkboxtree.rb +221 -0
  135. data/lib/watobo/gui/checks_policy_frame.rb +123 -0
  136. data/lib/watobo/gui/client_cert_dialog.rb +227 -0
  137. data/lib/watobo/gui/confirm_scan_dialog.rb +67 -0
  138. data/lib/watobo/gui/conversation_table.rb +386 -0
  139. data/lib/watobo/gui/conversation_table_ctrl.rb +175 -0
  140. data/lib/watobo/gui/csrf_token_dialog.rb +446 -0
  141. data/lib/watobo/gui/dashboard.rb +341 -0
  142. data/lib/watobo/gui/define_scope_frame.rb +380 -0
  143. data/lib/watobo/gui/edit_comment.rb +70 -0
  144. data/lib/watobo/gui/edit_scope_dialog.rb +69 -0
  145. data/lib/watobo/gui/finding_info.rb +212 -0
  146. data/lib/watobo/gui/findings_tree.rb +459 -0
  147. data/lib/watobo/gui/full_scan_dialog.rb +269 -0
  148. data/lib/watobo/gui/fuzzer_gui.rb +1522 -0
  149. data/lib/watobo/gui/hex_viewer.rb +106 -0
  150. data/lib/watobo/gui/interceptor_gui.rb +994 -0
  151. data/lib/watobo/gui/interceptor_settings_dialog.rb +201 -0
  152. data/lib/watobo/gui/log_viewer.rb +97 -0
  153. data/lib/watobo/gui/login_wizzard.rb +301 -0
  154. data/lib/watobo/gui/main_window.rb +1815 -0
  155. data/lib/watobo/gui/manual_request_editor.rb +1105 -0
  156. data/lib/watobo/gui/master_pw_dialog.rb +142 -0
  157. data/lib/watobo/gui/password_policy_dialog.rb +98 -0
  158. data/lib/watobo/gui/plugin/base.rb +82 -0
  159. data/lib/watobo/gui/plugin_board.rb +95 -0
  160. data/lib/watobo/gui/preferences_dialog.rb +116 -0
  161. data/lib/watobo/gui/progress_window.rb +102 -0
  162. data/lib/watobo/gui/project_wizzard.rb +369 -0
  163. data/lib/watobo/gui/proxy_dialog.rb +550 -0
  164. data/lib/watobo/gui/quick_scan_dialog.rb +242 -0
  165. data/lib/watobo/gui/request_editor.rb +480 -0
  166. data/lib/watobo/gui/save_chat_dialog.rb +158 -0
  167. data/lib/watobo/gui/scanner_settings_dialog.rb +360 -0
  168. data/lib/watobo/gui/select_chat_dialog.rb +169 -0
  169. data/lib/watobo/gui/session_management_dialog.rb +688 -0
  170. data/lib/watobo/gui/sites_tree.rb +347 -0
  171. data/lib/watobo/gui/status_bar.rb +88 -0
  172. data/lib/watobo/gui/table_editor.rb +445 -0
  173. data/lib/watobo/gui/tagless_viewer.rb +62 -0
  174. data/lib/watobo/gui/templates/plugin.rb +80 -0
  175. data/lib/watobo/gui/templates/plugin2.rb +103 -0
  176. data/lib/watobo/gui/text_viewer.rb +247 -0
  177. data/lib/watobo/gui/transcoder_window.rb +215 -0
  178. data/lib/watobo/gui/utils/gui_utils.rb +129 -0
  179. data/lib/watobo/gui/utils/init_icons.rb +106 -0
  180. data/lib/watobo/gui/utils/load_icons.rb +54 -0
  181. data/lib/watobo/gui/utils/load_plugins.rb +94 -0
  182. data/lib/watobo/gui/utils/master_password.rb +90 -0
  183. data/lib/watobo/gui/utils/save_default_settings.rb +99 -0
  184. data/lib/watobo/gui/utils/save_project_settings.rb +21 -0
  185. data/lib/watobo/gui/utils/save_proxy_settings.rb +45 -0
  186. data/lib/watobo/gui/utils/save_session_settings.rb +21 -0
  187. data/lib/watobo/gui/utils/session_history.rb +134 -0
  188. data/lib/watobo/gui/workspace_dialog.rb +89 -0
  189. data/lib/watobo/gui/www_auth_dialog.rb +348 -0
  190. data/lib/watobo/gui/xml_viewer_frame.rb +114 -0
  191. data/lib/watobo/gui.rb +139 -0
  192. data/lib/watobo/mixins/httpparser.rb +664 -0
  193. data/lib/watobo/mixins/request_parser.rb +210 -0
  194. data/lib/watobo/mixins/shapers.rb +345 -0
  195. data/lib/watobo/mixins/transcoders.rb +88 -0
  196. data/lib/watobo/mixins.rb +32 -0
  197. data/lib/watobo/utils/check_regex.rb +36 -0
  198. data/lib/watobo/utils/copy_object.rb +29 -0
  199. data/lib/watobo/utils/crypto.rb +74 -0
  200. data/lib/watobo/utils/expand_range.rb +45 -0
  201. data/lib/watobo/utils/file_management.rb +73 -0
  202. data/lib/watobo/utils/load_chat.rb +219 -0
  203. data/lib/watobo/utils/load_icon.rb +47 -0
  204. data/lib/watobo/utils/print_debug.rb +34 -0
  205. data/lib/watobo/utils/response_hash.rb +143 -0
  206. data/lib/watobo/utils/secure_eval.rb +57 -0
  207. data/lib/watobo/utils/text2request.rb +96 -0
  208. data/lib/watobo/utils.rb +32 -0
  209. data/lib/watobo.rb +76 -0
  210. data/modules/active/Apache/mod_status.rb +123 -0
  211. data/modules/active/Flash/crossdomain.rb +102 -0
  212. data/modules/active/directories/dirwalker.rb +89 -0
  213. data/modules/active/discovery/fileextensions.rb +151 -0
  214. data/modules/active/discovery/http_methods.rb +135 -0
  215. data/modules/active/domino/domino_db.lst +164 -0
  216. data/modules/active/domino/domino_db.rb +128 -0
  217. data/modules/active/fileinclusion/lfi_simple.rb +134 -0
  218. data/modules/active/jboss/jboss_basic.rb +119 -0
  219. data/modules/active/sap/business_objects.rb +73 -0
  220. data/modules/active/sap/its_commands.rb +101 -0
  221. data/modules/active/sap/its_service_parameter.rb +105 -0
  222. data/modules/active/sap/its_services.rb +103 -0
  223. data/modules/active/sap/its_xss.rb +98 -0
  224. data/modules/active/sqlinjection/sql_boolean.rb +262 -0
  225. data/modules/active/sqlinjection/sqli_simple.rb +205 -0
  226. data/modules/active/xss/xss_simple.rb +179 -0
  227. data/modules/passive/cookie_options.rb +97 -0
  228. data/modules/passive/cookie_xss.rb +85 -0
  229. data/modules/passive/detect_code.rb +89 -0
  230. data/modules/passive/detect_fileupload.rb +80 -0
  231. data/modules/passive/detect_infrastructure.rb +98 -0
  232. data/modules/passive/detect_one_time_tokens.rb +86 -0
  233. data/modules/passive/dirindexing.rb +81 -0
  234. data/modules/passive/disclosure_emails.rb +82 -0
  235. data/modules/passive/disclosure_ipaddr.rb +87 -0
  236. data/modules/passive/filename_as_parameter.rb +85 -0
  237. data/modules/passive/form_spotter.rb +75 -0
  238. data/modules/passive/hotspots.rb +86 -0
  239. data/modules/passive/in_script_parameter.rb +92 -0
  240. data/modules/passive/multiple_server_headers.rb +98 -0
  241. data/modules/passive/possible_login.rb +134 -0
  242. data/modules/passive/redirect_url.rb +88 -0
  243. data/modules/passive/redirectionz.rb +96 -0
  244. data/modules/passive/xss_dom.rb +91 -0
  245. data/plugins/catalog/catalog.ico +0 -0
  246. data/plugins/catalog/catalog.rb +726 -0
  247. data/plugins/catalog/db_tests +6483 -0
  248. data/plugins/catalog/db_variables +29 -0
  249. data/plugins/filefinder/dbs/hbci.db +12 -0
  250. data/plugins/filefinder/filefinder.rb +602 -0
  251. data/plugins/sslchecker/cli/sslchecker_cli.rb +21 -0
  252. data/plugins/sslchecker/gui/cipher_table.rb +260 -0
  253. data/plugins/sslchecker/gui/gui.rb +245 -0
  254. data/plugins/sslchecker/gui/sslchecker.rb +26 -0
  255. data/plugins/sslchecker/icons/green_16x16.ico +0 -0
  256. data/plugins/sslchecker/icons/grey_16x16.ico +0 -0
  257. data/plugins/sslchecker/icons/red_16x16.ico +0 -0
  258. data/plugins/sslchecker/icons/sslchecker.ico +0 -0
  259. data/plugins/sslchecker/lib/check.rb +117 -0
  260. metadata +317 -0
@@ -0,0 +1,726 @@
1
+ # .
2
+ # catalog.rb
3
+ #
4
+ # Copyright 2012 by siberas, http://www.siberas.de
5
+ #
6
+ # This file is part of WATOBO (Web Application Tool Box)
7
+ # http://watobo.sourceforge.com
8
+ #
9
+ # WATOBO is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation version 2 of the License.
12
+ #
13
+ # WATOBO 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 WATOBO; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # .
22
+ module Watobo
23
+ module Plugin
24
+ module Catalog
25
+
26
+ class Check < Watobo::ActiveCheck
27
+ attr_writer :db_files
28
+ attr_writer :var_files
29
+ attr_writer :path
30
+
31
+ def loadVars(path)
32
+ dbpath = Dir.getwd
33
+ dbpath = path if not path.nil?
34
+ @dbvars.clear
35
+ @var_files.each do |file|
36
+ # puts "* loading var-file #{file}"
37
+ fname = File.join( dbpath, file)
38
+ if File.exists?(fname)
39
+ File.open(fname) { |fh|
40
+ fh.each do |line|
41
+ if line.strip =~ /^[^#]/ and line =~ /=/
42
+ key,vars = line.split("=")
43
+ key.strip!
44
+
45
+ @dbvars[key] = vars.strip.split(" ")
46
+ end
47
+ end
48
+ }
49
+ else
50
+ puts "* file (#{fname}) does not exist. Please check path and name."
51
+ end
52
+ # puts "* db vars total: #{@dbvars.length}"
53
+ end
54
+ end
55
+
56
+ def loadDBFiles(path, *opts)
57
+ dbpath = Dir.getwd
58
+ dbpath = path if not path.nil?
59
+ @catalog_checks.clear
60
+
61
+ @db_files.each do |file|
62
+ # puts "* loading db file #{file}.."
63
+ fname = File.join( dbpath, file)
64
+ if File.exists?(fname)
65
+ File.open(fname) { |fh|
66
+ fh.each do |line|
67
+
68
+ next if line.strip =~ /^#/
69
+ # puts "+ #{line}"
70
+ fields = line.split("\",")
71
+ fields.map!{ |f| f.gsub!(/^"/,'') }
72
+ fields.first.gsub!(/^\"/,"")
73
+ fields.last.gsub!(/\"?/,"")
74
+ # puts fields.join(" : ")
75
+ # puts "*" + fields.length.to_s
76
+ # gets
77
+ @catalog_checks.push fields
78
+ end
79
+ }
80
+ # puts "* db checks total: #{@catalog_checks.length}"
81
+ else
82
+ puts "* file (#{fname}) does not exist. Please check path and name."
83
+ end
84
+ end
85
+ end
86
+
87
+ def loadChecks(path)
88
+ begin
89
+ puts "=== Initialize Catalog Scanner ==="
90
+ loadVars(path)
91
+ loadDBFiles(path)
92
+ # setup regex
93
+ dummy = []
94
+ pattern = nil
95
+ count = 0
96
+ @dbvars.each_key do |k| dummy << k; end
97
+ pattern = "(#{dummy.join("|")})" if dummy.length > 0
98
+ @catalog_checks.each do |dbid, osvdb, threat, uri, method, match, or_match, and_match, fail, or_fail, summary, post_data, headers|
99
+
100
+ if pattern and uri =~ /(#{pattern})/
101
+ key = $1
102
+ #puts "+ found var key: #{key}"
103
+ @dbvars[key].each do |v|
104
+ # puts "--#{v}"
105
+ new_uri = uri.gsub(/#{key}/, v)
106
+ #count += 1
107
+ #print "\r[Plugin] Total Checks. #{count} "
108
+ yield dbid, osvdb, threat, new_uri, method, match, or_match, and_match, fail, or_fail, summary, post_data, headers
109
+ end
110
+ else
111
+ #count += 1
112
+ #print "\r[Plugin] Total Checks. #{count} "
113
+ yield dbid, osvdb, threat, uri, method, match, or_match, and_match, fail, or_fail, summary, post_data, headers
114
+ end
115
+ end
116
+ #puts "[Plugin] Total Checks. #{count}"
117
+ rescue => bang
118
+ puts bang
119
+ puts bang.backtrace if $DEBUG
120
+ end
121
+ end
122
+
123
+ def initialize(project)
124
+ super(project, project.getScanPreferences())
125
+
126
+ @info.update(
127
+ :check_name => 'Catalog-Scan', # name of check which briefly describes functionality, will be used for tree and progress views
128
+ :description => "Using catalog databases for testing the web application.", # description of checkfunction
129
+ :author => "Andreas Schmidt", # author of check
130
+ :version => "1.0" # check version
131
+ )
132
+
133
+ @finding.update(
134
+ :threat => 'catalog db finding', # thread of vulnerability, e.g. loss of information
135
+ :class => "Catalog", # vulnerability class, e.g. Stored XSS, SQL-Injection, ...
136
+ :type => FINDING_TYPE_VULN, # FINDING_TYPE_HINT, FINDING_TYPE_INFO, FINDING_TYPE_VULN
137
+ :rating => VULN_RATING_LOW
138
+ )
139
+
140
+ @path = nil
141
+
142
+ @dbvars = Hash.new
143
+
144
+ @catalog_checks = []
145
+
146
+ @db_files = %w( db_tests )
147
+ @var_files = %w( db_variables )
148
+
149
+ @threat_list = [ "File Upload", "Interesting File", "Misconfiguration", "Information Disclosure", "Injection (XSS/Script/HTML)",
150
+ "Remote File Retrieval", "Denial of Service", "Remote File Retrieval", "Command Execution", "SQL Injection",
151
+ "Authentication Bypass", "Software Identification", "Remote source inclusion" ]
152
+
153
+ end
154
+
155
+ def reset()
156
+ @catalog_checks.clear
157
+ end
158
+
159
+ def generateChecks(chat)
160
+ begin
161
+ loadChecks(@path) do |dbid, osvdb, threat, uri, method, match, or_match, and_match, fail, or_fail, summary, post_data, headers|
162
+
163
+ checker = proc {
164
+ test_request = nil
165
+ test_response = nil
166
+ # !!! ATTENTION !!!
167
+ # MAKE COPY BEFORE MODIFIYING REQUEST
168
+ test = chat.copyRequest
169
+ test.replaceFileExt(uri.gsub(/^\//,''))
170
+
171
+ if method !~ /get/i then
172
+ test.replaceMethod(method)
173
+ end
174
+
175
+ if method =~ /post/i then
176
+ test.addHeader("Content-Length", "0")
177
+ end
178
+
179
+ status, test_request, test_response = fileExists?(test, :default => true)
180
+ # puts "[#{status}] - #{test_request.url}"
181
+ unless test_request.nil? or test_response.nil? then
182
+ test_result = false
183
+ response = test_response.join
184
+ if status == true
185
+
186
+ if ( ( match != "" and response =~ /#{Regexp.quote(match)}/i) or ( or_match != "" and response =~ /#{Regexp.quote(or_match)}/i )) then
187
+ test_result = true
188
+ if and_match != "" then
189
+ test_result = false
190
+ test_result = true if response =~ /#{Regexp.quote(and_match)}/i
191
+
192
+ end
193
+ end
194
+ test_result = false if fail != "" and response =~ /#{Regexp.quote(fail)}/i
195
+ test_result = false if or_fail != "" and response =~ /#{Regexp.quote(or_fail)}/i
196
+
197
+ # test_chat = Chat.new(test_request, test_response, chat.id)
198
+
199
+ if test_result then
200
+ # path = test_request.url.gsub(/#{uri}/,"")
201
+ path = test_request.path
202
+ addFinding( test_request, test_response,
203
+ :test_item => uri,
204
+ :proof_pattern => "#{Regexp.quote(match)}",
205
+ :check_pattern => "#{Regexp.quote(uri)}",
206
+ :chat => chat,
207
+ :threat => "#{summary}",
208
+ :title => "[#{uri}] - #{path}"
209
+
210
+ )
211
+
212
+ end
213
+ end
214
+ end
215
+
216
+ # notify(:db_finished)
217
+ [ test_request, test_response ]
218
+ }
219
+ yield checker
220
+ end
221
+ rescue => bang
222
+ puts "!error in module #{Module.nesting[0].name}"
223
+ puts bang
224
+ end
225
+ end
226
+ end
227
+
228
+ class Catalog < Watobo::Template::Plugin
229
+
230
+ include Watobo::Constants
231
+
232
+ def updateView()
233
+ #@project = project
234
+ @sites_combo.clearItems()
235
+ @dir_combo.clearItems()
236
+ @dir_combo.disable
237
+
238
+ if @project then
239
+ @sites_combo.appendItem("no site selected", nil)
240
+ @project.listSites(:in_scope => @scope_only_cb.checked? ).each do |site|
241
+ #puts "Site: #{site}"
242
+ @sites_combo.appendItem(site.slice(0..35), site)
243
+ end
244
+ @sites_combo.numVisible = @sites_combo.numItems >= 20 ? 20 : @sites_combo.numItems
245
+ @sites_combo.setCurrentItem(0) if @sites_combo.numItems > 0
246
+ ci = @sites_combo.currentItem
247
+ site = ( ci >= 0 ) ? @sites_combo.getItemData(ci) : nil
248
+
249
+ if site
250
+ @dir_combo.enable
251
+ @project.listDirs(@site) do |dir|
252
+ @dir_combo.appendItem(dir.slice(0..35), dir)
253
+ end
254
+ @dir_combo.setCurrentItem(0, true) if @dir_combo.numItems > 0
255
+
256
+ end
257
+ end
258
+
259
+ end
260
+
261
+ def onClose
262
+
263
+ end
264
+
265
+ def initialize(owner, project)
266
+ super(owner, "Catalog Scanner", project, :opts => DECOR_ALL, :width=>800, :height=>400)
267
+ load_icon(__FILE__)
268
+ self.connect(SEL_CLOSE, method(:onClose))
269
+
270
+ @event_dispatcher_listeners = Hash.new
271
+ @scanner = nil
272
+ @plugin_name = "Catalog-Scan"
273
+ @project = project
274
+ @path = File.expand_path(File.dirname(__FILE__))
275
+ catalog_ready = true
276
+ db_files = %w( db_tests db_variables )
277
+ db_files.each do |file|
278
+ fname = File.join( @path, file)
279
+ if not File.exists?(fname)
280
+ catalog_ready = false
281
+ puts "WARNING: Missing catalog db file: #{fname}"
282
+ end
283
+ end
284
+
285
+ @site = nil
286
+ @dir = nil
287
+
288
+ begin
289
+ hs_green = FXHiliteStyle.new
290
+ hs_green.normalForeColor = FXRGBA(255,255,255,255) #FXColor::Red
291
+ hs_green.normalBackColor = FXRGBA(0,255,0,1) # FXColor::White
292
+ hs_green.style = FXText::STYLE_BOLD
293
+
294
+ hs_red = FXHiliteStyle.new
295
+ hs_red.normalForeColor = FXRGBA(255,255,255,255) # FXColor::Red
296
+ hs_red.normalBackColor = FXRGBA(255,0,0,1) # FXColor::White
297
+ hs_red.style = FXText::STYLE_BOLD
298
+
299
+ path = Dir.getwd
300
+
301
+ mr_splitter = FXSplitter.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL|SPLITTER_REVERSED|SPLITTER_TRACKING)
302
+ # top = FXHorizontalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_SIDE_BOTTOM)
303
+ top_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM,:height => 500)
304
+ top_splitter = FXSplitter.new(top_frame, LAYOUT_FILL_X|SPLITTER_HORIZONTAL|LAYOUT_FILL_Y|SPLITTER_TRACKING)
305
+ log_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,:height => 100)
306
+
307
+ @settings_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_Y)
308
+ result_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
309
+ @requestCombo = FXComboBox.new(result_frame, 5, nil, 0,
310
+ COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
311
+ #@filterCombo.width =200
312
+
313
+ @requestCombo.numVisible = 0
314
+ @requestCombo.numColumns = 50
315
+ @requestCombo.editable = false
316
+ @requestCombo.connect(SEL_COMMAND, method(:onSelectRequest))
317
+
318
+ log_text_frame = FXVerticalFrame.new(result_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
319
+ # @request_box = FXText.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
320
+ # @request_box.styled = true
321
+ # Set the styles
322
+ # @request_box.hiliteStyles = [ hs_green, hs_red]
323
+
324
+ @request_editor = RequestEditor.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
325
+
326
+ FXLabel.new(@settings_frame, "Select Site:")
327
+
328
+ @scope_only_cb = FXCheckButton.new(@settings_frame, "target scope only", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
329
+ @scope_only_cb.setCheck(false)
330
+ @scope_only_cb.connect(SEL_COMMAND) { updateView() }
331
+
332
+ @sites_combo = FXComboBox.new(@settings_frame, 5, nil, 0,
333
+ COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
334
+ #@filterCombo.width =200
335
+
336
+ @sites_combo.numVisible = @sites_combo.numItems >= 20 ? 20 : @sites_combo.numItems
337
+ @sites_combo.numColumns = 35
338
+ @sites_combo.editable = false
339
+ @sites_combo.connect(SEL_COMMAND, method(:onSiteSelect))
340
+
341
+ FXLabel.new(@settings_frame, "Root Directory:")
342
+ @dir_combo = FXComboBox.new(@settings_frame, 5, nil, 0,
343
+ COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
344
+ @dir_combo.numVisible = 20
345
+ @dir_combo.numColumns = 35
346
+ @dir_combo.editable = false
347
+ @dir_combo.connect(SEL_COMMAND, method(:onDirSelect))
348
+
349
+ @test_all_dirs = FXCheckButton.new(@settings_frame, "test all sub-directories", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
350
+ @test_all_dirs.setCheck(false)
351
+
352
+ # @use_ssl = FXCheckButton.new(@settings_frame, "use SSL", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
353
+
354
+ # @run_passive_checks = FXCheckButton.new(@settings_frame, "run passive checks", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
355
+ # @run_passive_checks.setCheck(false)
356
+
357
+ frame = FXGroupBox.new(@settings_frame, "Logging", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
358
+ @logScanChats = FXCheckButton.new(frame, "Log Scan", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
359
+ @logScanChats.checkState = false
360
+
361
+ @logScanChats.connect(SEL_COMMAND) do |sender, sel, item|
362
+ if @logScanChats.checked? then
363
+ @scanlog_dir_text.enabled = true
364
+ @scanlog_dir_label.enabled = true
365
+ @scanlog_dir_btn.enable
366
+ else
367
+ @scanlog_dir_text.enabled = false
368
+ @scanlog_dir_label.enabled = false
369
+ @scanlog_dir_btn.disable
370
+ end
371
+ end
372
+
373
+ @scanlog_dir_dt = FXDataTarget.new('')
374
+ # @scanlog_dir_dt.value = @project.scanLogDirectory() if File.exist?(@project.scanLogDirectory())
375
+ @scanlog_dir_label = FXLabel.new(frame, "Scan-Log Directory:" )
376
+ scanlog_frame = FXHorizontalFrame.new(frame,:opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP)
377
+ @scanlog_dir_text = FXTextField.new(scanlog_frame, 20,
378
+ :target => @scanlog_dir_dt, :selector => FXDataTarget::ID_VALUE,
379
+ :opts => TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
380
+ @scanlog_dir_text.handle(self, FXSEL(SEL_UPDATE, 0), nil)
381
+ @scanlog_dir_btn = FXButton.new(scanlog_frame, "Change")
382
+ # @scanlog_dir_btn.connect(SEL_COMMAND, method(:selectScanlogDirectory))
383
+
384
+ @pbar = FXProgressBar.new(@settings_frame, nil, 0, LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|PROGRESSBAR_HORIZONTAL)
385
+ @pbar.progress = 0
386
+ @pbar.total = 0
387
+ @pbar.barColor=0
388
+ @pbar.barColor = 'grey' #FXRGB(255,0,0)
389
+
390
+ @speed = FXLabel.new(@settings_frame, "Requests per second: 0")
391
+
392
+ @start_button = FXButton.new(@settings_frame, "start")
393
+ @start_button.connect(SEL_COMMAND, method(:start))
394
+ @start_button.disable
395
+
396
+ gbox = FXGroupBox.new(@settings_frame, "Info", LAYOUT_SIDE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 150)
397
+ gbframe = FXVerticalFrame.new(gbox, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
398
+ fxtext = FXText.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
399
+ fxtext.backColor = fxtext.parent.backColor
400
+ fxtext.disable
401
+ text = "Catalog-Scanner will test the web application for known directories and/or files. There must be two files in the appropriate plugin folder:\n"
402
+ text << "- db_tests\n- db_variables\n\nThe format of these files is very similar to the format nikto (http://cirt.net/nikto2) is using. So if you have your own nikto.db-files, you"
403
+ text << " can use them with this plugin."
404
+ text << "\n\nCatalog Directory:\n#{File.dirname(__FILE__)}"
405
+ fxtext.setText(text)
406
+
407
+ @check = nil
408
+
409
+ log_frame_header = FXHorizontalFrame.new(log_frame, :opts => LAYOUT_FILL_X)
410
+ FXLabel.new(log_frame_header, "Logs:" )
411
+
412
+ #log_text_frame = FXHorizontalFrame.new(bottom_frame, :opts => LAYOUT_FILL_X|FRAME_SUNKEN|LAYOUT_BOTTOM)
413
+ log_text_frame = FXVerticalFrame.new(log_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
414
+ @log_viewer = LogViewer.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
415
+
416
+ updateView()
417
+ rescue => bang
418
+ puts bang
419
+ puts bang.backtrace if $DEBUG
420
+ end
421
+ end
422
+
423
+ def create
424
+ @log_viewer.purge
425
+ @request_editor.setText('')
426
+ @requestCombo.clearItems()
427
+
428
+ @start_button.text = "Start"
429
+ super # Create the windows
430
+ show(PLACEMENT_SCREEN) # Make the main window appear
431
+ disableOptions()
432
+ end
433
+
434
+
435
+
436
+ private
437
+
438
+ def updateRequestEditor(chat=nil)
439
+ @request_editor.setText('')
440
+ return if chat.nil?
441
+ #chat = createChat(site, dir)
442
+ #@request_box.setText(chat)
443
+ request = chat.copyRequest
444
+ # request.replaceFileExt('')
445
+ @request_editor.setText(request.join.gsub(/\r/,""))
446
+ end
447
+
448
+ def createChat()
449
+ request = @request_editor.parseRequest()
450
+ puts "[#{self}] - createChat:"
451
+ puts request
452
+ chat = Watobo::Chat.new(request, [], :id => 0)
453
+ end
454
+
455
+ def onSelectRequest(sender, sel, item)
456
+ begin
457
+ chat = @requestCombo.getItemData(@requestCombo.currentItem)
458
+ updateRequestEditor(chat)
459
+ rescue => bang
460
+ puts "could not update request"
461
+ puts bang
462
+ end
463
+ end
464
+
465
+ def updateRequestCombo(chat_list)
466
+ @requestCombo.clearItems()
467
+ chat_list.each do |chat|
468
+ text = "[#{chat.id}] #{chat.request.url}"
469
+ @requestCombo.appendItem(text.slice(0..60), chat)
470
+ end
471
+ if @requestCombo.numItems > 0 then
472
+ if @requestCombo.numItems < 10 then
473
+ @requestCombo.numVisible = @requestCombo.numItems
474
+ else
475
+ @requestCombo.numVisible = 10
476
+ end
477
+ @requestCombo.setCurrentItem(0, true)
478
+ chat = @requestCombo.getItemData(0)
479
+ end
480
+
481
+ end
482
+
483
+ def onSiteSelect(sender, sel, item)
484
+ ci = @sites_combo.currentItem
485
+ @dir_combo.clearItems()
486
+ @dir = ""
487
+ @request_editor.setText('')
488
+ @requestCombo.clearItems()
489
+
490
+ if ci > 0 then
491
+ @site = @sites_combo.getItemData(ci)
492
+ if @site
493
+ @dir_combo.appendItem("/", nil)
494
+
495
+ chats = @project.findChats(@site, :method => "GET")
496
+ updateRequestCombo(chats)
497
+ updateRequestEditor(chats.first)
498
+ if @project then
499
+ @project.listDirs(@site) do |dir|
500
+ text = "/" + dir.slice(0..35)
501
+ text.gsub!(/\/+/, '/')
502
+ @dir_combo.appendItem(text, dir)
503
+ end
504
+ @dir_combo.setCurrentItem(0, true) if @dir_combo.numItems > 0
505
+ end
506
+ end
507
+ enableOptions()
508
+ @dir_combo.enable
509
+ @start_button.enable
510
+ else
511
+ @site = nil
512
+ @request_editor.setText('')
513
+ disableOptions()
514
+ @start_button.disable
515
+ end
516
+ end
517
+
518
+ def disableOptions()
519
+ # @use_ssl.setCheck(false)
520
+ # @use_ssl.disable
521
+ @test_all_dirs.setCheck(false)
522
+ @test_all_dirs.disable
523
+ # @run_passive_checks.setCheck(false)
524
+ @dir_combo.disable
525
+ #@run_passive_checks.disable
526
+ @request_editor.enabled = false
527
+ @request_editor.backColor = FXColor::LightGrey
528
+ end
529
+
530
+ def selectScanlogDirectory(sender, sel, item)
531
+ workspace_dt = FXFileDialog.getOpenDirectory(self, "Select Scanlog Directory", @scanlog_dir_dt.value)
532
+ if workspace_dt != "" then
533
+ if File.exists?(workspace_dt) then
534
+ @scanlog_dir_dt.value = workspace_dt
535
+ @scanlog_dir_text.handle(self, FXSEL(SEL_UPDATE, 0), nil)
536
+ end
537
+ end
538
+ end
539
+
540
+ def enableOptions()
541
+ # @use_ssl.enable
542
+ @test_all_dirs.enable
543
+ @dir_combo.enable
544
+ @request_editor.enabled = true
545
+ @request_editor.backColor = FXColor::White
546
+ #@run_passive_checks.enable
547
+ end
548
+
549
+ def onDirSelect(sender, sel, item)
550
+
551
+ ci = @dir_combo.currentItem
552
+
553
+ if ci > 0 then
554
+ @dir = @dir_combo.getItemData(ci)
555
+ else
556
+ @dir = ""
557
+ end
558
+ chats = @project.findChats(@site, :method => "GET", :dir => @dir)
559
+ updateRequestCombo(chats)
560
+ updateRequestEditor(chats.first)
561
+ end
562
+
563
+ def hide()
564
+
565
+ # puts "* #{self.class} closed"
566
+ @scanner.cancel() if @scanner
567
+
568
+ self.destroy
569
+
570
+ end
571
+
572
+ def start(sender, sel, item)
573
+ if @start_button.text =~ /cancel/i then
574
+ @scanner.cancel()
575
+ @start_button.text = "Start"
576
+ @pbar.progress = 0
577
+ return
578
+ end
579
+
580
+ if @logScanChats.checked?
581
+ if @scanlog_dir_dt.value.empty?
582
+ FXMessageBox.information(self,MBOX_OK,"Need Scan-Name", "Please provide a scan name!")
583
+ return false
584
+ end
585
+ end
586
+
587
+ @start_button.text = "Cancel"
588
+
589
+
590
+ @check = Check.new(@project)
591
+
592
+ #@check.subscribe(:db_finished) {
593
+ # @pbar.increment(1)
594
+ #puts @pbar.progress.to_s + "/" + @pbar.total.to_s
595
+ # if @pbar.progress == @pbar.total-1
596
+ # @pbar.barColor = 'grey'
597
+ # puts @pbar.progress.to_s + "/" + @pbar.total.to_s
598
+ # end
599
+
600
+ #}
601
+
602
+ @check.subscribe(:new_finding) { |f|
603
+ @project.addFinding(f)
604
+ }
605
+
606
+ @check.path = @path
607
+
608
+ chatlist = []
609
+ checklist = []
610
+ checklist.push @check
611
+ @check.resetCounters()
612
+
613
+ @log_viewer.log( LOG_INFO, "Starting ...")
614
+ puts "Site: #{@site}"
615
+ # progressWindow = Watobo::Gui::ProgressWindow.new(self, "Initialize Plugin")
616
+
617
+ # progressWindow.create
618
+ # progressWindow.show(PLACEMENT_SCREEN)
619
+ # progressWindow.newProject(@active_project, project_settings)
620
+
621
+ # progressWindow.register(self)
622
+ progressWindow = nil
623
+ # Thread.new(progressWindow){ |pw|
624
+ begin
625
+ c=1
626
+ if @test_all_dirs.checked? then
627
+ c = 0
628
+ @project.listDirs(@site, :base_dir => @dir, :include_subdirs => @test_all_dirs.checked?) { c += 1 }
629
+ notify(:update_progress, :total => c, :job => @dir)
630
+ @project.listDirs(@site, :base_dir => @dir, :include_subdirs => @test_all_dirs.checked?) do |dir|
631
+ msg = "running checks on #{dir}"
632
+ puts msg
633
+ @log_viewer.log(LOG_INFO, msg)
634
+ chat = createChat()
635
+ chat.request.replaceFileExt('')
636
+ chat.request.setDir(dir)
637
+ chatlist.push chat
638
+ # @check.getCheckCount(chat)
639
+ @check.updateCounters(chat)
640
+ # pw.update_progress( :progress => 1)
641
+ end
642
+ else
643
+ # notify(:update_progress, :total => c, :job => @dir)
644
+ msg = "running checks on #{@dir}"
645
+ puts msg
646
+ @log_viewer.log(LOG_INFO, msg)
647
+ chat = createChat()
648
+ # puts chat.request.first
649
+ chat.request.replaceFileExt('')
650
+ chat.request.setDir(@dir)
651
+ # puts chat.request.first
652
+ chatlist.push chat
653
+ @check.updateCounters(chat)
654
+ # notify(:update_progress, :progress => 1)
655
+ end
656
+ rescue => bang
657
+ puts bang
658
+ puts bang.backtrace if $DEBUG
659
+ ensure
660
+ # pw.hide
661
+ end
662
+ # }
663
+
664
+ # getApp().runModalWhileShown(progressWindow)
665
+
666
+ scan_prefs = @project.getScanPreferences
667
+
668
+
669
+ if @logScanChats.checked?
670
+ scan_prefs[:scanlog_name] = @scanlog_dir_dt.value unless @scanlog_dir_dt.value.empty?
671
+ end
672
+
673
+
674
+ @scanner = Watobo::Scanner2.new(chatlist, checklist, @project.passive_checks, scan_prefs)
675
+ @pbar.total = @check.numChecks * chatlist.length
676
+ @pbar.progress = 0
677
+ @pbar.barColor = 'red'
678
+
679
+ speed = 0
680
+ lasttime = 0
681
+ @scanner.subscribe(:progress) { |m|
682
+ time = Time.now.to_i
683
+ if time == lasttime then
684
+ speed += 1
685
+ else
686
+ @speed.text = "Requests per second: #{speed}"
687
+ speed = 1
688
+ lasttime = time
689
+ end
690
+ @pbar.increment(1)
691
+ }
692
+
693
+ msg= "Total Requests: #{@check.numChecks}"
694
+ @log_viewer.log(LOG_INFO, msg)
695
+
696
+
697
+ st = Thread.new(@scanner){ |scan|
698
+ begin
699
+ msg = "start scanning..."
700
+ @log_viewer.log(LOG_INFO, msg)
701
+
702
+ scan.run(:run_passive_checks => false)
703
+
704
+ msg = "scanning finished!"
705
+ @log_viewer.log(LOG_INFO, msg)
706
+ rescue => bang
707
+ puts bang
708
+ puts bang.backtrace if $DEBUG
709
+ end
710
+ @pbar.progress = 0
711
+ @pbar.barColor = 'grey'
712
+ @speed.text = "Requests per second: 0"
713
+ @start_button.text = "Start"
714
+ }
715
+ # st.join
716
+ end
717
+
718
+ end
719
+ end
720
+ end
721
+ end
722
+
723
+ if __FILE__ == $0
724
+ puts "Running #{__FILE__}"
725
+ catalog = Watobo::Plugin::Catalog.new(project)
726
+ end