watobo 0.9.14 → 0.9.15

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 (47) hide show
  1. data/CHANGELOG.md +29 -0
  2. data/config/interceptor.yml +1 -0
  3. data/lib/watobo/core/active_check.rb +1 -2
  4. data/lib/watobo/core/client_cert_store.rb +47 -0
  5. data/lib/watobo/core/scanner3.rb +124 -88
  6. data/lib/watobo/core/session.rb +52 -47
  7. data/lib/watobo/core.rb +1 -11
  8. data/lib/watobo/gui/chatviewer_frame.rb +5 -3
  9. data/lib/watobo/gui/checkboxtree.rb +59 -14
  10. data/lib/watobo/gui/checks_policy_frame.rb +1 -5
  11. data/lib/watobo/gui/client_cert_dialog.rb +260 -96
  12. data/lib/watobo/gui/conversation_table.rb +7 -1
  13. data/lib/watobo/gui/conversation_table_ctrl2.rb +14 -5
  14. data/lib/watobo/gui/edit_comment.rb +1 -1
  15. data/lib/watobo/gui/main_window.rb +40 -5
  16. data/lib/watobo/gui/manual_request_editor.rb +10 -8
  17. data/lib/watobo/gui/quick_scan_dialog.rb +8 -6
  18. data/lib/watobo/gui/scanner_settings_dialog.rb +1 -0
  19. data/lib/watobo/gui/text_viewer.rb +5 -3
  20. data/lib/watobo/http/cookies/cookies.rb +3 -1
  21. data/lib/watobo/http_socket/agent.rb +1 -1
  22. data/lib/watobo/http_socket/client_socket.rb +409 -98
  23. data/lib/watobo/http_socket/connection.rb +1 -1
  24. data/lib/watobo/http_socket/http_socket.rb +47 -39
  25. data/lib/watobo/interceptor/proxy.rb +41 -212
  26. data/lib/watobo/mixins/httpparser.rb +17 -16
  27. data/lib/watobo/mixins/shapers.rb +3 -7
  28. data/lib/watobo.rb +2 -1
  29. data/modules/active/domino/domino_db.rb +5 -7
  30. data/modules/active/struts2/default_handler_ognl.rb +128 -0
  31. data/modules/active/struts2/include_params_ognl.rb +127 -0
  32. data/modules/passive/ajax.rb +5 -3
  33. data/modules/passive/detect_infrastructure.rb +2 -3
  34. data/modules/passive/dirindexing.rb +8 -6
  35. data/modules/passive/disclosure_emails.rb +13 -14
  36. data/modules/passive/disclosure_ipaddr.rb +13 -13
  37. data/modules/passive/hotspots.rb +6 -4
  38. data/modules/passive/in_script_parameter.rb +25 -19
  39. data/modules/passive/redirectionz.rb +1 -1
  40. data/modules/passive/sap-headers.rb +78 -0
  41. data/modules/passive/xss_dom.rb +5 -3
  42. data/plugins/catalog/catalog.rb +7 -2
  43. data/plugins/crawler/gui/auth_frame.rb +20 -5
  44. data/plugins/crawler/gui/crawler_gui.rb +56 -9
  45. data/plugins/crawler/lib/engine.rb +12 -14
  46. data/plugins/filefinder/dbs/sap.db +157 -0
  47. metadata +23 -2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ Version 0.9.15
2
+ ==
3
+ Fixes
4
+ --
5
+ **General**
6
+ * improved socket handling
7
+ * fixed some UTF-8 issues in passive modules
8
+ * added application/octet-stream to pass-through content-types
9
+ * `shapers.rb` didn't replace single quotes in `replace_post_parm`
10
+ * setting/replacing http-headers is now case-in-sensitive
11
+
12
+ **Passive Modules**
13
+ * fixed `Disclosure_ipaddr`; now all IPs inside body are reported
14
+
15
+ **Active Modules**
16
+ * Domino DB enumeration will now run on all requests
17
+
18
+ **Crawler Plugin**
19
+ * extended allowed/excluded URL checks on full url path /w query
20
+
21
+ News
22
+ ---
23
+ * Struts2 module for detecting CVE-2013-2251
24
+ * Struts2 module for detecting CVE-2013-1966
25
+ * conversation filter; added some shortcuts
26
+ * conversation table; added `send to->Crawler`
27
+ * client certificates; added PKCS12
28
+ * SAP passive module; extracts SAP headers, e.g. `sap-system`
29
+
1
30
  Version 0.9.14
