watobo 0.9.13 → 0.9.14

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/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