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.
- data/bin/watobo_gui.rb +39 -0
- data/certificates/cert.pem +19 -0
- data/certificates/privkey.pem +15 -0
- data/certificates/watobo_dh.key +5 -0
- data/config/datastore.yml +5 -0
- data/config/forwarding_proxy.yml +12 -0
- data/config/general.yml +4 -0
- data/config/gui.yml +23 -0
- data/config/interceptor.yml +16 -0
- data/config/scan_policy.yml +13 -0
- data/config/scanner.yml +34 -0
- data/icons/Add.ico +0 -0
- data/icons/Add_24x24.ico +0 -0
- data/icons/Bandwidth.ico +0 -0
- data/icons/Bandwidth_24x24.ico +0 -0
- data/icons/Mr. Bomb.ico +0 -0
- data/icons/Mr. Bomb_16x16.ico +0 -0
- data/icons/Mr. Bomb_24x24.ico +0 -0
- data/icons/Orange Ball.ico +0 -0
- data/icons/Orange Ball_16x16.ico +0 -0
- data/icons/Orange Ball_24x24.ico +0 -0
- data/icons/Pause.ico +0 -0
- data/icons/Play.ico +0 -0
- data/icons/Play_24x24.ico +0 -0
- data/icons/Red Ball.ico +0 -0
- data/icons/Red Ball_16x16.ico +0 -0
- data/icons/Red Ball_24x24.ico +0 -0
- data/icons/Run.ico +0 -0
- data/icons/Stop.ico +0 -0
- data/icons/Stop_24x24.ico +0 -0
- data/icons/Terminal.ico +0 -0
- data/icons/Transfer.ico +0 -0
- data/icons/Transfer_16x16.ico +0 -0
- data/icons/User.ico +0 -0
- data/icons/User_16x16.ico +0 -0
- data/icons/User_24x24.ico +0 -0
- data/icons/Web Browser.ico +0 -0
- data/icons/Web Browser_16x16.ico +0 -0
- data/icons/Write Document.ico +0 -0
- data/icons/Yellow Ball.ico +0 -0
- data/icons/Yellow Ball_16x16.ico +0 -0
- data/icons/Yellow Ball_24x24.ico +0 -0
- data/icons/advanced.ico +0 -0
- data/icons/advanced_16x16.ico +0 -0
- data/icons/advanced_24x24.ico +0 -0
- data/icons/applications.ico +0 -0
- data/icons/applications_16x16.ico +0 -0
- data/icons/applications_24x24.ico +0 -0
- data/icons/browser_16x16.ico +0 -0
- data/icons/browser_24x24.ico +0 -0
- data/icons/burn.ico +0 -0
- data/icons/burn_16x16.ico +0 -0
- data/icons/burn_24x24.ico +0 -0
- data/icons/calculator.ico +0 -0
- data/icons/calculator_24x24.ico +0 -0
- data/icons/cb_checked.ico +0 -0
- data/icons/cb_checked_orange.ico +0 -0
- data/icons/cb_unchecked.ico +0 -0
- data/icons/coin_24x24.ico +0 -0
- data/icons/conversation.ico +0 -0
- data/icons/conversation_24x24.ico +0 -0
- data/icons/engine.ico +0 -0
- data/icons/filter.ico +0 -0
- data/icons/folder.ico +0 -0
- data/icons/folder_16x16.ico +0 -0
- data/icons/fuzzer_16x16.ico +0 -0
- data/icons/fuzzer_24x24.ico +0 -0
- data/icons/go-down_16x16.png +0 -0
- data/icons/go-up_16x16.png +0 -0
- data/icons/help.ico +0 -0
- data/icons/help_16x16.ico +0 -0
- data/icons/help_24x24.ico +0 -0
- data/icons/iChat.ico +0 -0
- data/icons/iChat_16x16.ico +0 -0
- data/icons/iChat_24x24.ico +0 -0
- data/icons/icons.txt +3 -0
- data/icons/info.ico +0 -0
- data/icons/info_16x16.ico +0 -0
- data/icons/info_24x24.ico +0 -0
- data/icons/interceptor_24x24.ico +0 -0
- data/icons/lock.ico +0 -0
- data/icons/lock_12x12.ico +0 -0
- data/icons/lock_16x16.ico +0 -0
- data/icons/monitor.ico +0 -0
- data/icons/plugin.ico +0 -0
- data/icons/plugin_24x24.ico +0 -0
- data/icons/scan_16x16.png +0 -0
- data/icons/send.ico +0 -0
- data/icons/server.ico +0 -0
- data/icons/server_16x16.ico +0 -0
- data/icons/siberas_logo_x24.gif +0 -0
- data/icons/tag_blue_32x32.ico +0 -0
- data/icons/watobo-48x48.png +0 -0
- data/icons/watobo-logo.png +0 -0
- data/icons/watobo.ico +0 -0
- data/lib/watobo/adapters/data_store.rb +38 -0
- data/lib/watobo/adapters/file/file_store.rb +211 -0
- data/lib/watobo/adapters/session_store.rb +27 -0
- data/lib/watobo/adapters.rb +26 -0
- data/lib/watobo/config.rb +143 -0
- data/lib/watobo/constants.rb +92 -0
- data/lib/watobo/core/active_check.rb +404 -0
- data/lib/watobo/core/cookie.rb +69 -0
- data/lib/watobo/core/fuzz_gen.rb +160 -0
- data/lib/watobo/core/http_socket.rb +142 -0
- data/lib/watobo/core/interceptor.rb +729 -0
- data/lib/watobo/core/passive_check.rb +141 -0
- data/lib/watobo/core/project.rb +1058 -0
- data/lib/watobo/core/scanner.rb +396 -0
- data/lib/watobo/core/session.rb +1320 -0
- data/lib/watobo/core/simple_ca.rb +393 -0
- data/lib/watobo/core.rb +34 -0
- data/lib/watobo/defaults.rb +40 -0
- data/lib/watobo/external/diff/lcs/array.rb +42 -0
- data/lib/watobo/external/diff/lcs/block.rb +72 -0
- data/lib/watobo/external/diff/lcs/callbacks.rb +343 -0
- data/lib/watobo/external/diff/lcs/change.rb +190 -0
- data/lib/watobo/external/diff/lcs/hunk.rb +279 -0
- data/lib/watobo/external/diff/lcs/ldiff.rb +247 -0
- data/lib/watobo/external/diff/lcs/string.rb +40 -0
- data/lib/watobo/external/diff/lcs.rb +1124 -0
- data/lib/watobo/external/ntlm/ntlm.rb +797 -0
- data/lib/watobo/externals.rb +28 -0
- data/lib/watobo/framework/create_project.rb +55 -0
- data/lib/watobo/framework/init.rb +149 -0
- data/lib/watobo/framework/init_modules.rb +116 -0
- data/lib/watobo/framework/license_text.rb +50 -0
- data/lib/watobo/framework.rb +26 -0
- data/lib/watobo/gui/about_watobo.rb +68 -0
- data/lib/watobo/gui/browser_preview.rb +460 -0
- data/lib/watobo/gui/certificate_dialog.rb +132 -0
- data/lib/watobo/gui/chat_diff.rb +415 -0
- data/lib/watobo/gui/chatviewer_frame.rb +427 -0
- data/lib/watobo/gui/checkboxtree.rb +221 -0
- data/lib/watobo/gui/checks_policy_frame.rb +123 -0
- data/lib/watobo/gui/client_cert_dialog.rb +227 -0
- data/lib/watobo/gui/confirm_scan_dialog.rb +67 -0
- data/lib/watobo/gui/conversation_table.rb +386 -0
- data/lib/watobo/gui/conversation_table_ctrl.rb +175 -0
- data/lib/watobo/gui/csrf_token_dialog.rb +446 -0
- data/lib/watobo/gui/dashboard.rb +341 -0
- data/lib/watobo/gui/define_scope_frame.rb +380 -0
- data/lib/watobo/gui/edit_comment.rb +70 -0
- data/lib/watobo/gui/edit_scope_dialog.rb +69 -0
- data/lib/watobo/gui/finding_info.rb +212 -0
- data/lib/watobo/gui/findings_tree.rb +459 -0
- data/lib/watobo/gui/full_scan_dialog.rb +269 -0
- data/lib/watobo/gui/fuzzer_gui.rb +1522 -0
- data/lib/watobo/gui/hex_viewer.rb +106 -0
- data/lib/watobo/gui/interceptor_gui.rb +994 -0
- data/lib/watobo/gui/interceptor_settings_dialog.rb +201 -0
- data/lib/watobo/gui/log_viewer.rb +97 -0
- data/lib/watobo/gui/login_wizzard.rb +301 -0
- data/lib/watobo/gui/main_window.rb +1815 -0
- data/lib/watobo/gui/manual_request_editor.rb +1105 -0
- data/lib/watobo/gui/master_pw_dialog.rb +142 -0
- data/lib/watobo/gui/password_policy_dialog.rb +98 -0
- data/lib/watobo/gui/plugin/base.rb +82 -0
- data/lib/watobo/gui/plugin_board.rb +95 -0
- data/lib/watobo/gui/preferences_dialog.rb +116 -0
- data/lib/watobo/gui/progress_window.rb +102 -0
- data/lib/watobo/gui/project_wizzard.rb +369 -0
- data/lib/watobo/gui/proxy_dialog.rb +550 -0
- data/lib/watobo/gui/quick_scan_dialog.rb +242 -0
- data/lib/watobo/gui/request_editor.rb +480 -0
- data/lib/watobo/gui/save_chat_dialog.rb +158 -0
- data/lib/watobo/gui/scanner_settings_dialog.rb +360 -0
- data/lib/watobo/gui/select_chat_dialog.rb +169 -0
- data/lib/watobo/gui/session_management_dialog.rb +688 -0
- data/lib/watobo/gui/sites_tree.rb +347 -0
- data/lib/watobo/gui/status_bar.rb +88 -0
- data/lib/watobo/gui/table_editor.rb +445 -0
- data/lib/watobo/gui/tagless_viewer.rb +62 -0
- data/lib/watobo/gui/templates/plugin.rb +80 -0
- data/lib/watobo/gui/templates/plugin2.rb +103 -0
- data/lib/watobo/gui/text_viewer.rb +247 -0
- data/lib/watobo/gui/transcoder_window.rb +215 -0
- data/lib/watobo/gui/utils/gui_utils.rb +129 -0
- data/lib/watobo/gui/utils/init_icons.rb +106 -0
- data/lib/watobo/gui/utils/load_icons.rb +54 -0
- data/lib/watobo/gui/utils/load_plugins.rb +94 -0
- data/lib/watobo/gui/utils/master_password.rb +90 -0
- data/lib/watobo/gui/utils/save_default_settings.rb +99 -0
- data/lib/watobo/gui/utils/save_project_settings.rb +21 -0
- data/lib/watobo/gui/utils/save_proxy_settings.rb +45 -0
- data/lib/watobo/gui/utils/save_session_settings.rb +21 -0
- data/lib/watobo/gui/utils/session_history.rb +134 -0
- data/lib/watobo/gui/workspace_dialog.rb +89 -0
- data/lib/watobo/gui/www_auth_dialog.rb +348 -0
- data/lib/watobo/gui/xml_viewer_frame.rb +114 -0
- data/lib/watobo/gui.rb +139 -0
- data/lib/watobo/mixins/httpparser.rb +664 -0
- data/lib/watobo/mixins/request_parser.rb +210 -0
- data/lib/watobo/mixins/shapers.rb +345 -0
- data/lib/watobo/mixins/transcoders.rb +88 -0
- data/lib/watobo/mixins.rb +32 -0
- data/lib/watobo/utils/check_regex.rb +36 -0
- data/lib/watobo/utils/copy_object.rb +29 -0
- data/lib/watobo/utils/crypto.rb +74 -0
- data/lib/watobo/utils/expand_range.rb +45 -0
- data/lib/watobo/utils/file_management.rb +73 -0
- data/lib/watobo/utils/load_chat.rb +219 -0
- data/lib/watobo/utils/load_icon.rb +47 -0
- data/lib/watobo/utils/print_debug.rb +34 -0
- data/lib/watobo/utils/response_hash.rb +143 -0
- data/lib/watobo/utils/secure_eval.rb +57 -0
- data/lib/watobo/utils/text2request.rb +96 -0
- data/lib/watobo/utils.rb +32 -0
- data/lib/watobo.rb +76 -0
- data/modules/active/Apache/mod_status.rb +123 -0
- data/modules/active/Flash/crossdomain.rb +102 -0
- data/modules/active/directories/dirwalker.rb +89 -0
- data/modules/active/discovery/fileextensions.rb +151 -0
- data/modules/active/discovery/http_methods.rb +135 -0
- data/modules/active/domino/domino_db.lst +164 -0
- data/modules/active/domino/domino_db.rb +128 -0
- data/modules/active/fileinclusion/lfi_simple.rb +134 -0
- data/modules/active/jboss/jboss_basic.rb +119 -0
- data/modules/active/sap/business_objects.rb +73 -0
- data/modules/active/sap/its_commands.rb +101 -0
- data/modules/active/sap/its_service_parameter.rb +105 -0
- data/modules/active/sap/its_services.rb +103 -0
- data/modules/active/sap/its_xss.rb +98 -0
- data/modules/active/sqlinjection/sql_boolean.rb +262 -0
- data/modules/active/sqlinjection/sqli_simple.rb +205 -0
- data/modules/active/xss/xss_simple.rb +179 -0
- data/modules/passive/cookie_options.rb +97 -0
- data/modules/passive/cookie_xss.rb +85 -0
- data/modules/passive/detect_code.rb +89 -0
- data/modules/passive/detect_fileupload.rb +80 -0
- data/modules/passive/detect_infrastructure.rb +98 -0
- data/modules/passive/detect_one_time_tokens.rb +86 -0
- data/modules/passive/dirindexing.rb +81 -0
- data/modules/passive/disclosure_emails.rb +82 -0
- data/modules/passive/disclosure_ipaddr.rb +87 -0
- data/modules/passive/filename_as_parameter.rb +85 -0
- data/modules/passive/form_spotter.rb +75 -0
- data/modules/passive/hotspots.rb +86 -0
- data/modules/passive/in_script_parameter.rb +92 -0
- data/modules/passive/multiple_server_headers.rb +98 -0
- data/modules/passive/possible_login.rb +134 -0
- data/modules/passive/redirect_url.rb +88 -0
- data/modules/passive/redirectionz.rb +96 -0
- data/modules/passive/xss_dom.rb +91 -0
- data/plugins/catalog/catalog.ico +0 -0
- data/plugins/catalog/catalog.rb +726 -0
- data/plugins/catalog/db_tests +6483 -0
- data/plugins/catalog/db_variables +29 -0
- data/plugins/filefinder/dbs/hbci.db +12 -0
- data/plugins/filefinder/filefinder.rb +602 -0
- data/plugins/sslchecker/cli/sslchecker_cli.rb +21 -0
- data/plugins/sslchecker/gui/cipher_table.rb +260 -0
- data/plugins/sslchecker/gui/gui.rb +245 -0
- data/plugins/sslchecker/gui/sslchecker.rb +26 -0
- data/plugins/sslchecker/icons/green_16x16.ico +0 -0
- data/plugins/sslchecker/icons/grey_16x16.ico +0 -0
- data/plugins/sslchecker/icons/red_16x16.ico +0 -0
- data/plugins/sslchecker/icons/sslchecker.ico +0 -0
- data/plugins/sslchecker/lib/check.rb +117 -0
- metadata +317 -0
|
@@ -0,0 +1,1058 @@
|
|
|
1
|
+
# .
|
|
2
|
+
# project.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
|
+
class Conversation
|
|
24
|
+
include Watobo::Constants
|
|
25
|
+
attr_accessor :file
|
|
26
|
+
def id()
|
|
27
|
+
# must be defined
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def copyRequest()
|
|
31
|
+
# req_copy = []
|
|
32
|
+
# self.request.each do |line|
|
|
33
|
+
# req_copy.push line.clone
|
|
34
|
+
# end
|
|
35
|
+
copy = Utils.copyObject(@request)
|
|
36
|
+
# now extend the new request with the Watobo mixins
|
|
37
|
+
copy.extend Watobo::Mixin::Parser::Url
|
|
38
|
+
copy.extend Watobo::Mixin::Parser::Web10
|
|
39
|
+
copy.extend Watobo::Mixin::Shaper::Web10
|
|
40
|
+
return copy
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def extendRequest
|
|
46
|
+
@request.extend Watobo::Mixin::Shaper::Web10
|
|
47
|
+
@request.extend Watobo::Mixin::Parser::Web10
|
|
48
|
+
@request.extend Watobo::Mixin::Parser::Url
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def extendResponse
|
|
52
|
+
@response.extend Watobo::Mixin::Parser::Web10
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def initialize(request, response)
|
|
56
|
+
@request = request
|
|
57
|
+
@response = response
|
|
58
|
+
@file = nil
|
|
59
|
+
|
|
60
|
+
extendRequest()
|
|
61
|
+
extendResponse()
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class Chat < Conversation
|
|
68
|
+
attr :request
|
|
69
|
+
attr :response
|
|
70
|
+
attr :settings
|
|
71
|
+
|
|
72
|
+
@@numChats = 0
|
|
73
|
+
@@max_id = 0
|
|
74
|
+
|
|
75
|
+
@@lock = Mutex.new
|
|
76
|
+
|
|
77
|
+
public
|
|
78
|
+
def resetCounters()
|
|
79
|
+
@@numChats = 0
|
|
80
|
+
@@max_id = 0
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def tested?()
|
|
84
|
+
return false unless @settings.has_key?(:tested)
|
|
85
|
+
return @settings[:tested]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def tested=(truefalse)
|
|
89
|
+
@settings[:tested] = truefalse
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def tstart()
|
|
93
|
+
@settings[:tstart]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def tstop()
|
|
97
|
+
@settings[:tstop]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def id()
|
|
101
|
+
@settings[:id]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def comment=(c)
|
|
105
|
+
@settings[:comment] = c
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def comment()
|
|
109
|
+
@settings[:comment]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def source()
|
|
113
|
+
@settings[:source]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# INITIALIZE ( request, response, prefs )
|
|
117
|
+
# prefs:
|
|
118
|
+
# :source - source of request/response CHAT_SOURCE
|
|
119
|
+
# :id - an initial id, if no id is given it will be set to the @@max_id, if id == 0 counters will be ignored.
|
|
120
|
+
# :start - starting time of request format is Time.now.to_f
|
|
121
|
+
# :stop - time of loading response has finished
|
|
122
|
+
# :
|
|
123
|
+
def initialize(request, response, prefs = {})
|
|
124
|
+
|
|
125
|
+
begin
|
|
126
|
+
super(request, response)
|
|
127
|
+
|
|
128
|
+
@settings = {
|
|
129
|
+
:source => CHAT_SOURCE_UNDEF,
|
|
130
|
+
:id => -1,
|
|
131
|
+
:start => 0,
|
|
132
|
+
:stop => -1,
|
|
133
|
+
:comment => '',
|
|
134
|
+
:tested => false
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@settings.update prefs
|
|
138
|
+
# puts @settings[:id].to_s
|
|
139
|
+
|
|
140
|
+
@@lock.synchronize{
|
|
141
|
+
# enter critical section here ???
|
|
142
|
+
if @settings[:id] > @@max_id
|
|
143
|
+
@@max_id = @settings[:id]
|
|
144
|
+
elsif @settings[:id] < 0
|
|
145
|
+
@@max_id += 1
|
|
146
|
+
@settings[:id] = @@max_id
|
|
147
|
+
end
|
|
148
|
+
@@numChats += 1
|
|
149
|
+
# @comment = ''
|
|
150
|
+
# leafe critical section here ???
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
rescue => bang
|
|
154
|
+
puts bang
|
|
155
|
+
puts bang.backtrace if $DEBUG
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
class Finding < Conversation
|
|
162
|
+
|
|
163
|
+
@@numFindings = 0
|
|
164
|
+
@@max_id = 0
|
|
165
|
+
|
|
166
|
+
@@lock = Mutex.new
|
|
167
|
+
|
|
168
|
+
attr :details
|
|
169
|
+
attr :request
|
|
170
|
+
attr :response
|
|
171
|
+
def resetCounters()
|
|
172
|
+
@@numFindings = 0
|
|
173
|
+
@@max_id = 0
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def id()
|
|
177
|
+
@details[:id]
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def false_positive?
|
|
181
|
+
@details[:false_positive]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def set_false_positive
|
|
185
|
+
@details[:false_positive] = true
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def unset_false_positive
|
|
189
|
+
@details[:false_positive] = false
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def initialize(request, response, details = {})
|
|
193
|
+
super(request, response)
|
|
194
|
+
@details = {
|
|
195
|
+
:id => -1,
|
|
196
|
+
:comment => '',
|
|
197
|
+
:false_positive => false # FalsePositive
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@details.update details if details.is_a? Hash
|
|
201
|
+
|
|
202
|
+
@@lock.synchronize{
|
|
203
|
+
# enter critical section here ???
|
|
204
|
+
if @details[:id] > 0 and @details[:id] > @@max_id
|
|
205
|
+
@@max_id = @details[:id]
|
|
206
|
+
elsif @details[:id] < 0
|
|
207
|
+
@@max_id += 1
|
|
208
|
+
@details[:id] = @@max_id
|
|
209
|
+
end
|
|
210
|
+
@@numFindings += 1
|
|
211
|
+
|
|
212
|
+
}
|
|
213
|
+
extendRequest()
|
|
214
|
+
extendResponse()
|
|
215
|
+
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
class Project
|
|
221
|
+
# SessionManager
|
|
222
|
+
#
|
|
223
|
+
# class SessionManager < Watobo::Session
|
|
224
|
+
# def initialize(project)
|
|
225
|
+
# super(project.session )
|
|
226
|
+
|
|
227
|
+
# end
|
|
228
|
+
# def runLogin
|
|
229
|
+
# print "[L"
|
|
230
|
+
# @project.loginscript_ids.each do |chatid|
|
|
231
|
+
# test_req = @project.getChat(chatid).copyRequest
|
|
232
|
+
# request, response = doRequest(test_req, :update_sids => true, :update_session => true, :update_contentlength => true)
|
|
233
|
+
# end
|
|
234
|
+
|
|
235
|
+
# end
|
|
236
|
+
# end
|
|
237
|
+
attr :chats
|
|
238
|
+
attr_accessor :findings
|
|
239
|
+
attr :scan_settings
|
|
240
|
+
attr :forward_proxy_settings
|
|
241
|
+
attr :date
|
|
242
|
+
attr :project_name
|
|
243
|
+
attr :session_name
|
|
244
|
+
attr :session_store
|
|
245
|
+
attr_accessor :settings
|
|
246
|
+
|
|
247
|
+
# attr_accessor :numRunningChecks
|
|
248
|
+
|
|
249
|
+
# attr_accessor :valid_sids
|
|
250
|
+
## attr_accessor :loginscript_ids
|
|
251
|
+
attr :active_checks
|
|
252
|
+
attr :passive_checks
|
|
253
|
+
attr_accessor :plugins
|
|
254
|
+
attr_accessor :excluded_chats
|
|
255
|
+
|
|
256
|
+
# attr_accessor :intercept_request
|
|
257
|
+
# attr_accessor :intercept_response
|
|
258
|
+
# attr_accessor :interceptor
|
|
259
|
+
|
|
260
|
+
attr :target_filter
|
|
261
|
+
def subscribe(event, &callback)
|
|
262
|
+
(@event_dispatcher_listeners[event] ||= []) << callback
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def notify(event, *args)
|
|
266
|
+
if @event_dispatcher_listeners[event]
|
|
267
|
+
@event_dispatcher_listeners[event].each do |m|
|
|
268
|
+
m.call(*args) if m.respond_to? :call
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def sessionSettingsFile
|
|
274
|
+
@session_file
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def projectSettingsFile
|
|
278
|
+
@project_file
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def getLoginChats()
|
|
282
|
+
@scan_settings[:login_chat_ids] ||= []
|
|
283
|
+
login_chats = []
|
|
284
|
+
@scan_settings[:login_chat_ids].each do |cid|
|
|
285
|
+
chat = getChat(cid)
|
|
286
|
+
login_chats.push chat if chat
|
|
287
|
+
end
|
|
288
|
+
login_chats
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def getWwwAuthentication()
|
|
292
|
+
@scan_settings[:www_auth]
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def getLoginChatIds()
|
|
296
|
+
#p @settings[:login_chat_ids]
|
|
297
|
+
# p @settings.to_yaml
|
|
298
|
+
@scan_settings[:login_chat_ids] ||= []
|
|
299
|
+
@scan_settings[:login_chat_ids]
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def setLoginChatIds(ids)
|
|
303
|
+
@scan_settings[:login_chat_ids] = ids if ids.is_a? Array
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def getSidPatterns
|
|
307
|
+
@scan_settings[:sid_patterns]
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def setProxyOptions(proxy_prefs)
|
|
311
|
+
@forward_proxy_settings = proxy_prefs
|
|
312
|
+
|
|
313
|
+
@sessionController.addProxy(getCurrentProxy())
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# gives the currently selected proxy
|
|
317
|
+
# format <host>:<port>
|
|
318
|
+
def getCurrentProxy()
|
|
319
|
+
c_proxy = nil
|
|
320
|
+
begin
|
|
321
|
+
name = @forward_proxy_settings[:default_proxy]
|
|
322
|
+
cproxy = @forward_proxy_settings[name]
|
|
323
|
+
return cproxy
|
|
324
|
+
rescue
|
|
325
|
+
puts "! no proxy settings available"
|
|
326
|
+
end
|
|
327
|
+
return nil
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def setSidPatterns(sp)
|
|
331
|
+
@scan_settings[:sid_patterns] = sp if sp.is_a? Array
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def getLogoutSignatures
|
|
335
|
+
@scan_settings[:logout_signatures]
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def getCSRFPatterns
|
|
339
|
+
@scan_settings[:csrf_patterns]
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# setCSRFRequest
|
|
343
|
+
# =Parameters
|
|
344
|
+
# request: test request which requires csrf handling
|
|
345
|
+
# ids: csrf request ids of current conversation
|
|
346
|
+
# patterns: csrf patterns for identifiying and updating tokens
|
|
347
|
+
def setCSRFRequest(request, ids, patterns=[])
|
|
348
|
+
puts "* setting CSRF Request"
|
|
349
|
+
# puts request.class
|
|
350
|
+
# puts request
|
|
351
|
+
urh = uniqueRequestHash(request)
|
|
352
|
+
@scan_settings[:csrf_request_ids][urh] = ids
|
|
353
|
+
@scan_settings[:csrf_patterns].concat patterns unless patterns.empty?
|
|
354
|
+
@scan_settings[:csrf_patterns].uniq!
|
|
355
|
+
notify(:settings_changed)
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def getCSRFRequestIDs(request)
|
|
359
|
+
urh = uniqueRequestHash(request)
|
|
360
|
+
@scan_settings[:csrf_request_ids] ||= {}
|
|
361
|
+
ids = @scan_settings[:csrf_request_ids][urh]
|
|
362
|
+
# puts "* found csrf req ids #{ids}"
|
|
363
|
+
ids = [] if ids.nil?
|
|
364
|
+
ids
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def setLogoutSignatures(ls)
|
|
368
|
+
@scan_settings[:logout_signatures] = ls if ls.is_a? Array
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Helper function to get all necessary preferences for starting a scan.
|
|
372
|
+
def getScanPreferences()
|
|
373
|
+
settings = {
|
|
374
|
+
:smart_scan => @scan_settings[:smart_scan],
|
|
375
|
+
:non_unique_parms => @scan_settings[:non_unique_parms],
|
|
376
|
+
:excluded_parms => @scan_settings[:excluded_parms],
|
|
377
|
+
:sid_patterns => @scan_settings[:sid_patterns],
|
|
378
|
+
:csrf_patterns => @scan_settings[:csrf_patterns],
|
|
379
|
+
:run_passive_checks => false,
|
|
380
|
+
:login_chat_ids => [],
|
|
381
|
+
:proxy => getCurrentProxy(),
|
|
382
|
+
:login_chats => getLoginChats(),
|
|
383
|
+
:max_parallel_checks => @scan_settings[:max_parallel_checks],
|
|
384
|
+
:logout_signatures => @scan_settings[:logout_signatures],
|
|
385
|
+
:custom_error_patterns => @scan_settings[:custom_error_patterns],
|
|
386
|
+
:scan_session => self.object_id,
|
|
387
|
+
:www_auth => @scan_settings[:www_auth].nil? ? Hash.new : @scan_settings[:www_auth],
|
|
388
|
+
:client_certificates => @scan_settings[:client_certificates],
|
|
389
|
+
:session_store => @session_store
|
|
390
|
+
}
|
|
391
|
+
return settings
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# returns a project/session specific ID needed for synchronising Sessions
|
|
395
|
+
def getSessionID()
|
|
396
|
+
sid = @settings[:project_name] + @settings[:session_name]
|
|
397
|
+
return sid
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def getClientCertificates()
|
|
401
|
+
client_certs = @settings[:client_certificates]
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def setClientCertificates(certs)
|
|
405
|
+
@scan_settings[:client_certificates] = certs
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def add_client_certificate(client_cert={})
|
|
409
|
+
return false unless client_cert.is_a? Hash
|
|
410
|
+
[ :site, :certificate_file, :key_file].each do |p|
|
|
411
|
+
return false unless client_cert.has_key? p
|
|
412
|
+
end
|
|
413
|
+
cs = @scan_settings[:client_certificates]
|
|
414
|
+
site = client_cert[:site]
|
|
415
|
+
if cs.has_key? site
|
|
416
|
+
cs[site][certificate] = nil
|
|
417
|
+
cs[site][key] = nil
|
|
418
|
+
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def client_certificates=(certs)
|
|
424
|
+
@scan_settings[:client_certificates] = certs
|
|
425
|
+
cs = @scan_settings[:client_certificates]
|
|
426
|
+
cs.each_key do |site|
|
|
427
|
+
unless cs[site].has_key? :ssl_client_cert
|
|
428
|
+
crt_file = cs[site][:certificate_file]
|
|
429
|
+
if File.exist?(crt_file)
|
|
430
|
+
puts "* loading certificate #{crt_file}" if $DEBUG
|
|
431
|
+
cs[site][:ssl_client_cert] = OpenSSL::X509::Certificate.new(File.read(crt_file))
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
unless cs[site].has_key? :ssl_client_key
|
|
436
|
+
key_file = cs[site][:key_file]
|
|
437
|
+
if File.exist?(key_file)
|
|
438
|
+
puts "* loading private key #{key_file}" if $DEBUG
|
|
439
|
+
password = cs[site][:password].empty? ? nil : cs[site][:password]
|
|
440
|
+
cs[site][:ssl_client_key] = OpenSSL::PKey::RSA.new(File.read(key_file), password)
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def getScanPolicy()
|
|
447
|
+
@settings[:policy]
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def uniqueRequestHash(request)
|
|
451
|
+
begin
|
|
452
|
+
hashbase = request.site + request.method + request.path
|
|
453
|
+
request.get_parm_names.sort.each do |p|
|
|
454
|
+
if @scan_settings[:non_unique_parms].include?(p) then
|
|
455
|
+
hashbase += p + request.get_parm_value(p)
|
|
456
|
+
else
|
|
457
|
+
hashbase += p
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
end
|
|
461
|
+
request.post_parm_names.sort.each do |p|
|
|
462
|
+
if @scan_settings[:non_unique_parms].include?(p) then
|
|
463
|
+
hashbase += p + request.post_parm_value(p)
|
|
464
|
+
else
|
|
465
|
+
hashbase += p
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
end
|
|
469
|
+
return Digest::MD5.hexdigest(hashbase)
|
|
470
|
+
rescue => bang
|
|
471
|
+
puts bang
|
|
472
|
+
puts bang.backtrace if $DEBUG
|
|
473
|
+
return nil
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def last_chatid
|
|
478
|
+
if @chats.length > 0
|
|
479
|
+
return @chats.last.id
|
|
480
|
+
else
|
|
481
|
+
return 0
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def extendRequest(request)
|
|
486
|
+
request.extend Watobo::Mixin::Shaper::Web10
|
|
487
|
+
request.extend Watobo::Mixin::Parser::Web10
|
|
488
|
+
request.extend Watobo::Mixin::Parser::Url
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def extendResponse(response)
|
|
492
|
+
response.extend Watobo::Mixin::Shaper::Web10
|
|
493
|
+
response.extend Watobo::Mixin::Parser::Web10
|
|
494
|
+
response.extend Watobo::Mixin::Parser::Url
|
|
495
|
+
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def updateSettings(new_settings)
|
|
499
|
+
# new_settings.keys.each do |k|
|
|
500
|
+
# @settings[k] = new_settings[k]
|
|
501
|
+
# end
|
|
502
|
+
@scan_settings.update new_settings
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def findChats(site, opts={})
|
|
507
|
+
o = {
|
|
508
|
+
:dir => "",
|
|
509
|
+
#:file => nil,
|
|
510
|
+
:method => nil,
|
|
511
|
+
:max_count => 0
|
|
512
|
+
}
|
|
513
|
+
o.update opts
|
|
514
|
+
o[:dir].strip!
|
|
515
|
+
o[:dir].gsub!(/^\//,"")
|
|
516
|
+
|
|
517
|
+
matches = []
|
|
518
|
+
@chats.each do |c|
|
|
519
|
+
if c.request.site == site then
|
|
520
|
+
matches.push c if o[:dir] == c.request.dir
|
|
521
|
+
end
|
|
522
|
+
return matches if o[:max_count] > 0 and matches.length >= o[:max_count]
|
|
523
|
+
end
|
|
524
|
+
return matches
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def getChat(chatid)
|
|
528
|
+
#TODO: Improvement for faster results => Fuzzy-Logic
|
|
529
|
+
@chats.each do |c|
|
|
530
|
+
if c.id.to_s == chatid.to_s then
|
|
531
|
+
return c
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
return nil
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
def projectName
|
|
538
|
+
@settings[:project_name]
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def sessionName
|
|
542
|
+
@settings[:session_name]
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
def interceptPort
|
|
546
|
+
@settings[:project_name]
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
# runs passive checks on specific chat
|
|
550
|
+
def runPassiveChecks(chat)
|
|
551
|
+
tlist = []
|
|
552
|
+
@passive_checks.each do |test_module|
|
|
553
|
+
|
|
554
|
+
tlist << Thread.new(chat, test_module) {|c,m|
|
|
555
|
+
m.do_test(c)
|
|
556
|
+
}
|
|
557
|
+
end
|
|
558
|
+
return tlist
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
def addChat(chat, prefs={})
|
|
562
|
+
@chats_lock.synchronize do
|
|
563
|
+
begin
|
|
564
|
+
if chat.request.host then
|
|
565
|
+
chats.push chat
|
|
566
|
+
|
|
567
|
+
options = {
|
|
568
|
+
:run_passive_checks => true,
|
|
569
|
+
:notify => true
|
|
570
|
+
}
|
|
571
|
+
options.update prefs
|
|
572
|
+
|
|
573
|
+
runPassiveChecks(chat) if options[:run_passive_checks] == true
|
|
574
|
+
|
|
575
|
+
#@interface.addChat(self, chat) if @interface
|
|
576
|
+
notify(:new_chat, chat) if options[:notify] == true
|
|
577
|
+
|
|
578
|
+
if chat.id != 0 then
|
|
579
|
+
@session_store.add_chat(chat)
|
|
580
|
+
else
|
|
581
|
+
puts "!!! Could not add chat #{chat.id}"
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
# p "!P!"
|
|
585
|
+
rescue => bang
|
|
586
|
+
puts bang
|
|
587
|
+
puts bang.backtrace if $DEBUG
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
def runLogin
|
|
593
|
+
@sessionMgr.runLogin(loginChats)
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
def has_scope?()
|
|
597
|
+
return false if @scan_settings[:scope].nil?
|
|
598
|
+
@scan_settings[:scope].each_key do |k|
|
|
599
|
+
return true if @scan_settings[:scope][k][:enabled] == true
|
|
600
|
+
end
|
|
601
|
+
return false
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def scope
|
|
605
|
+
@scan_settings[:scope]
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
def scope=(scope)
|
|
609
|
+
@scan_settings[:scope] = scope
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
def setScope(scope)
|
|
613
|
+
@scan_settings[:scope] = scope
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def setWwwAuthentication(www_auth)
|
|
617
|
+
@scan_settings[:www_auth] = www_auth
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
def setCSRFPatterns(patterns)
|
|
621
|
+
@scan_settings[:csrf_patterns] = patterns
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
def add_login_chat_id(id)
|
|
625
|
+
@scan_settings[:login_chat_ids] ||= []
|
|
626
|
+
@scan_settings[:login_chat_ids].push id
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
def addToScope(site)
|
|
630
|
+
return false if !@scan_settings[:scope][site].nil?
|
|
631
|
+
|
|
632
|
+
scope_details = {
|
|
633
|
+
:site => site,
|
|
634
|
+
:enabled => true,
|
|
635
|
+
:root_path => '',
|
|
636
|
+
:excluded_paths => [],
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
@scan_settings[:scope][site] = scope_details
|
|
640
|
+
return true
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
def addFinding(finding, opts={})
|
|
644
|
+
@findings_lock.synchronize do
|
|
645
|
+
options = {
|
|
646
|
+
:notify => true,
|
|
647
|
+
:save_finding => true
|
|
648
|
+
}
|
|
649
|
+
options.update opts
|
|
650
|
+
# puts "* add finding #{finding.details[:fid]}" if $DEBUG
|
|
651
|
+
|
|
652
|
+
unless @findings.has_key?(finding.details[:fid])
|
|
653
|
+
begin
|
|
654
|
+
@findings[finding.details[:fid]] = finding
|
|
655
|
+
#@interface.addFinding(new_finding)
|
|
656
|
+
# puts "* new finding"
|
|
657
|
+
notify(:new_finding, finding) if options[:notify] == true
|
|
658
|
+
|
|
659
|
+
@session_store.add_finding(finding) if options[:save_finding] == true
|
|
660
|
+
rescue => bang
|
|
661
|
+
puts "!!!ERROR: #{Module.nesting[0].name}"
|
|
662
|
+
puts bang
|
|
663
|
+
puts bang.backtrace if $DEBUG
|
|
664
|
+
end
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
def delete_finding(f)
|
|
671
|
+
@findings_lock.synchronize do
|
|
672
|
+
@session_store.delete_finding(f)
|
|
673
|
+
@findings.delete f.details[:fid]
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
def set_false_positive(finding)
|
|
678
|
+
@findings_lock.synchronize do
|
|
679
|
+
puts "Set Finding #{finding.id} / #{finding.details[:fid]} False-Positive" if $DEBUG
|
|
680
|
+
if @findings.has_key? finding.details[:fid]
|
|
681
|
+
@findings[finding.details[:fid]].set_false_positive
|
|
682
|
+
@session_store.update_finding(finding)
|
|
683
|
+
return true
|
|
684
|
+
end
|
|
685
|
+
return false
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
def unset_false_positive(finding)
|
|
690
|
+
@findings_lock.synchronize do
|
|
691
|
+
if @findings.has_key? finding.id
|
|
692
|
+
@findings[finding.id].unset_false_positive
|
|
693
|
+
@session_store.update_finding(finding)
|
|
694
|
+
return true
|
|
695
|
+
end
|
|
696
|
+
return false
|
|
697
|
+
end
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def setupProject(progress_window=nil)
|
|
702
|
+
begin
|
|
703
|
+
puts "DEBUG: Setup Project" if $DEBUG and $debug_project
|
|
704
|
+
importSession()
|
|
705
|
+
=begin
|
|
706
|
+
importSession(progress_window)
|
|
707
|
+
|
|
708
|
+
init_active_modules(progress_window)
|
|
709
|
+
|
|
710
|
+
init_passive_modules(progress_window)
|
|
711
|
+
|
|
712
|
+
initPlugins(progress_window)
|
|
713
|
+
=end
|
|
714
|
+
rescue => bang
|
|
715
|
+
puts bang
|
|
716
|
+
puts bang.backtrace if $DEBUG
|
|
717
|
+
end
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
# returns all chats which are in the target scope
|
|
721
|
+
|
|
722
|
+
def chatsInScope(chats=nil, scope=nil)
|
|
723
|
+
scan_prefs = @scan_settings
|
|
724
|
+
unique_list = Hash.new
|
|
725
|
+
chatlist = chats.nil? ? @chats : chats
|
|
726
|
+
new_scope = scope.nil? ? scan_prefs[:scope] : scope
|
|
727
|
+
# puts new_scope.to_yaml
|
|
728
|
+
cis = []
|
|
729
|
+
chat_in_scope = nil
|
|
730
|
+
chatlist.each do |chat|
|
|
731
|
+
next if scan_prefs[:excluded_chats].include?(chat.id)
|
|
732
|
+
uch = uniqueRequestHash(chat.request)
|
|
733
|
+
|
|
734
|
+
next if unique_list.has_key?(uch) and scan_prefs[:smart_scan] == true
|
|
735
|
+
unique_list[uch] = nil
|
|
736
|
+
|
|
737
|
+
chat_in_scope = chat
|
|
738
|
+
# filter by targets first
|
|
739
|
+
new_scope.each do |s, c_scope|
|
|
740
|
+
chat_in_scope = nil
|
|
741
|
+
|
|
742
|
+
if chat.request.site == c_scope[:site] then
|
|
743
|
+
chat_in_scope = chat
|
|
744
|
+
|
|
745
|
+
if chat_in_scope and c_scope[:root_path] != ''
|
|
746
|
+
chat_in_scope = ( chat.request.path =~ /^(\/)?#{c_scope[:root_path]}/i ) ? chat : nil
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
if chat_in_scope and c_scope[:excluded_paths] and c_scope[:excluded_paths].length > 0
|
|
750
|
+
c_scope[:excluded_paths].each do |p|
|
|
751
|
+
if ( chat.request.url =~ /#{p}/i )
|
|
752
|
+
chat_in_scope = nil
|
|
753
|
+
break
|
|
754
|
+
end
|
|
755
|
+
end
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
cis.push chat_in_scope unless chat_in_scope.nil?
|
|
759
|
+
end
|
|
760
|
+
end
|
|
761
|
+
cis
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
def siteInScope?(site)
|
|
765
|
+
#in_scope = false
|
|
766
|
+
@scan_settings[:scope].keys.each do |scope_site|
|
|
767
|
+
return true if scope_site == site
|
|
768
|
+
end
|
|
769
|
+
return false
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
def siteSSL?(site)
|
|
773
|
+
@chats.each do |c|
|
|
774
|
+
if c.request.site == site
|
|
775
|
+
return true if c.request.proto =~ /https/
|
|
776
|
+
return false
|
|
777
|
+
end
|
|
778
|
+
end
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
#
|
|
782
|
+
# I NITIALIZE
|
|
783
|
+
#
|
|
784
|
+
#
|
|
785
|
+
def initialize(project_settings)
|
|
786
|
+
|
|
787
|
+
puts "DEBUG: Initializing Project" if $DEBUG
|
|
788
|
+
@event_dispatcher_listeners = Hash.new
|
|
789
|
+
@settings = {}
|
|
790
|
+
|
|
791
|
+
@active_checks = []
|
|
792
|
+
@passive_checks = []
|
|
793
|
+
@plugins = []
|
|
794
|
+
|
|
795
|
+
@chats = []
|
|
796
|
+
@findings = Hash.new
|
|
797
|
+
@findings_lock = Mutex.new
|
|
798
|
+
@chats_lock = Mutex.new
|
|
799
|
+
|
|
800
|
+
# puts project_prefs.to_yaml
|
|
801
|
+
#setDefaults()
|
|
802
|
+
|
|
803
|
+
# reset counters
|
|
804
|
+
Watobo::Chat.new([],[]).resetCounters
|
|
805
|
+
Watobo::Finding.new([],[]).resetCounters
|
|
806
|
+
|
|
807
|
+
# UPDATE SETTINGS
|
|
808
|
+
@settings.update(project_settings)
|
|
809
|
+
|
|
810
|
+
@scan_settings = Watobo::Conf::Scanner.dump
|
|
811
|
+
@forward_proxy_settings = Watobo::Conf::ForwardingProxy.dump
|
|
812
|
+
|
|
813
|
+
raise ArgumentError, "No SessionStore Defined" unless @settings.has_key? :session_store
|
|
814
|
+
|
|
815
|
+
@session_store = @settings[:session_store]
|
|
816
|
+
# @passive_checks = @settings[:passive_checks] if @settings.has_key? :passive_checks
|
|
817
|
+
|
|
818
|
+
@settings[:passive_checks].each do |pm|
|
|
819
|
+
pc = pm.new(self)
|
|
820
|
+
pc.subscribe(:new_finding){ |nf| addFinding(nf) }
|
|
821
|
+
@passive_checks << pc
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
# @active_checks = @settings[:active_checks]
|
|
825
|
+
@settings[:active_checks].each do |am|
|
|
826
|
+
ac = am.new(self)
|
|
827
|
+
puts "+#{ac.class}"
|
|
828
|
+
ac.subscribe(:new_finding){ |nf| addFinding(nf) }
|
|
829
|
+
@active_checks << ac
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
@date = Time.now.to_i
|
|
833
|
+
# @date_str = Time.at(@date).strftime("%m/%d/%Y@%H:%M:%S")
|
|
834
|
+
|
|
835
|
+
@sessionController = Watobo::Session.new(self)
|
|
836
|
+
|
|
837
|
+
@sessionController.addProxy(getCurrentProxy())
|
|
838
|
+
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
#
|
|
842
|
+
# S E S S I O N _ I N I T
|
|
843
|
+
#
|
|
844
|
+
|
|
845
|
+
def listSites(prefs={}, &block)
|
|
846
|
+
list = Hash.new
|
|
847
|
+
|
|
848
|
+
cprefs = { :in_scope => false,
|
|
849
|
+
:ssl => false
|
|
850
|
+
}
|
|
851
|
+
cprefs.update prefs
|
|
852
|
+
|
|
853
|
+
@chats.each do |chat|
|
|
854
|
+
next if list.has_key?(chat.request.site)
|
|
855
|
+
site = chat.request.site
|
|
856
|
+
site = nil if cprefs[:in_scope] == true and not siteInScope?(site)
|
|
857
|
+
site = nil if cprefs[:ssl] and not siteSSL?(site)
|
|
858
|
+
unless site.nil?
|
|
859
|
+
yield site if block_given?
|
|
860
|
+
list[site] = nil
|
|
861
|
+
end
|
|
862
|
+
# yield chat.request.site if chat.request.site
|
|
863
|
+
end
|
|
864
|
+
return list.keys
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
def listDirs(site, list_opts={}, &block)
|
|
868
|
+
opts = { :base_dir => "",
|
|
869
|
+
:include_subdirs => true
|
|
870
|
+
}
|
|
871
|
+
opts.update(list_opts) if list_opts.is_a? Hash
|
|
872
|
+
list = Hash.new
|
|
873
|
+
@chats.each do |chat|
|
|
874
|
+
next if chat.request.site != site
|
|
875
|
+
next if list.has_key?(chat.request.path)
|
|
876
|
+
next if opts[:base_dir] != "" and chat.request.path !~ /^#{Regexp.quote(opts[:base_dir])}/
|
|
877
|
+
subdirs = chat.request.subDirs
|
|
878
|
+
subdirs.each do |dir|
|
|
879
|
+
next if dir.nil?
|
|
880
|
+
next if list.has_key?(dir)
|
|
881
|
+
list[dir] = :path
|
|
882
|
+
if opts[:include_subdirs] == true then
|
|
883
|
+
yield dir if block
|
|
884
|
+
else
|
|
885
|
+
d = dir.gsub(/#{Regexp.quote(opts[:base_dir])}/,"")
|
|
886
|
+
yield dir unless d =~ /\// and block
|
|
887
|
+
# otherwise it is a subdir of base_dir
|
|
888
|
+
end
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
private
|
|
894
|
+
|
|
895
|
+
def listChatIds(path, pattern)
|
|
896
|
+
id_list = []
|
|
897
|
+
Dir.foreach(path) do |file|
|
|
898
|
+
if file =~ /#{pattern}/ then
|
|
899
|
+
id = file.gsub!(/-#{pattern}/,'').to_i
|
|
900
|
+
id_list.push id
|
|
901
|
+
end
|
|
902
|
+
end
|
|
903
|
+
return id_list.uniq.sort
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
def importSession()
|
|
907
|
+
num_chats = @session_store.num_chats
|
|
908
|
+
num_findings = @session_store.num_findings
|
|
909
|
+
num_imports = num_chats + num_findings
|
|
910
|
+
notify(:update_progress, :progress => 0, :total => num_imports, :task => "Import Conversation")
|
|
911
|
+
@session_store.each_chat do |c|
|
|
912
|
+
notify(:update_progress, :increment =>1, :job => "chat #{c.id}" )
|
|
913
|
+
addChat(c, :run_passive_checks => false, :notify => false ) if c
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
notify(:update_progress, :task => "Import Findings")
|
|
917
|
+
@session_store.each_finding do |f|
|
|
918
|
+
notify(:update_progress, :increment =>1, :job => "finding #{f.id}" )
|
|
919
|
+
addFinding(f, :notify => true, :save_finding => false ) if f
|
|
920
|
+
end
|
|
921
|
+
=begin
|
|
922
|
+
puts "* Import Session:"
|
|
923
|
+
puts "+ Conversation Path:\n>> #{File.expand_path(@conversations_path)}"
|
|
924
|
+
|
|
925
|
+
puts
|
|
926
|
+
chatIds = listChatIds(@conversations_path, "chat")
|
|
927
|
+
findingIds = listChatIds(@findings_path, "finding")
|
|
928
|
+
|
|
929
|
+
numChats = chatIds.length
|
|
930
|
+
numFindings = findingIds.length
|
|
931
|
+
numImports = numChats + numFindings
|
|
932
|
+
pc = 0
|
|
933
|
+
|
|
934
|
+
notify(:update_progress, :total => numImports, :task => "Import Conversation")
|
|
935
|
+
|
|
936
|
+
begin
|
|
937
|
+
chatIds.each_with_index do |id, index|
|
|
938
|
+
|
|
939
|
+
notify(:update_progress, :increment =>1, :job => "chat #{index}/#{numChats}" )
|
|
940
|
+
|
|
941
|
+
fname = File.join(@conversations_path, "#{id}-chat")
|
|
942
|
+
chat = Watobo::Utils.loadChatYAML(fname)
|
|
943
|
+
addChat(chat, :run_passive_checks => false, :notify => false ) if chat
|
|
944
|
+
end
|
|
945
|
+
rescue => bang
|
|
946
|
+
puts "!!!ERROR: Could not import conversations"
|
|
947
|
+
puts bang
|
|
948
|
+
puts bang.backtrace if $DEBUG
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
puts "+ Findings Path:\n>> #{File.expand_path(@findings_path)}"
|
|
952
|
+
|
|
953
|
+
notify(:update_progress, :task => "Import Findings")
|
|
954
|
+
begin
|
|
955
|
+
findingIds.each_with_index do |id, index|
|
|
956
|
+
notify(:update_progress, :increment => 1, :job => "Finding #{index}/#{numFindings}")
|
|
957
|
+
|
|
958
|
+
fname = File.join(@findings_path, "#{id}-finding")
|
|
959
|
+
finding = Watobo::Utils.loadFindingYAML(fname)
|
|
960
|
+
|
|
961
|
+
addFinding(finding, :notify => false) if finding
|
|
962
|
+
|
|
963
|
+
end
|
|
964
|
+
rescue => bang
|
|
965
|
+
puts "!!!ERROR: Could not import finding [#{id}]"
|
|
966
|
+
puts bang
|
|
967
|
+
|
|
968
|
+
end
|
|
969
|
+
=end
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
def setDefaults()
|
|
973
|
+
@settings = {
|
|
974
|
+
:excluded_chats => [],
|
|
975
|
+
:scope => Hash.new,
|
|
976
|
+
#:project_prefs => {
|
|
977
|
+
# :project_settings_file_ext => '.wps',
|
|
978
|
+
# :session_settings_file_ext => '.wss',
|
|
979
|
+
:project_path => '',
|
|
980
|
+
:session_path => '',
|
|
981
|
+
:project_name => '',
|
|
982
|
+
:session_name => '',
|
|
983
|
+
:module_dir => 'modules',
|
|
984
|
+
:plugin_dir => 'plugins',
|
|
985
|
+
:conversations_dir => "conversations",
|
|
986
|
+
:findings_dir => "findings",
|
|
987
|
+
:logs_dir => "logs",
|
|
988
|
+
#},
|
|
989
|
+
|
|
990
|
+
#:scan_prefs => {
|
|
991
|
+
:custom_error_patterns => [],
|
|
992
|
+
:max_parallel_checks => 15,
|
|
993
|
+
:excluded_parms => [ "__VIEWSTATE", "__EVENTVALIDATION"],
|
|
994
|
+
:non_unique_parms => [],
|
|
995
|
+
:smart_scan => true,
|
|
996
|
+
:run_passive_checks => false,
|
|
997
|
+
#},
|
|
998
|
+
:policy => { :name => 'Default',
|
|
999
|
+
:list => {
|
|
1000
|
+
'Default' => {
|
|
1001
|
+
'Watobo::Modules::Active::Directories::Dir_indexing' => false,
|
|
1002
|
+
'Watobo::Modules::Active::Discovery::Http_methods' => false,
|
|
1003
|
+
'Watobo::Modules::Active::Domino::Domino_db' => false,
|
|
1004
|
+
'Watobo::Modules::Active::Sap::Its_commands' => false,
|
|
1005
|
+
'Watobo::Modules::Active::Sap::Its_services' => false,
|
|
1006
|
+
'Watobo::Modules::Active::Sap::Its_service_parameter' => false,
|
|
1007
|
+
'Watobo::Modules::Active::Sap::Its_xss' => false,
|
|
1008
|
+
'Watobo::Modules::Active::Sqlinjection::Sqli_simple' => true,
|
|
1009
|
+
'Watobo::Modules::Active::Sqlinjection::Sql_boolean' => true,
|
|
1010
|
+
'Watobo::Modules::Active::Sqlinjection::Sql_numerical' => false,
|
|
1011
|
+
'Watobo::Modules::Active::Xss::Xss_simple' => true,
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
|
|
1016
|
+
#@interface = Hash.new
|
|
1017
|
+
#:session_management => {
|
|
1018
|
+
:csrf_patterns => [
|
|
1019
|
+
"name=\"(token)\" value=\"([0-9a-zA-Z!-]*)\"",
|
|
1020
|
+
"(token)=([-0-9a-zA-Z_:]*)(;|&)?"
|
|
1021
|
+
],
|
|
1022
|
+
:csrf_request_ids => Hash.new,
|
|
1023
|
+
|
|
1024
|
+
:login_chat_ids => [],
|
|
1025
|
+
:sid_patterns => [
|
|
1026
|
+
"name=\"(sessid)\" value=\"([0-9a-zA-Z!-]*)\"",
|
|
1027
|
+
"(sessid)=([-0-9a-zA-Z_:]*)(;|&)?",
|
|
1028
|
+
'(SESSIONID)=([-0-9a-zA-Z_:\.\(\)]*)(;|&)?',
|
|
1029
|
+
"(PHPSESSID)=([0-9a-zA-Z]*)(;|&)?",
|
|
1030
|
+
'(ASPSESSIONID)\w*=([0-9a-zA-Z]*)(;|&)?',
|
|
1031
|
+
'(ASP.NET_SessionId)=([0-9a-zA-Z]*)(;|&)?',
|
|
1032
|
+
"(MYSAPSSO2)=([0-9a-zA-Z.=%]*)(;|&)?",
|
|
1033
|
+
"(ELEXIRSID)=([0-9a-zA-Z!-]*)(;|&)?",
|
|
1034
|
+
"(SLSID)=([0-9a-zA-Z!-]*)(;|&)?",
|
|
1035
|
+
"(sid)=([0-9a-z]*)(')?", #servlet?sid=9912ad967cc578a12ada85d91f841e18')
|
|
1036
|
+
'(saplb_\*)=([-0-9a-zA-Z_:\(\)]*)(;|&)?',
|
|
1037
|
+
"(DomAuthSessId)=([0-9a-zA-Z]*)(;|&)?",
|
|
1038
|
+
'(wgate)\/([\w]{4,}\/[\w=~]*)(;|&|\'|")?', # SAP ITS WGATE Session Handling
|
|
1039
|
+
'(session)=([-0-9a-zA-Z_:\.]*)(;|&)?' # SAP ITS Session Cookie
|
|
1040
|
+
],
|
|
1041
|
+
:logout_signatures => [
|
|
1042
|
+
"^Location.*login"
|
|
1043
|
+
],
|
|
1044
|
+
#},
|
|
1045
|
+
|
|
1046
|
+
# :settings => {
|
|
1047
|
+
# :module_path => ''
|
|
1048
|
+
# },
|
|
1049
|
+
:history => [],
|
|
1050
|
+
:www_auth => {},
|
|
1051
|
+
:client_certificates => {} # e.g. { :site => { :certificate_file => "host.crt", :key_file => "host.key", :password => "lkajsdflk" }
|
|
1052
|
+
}
|
|
1053
|
+
end
|
|
1054
|
+
|
|
1055
|
+
private
|
|
1056
|
+
|
|
1057
|
+
end
|
|
1058
|
+
end # Watobo
|