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 +12 -0
- data/README.md +1 -1
- data/lib/watobo/constants.rb +1 -0
- data/lib/watobo/core/chat.rb +4 -2
- data/lib/watobo/core/cookie.rb +30 -16
- data/lib/watobo/core/passive_scanner.rb +2 -2
- data/lib/watobo/core/request.rb +1 -1
- data/lib/watobo/core/response.rb +1 -1
- data/lib/watobo/core/session.rb +15 -9
- data/lib/watobo/gui/conversation_table.rb +6 -1
- data/lib/watobo/gui/csrf_token_dialog.rb +1 -1
- data/lib/watobo/gui/main_window.rb +20 -1
- data/lib/watobo/gui/templates/plugin_base.rb +4 -5
- data/lib/watobo/gui/utils/gui_utils.rb +5 -2
- data/lib/watobo/gui/utils/load_plugins.rb +3 -3
- data/lib/watobo/http_socket/client_socket.rb +24 -11
- data/lib/watobo/http_socket/http_socket.rb +67 -0
- data/lib/watobo/interceptor/proxy.rb +102 -104
- data/lib/watobo/mixins/httpparser.rb +16 -17
- data/lib/watobo/mixins/shapers.rb +6 -4
- data/lib/watobo.rb +5 -1
- data/modules/passive/possible_login.rb +2 -5
- data/plugins/crawler/crawler.rb +1 -56
- data/plugins/crawler/gui/crawler_gui.rb +4 -5
- data/plugins/crawler/gui.rb +2 -90
- data/plugins/crawler/lib/engine.rb +6 -3
- data/plugins/crawler/lib/grabber.rb +4 -1
- data/plugins/sqlmap/bin/test.rb +2 -1
- data/plugins/sqlmap/gui.rb +2 -3
- data/plugins/sqlmap/sqlmap.rb +1 -3
- data/plugins/sslchecker/gui/sslchecker.rb +4 -4
- metadata +2 -4
- data/lib/watobo/http_socket/proxy.rb +0 -31
- data/modules/active/RoR/cve_2013_015x.rb +0 -21
data/CHANGELOG.md
CHANGED
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
|
|
data/lib/watobo/constants.rb
CHANGED
data/lib/watobo/core/chat.rb
CHANGED
@@ -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
|
data/lib/watobo/core/cookie.rb
CHANGED
@@ -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
|
-
|
34
|
+
"#{@name}=#{@value}"
|
38
35
|
end
|
39
|
-
|
40
|
-
def initialize(
|
41
|
-
@secure =
|
42
|
-
@http_only =
|
43
|
-
@location = :cookie
|
36
|
+
|
37
|
+
def initialize(cookie_prefs)
|
38
|
+
@secure = false
|
39
|
+
@http_only = false
|
44
40
|
|
45
|
-
if
|
46
|
-
|
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
|
-
|
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
|
data/lib/watobo/core/request.rb
CHANGED
data/lib/watobo/core/response.rb
CHANGED
data/lib/watobo/core/session.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
218
|
-
|
219
|
-
|
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
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
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
|
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::
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
48
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
43
|
-
elsif @socket.respond_to? :shutdown
|
44
|
-
|
45
|
-
|
46
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|