2
31
  ===
3
32
  Fixes
@@ -5,6 +5,7 @@
5
5
  - application\/image
6
6
  - application\/pdf
7
7
  - application\/.*flash
8
+ - application\/octet-stream
8
9
  - image\/
9
10
  :content_length: 100000
10
11
  :port: 8081
@@ -92,10 +92,9 @@ module Watobo#:nodoc: all
92
92
  if id_string == '' then
93
93
  id_string = (Time.now.to_i + rand(10000)).to_s
94
94
  end
95
- puts id_string
96
95
  #
97
96
  new_details[:fid] = Digest::MD5.hexdigest(id_string)
98
- puts new_details[:fid]
97
+
99
98
  puts new_details[:fid] if $DEBUG
100
99
 
101
100
  new_details[:module] = self.class.to_s
@@ -0,0 +1,47 @@
1
+ # .
2
+ # client_cert_store.rb
3
+ #
4
+ # Copyright 2013 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
+ @private
23
+ module Watobo#:nodoc: all
24
+ module ClientCertStore#:nodoc: all
25
+ @client_certs = {}
26
+
27
+ # :ssl_client_cert
28
+ # :ssl_client_key
29
+ # :extra_chain_certs
30
+
31
+ def self.clear
32
+ @client_certs.clear
33
+ end
34
+
35
+ def self.set( site, cert )
36
+ return false if cert.nil?
37
+ @client_certs[ site.to_sym ] = cert
38
+ true
39
+ end
40
+
41
+ def self.get( site )
42
+ return nil unless @client_certs.has_key? site.to_sym
43
+ @client_certs[ site.to_sym ]
44
+ end
45
+
46
+ end
47
+ end
@@ -19,10 +19,10 @@
19
19
  # along with WATOBO; if not, write to the Free Software
20
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  # .
22
- # @private
22
+ # @private
23
23
  module Watobo#:nodoc: all
24
24
  class Scanner3
25
-
25
+
26
26
  include Watobo::Constants
27
27
  include Watobo::Subscriber
28
28
 
@@ -34,55 +34,58 @@ module Watobo#:nodoc: all
34
34
  class Worker
35
35
  include Watobo::Constants
36
36
  include Watobo::Subscriber
37
-
37
+
38
38
  attr :engine
39
-
39
+
40
40
  STATE_IDLE = 0x00
41
41
  STATE_RUNNING = 0x01
42
42
  STATE_WAIT_FOR_LOGIN = 0x02
43
-
44
43
  def state
45
44
  state = nil
46
- @state_mutex.synchronize do
45
+ @state_mutex.synchronize do
47
46
  state = @state
48
47
  end
49
48
  state
50
49
  end
51
-
50
+
52
51
  def run
53
52
  @state_mutex.synchronize do @state = STATE_RUNNING; end
54
53
  Thread.new{ @engine.run }
55
54
  end
56
-
55
+
57
56
  def start
