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,729 @@
1
+ # .
2
+ # interceptor.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
+ INTERCEPT_NONE = 0x00
24
+ INTERCEPT_REQUEST = 0x01
25
+ INTERCEPT_RESPONSE = 0x02
26
+ INTERCEPT_BOTH = 0x03
27
+
28
+ INTERCEPT_DEFAULT_PORT = 8081
29
+ # I N T E R C E P T P R O X Y
30
+ #
31
+ class InterceptProxy
32
+
33
+ include Watobo::Constants
34
+ # include Watobo::Conf::Interceptor
35
+
36
+ attr :port
37
+
38
+
39
+ attr_accessor :mode
40
+
41
+ attr_accessor :contentLength
42
+ attr_accessor :contentTypes
43
+ attr_accessor :target
44
+ attr_accessor :www_auth
45
+ attr_accessor :client_certificates
46
+
47
+ def server
48
+ @bind_addr
49
+ end
50
+
51
+ def subscribe(event, &callback)
52
+ (@event_dispatcher_listeners[event] ||= []) << callback
53
+ end
54
+
55
+ def clearEvents(event)
56
+ @event_dispatcher_listener[event].clear
57
+ end
58
+
59
+ def getResponseFilter()
60
+ YAML.load(YAML.dump(@response_filter_settings))
61
+ end
62
+
63
+ def getRequestFilter()
64
+ YAML.load(YAML.dump(@request_filter_settings))
65
+ end
66
+
67
+ def setResponseFilter(new_settings)
68
+ @response_filter_settings.update new_settings unless new_settings.nil?
69
+ end
70
+
71
+ def setRequestFilter(new_settings)
72
+ @request_filter_settings.update new_settings unless new_settings.nil?
73
+ puts @request_filter_settings.to_yaml
74
+ end
75
+
76
+ # def getRequestFilter
77
+ # @request_filter_settings
78
+ # end
79
+
80
+ # def getResponseFilter
81
+ # @response_filter_settings
82
+ # end
83
+
84
+ def addPreview(response)
85
+ preview_id = Digest::MD5.hexdigest(response.join)
86
+ @preview[preview_id] = response
87
+ return preview_id
88
+ end
89
+
90
+ def stop()
91
+ begin
92
+ puts "[#{self.class}] stop"
93
+ puts @t_server.status
94
+ @t_server.kill
95
+ @intercept_srv.close
96
+ rescue IOError => bang
97
+ puts bang
98
+ puts bang.backtrace if $DEBUG
99
+ end
100
+ end
101
+
102
+ #
103
+ # R U N
104
+ #
105
+
106
+ def run(settings={})
107
+ begin
108
+ # @server = '127.0.0.1'
109
+ # @port = settings[:port] if settings[:port]
110
+ # @server = settings[:server] if settings[:server]
111
+ # @contentLength = settings[:content_length] if settings[:content_length]
112
+ # @contentTypes = settings[:content_types] if settings[:content_types]
113
+
114
+ @intercept_srv = TCPServer.new(@bind_addr, @port)
115
+ @intercept_srv.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
116
+
117
+ rescue => bang
118
+ puts "\n!!!Could not start InterceptProxy"
119
+ puts bang
120
+ return nil
121
+ end
122
+ puts "\n* Intercepor started on #{@bind_addr}:#{@port}"
123
+ session_list = []
124
+
125
+ @t_server = Thread.new(@intercept_srv) { |server|
126
+ while (new_session = server.accept)
127
+ # new_session.sync = true
128
+ Thread.new(new_session) { |session|
129
+ begin
130
+ request, c_sock = read_request(session)
131
+
132
+ if request.nil? or request.empty? then
133
+ # puts "! empty request ? :("
134
+ c_sock.close
135
+ Thread.current.exit
136
+ #return
137
+ end
138
+ puts "*[I] #{request.url}"
139
+
140
+ rescue => bang
141
+ puts "!!! Error reading client request "
142
+ puts bang
143
+ Thread.current.exit
144
+ #break
145
+ end
146
+
147
+ # check if preview is requested
148
+ if request.host =='watobo.localhost' or request.first =~ /WATOBOPreview/ then
149
+ if request.first =~ /WATOBOPreview=([0-9a-zA-Z]*)/ then
150
+
151
+ puts "* preview requested ..."
152
+ puts request.url
153
+
154
+ hashid = $1
155
+ response = @preview[hashid]
156
+
157
+ if response then
158
+ c_sock.write response.join
159
+ closeSocket(c_sock)
160
+ end
161
+ end
162
+ next
163
+ end
164
+ request_intercepted = false
165
+ # no preview, check if interception request is turned on
166
+ if @target and @mode & INTERCEPT_REQUEST > 0 then
167
+
168
+ if matchRequestFilter(request)
169
+ @awaiting_requests += 1
170
+ request_intercepted = true
171
+
172
+ if @target.respond_to? :modifyRequest
173
+ # puts "*INTERCEPT REQUEST"
174
+ # puts @target
175
+ #notify(:modify_request, request, Thread.current)
176
+ Watobo.print_debug "send request to target"
177
+ @target.addRequest(request, Thread.current)
178
+ puts "* stopping thread: #{Thread.current} ..."
179
+ Thread.stop
180
+ puts "* released thread: #{Thread.current}"
181
+ else
182
+ p "! no target for editing request"
183
+ end
184
+ @awaiting_requests -= 1
185
+ end
186
+ end
187
+ # req, resp = @sender.sendRequest(request, :update_sids => false, :update_session => false, :update_contentlength => true)
188
+
189
+ #p "getHTTPHeader"
190
+ #s_sock, req, resp = @sender.getHTTPHeader(request, :update_sids => true, :update_session => false, :update_contentlength => true)
191
+ s_sock, req, resp = @sender.sendHTTPRequest(request, :update_sids => true, :update_session => false, :update_contentlength => true, :www_auth => @www_auth, :client_certificates => @client_certificates)
192
+
193
+ if s_sock.nil? then
194
+ c_sock.print resp.join unless resp.nil?
195
+ closeSocket(c_sock)
196
+ next
197
+ end
198
+
199
+ # check if response should be passed throug
200
+ Thread.current.exit if isPassThrough?(req, resp, s_sock, c_sock)
201
+ #p "no pass-through"
202
+
203
+ begin
204
+ # puts "* got response status: #{resp.status}"
205
+ rs = resp.status
206
+ if rs =~ /^(401|407)/ then
207
+ resp.extend Watobo::Mixin::Shaper::Web10
208
+
209
+ auth_type = AUTH_TYPE_NONE
210
+ resp.each do |rl|
211
+ if rl =~ /^(Proxy|WWW)-Authenticate: Basic/i
212
+ auth_type = AUTH_TYPE_BASIC
213
+ break
214
+ elsif rl =~ /^(Proxy|WWW)-Authenticate: NTLM/i
215
+ auth_type = AUTH_TYPE_NTLM
216
+ break
217
+ end
218
+ end
219
+ # when auth type not basic assume it's ntlm -> ntlm credentials must be set in watobo
220
+ unless auth_type == AUTH_TYPE_NONE
221
+ if auth_type == AUTH_TYPE_NTLM
222
+ if rs =~ /^401/ then
223
+ resp.push "WATOBO: Server requires (NTLM) authorization, please set WWW_Auth Credentials!"
224
+ resp.shift
225
+ resp.unshift "HTTP/1.1 200 OK\r\n"
226
+ else
227
+ resp.push "WATOBO: Proxy requires (NTLM) authorization, please set Proxy Credentials!"
228
+ resp.shift
229
+ resp.unshift "HTTP/1.1 200 OK\r\n"
230
+ end
231
+ end
232
+ else
233
+
234
+ resp.push "WATOBO: Unknown authorization type.<br><br>\r\n" + resp.join("<br>\r\n")
235
+ resp.shift
236
+ resp.unshift "HTTP/1.1 200 OK\r\n"
237
+ resp.fix_content_length
238
+
239
+ end
240
+ else
241
+ @sender.readHTTPBody(s_sock, resp, req, :update_sids => true)
242
+ end
243
+ rescue => bang
244
+ puts "!!! could not send request !!!"
245
+ puts bang
246
+ puts bang.backtrace if $DEBUG
247
+ # puts "* Error sending request"
248
+ end
249
+
250
+ begin
251
+ if @target and @mode & INTERCEPT_RESPONSE > 0 then
252
+ if matchResponseFilter(resp)
253
+ # if resp.content_type =~ /text/ or resp.content_type =~ /application\/javascript/ then
254
+ if @target.respond_to? :modifyResponse
255
+ @target.modifyResponse(resp, Thread.current)
256
+ Thread.stop
257
+ else
258
+ p "! no target for editing response"
259
+ end
260
+ end
261
+ end
262
+
263
+ c_sock.write resp.join
264
+ closeSocket(c_sock)
265
+ rescue Errno::ECONNRESET
266
+ print "x"
267
+ # puts "!!! ERROR (Reset): reading body"
268
+ # puts "* last data seen on socket: #{buf}"
269
+ #return
270
+ rescue Errno::ECONNABORTED
271
+ print "x"
272
+ #return
273
+ rescue => bang
274
+ puts "!!! Error (???) in Client Communication:"
275
+ puts bang
276
+ puts bang.class
277
+ puts bang.backtrace if $DEBUG
278
+ #return
279
+ end
280
+ #if req then # when req == nil an error occured -> no chat necessary
281
+ chat = Chat.new(request, resp, :source => CHAT_SOURCE_INTERCEPT)
282
+ notify(:new_interception, chat)
283
+ # end
284
+ #else
285
+ # puts "* got no response"
286
+ # session_new.close
287
+ }
288
+ end
289
+ }
290
+ end
291
+
292
+ def initialize(settings=nil)
293
+ @event_dispatcher_listeners = Hash.new
294
+ begin
295
+
296
+ puts
297
+ puts "=== Initialize Interceptor/Proxy ==="
298
+ # @project = project
299
+ # @settings = settings
300
+ # @port = @settings[:intercept_port]
301
+ # puts settings.to_yaml
302
+
303
+ @mode = INTERCEPT_NONE
304
+ @www_auth = {}
305
+ @client_certificates = {}
306
+ @target = nil
307
+ @sender = Watobo::Session.new(@target)
308
+
309
+ @bind_addr = Watobo::Conf::Interceptor.server
310
+ puts "> Server: #{@bind_addr}"
311
+ @port = Watobo::Conf::Interceptor.port
312
+ puts "> Port: #{@port}"
313
+
314
+ pt = Watobo::Conf::Interceptor.pass_through
315
+ @contentLength = pt[:content_length]
316
+ puts "> PT-ContentLength: #{@contentLength}"
317
+ @contentTypes = pt[:content_types]
318
+ puts "> PT-ContentTypes: #{@contentTypes}"
319
+
320
+ @awaiting_requests = 0
321
+ @awaiting_responses = 0
322
+
323
+ @request_filter_settings = {
324
+ :site_in_scope => false,
325
+ :method_filter => '(get|post|put)',
326
+ :negate_method_filter => false,
327
+ :negate_url_filter => false,
328
+ :url_filter => '',
329
+ :file_type_filter => '(jpg|gif|png|jpeg|bmp)',
330
+ :negate_file_type_filter => true,
331
+
332
+ :parms_filter => '',
333
+ :negate_parms_filter => false
334
+ #:regex_location => 0, # TODO: HEADER_LOCATION, BODY_LOCATION, ALL
335
+
336
+ }
337
+
338
+ @response_filter_settings = {
339
+ :content_type_filter => '(text|script)',
340
+ :negate_content_type_filter => false,
341
+ :response_code_filter => '2\d{2}',
342
+ :negate_response_code_filter => false,
343
+ :request_intercepted => false,
344
+ :content_printable => true,
345
+ :enable_printable_check => false
346
+ }
347
+
348
+ @preview = Hash.new
349
+ @preview['ProxyTest'] = ["HTTP/1.0 200 OK\r\nServer: Watobo-Interceptor\r\nConnection: close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<html><body>PROXY_OK</body></html>"]
350
+
351
+ # p @settings[:certificate_path]
352
+ # p @settings[:cert_file]
353
+ # p @settings[:key_file]
354
+ crt_path = Watobo::Conf::Interceptor.certificate_path
355
+ crt_file = Watobo::Conf::Interceptor.cert_file
356
+ key_file = Watobo::Conf::Interceptor.key_file
357
+ dh_key_file = Watobo::Conf::Interceptor.dh_key_file
358
+
359
+ crt_filename = File.join(Watobo.base_directory, crt_path, crt_file)
360
+ key_filename = File.join(Watobo.base_directory, crt_path, key_file)
361
+ dh_filename = File.join(Watobo.base_directory, crt_path, dh_key_file)
362
+ unless File.exist? dh_filename
363
+ #puts "* no dh key file found"
364
+ File.open(dh_filename,"w") do |fh|
365
+ puts "* creating SSL key (DH 1024) ... "
366
+ fh.write OpenSSL::PKey::DH.new(1024).to_pem
367
+ print " DONE\r\n"
368
+ end
369
+ end
370
+
371
+ # @ctx = OpenSSL::SSL::SSLContext.new('SSLv23_server')
372
+ puts "* read certificat (#{crt_path})"
373
+ @cert = OpenSSL::X509::Certificate.new(File.read(crt_filename))
374
+ @key = OpenSSL::PKey::RSA.new(File.read(key_filename))
375
+
376
+ @dh_key = OpenSSL::PKey::DH.new(File.read(dh_filename))
377
+ # @ctx.ciphers = nil # ['TLSv1/SSLv3', 56, 56 ]
378
+
379
+ rescue => bang
380
+ puts "!!!could not read certificate files:"
381
+ puts bang
382
+ puts bang.backtrace if $DEBUG
383
+ end
384
+
385
+ end
386
+
387
+ private
388
+
389
+ #
390
+ #
391
+ # matchContentType(content_type)
392
+ #
393
+ #
394
+ def matchContentType?(content_type)
395
+ @contentTypes.each do |p|
396
+ return true if content_type =~ /#{p}/
397
+ end
398
+ return false
399
+ end
400
+
401
+ #
402
+ #
403
+ # matchRequestFilter(request)
404
+ #
405
+ #
406
+ def matchRequestFilter(request)
407
+ match_url = true
408
+ # puts @request_filter_settings.to_yaml
409
+ url_filter = @request_filter_settings[:url_filter]
410
+ if url_filter != ''
411
+ match_url = false
412
+ if request.url =~ /#{url_filter}/i
413
+ match_url = true
414
+ end
415
+ if @request_filter_settings[:negate_url_filter] == true
416
+ match_url = ( match_url == true ) ? false : true
417
+ end
418
+ end
419
+
420
+ return false if match_url == false
421
+
422
+ match_method = true
423
+ method_filter = @request_filter_settings[:method_filter]
424
+ if method_filter != ''
425
+ match_method = false
426
+ if request.method =~ /#{method_filter}/i
427
+ match_method = true
428
+ end
429
+
430
+ if @request_filter_settings[:negate_method_filter] == true
431
+ match_method = ( match_method == true ) ? false : true
432
+ end
433
+ end
434
+
435
+ return false if match_method == false
436
+
437
+ match_ftype = true
438
+ ftype_filter = @request_filter_settings[:file_type_filter]
439
+ if ftype_filter != ''
440
+ match_ftype = false
441
+ if request.doctype != '' and request.doctype =~ /#{ftype_filter}/i
442
+ match_ftype = true
443
+ end
444
+ if @request_filter_settings[:negate_file_type_filter] == true
445
+ match_ftype = ( match_ftype == true ) ? false : true
446
+ end
447
+ end
448
+ return false if match_ftype == false
449
+
450
+ match_parms = true
451
+ parms_filter = @request_filter_settings[:parms_filter]
452
+ if parms_filter != ''
453
+ puts "!PARMS FILTER: #{parms_filter}"
454
+ match_parms = false
455
+ puts request.parms
456
+ match_parms = request.parms.find {|x| x =~ /#{parms_filter}/ }
457
+ match_parms = ( match_parms.nil? ) ? false : true
458
+ if @request_filter_settings[:negate_parms_filter] == true
459
+ match_parms = ( match_parms == true ) ? false : true
460
+ end
461
+ end
462
+ return false if match_parms == false
463
+
464
+ true
465
+ end
466
+
467
+ #
468
+ #
469
+ # matchResponseFilter(response)
470
+ #
471
+ #
472
+
473
+ def matchResponseFilter(response)
474
+ match_ctype = true
475
+ ct_filter = @response_filter_settings[:content_type_filter]
476
+ unless ct_filter.empty?
477
+ match_ctype = false
478
+ negate = @response_filter_settings[:negate_content_type_filter]
479
+ if response.content_type =~ /#{ct_filter}/
480
+ match_ctype = true
481
+
482
+ end
483
+ if negate == true
484
+ match_ctype = ( match_ctype == true ) ? false : true
485
+ end
486
+ end
487
+ return false if match_ctype == false
488
+ puts "* pass ctype filter"
489
+ match_rcode = true
490
+ rcode_filter = @response_filter_settings[:response_code_filter]
491
+ negate = @response_filter_settings[:negate_response_code_filter]
492
+ unless rcode_filter.empty?
493
+ match_rcode = false
494
+ puts rcode_filter
495
+ puts response.responseCode
496
+ if response.responseCode =~ /#{rcode_filter}/
497
+ match_rcode = true
498
+ end
499
+ if negate == true
500
+ match_rcode = ( match_rcode == true ) ? false : true
501
+ end
502
+ end
503
+ return false if match_rcode == false
504
+ puts "* pass rcode filter"
505
+ true
506
+ end
507
+
508
+ #
509
+ #
510
+ # pass_through(server, client, maxbytes)
511
+ #
512
+ #
513
+ def pass_through(server, client, maxbytes = 0)
514
+ buf = ''
515
+ print "[~"
516
+ bytes_read = 0
517
+ while buf
518
+ begin
519
+ #timeout(2) do
520
+ buf = nil
521
+ buf = server.readpartial(2048)
522
+ #end
523
+ rescue EOFError
524
+ #client.write buf if buf
525
+ #print "~]"
526
+ return if buf.nil?
527
+ rescue Errno::ECONNRESET
528
+ puts "!!! ERROR (Reset): reading body"
529
+ puts "* last data seen on socket: #{buf}"
530
+ return if buf.nil?
531
+ rescue Timeout::Error
532
+ puts "!!! ERROR (Timeout): reading body"
533
+ puts "* last data seen on socket:"
534
+ #client.write buf if buf
535
+ print "!~]"
536
+ return if buf.nil?
537
+ rescue => bang
538
+ puts "!!! could not read body !!!"
539
+ puts bang
540
+ puts bang.class
541
+ puts bang.backtrace if $DEBUG
542
+ # puts "* last data seen on socket:"
543
+ # print "~]"
544
+ #client.write buf if buf
545
+ return
546
+ end
547
+
548
+ begin
549
+ return if buf.nil?
550
+ print "~"
551
+ client.write buf
552
+ bytes_read += buf.length
553
+ # puts "##{bytes_read} of #{maxbytes}"
554
+ if maxbytes > 0 and bytes_read >= maxbytes
555
+ print "~]"
556
+ return
557
+ end
558
+
559
+ rescue Errno::ECONNRESET
560
+ print "~x]"
561
+ # puts "!!! ERROR (Reset): reading body"
562
+ # puts "* last data seen on socket: #{buf}"
563
+ return
564
+ rescue Errno::ECONNABORTED
565
+ print "~x]"
566
+ return
567
+ rescue Errno::EPIPE
568
+ print "~x]"
569
+ return
570
+ rescue => bang
571
+ puts "!!! client communication broken !!!"
572
+ puts bang
573
+ puts bang.class
574
+ puts bang.backtrace if $DEBUG
575
+ return
576
+ end
577
+ end
578
+ end
579
+
580
+ def read_request(socket)
581
+ request = []
582
+ # read http header lines
583
+ session = socket
584
+ # puts "* read header ..."
585
+ Watobo::HTTP.read_header(socket) do |line|
586
+ request.push line
587
+ end
588
+
589
+ if request.first =~ /^CONNECT (.*):(\d{1,5}) HTTP\/1\./ then
590
+ target = $1
591
+ tport = $2
592
+ # puts request.first
593
+ # print "\n* CONNECT: #{method} #{target} on port #{tport}\n"
594
+
595
+ socket.print "HTTP/1.0 200 Connection established\r\n" +
596
+ "Proxy-connection: Keep-alive\r\n" +
597
+ "Proxy-agent: WATOBO-Proxy/1.1\r\n" +
598
+ "\r\n"
599
+ bscount = 0 # bad handshake counter
600
+ # puts "* wait for ssl handshake ..."
601
+ begin
602
+
603
+ ctx = OpenSSL::SSL::SSLContext.new()
604
+
605
+ ctx.cert = @cert
606
+ # @ctx.key = OpenSSL::PKey::DSA.new(File.read(key_file))
607
+ ctx.key = @key
608
+
609
+ ctx.tmp_dh_callback = proc { |*args|
610
+ @dh_key
611
+ }
612
+
613
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
614
+ ctx.timeout = 10
615
+
616
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
617
+ ssl_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
618
+ #ssl_socket.sync_close = true
619
+ ssl_socket.sync = true
620
+ # puts ssl_socket.methods.sort
621
+
622
+ ssl_session = ssl_socket.accept
623
+ rescue => bang
624
+ puts bang
625
+ puts bang.backtrace if $DEBUG
626
+ #puts ssl_session
627
+ #if not ssl_session then bscount += 1;end
628
+ #if bscount > 10 then
629
+ # puts "!!! Error: SSL-Handshake with Client/Browser"
630
+ # puts bang
631
+ return nil, socket
632
+ #end
633
+ #retry
634
+ end
635
+ session = ssl_session
636
+ # puts "* ssl ok!"
637
+ # now read ssl request header
638
+ request = []
639
+ Watobo::HTTP.read_header(session) do |line|
640
+ request.push line
641
+ end
642
+
643
+ return nil, session if not request.first
644
+
645
+ request.first.gsub!(/(^[^[:space:]]{1,})( )(\/.*)/, "\\1 https://#{target}:#{tport}\\3")
646
+ end
647
+ #puts request
648
+ request.extend Watobo::Mixin::Parser::Url
649
+ request.extend Watobo::Mixin::Parser::Web10
650
+ request.extend Watobo::Mixin::Shaper::Web10
651
+
652
+ clen = request.content_length
653
+ if clen > 0 then
654
+ body = ""
655
+ Watobo::HTTP.read_body(session) do |data|
656
+ body += data
657
+ break if body.length == clen
658
+ end
659
+ request.push body
660
+ end
661
+
662
+ return request, session
663
+ end
664
+
665
+ def isPassThrough?(request, response, s_sock, c_sock)
666
+ begin
667
+ reason = nil
668
+ clen = response.content_length
669
+
670
+ if matchContentType?(response.content_type) then
671
+ # first forward headers
672
+ c_sock.write response.join
673
+ reason = []
674
+ reason.push "---> WATOBO: PASS_THROUGH <---"
675
+ reason.push "Reason: Content-Type = #{response.content_type}"
676
+ elsif clen > @contentLength
677
+ # puts "PASS-THROUGH: #{response.content_length}"
678
+ c_sock.write response.join
679
+ reason = []
680
+ reason.push "---> WATOBO: PASS_THROUGH <---"
681
+ reason.push "Reason: Content-Length > #{@contentLength} (#{response.content_length})"
682
+ end
683
+
684
+ return false if reason.nil?
685
+ reason.push "* DO MANUAL REQUEST TO GET FULL RESPONSE *"
686
+ response.push reason.join("\n")
687
+ chat = Watobo::Chat.new(request, response, :source => CHAT_SOURCE_INTERCEPT)
688
+ notify(:new_interception, chat)
689
+
690
+ pass_through(s_sock, c_sock, clen)
691
+ # puts "* Close Server Socket..."
692
+ closeSocket(c_sock)
693
+ # puts "* Close Client Socket..."
694
+ closeSocket(s_sock)
695
+ # puts "... done."
696
+ true
697
+ rescue => bang
698
+ puts bang
699
+ puts bang.backtrace if $DEBUG
700
+ return false
701
+ end
702
+ end
703
+
704
+ def notify(event, *args)
705
+ if @event_dispatcher_listeners[event]
706
+ @event_dispatcher_listeners[event].each do |m|
707
+ m.call(*args) if m.respond_to? :call
708
+ end
709
+ end
710
+ end
711
+
712
+ def closeSocket(socket)
713
+ #puts socket.class
714
+ begin
715
+ #if socket.class.to_s =~ /SSLSocket/
716
+ if socket.is_a? OpenSSL::SSL::SSLSocket
717
+ socket.io.shutdown(2)
718
+ else
719
+ socket.shutdown(2)
720
+ end
721
+ socket.close
722
+ rescue => bang
723
+ puts bang
724
+ puts bang.backtrace if $DEBUG
725
+ end
726
+ end
727
+
728
+ end
729
+ end