watobo 0.9.13 → 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ Version 0.9.14
2
+ ===
3
+ Fixes
4
+ ---
5
+ **Manual Request Editor**
6
+
7
+ * fixed crash when clicking OTT-Settings
8
+
9
+ **Crawler**
10
+
11
+ * watobo stopped working when crawler was started (Linux only) - workaround
12
+
1
13
  Version 0.9.13
2
14
  ===
3
15
  News
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  WATOBO - THE Web Application Toolbox
2
2
  ===
3
- WATOBO is a security tool for web applications. It is intended to enable security professionals to perform efficient (semi-automated) web application security audits.
3
+ WATOBO is a security tool for testing web applications. It is intended to enable security professionals to perform efficient (semi-automated) web application security audits.
4
4
 
5
5
  Most important features:
6
6
 
@@ -83,6 +83,7 @@ module Watobo#:nodoc: all
83
83
  AUTH_TYPE_BASIC = 0x01
84
84
  AUTH_TYPE_DIGEST = 0x02
85
85
  AUTH_TYPE_NTLM = 0x04
86
+ AUTH_TYPE_UNKNOWN = 0x10
86
87
 
87
88
  GUI_SMALL_FONT_SIZE = 7
88
89
  GUI_REGULAR_FONT_SIZE = 9
@@ -85,8 +85,6 @@ module Watobo#:nodoc: all
85
85
  def initialize(request, response, prefs = {})
86
86
 
87
87
  begin
88
- super(request, response)
89
-
90
88
  @settings = {
91
89
  :source => CHAT_SOURCE_UNDEF,
92
90
  :id => -1,
@@ -95,6 +93,10 @@ module Watobo#:nodoc: all
95
93
  :comment => '',
96
94
  :tested => false
97
95
  }
96
+
97
+ super(request, response)
98
+
99
+
98
100
 
99
101
  @settings.update prefs
100
102
  # puts @settings[:id].to_s
@@ -19,35 +19,49 @@
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
-
25
-
26
- #Set-Cookie: mycookie=b41dc9e55d6163f78321996b10c940edcec1b4e55a76464c4e9d25e160ac0ec5b769806b; path=/; secure
27
24
 
25
+ #Set-Cookie: mycookie=b41dc9e55d6163f78321996b10c940edcec1b4e55a76464c4e9d25e160ac0ec5b769806b; path=/; secure
28
26
  class Cookie < Parameter
29
-
27
+
30
28
  attr :name
31
29
  attr :value
32
30
  attr :path
33
31
  attr :secure
34
32
  attr :http_only
35
-
36
33
  def name_value
37
- "#{@name}=#{@value}"
34
+ "#{@name}=#{@value}"
38
35
  end
39
-
40
- def initialize(prefs)
41
- @secure = prefs.has_key?(:secure) ? prefs[:secure] : false
42
- @http_only = prefs.has_key?(:http_only) ? prefs[:http_only] : false
43
- @location = :cookie
36
+
37
+ def initialize(cookie_prefs)
38
+ @secure = false
39
+ @http_only = false
44
40
 
45
- if prefs.is_a? Hash
46
- #TODO: create cookie with hash-settings
41
+ if cookie_prefs.respond_to? :has_key?
42
+ @secure = prefs.has_key?(:secure) ? prefs[:secure] : false
43
+ @http_only = prefs.has_key?(:http_only) ? prefs[:http_only] : false
44
+ @location = :cookie
45
+ @path = prefs[:path]
46
+ @name = prefs[:name]
47
+ @value = prefs[:value]
47
48
  else
48
- raise ArgumentError, "Need hash (:name, :value, ...) or string (Set-Cookie:...)"
49
+ chunks = cookie_prefs.split(";")
50
+ # first chunk
51
+ @name, @value = chunks.first.split(":").last.split("=")
52
+
53
+ m = cookie_prefs.match(/path=([^;]*)/)
54
+ @path = m.nil? ? "" : m[1].strip
55
+ @secure = true if chunks.select{|c| c =~ /Secure/i }
56
+ @http_only = true if chunks.select{|c| c =~ /HttpOnly/i }
49
57
  end
58
+
59
+ #if prefs.is_a? Hash
60
+ # #TODO: create cookie with hash-settings
61
+ # else
62
+ # raise ArgumentError, "Need hash (:name, :value, ...) or string (Set-Cookie:...)"
63
+ #end
50
64
  end
51
-
65
+
52
66
  end
53
67
  end
@@ -40,8 +40,8 @@ module Watobo#:nodoc: all
40
40
  test_module.do_test(chat)
41
41
  rescue => bang
42
42
  puts bang
43
- puts bang.backtrace if $DEBUG
44
- return false
43
+ puts bang.backtrace #if $DEBUG
44
+ #return false
45
45
  end