58
- @engine = Thread.new(@tasks, @logged_out_queue, @prefs){ |tasks, logged_out_queue, prefs|
57
+ @engine = Thread.new(@prefs){ |prefs|
59
58
  relogin_count = 0
60
59
  loop do
61
- task = tasks.deq
60
+ Thread.current[:pos] = "wait for task"
61
+ task = @tasks.deq
62
62
  begin
63
63
  #puts "RUNNING #{task[:module]}"
64
64
  request, response = task[:check].call()
65
-
66
-
65
+
66
+ next if response.nil?
67
+
67
68
  unless prefs[:logout_signatures].empty? or prefs[:auto_login] == false
68
69
  logged_out = false
69
70
  prefs[:logout_signatures].each do |sig|
70
71
  logged_out = true if response.join =~ /#{sig}/
71
72
  end
72
-
73
- if logged_out
73
+
74
+ if logged_out
75
+ Thread.current[:pos] = "logged out"
74
76
  @state_mutex.synchronize do @state = STATE_WAIT_FOR_LOGIN; end
75
- logged_out_queue.push self
77
+ @logged_out_queue.push self
76
78
  # stop current thread, will be waked-up by scanner
77
79
  Thread.stop
78
80
  relogin_count += 1
81
+ Thread.current[:pos] = "set state"
79
82
  @state_mutex.synchronize do @state = STATE_RUNNING; end
80
83
  unless relogin_count > 5
81
84
  request, response = task[:check].call()
82
- end
85
+ end
83
86
  end
84
87
  end
85
-
88
+
86
89
  unless prefs[:scanlog_name].nil?
87
90
  chat = Chat.new(request, response, :id => 0, :chat_source => prefs[:chat_source])
88
91
  Watobo::DataStore.add_scan_log(chat, prefs[:scanlog_name])
@@ -93,6 +96,7 @@ module Watobo#:nodoc: all
93
96
  puts bang.backtrace if $DEBUG
94
97
  ensure
95
98
  #puts "FINISHED #{task[:module]}"
99
+ Thread.current[:pos] = "scan_finished"
96
100
  notify(:task_finished, task[:module])
97
101
  end
98
102
  Thread.exit if relogin_count > 5
@@ -102,10 +106,21 @@ module Watobo#:nodoc: all
102
106
  end
103
107
 
104
108
  def stop
105
- @state = STATE_IDLE
106
- Thread.kill @engine if @engine.alive?
109
+ @state_mutex.synchronize{ @state = STATE_IDLE }
110
+ begin
111
+ return false if @engine.nil?
112
+ if @engine.alive?
113
+ puts "[#{self}] got stopped"
114
+ Thread.kill @engine
115
+ end
116
+ @engine = nil
117
+ rescue => bang
118
+ puts "!!! could not stop worker !!!"
119
+ puts bang
120
+ puts bang.backtrace
121
+ end
107
122
  end
108
-
123
+
109
124
  def wait_for_login?
110
125
  state = false
111
126
  @state_mutex.synchronize do
@@ -113,7 +128,7 @@ module Watobo#:nodoc: all
113
128
  end
114
129
  state
115
130
  end
116
-
131
+
117
132
  def running?
118
133
  @state_mutex.synchronize do
119
134
  running = ( @state == STATE_RUNNING )
@@ -129,7 +144,7 @@ module Watobo#:nodoc: all
129
144
  @relogin_count = 0
130
145
  @state_mutex = Mutex.new
131
146
  @state = STATE_IDLE
132
-
147
+
133
148
  end
134
149
 
135
150
  end
@@ -139,42 +154,57 @@ module Watobo#:nodoc: all
139
154
  def tasks
140
155
  @tasks
141
156
  end
142
-
157
+
143
158
  def status_running?
144
159
  ( status & SCANNER_RUNNING ) > 0
145
160
  end
146
-
161
+
147
162
  def generation_finished?
148
163
  ( status & GENERATION_FINISHED ) > 0
149
164
  end
150
-
165
+
151
166
  def finished?
167
+ # puts "num_waiting: #{@tasks.num_waiting}"
168
+ # puts "workers: #{@workers.length}"
169
+ # puts "generation finished? #{generation_finished?.class}"
170
+ # puts "num tasks: #{@tasks.size}"
171
+ # puts "running workers: #{running_workers}"
152
172
  return true if (
153
- status_running? &&
154
- ( @tasks.num_waiting == @workers.length ) &&
155
- ( @tasks.size == 0 ) &&
156
- generation_finished?
157
- )
173
+ status_running? &&
174
+ ( @tasks.num_waiting == @workers.length ) &&
175
+ ( @tasks.size == 0 ) &&
176
+ generation_finished?
177
+ )
158
178
  false
159
179
  end
160
180
 
161
- def running?()
162
- return false if (
163
- status_running? &&
164
- ( @tasks.num_waiting == @workers.length ) &&
165
- ( @tasks.size == 0 ) &&
166
- generation_finished?
167
- )
168
- return true if status_running?
181
+ def running?()
182
+
183
+ return false if (
184
+ status_running? &&
185
+ ( @tasks.num_waiting == @workers.length ) &&
186
+ ( @tasks.size == 0 ) &&
187
+ generation_finished?
188
+ )
189
+ return true if status_running?
169
190
  return false
170
191
  end
171
192
 
172
193
  def stop()
194
+ print "\n[#{self}] stopping ... "
173
195
  begin
174
196
  @workers.each do |w|
175
197
  w.stop
176
198
  end
199
+ unless @ctrl_thread.nil?
200
+ if @ctrl_thread.alive?
201
+ puts "stop ctrl_thread"
202
+ Thread.kill @ctrl_thread
203
+ end
204
+ end
205
+ print "[OK]\n"
177
206
  rescue => bang
207
+ print "[OUTCH]\n"
178
208
  puts bang
179
209
  puts bang.backtrace if $DEBUG
180
210
  end
@@ -200,7 +230,7 @@ module Watobo#:nodoc: all
200
230
  YAML.load(YAML.dump(@task_counter))
201
231
  end
202
232
  end
203
-
233
+
204
234
  def sum_total
205
235
  sum = 0
206
236
  @task_count_lock.synchronize do
@@ -208,7 +238,7 @@ module Watobo#:nodoc: all
208
238
  end
209
239
  sum
210
240
  end
211
-
241
+
212
242
  def sum_progress
213
243
  sum = 0
214
244
  @task_count_lock.synchronize do
@@ -225,19 +255,28 @@ module Watobo#:nodoc: all
225
255
  @login_count = 0
226
256
  @max_login_count = 20
227
257
 
228
- Thread.new{
258
+ @ctrl_thread = Thread.new{
229
259
  size = -1
230
260
  loop do
231
261
  if @tasks.num_waiting == @workers.length and @tasks.size == 0 and generation_finished?
232
- @workers.map{|w| w.stop }
262
+ begin
263
+ puts "[#{self}] seems scan is finished. stopping workers now ..."
264
+ @workers.map{|w|
265
+ #puts "[]#{self}] stopping worker #{w}"
266
+ w.stop
267
+ }
233
268
  # suizide!
234
269
  Thread.exit
270
+ rescue => bang
271
+ puts bang
272
+ puts bang.backtrace
273
+ end
235
274
  end
236
-
275
+
237
276
  if @logged_out.size == ( @workers.length - @tasks.num_waiting) or @tasks.num_waiting == @workers.size
238
277
  @logged_out.clear
239
278
  #puts "!LOGOUT DETECTED!\n#{@logged_out.size} - #{@workers.length} - #{@tasks.num_waiting}\n\n"
240
- begin
279
+ begin
241
280
  puts "Run login ..."
242
281
  login
243
282
  @workers.each do |wrkr|
@@ -246,14 +285,14 @@ module Watobo#:nodoc: all
246
285
  wrkr.engine.run
247
286
  end
248
287
  end
249
-
288
+
250
289
  rescue => bang
251
290
  puts bang
252
291
  puts bang.backtrace
253
292
  end
254
-
293
+
255
294
  end
256
-
295
+
257
296
  sleep 1
258
297
  end
259
298
  }
@@ -262,32 +301,32 @@ module Watobo#:nodoc: all
262
301
  msg = "\n[Scanner] Starting Scan ..."
263
302
  notify(:logger, LOG_INFO, msg )
264
303
  puts msg
265
-
304
+
266
305
  # starting workers before check generation
267
306
  start_workers( @prefs)
268
307
  @max_tasks = 1000
269
-
308
+
270
309
  # start check generation in seperate thread
271
310
  Thread.new{
272
311
  begin
273
- set_status GENERATION_STARTED
274
- @chat_list.uniq.each do |chat|
275
- # puts chat.request.url.to_s
276
- @active_checks.uniq.each do |ac|
277
- ac.reset()
278
- if site_alive?(chat) then
279
- ac.generateChecks(chat){ |check|
280
- while @tasks.size > @max_tasks
281
- sleep 1
282
- end
283
- task = { :module => ac,
284
- :check => check
312
+ set_status GENERATION_STARTED
313
+ @chat_list.uniq.each do |chat|
314
+ # puts chat.request.url.to_s
315
+ @active_checks.uniq.each do |ac|
316
+ ac.reset()
317
+ if site_alive?(chat) then
318
+ ac.generateChecks(chat){ |check|
319
+ while @tasks.size > @max_tasks
320
+ sleep 1
321
+ end
322
+ task = { :module => ac,
323
+ :check => check
324
+ }
325
+ @tasks.push task
285
326
  }
286
- @tasks.push task
287
- }
327
+ end
288
328
  end
289
329
  end
290
- end
291
330
  rescue => bang
292
331
  puts bang
293
332
  puts bang.backtrace if $DEBUG
@@ -302,39 +341,36 @@ module Watobo#:nodoc: all
302
341
  @chat_list = chat_list
303
342
  @active_checks = []
304
343
  @passive_checks = passive_checks
305
-
344
+
306
345
  @tasks = Queue.new
307
346
  @logged_out = Queue.new
308
-
309
- @workers = []
310
347
 
311
-
348
+ @workers = []
312
349
 
313
350
  @status_lock = Mutex.new
314
351
 
315
352
  @task_count_lock = Mutex.new
316
353
  @task_counter = {}
354
+
355
+ @ctrl_thread = nil
317
356
 
318
357
  # @onlineCheck = OnlineCheck.new(@project)
319
358
  msg = "Initializing Scanner ..."
320
359
  notify(:logger, LOG_INFO, msg)
321
360
  puts msg
322
-
361
+
323
362
  @prefs = Watobo::Conf::Scanner.to_h
324
363
 
325
364
  @prefs.update prefs
326
- #puts "set up scanner"
327
- #puts @prefs[:login_chats]
328
- #puts @prefs[:logout_signatures]
329
- puts "= create scanner =" if $DEBUG
330
- puts @prefs.to_yaml
365
+
366
+ puts @prefs.to_yaml
331
367
 
332
368
  unique_checks = {}
333
369
  active_checks.each do |x|
334
370
  if x.respond_to? :new
335
- ac = x.new(self.object_id, @prefs)
371
+ ac = x.new(self.object_id, @prefs)
336
372
  else
337
- ac = x
373
+ ac = x
338
374
  end
339
375
  unique_checks[ac.class.to_s] = ac unless unique_checks.has_key?(ac.class.to_s)
340
376
  end
@@ -348,7 +384,7 @@ module Watobo#:nodoc: all
348
384
 
349
385
  check.resetCounters()
350
386
  @chat_list.each_with_index do |chat, index|
351
- #print "."
387
+ #print "."
352
388
  check.updateCounters(chat, @prefs)
353
389
  puts "* [#{index}] CheckCounter #{chat.id}: #{check.check_name} - #{check.numChecks}"
354
390
  end
@@ -361,7 +397,7 @@ module Watobo#:nodoc: all
361
397
  :progress => 0
362
398
  }
363
399
  end
364
- @status = SCANNER_READY
400
+ @status = SCANNER_READY
365
401
  msg = "Scanner Ready!"
366
402
  notify(:logger, LOG_INFO, msg)
367
403
  puts msg
@@ -388,7 +424,7 @@ module Watobo#:nodoc: all
388
424
 
389
425
  def start_workers(check_prefs)
390
426
  num_workers = @prefs.has_key?(:max_parallel_checks) ? @prefs[:max_parallel_checks] : Watobo::Conf::Scanner.max_parallel_checks
391
-
427
+
392
428
  puts "Starting #{num_workers} Workers ..."
393
429
 
394
430
  num_workers.times do |i|
@@ -401,26 +437,26 @@ module Watobo#:nodoc: all
401
437
  @task_counter[cn][:progress] += 1
402
438
  end
403
439
  }
404
-
440
+
405
441
  @logout_count ||= 0
406
442
  @logout_count_lock ||= Mutex.new
407
443
  @num_waiting = 0
408
-
444
+
409
445
  w.start
410
446
  @workers << w
411
447
  end
412
448
  print "\n"
413
449
 
414
450
  end
415
-
451
+
416
452
  def login
417
- puts "do relogin"
418
- login_chats = Watobo::Conf::Scanner.login_chat_ids.uniq.map{|id| Watobo::Chats.get_by_id(id) }
419
- # puts "running #{login_chats.length} login requests"
420
- # puts login_chats.first.class
421
-
453
+ puts "do relogin"
454
+ login_chats = Watobo::Conf::Scanner.login_chat_ids.uniq.map{|id| Watobo::Chats.get_by_id(id) }
455
+ # puts "running #{login_chats.length} login requests"
456
+ # puts login_chats.first.class
457
+
422
458
  @active_checks.first.runLogin(login_chats, @prefs)
423
-
459
+
424
460
  end
425
461
 
426
462
  def site_alive?(chat)