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