46
46
  end
47
47
  end
@@ -51,7 +51,7 @@ module Watobo#:nodoc: all
51
51
  end
52
52
 
53
53
  def copy
54
- c = YAML.load(YAML.dump(self))
54
+ c = Watobo::Utils.copyObject self
55
55
  Watobo::Request.new c
56
56
  end
57
57
 
@@ -46,7 +46,7 @@ module Watobo#:nodoc: all
46
46
  end
47
47
 
48
48
  def copy
49
- c = YAML.load(YAML.dump(self))
49
+ c = Watobo::Utils.copyObject self
50
50
  Watobo::Request.new c
51
51
  end
52
52
 
@@ -170,7 +170,11 @@ module Watobo#:nodoc: all
170
170
  # timeout(6) do
171
171
  #puts "* no proxy - direct connection"
172
172
  tcp_socket = TCPSocket.new( host, port )
173
- tcp_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
173
+ optval = [1, 5000].pack("I_2")
174
+ tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
175
+ tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
176
+ tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
177
+ tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1
174
178
  tcp_socket.sync = true
175
179
 
176
180
  socket = tcp_socket
@@ -214,17 +218,19 @@ module Watobo#:nodoc: all
214
218
  unless request.has_body?
215
219
  data << "\r\n" unless data =~ /\r\n\r\n$/
216
220
  end
217
- # puts "= SESSION ="
218
- # puts data
219
- # puts data.unpack("H*")[0].gsub(/0d0a/,"0d0a\n")
221
+ # puts "= SESSION ="
222
+ # puts data
223
+ # puts data.unpack("H*")[0]#.gsub(/0d0a/,"0d0a\n")
220
224
 
221
225
  unless socket.nil?
222
226
  socket.print data
223
- # if socket.is_a? OpenSSL::SSL::SSLSocket
224
- # socket.io.shutdown(Socket::SHUT_WR)
225
- # else
226
- # socket.shutdown(Socket::SHUT_WR)
227
- # end
227
+ socket.flush
228
+ # tell finished sending data
229
+ if socket.is_a? OpenSSL::SSL::SSLSocket
230
+ socket.io.shutdown(Socket::SHUT_WR)
231
+ else
232
+ socket.shutdown(Socket::SHUT_WR)
233
+ end
228
234
  response_header = readHTTPHeader(socket, current_prefs)
229
235
  end
230
236
  # RESTORE URI FOR HISTORY/LOG
@@ -211,12 +211,13 @@ module Watobo#:nodoc: all
211
211
  end
212
212
 
213
213
  def addChat(chat, *prefs)
214
+ return false if chat.nil?
214
215
  if self.getNumRows <= 0 then
215
216
  clearConversation()
216
217
  # initColumns()
217
218
  end
218
219
 
219
- @current_chat_list.push chat unless chat.nil?
220
+ @current_chat_list.push chat
220
221
  if prefs.include? :ignore_filter
221
222
  add_chat_row(chat)
222
223
  return true
@@ -379,6 +380,10 @@ module Watobo#:nodoc: all
379
380
 
380
381
  def add_chat_row(chat)
381
382
  return false unless chat.respond_to? :request
383
+ return false unless chat.respond_to? :response
384
+ return false if chat.request.nil?
385
+ return false if chat.response.nil?
386
+
382
387
  lastRowIndex = self.getNumRows
383
388
  self.appendRows(1)
384
389
 
@@ -240,7 +240,7 @@ module Watobo#:nodoc: all
240
240
  sunken = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN, :padding => 0)
241
241
  @response_viewer = SidPreview.new(sunken, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
242
242
 
243
- Watobo::Conf::Scanner.csrf_patterns.each do |p|
243
+ Watobo::Conf::OttCache.patterns.each do |p|
244
244
  item = @pattern_list.appendItem("#{p}")
245
245
  @pattern_list.setItemData(item, p)
246
246
  end
@@ -93,6 +93,18 @@ module Watobo#:nodoc: all
93
93
 
94
94
  end
95
95
 
96
+ @msg_lock.synchronize do
97
+ while @msg_queue.length > 0
98
+ msg = @msg_queue.shift
99
+ case msg
100
+ when :modal_finished
101
+ puts "stopping modal ..."
102
+ getApp.stopModal
103
+ puts "modal stopped"
104
+ end
105
+ end
106
+ end
107
+
96
108
  }
97
109
  end
98
110
 
@@ -766,7 +778,9 @@ module Watobo#:nodoc: all
766
778
 
767
779
 
768
780
  Watobo::Gui.clear_plugins
781
+ print "* load plugins ..."
769
782
  Watobo::Gui::Utils.load_plugins(@project)
783
+ print "[OK]\n"
770
784
 
771
785
  @sites_tree.project = @project
772
786
  @findings_tree.project = @project
@@ -780,7 +794,10 @@ module Watobo#:nodoc: all
780
794
  puts "!!! Could not create project :("
781
795
  ensure
782
796
  puts "* stop modal mode" if $DEBUG
783
- getApp.stopModal
797
+ @msg_lock.synchronize do
798
+ #getApp.stopModal
799
+ @msg_queue << :modal_finished
800
+ end
784
801
 
785
802
  end
786
803
 
@@ -1165,9 +1182,11 @@ module Watobo#:nodoc: all
1165
1182
  @finding_lock = Mutex.new
1166
1183
  @chat_lock = Mutex.new
1167
1184
  @status_lock = Mutex.new
1185
+ @msg_lock = Mutex.new
1168
1186
 
1169
1187
  @finding_queue = []
1170
1188
  @chat_queue = []
1189
+ @msg_queue = []
1171
1190
 
1172
1191
  # setup clipboard
1173
1192
  @clipboard_text = ""
@@ -42,11 +42,10 @@ module Watobo#:nodoc: all
42
42
  if order.empty?
43
43
  libs = Dir.glob("#{lpath}/*")
44
44
  else
45
- libs = order
45
+ libs = order.map{|l| l.to_s + ".rb" }
46
46
  end
47
47
  libs.each do |lib|
48
- puts "> #{lib.to_s}"
49
- require File.join(lib.to_s)
48
+ load File.join(lib)
50
49
  end
51
50
  end
52
51
 
@@ -74,11 +73,11 @@ module Watobo#:nodoc: all
74
73
  if order.empty?
75
74
  libs = Dir.glob("#{gui_path}/*")
76
75
  else
77
- libs = order
76
+ libs = order.map{|l| l.to_s + ".rb" }
78
77
  end
79
78
  libs.each do |lib|
80
79
  puts "loading gui-lib #{lib} ..."
81
- require File.join(gui_path, lib.to_s)
80
+ load File.join(gui_path, lib)
82
81
  end
83
82
  else
84
83
  puts "WATOBO NOT IN GUI MODE!"
@@ -44,8 +44,11 @@ module Watobo#:nodoc: all
44
44
  if text.is_a?(Request) or text.is_a?(Response)
45
45
  dummy = []
46
46
  text.each do |line|
47
- chunk = line.gsub(/\r/,'').strip
48
- dummy.push chunk.gsub("\x00","")
47
+ clean = line.unpack("C*").pack("C*")
48
+ clean.gsub!(/\r/,'')
49
+ clean.strip!
50
+ clean.gsub!("\x00","")
51
+ dummy << clean
49
52
  end
50
53
  return dummy.join("\n")
51
54
  elsif text.is_a? String
@@ -55,7 +55,7 @@ module Watobo#:nodoc: all
55
55
  puts
56
56
  puts ">> ClassName: #{class_name}"
57
57
  puts
58
- require pgf
58
+ load pgf
59
59
  class_constant = Watobo.class_eval(class_name)
60
60
 
61
61
  Watobo::Gui.add_plugin class_constant.new(Watobo::Gui.application, project)
@@ -64,7 +64,7 @@ module Watobo#:nodoc: all
64
64
  Dir["#{sub}/#{File.basename(sub)}.rb"].each do |plugin_file|
65
65
  begin
66
66
  puts "* processing plugin file #{plugin_file}" if $DEBUG
67
- require plugin_file
67
+ load plugin_file
68
68
  group = File.basename(sub)
69
69
  plugin = File.basename(plugin_file).sub(/\.rb/,'')
70
70
  # load "#{@settings[:module_path]}/#{modules}/#{check}"
@@ -86,7 +86,7 @@ module Watobo#:nodoc: all
86
86
  Dir["#{sub}/gui/#{File.basename(sub)}.rb"].each do |plugin_file|
87
87
  begin
88
88
  puts "* processing plugin file #{plugin_file}" if $DEBUG
89
- require plugin_file
89
+ load plugin_file
90
90
  group = File.basename(sub)
91
91
  plugin = File.basename(plugin_file).sub(/\.rb/,'')
92
92
  # load "#{@settings[:module_path]}/#{modules}/#{check}"
@@ -32,6 +32,11 @@ module Watobo#:nodoc: all
32
32
 
33
33
  def write(data)
34
34
  @socket.write data
35
+ @socket.flush
36
+ end
37
+
38
+ def flush
39
+ @socket.flush
35
40
  end
36
41
 
37
42
  def close
@@ -39,11 +44,13 @@ module Watobo#:nodoc: all
39
44
  #if socket.class.to_s =~ /SSLSocket/
40
45
  if @socket.respond_to? :sysclose
41
46
  #socket.io.shutdown(2)
42
- @socket.sysclose
43
- elsif @socket.respond_to? :shutdown
44
- @socket.shutdown(2)
45
- elsif @socket.respond_to? :close
46
- @socket.close
47
+ @socket.sysclose
48
+ elsif @socket.respond_to? :shutdown
49
+ @socket.shutdown(Socket::SHUT_RDWR)
50
+ end
51
+ # finally close it
52
+ if @socket.respond_to? :close
53
+ @socket.close
47
54
  end
48
55
  return true
49
56
  rescue => bang
@@ -55,7 +62,7 @@ module Watobo#:nodoc: all
55
62
 
56
63
  def read_header
57
64
  request = []
58
- Watobo::HTTPSocket.read_header(@socket) do |line|
65
+ Watobo::HTTPSocket.read_client_header(@socket) do |line|
59
66
  request << line
60
67
  end
61
68
 
@@ -75,13 +82,12 @@ module Watobo#:nodoc: all
75
82
  begin
76
83
  unless @initial_request.nil?
77
84
  request = @initial_request.copy
78
- puts request
79
85
  @initial_request = nil
80
86
  return request
81
87
  end
82
-
88
+
83
89
  request = read_header
84
- puts request
90
+
85
91
  return nil if request.nil?
86
92
 
87
93
  clen = request.content_length
@@ -121,6 +127,13 @@ module Watobo#:nodoc: all
121
127
  ra = socket.remote_address
122
128
  cport = ra.ip_port
123
129
  caddr = ra.ip_address
130
+
131
+ optval = [1, 500_000].pack("I_2")
132
+ socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
133
+ socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
134
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
135
+ socket.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1
136
+ socket.sync = true
124
137
 
125
138
  session = socket
126
139
 
@@ -134,7 +147,7 @@ module Watobo#:nodoc: all
134
147
 
135
148
  begin
136
149
  ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
137
- ssl_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
150
+ #ssl_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
138
151
  # ssl_socket.sync_close = true
139
152
  ssl_socket.sync = true
140
153
  # puts ssl_socket.methods.sort
@@ -245,7 +258,7 @@ module Watobo#:nodoc: all
245
258
  session = ssl_session
246
259
  request = nil
247
260
  else
248
- puts "* create request object"
261
+ # puts "* create request object"
249
262
  request = Watobo::Request.new(request)
250
263
  site = request.site
251
264
  #puts request
@@ -22,6 +22,31 @@
22
22
  # @private
23
23
  module Watobo#:nodoc: all
24
24
  module HTTPSocket
25
+
26
+ def self.close(socket)
27
+ def close
28
+ begin
29
+ #if socket.class.to_s =~ /SSLSocket/
30
+ if socket.respond_to? :sysclose
31
+ #socket.io.shutdown(2)
32
+ socket.sysclose
33
+ elsif @socket.respond_to? :shutdown
34
+ puts "SHUTDOWN"
35
+ socket.shutdown(Socket::SHUT_RDWR)
36
+ end
37
+ # finally close it
38
+ if socket.respond_to? :close
39
+ socket.close
40
+ end
41
+ return true
42
+ rescue => bang
43
+ puts bang
44
+ puts bang.backtrace if $DEBUG
45
+ end
46
+ false
47
+ end
48
+ end
49
+
25
50
  def self.siteAlive?(chat)
26
51
  #puts chat.class
27
52
  site = nil
@@ -267,6 +292,48 @@ module Watobo#:nodoc: all
267
292
  return if buf.strip.empty?
268
293
  end
269
294
  end
295
+
296
+ def self.read_client_header(socket)
297
+ buf = ''
298
+
299
+ while true
300
+ begin
301
+ #Timeout::timeout(1.5) do
302
+ buf = socket.gets
303
+ #end
304
+ rescue EOFError => e
305
+ puts "EOFError: #{e}"
306
+ #puts "!!! EOF: reading header"
307
+ # buf = nil
308
+ return true
309
+ rescue Errno::ECONNRESET => e
310
+ puts "ECONNRESET: #{e}"
311
+ #puts "!!! CONNECTION RESET: reading header"
312
+ #buf = nil
313
+ #return
314
+ #raise
315
+ return false
316
+ rescue Errno::ECONNABORTED => e
317
+ puts "ECONNABORTED: #{e}"
318
+ #raise
319
+ return false
320
+ rescue Timeout::Error => e
321
+ puts "TIMEOUT: #{e}"
322
+ return false
323
+ rescue => bang
324
+ # puts "!!! READING HEADER:"
325
+ # puts buf
326
+ puts bang
327
+ puts bang.backtrace
328
+ raise
329
+ end
330
+
331
+ return false if buf.nil?
332
+
333
+ yield buf if block_given?
334
+ return if buf.strip.empty?
335
+ end
336
+ end
270
337
 
271
338
  end
272
339
  end