watobo 0.9.20 → 0.9.21
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 +54 -2
- data/README.md +1 -1
- data/config/scanner.yml +1 -0
- data/custom-views/prettify-json.rb +19 -0
- data/lib/watobo/adapters/file/marshal_store.rb +297 -0
- data/lib/watobo/adapters.rb +2 -1
- data/lib/watobo/core/active_check.rb +4 -0
- data/lib/watobo/core/chat.rb +8 -0
- data/lib/watobo/core/chats.rb +2 -1
- data/lib/watobo/core/cookie.rb +3 -3
- data/lib/watobo/core/finding.rb +7 -0
- data/lib/watobo/core/request.rb +3 -3
- data/lib/watobo/core/session.rb +6 -2
- data/lib/watobo/framework/init_modules.rb +18 -16
- data/lib/watobo/gui/conversation_table.rb +13 -16
- data/lib/watobo/gui/conversation_table_ctrl2.rb +1 -0
- data/lib/watobo/gui/custom_viewer.rb +101 -76
- data/lib/watobo/gui/define_scope_frame.rb +44 -10
- data/lib/watobo/gui/edit_scope_dialog.rb +1 -1
- data/lib/watobo/gui/fuzzer_gui.rb +61 -23
- data/lib/watobo/gui/main_window.rb +1 -1
- data/lib/watobo/gui/scanner_settings_dialog.rb +15 -0
- data/lib/watobo/http/data/json.rb +6 -0
- data/lib/watobo/interceptor/html/favicon.ico +0 -0
- data/lib/watobo/interceptor/html/index.html +13 -0
- data/lib/watobo/interceptor/proxy.rb +70 -18
- data/lib/watobo/mixins/httpparser.rb +26 -16
- data/lib/watobo/mixins/shapers.rb +49 -5
- data/lib/watobo/mixins/transcoders.rb +8 -8
- data/lib/watobo/sockets/connection.rb +1 -1
- data/lib/watobo/utils/load_chat.rb +62 -0
- data/lib/watobo/utils/response_hash.rb +3 -3
- data/lib/watobo.rb +1 -1
- data/modules/active/cq5/cq5_default_selectors.rb +116 -0
- data/modules/active/cq5/cqp_user_enumeration.rb +134 -0
- data/modules/active/struts2/include_params_ognl.rb +1 -1
- data/modules/active/xml/xml_xxe.rb +6 -1
- data/modules/passive/disclosure_domino.rb +1 -1
- data/modules/passive/in_script_parameter.rb +9 -4
- data/plugins/aem/aem.rb +21 -0
- data/plugins/aem/gui/main.rb +128 -0
- data/plugins/aem/gui/tree_view.rb +180 -0
- data/plugins/aem/icons/aem.ico +0 -0
- data/plugins/aem/lib/agent.rb +140 -0
- data/plugins/aem/lib/dispatcher.rb +53 -0
- data/plugins/aem/lib/engine.rb +187 -0
- data/plugins/filefinder/dbs/cq5.db +23 -0
- data/plugins/filefinder/dbs/subs-big.lst +44 -44
- data/plugins/filefinder/filefinder.rb +4 -4
- data/plugins/sqlmap/lib/sqlmap_ctrl.rb +11 -10
- metadata +16 -2
|
@@ -18,7 +18,12 @@ module Watobo#:nodoc: all
|
|
|
18
18
|
# if the result is the same, chances are good that XXE attacks will work
|
|
19
19
|
#
|
|
20
20
|
# Links:
|
|
21
|
-
# http://www.w3.org/TR/2004/REC-xml-20040204/#sec-external-ent
|
|
21
|
+
# http://www.w3.org/TR/2004/REC-xml-20040204/#sec-external-ent
|
|
22
|
+
|
|
23
|
+
# Exploitation notes:
|
|
24
|
+
# https://www.christian-schneider.net/GenericXxeDetection.html
|
|
25
|
+
# <!ENTITY % three SYSTEM "file:///etc/passwd">
|
|
26
|
+
# <!ENTITY % two "<!ENTITY % four SYSTEM 'file:///%three;'>">
|
|
22
27
|
|
|
23
28
|
@info.update(
|
|
24
29
|
:check_name => 'XML-XXE', # name of check which briefly describes functionality, will be used for tree and progress views
|
|
@@ -35,9 +35,11 @@ module Watobo#:nodoc: all
|
|
|
35
35
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
def showError(
|
|
39
|
-
puts "!!! Error #{Module.nesting[0].name}"
|
|
40
|
-
puts "Chat: [#{
|
|
38
|
+
def showError(chat, message)
|
|
39
|
+
puts "!!! Error in module #{Module.nesting[0].name}"
|
|
40
|
+
puts "Chat: [#{chat.id}]"
|
|
41
|
+
puts "URL: #{chat.request.url}"
|
|
42
|
+
puts "-- Error --"
|
|
41
43
|
puts message
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -78,7 +80,10 @@ module Watobo#:nodoc: all
|
|
|
78
80
|
end
|
|
79
81
|
rescue => bang
|
|
80
82
|
# raise
|
|
81
|
-
|
|
83
|
+
|
|
84
|
+
showError(chat, bang)
|
|
85
|
+
puts bang
|
|
86
|
+
puts "-- trace --"
|
|
82
87
|
puts bang.backtrace
|
|
83
88
|
|
|
84
89
|
end
|
data/plugins/aem/aem.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#.
|
|
2
|
+
# aem.rb
|
|
3
|
+
#.
|
|
4
|
+
# Copyright 2014 by siberas, http://www.siberas.de
|
|
5
|
+
# This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
|
|
6
|
+
# WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
|
|
7
|
+
# WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
8
|
+
# You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
9
|
+
|
|
10
|
+
# @private
|
|
11
|
+
module Watobo#:nodoc: all::Plugin
|
|
12
|
+
module Plugin
|
|
13
|
+
class AEM < Watobo::PluginBase
|
|
14
|
+
plugin_name "AEM"
|
|
15
|
+
description "Adobe Experience Manager Enumerator"
|
|
16
|
+
load_libs
|
|
17
|
+
load_gui :main, :tree_view
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#.
|
|
2
|
+
# main.rb
|
|
3
|
+
#.
|
|
4
|
+
# Copyright 2014 by siberas, http://www.siberas.de
|
|
5
|
+
# This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
|
|
6
|
+
# WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
|
|
7
|
+
# WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
8
|
+
# You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
9
|
+
|
|
10
|
+
# @private
|
|
11
|
+
module Watobo#:nodoc: all
|
|
12
|
+
module Plugin
|
|
13
|
+
class AEM
|
|
14
|
+
class Gui < Watobo::PluginGui
|
|
15
|
+
|
|
16
|
+
window_title "Adobe Experience Manager Enumerator"
|
|
17
|
+
icon_file "aem.ico"
|
|
18
|
+
def start
|
|
19
|
+
@results = []
|
|
20
|
+
@tree_view.clear
|
|
21
|
+
@tree_view.set_base_dir @url.text
|
|
22
|
+
Watobo::Plugin::CQ5.reset
|
|
23
|
+
# Watobo::Plugin::CQ5.use_relative_path = @relative_path_cb.checked?
|
|
24
|
+
Watobo::Plugin::CQ5.ignore_patterns = @ignore_cb.checked? ? @ignore_patterns_list.to_a : []
|
|
25
|
+
Watobo::Plugin::CQ5.run( @url.text , @results_queue)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def stop
|
|
29
|
+
Watobo::Plugin::CQ5.stop
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def initialize()
|
|
33
|
+
@results = []
|
|
34
|
+
@export_path = Watobo.workspace_path
|
|
35
|
+
@results_queue = Queue.new
|
|
36
|
+
|
|
37
|
+
super()
|
|
38
|
+
|
|
39
|
+
main_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
|
40
|
+
|
|
41
|
+
url_frame = FXHorizontalFrame.new(main_frame, :opts => LAYOUT_FILL_X)
|
|
42
|
+
@url = FXTextField.new(url_frame, 25, nil, 0, :opts => TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_LEFT)
|
|
43
|
+
|
|
44
|
+
@url.setFocus()
|
|
45
|
+
@url.setDefault()
|
|
46
|
+
|
|
47
|
+
@start_btn = FXButton.new(url_frame, "start")
|
|
48
|
+
|
|
49
|
+
@url.connect(SEL_COMMAND){ start }
|
|
50
|
+
@start_btn.connect(SEL_COMMAND){ start }
|
|
51
|
+
|
|
52
|
+
@stop_btn = FXButton.new(url_frame, "stop")
|
|
53
|
+
@stop_btn.connect(SEL_COMMAND){ stop }
|
|
54
|
+
|
|
55
|
+
splitter = FXSplitter.new(main_frame, LAYOUT_FILL_X|SPLITTER_HORIZONTAL|LAYOUT_FILL_Y|SPLITTER_TRACKING)
|
|
56
|
+
opts_frame = FXVerticalFrame.new(splitter, :opts => LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_WIDTH, :width => 450)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
gbframe = FXGroupBox.new(opts_frame, "Ignore Path Patterns", FRAME_GROOVE|LAYOUT_FILL_Y, 0, 0, 0, 0)
|
|
60
|
+
iframe = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
|
61
|
+
@ignore_cb = FXCheckButton.new(iframe, "enable", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
|
|
62
|
+
@ignore_cb.checkState = true
|
|
63
|
+
|
|
64
|
+
@invert_cb = FXCheckButton.new(iframe, "invert", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
|
|
65
|
+
@invert_cb.checkState = false
|
|
66
|
+
@invert_cb.disable
|
|
67
|
+
|
|
68
|
+
FXLabel.new(iframe, "Ignore if url matches one of the following patterns (regex):")
|
|
69
|
+
@ignore_patterns_list = Watobo::Gui::ListBox.new(iframe)
|
|
70
|
+
@ignore_patterns_list.set %w( replication\/data jcr.*versionstorage workflow\/instances audit\/com.day.cq.replication\/content )
|
|
71
|
+
#@scope_only_cb.connect(SEL_COMMAND) { }
|
|
72
|
+
|
|
73
|
+
#mr_splitter = FXSplitter.new(main_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_HORIZONTAL|SPLITTER_REVERSED|SPLITTER_TRACKING)
|
|
74
|
+
# top = FXHorizontalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_SIDE_BOTTOM)
|
|
75
|
+
top_frame = FXVerticalFrame.new(splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_HEIGHT|FRAME_SUNKEN,:height => 500)
|
|
76
|
+
@tree_view = TreeView.new top_frame
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
frame = FXHorizontalFrame.new(main_frame, :opts => LAYOUT_FILL_X)
|
|
80
|
+
@counter = FXLabel.new(frame, "")
|
|
81
|
+
@queue_size = FXLabel.new(frame, "")
|
|
82
|
+
update_counter
|
|
83
|
+
|
|
84
|
+
@tree_view.subscribe(:show_info){|item|
|
|
85
|
+
puts "Item clicked"
|
|
86
|
+
puts item[:url]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@save_btn = FXButton.new(frame, "save", :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
|
|
90
|
+
@save_btn.connect(SEL_COMMAND){ save_results }
|
|
91
|
+
|
|
92
|
+
update_timer(500){
|
|
93
|
+
max = 100
|
|
94
|
+
count = 0
|
|
95
|
+
while @results_queue.size > 0 and count < max
|
|
96
|
+
r = @results_queue.deq
|
|
97
|
+
@results << r
|
|
98
|
+
#puts @results.length
|
|
99
|
+
@tree_view.add r
|
|
100
|
+
count += 1
|
|
101
|
+
end
|
|
102
|
+
update_counter
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def update_counter
|
|
109
|
+
@counter.text = "Total: #{@results.length}"
|
|
110
|
+
@queue_size.text = "Queue: #{Watobo::Plugin::CQ5.queue_size}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def save_results
|
|
114
|
+
fname = "cq5_" + Time.now.to_i.to_s + ".json"
|
|
115
|
+
dst_file = File.join(@export_path, fname)
|
|
116
|
+
filename = FXFileDialog.getSaveFilename(self, "Select Export File", dst_file)
|
|
117
|
+
if filename != "" then
|
|
118
|
+
@export_path = File.dirname filename
|
|
119
|
+
Thread.new(filename){|fn|
|
|
120
|
+
File.open(fn,"wb"){|fh| fh.print JSON.pretty_generate(@results) }
|
|
121
|
+
}
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#.
|
|
2
|
+
# tree_view.rb
|
|
3
|
+
#.
|
|
4
|
+
# Copyright 2014 by siberas, http://www.siberas.de
|
|
5
|
+
# This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
|
|
6
|
+
# WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
|
|
7
|
+
# WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
8
|
+
# You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
9
|
+
|
|
10
|
+
#require 'qcustomize.rb'
|
|
11
|
+
|
|
12
|
+
# @private
|
|
13
|
+
module Watobo#:nodoc: all
|
|
14
|
+
module Plugin
|
|
15
|
+
class AEM
|
|
16
|
+
class Gui
|
|
17
|
+
class TreeView < FXTreeList
|
|
18
|
+
|
|
19
|
+
include Watobo::Constants
|
|
20
|
+
include Watobo::Gui::Icons
|
|
21
|
+
|
|
22
|
+
def subscribe(event, &callback)
|
|
23
|
+
(@event_dispatcher_listeners[event] ||= []) << callback
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def clear()
|
|
27
|
+
@results = []
|
|
28
|
+
self.clearItems
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#def refresh_tree()
|
|
32
|
+
# self.clearItems
|
|
33
|
+
|
|
34
|
+
#Watobo::Chats.each do |chat|
|
|
35
|
+
# addChat(chat)
|
|
36
|
+
#end
|
|
37
|
+
|
|
38
|
+
# @interface.updateRequestTable(@project)
|
|
39
|
+
#end
|
|
40
|
+
|
|
41
|
+
def expandFullTree(item)
|
|
42
|
+
self.expandTree(item)
|
|
43
|
+
item.each do |c|
|
|
44
|
+
expandFullTree(c) if !self.itemLeaf?(c)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def collapseFullTree(item)
|
|
49
|
+
self.collapseTree(item)
|
|
50
|
+
item.each do |c|
|
|
51
|
+
collapseFullTree(c) if !self.itemLeaf?(c)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def add(result)
|
|
58
|
+
addItem(result)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def set_base_dir(url)
|
|
62
|
+
url.gsub!(/^.*\/\//,'')
|
|
63
|
+
subdirs = url.split '/'
|
|
64
|
+
subdirs.shift
|
|
65
|
+
item = nil
|
|
66
|
+
subdirs.each do |d|
|
|
67
|
+
# puts "* append #{d}"
|
|
68
|
+
nxt = self.appendItem(item, d)#, @folderIcon, @folderIcon)
|
|
69
|
+
self.setItemData(nxt, :base_dir)
|
|
70
|
+
# puts nxt.class
|
|
71
|
+
item = nxt
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @base_dir = subdirs.join '/'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# end
|
|
78
|
+
def addItem(result)
|
|
79
|
+
#puts result
|
|
80
|
+
url = "#{result[:url].to_s}"
|
|
81
|
+
url.gsub!(/^.*\/\//,'')
|
|
82
|
+
subdirs = url.split '/'
|
|
83
|
+
subdirs.shift
|
|
84
|
+
|
|
85
|
+
puts subdirs.join ' | '
|
|
86
|
+
|
|
87
|
+
item = nil
|
|
88
|
+
subdirs.each do |d|
|
|
89
|
+
nxt = self.findItem(d, item, SEARCH_FORWARD)
|
|
90
|
+
break if nxt.nil?
|
|
91
|
+
item = nxt
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
unless item.nil?
|
|
95
|
+
unless subdirs.last == item.text
|
|
96
|
+
new_item = self.appendItem(item, subdirs.last)#, @folderIcon, @folderIcon)
|
|
97
|
+
self.setItemData(new_item, result)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def initialize(parent)
|
|
104
|
+
|
|
105
|
+
@parent = parent
|
|
106
|
+
@quick_filter = Hash.new
|
|
107
|
+
@show_scope_only = false
|
|
108
|
+
|
|
109
|
+
@results = []
|
|
110
|
+
|
|
111
|
+
super(parent, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_RIGHT|TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_ROOT_BOXES|TREELIST_EXTENDEDSELECT)
|
|
112
|
+
|
|
113
|
+
@event_dispatcher_listeners = Hash.new
|
|
114
|
+
|
|
115
|
+
@projectIcon = ICON_PROJECT
|
|
116
|
+
|
|
117
|
+
@folderIcon = ICON_FOLDER
|
|
118
|
+
@reqIcon = ICON_REQUEST
|
|
119
|
+
@siteIcon= ICON_SITE
|
|
120
|
+
|
|
121
|
+
@filtered_domains = Hash.new # domains which already have been filtered
|
|
122
|
+
|
|
123
|
+
@tree_filters = {
|
|
124
|
+
:response_status => []
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# session_leaf = self.appendItem(nil, @session_name, @projectIcon, @projectIcon)
|
|
128
|
+
|
|
129
|
+
self.connect(SEL_COMMAND) do |sender, sel, item|
|
|
130
|
+
url_parts = []
|
|
131
|
+
begin
|
|
132
|
+
if item.data.is_a? Hash
|
|
133
|
+
#if item.data.class.to_s =~ /Qchat/
|
|
134
|
+
#@interface.show_chat(item.data)
|
|
135
|
+
notify(:show_info, item.data)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
rescue => bang
|
|
139
|
+
# puts bang
|
|
140
|
+
# puts bang.backtrace if $DEBUG
|
|
141
|
+
#puts "!!! Error: could not show selected tree item"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
getApp().beginWaitCursor do
|
|
145
|
+
notify(:show_conversation, @quick_filter[item.object_id]) if @quick_filter[item.object_id]
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
self.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, event|
|
|
150
|
+
exclude_site = nil
|
|
151
|
+
unless event.moved?
|
|
152
|
+
FXMenuPane.new(self) do |menu_pane|
|
|
153
|
+
|
|
154
|
+
target = FXMenuCheck.new(menu_pane, "test" )
|
|
155
|
+
|
|
156
|
+
menu_pane.create
|
|
157
|
+
menu_pane.popup(nil, event.root_x, event.root_y)
|
|
158
|
+
app.runModalWhileShown(menu_pane)
|
|
159
|
+
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
def notify(event, *args)
|
|
168
|
+
if @event_dispatcher_listeners[event]
|
|
169
|
+
@event_dispatcher_listeners[event].each do |m|
|
|
170
|
+
m.call(*args) if m.respond_to? :call
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
end
|
|
176
|
+
# namespace end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#.
|
|
2
|
+
# agent.rb
|
|
3
|
+
#.
|
|
4
|
+
# Copyright 2014 by siberas, http://www.siberas.de
|
|
5
|
+
# This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
|
|
6
|
+
# WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
|
|
7
|
+
# WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
8
|
+
# You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
9
|
+
|
|
10
|
+
# @private
|
|
11
|
+
module Watobo#:nodoc: all
|
|
12
|
+
module Plugin
|
|
13
|
+
class CQ5
|
|
14
|
+
class Agent < Watobo::Session
|
|
15
|
+
def initialize(base_request, in_queue, out_queue )
|
|
16
|
+
@work_queue = in_queue
|
|
17
|
+
@disp_queue = out_queue
|
|
18
|
+
@request = base_request
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
super(@request.object_id, Watobo::Conf::Scanner.to_h )
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def stop
|
|
26
|
+
@agent_thread.kill
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def run
|
|
30
|
+
return nil if @work_queue.nil? or @disp_queue.nil?
|
|
31
|
+
|
|
32
|
+
@agent_thread = Thread.new(){
|
|
33
|
+
puts "#{self} running ..."
|
|
34
|
+
loop do
|
|
35
|
+
begin
|
|
36
|
+
|
|
37
|
+
item = @work_queue.deq
|
|
38
|
+
# not interested in jcr:content ... skip ...
|
|
39
|
+
next if item[:url] =~ /jcr%3acontent$/
|
|
40
|
+
|
|
41
|
+
get_pages item
|
|
42
|
+
file_info item
|
|
43
|
+
|
|
44
|
+
rescue => bang
|
|
45
|
+
puts bang
|
|
46
|
+
puts bang.backtrace
|
|
47
|
+
exit
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
}
|
|
51
|
+
@agent_thread
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def get_pages(item)
|
|
55
|
+
test = @request.copy
|
|
56
|
+
# puts item
|
|
57
|
+
url = item[:url].gsub(/\/$/,'') + '/.pages.json'
|
|
58
|
+
test.replaceURL( url )
|
|
59
|
+
|
|
60
|
+
request, response = sendRequest test
|
|
61
|
+
|
|
62
|
+
return false unless response.respond_to? :status
|
|
63
|
+
item[:pages_status] = response.status
|
|
64
|
+
# @disp_queue << item
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if response.content_type =~ /json/i
|
|
68
|
+
begin
|
|
69
|
+
ntpages = JSON.parse response.body.to_s
|
|
70
|
+
|
|
71
|
+
if ntpages['pages']
|
|
72
|
+
|
|
73
|
+
ntpages['pages'].each do |p|
|
|
74
|
+
#unless @use_relative_path
|
|
75
|
+
ep = p['escapedPath']
|
|
76
|
+
next if ep.nil?
|
|
77
|
+
next if ep.empty?
|
|
78
|
+
|
|
79
|
+
purl = ''
|
|
80
|
+
|
|
81
|
+
purl = @request.url.to_s.gsub(/\/$/, '') + p['escapedPath']
|
|
82
|
+
puts "+ #{purl}"
|
|
83
|
+
|
|
84
|
+
next if purl.empty?
|
|
85
|
+
|
|
86
|
+
item = {
|
|
87
|
+
:url => purl,
|
|
88
|
+
:page_info => p,
|
|
89
|
+
:file_info => nil,
|
|
90
|
+
:status => nil
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@disp_queue << item
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
rescue => bang
|
|
98
|
+
puts bang
|
|
99
|
+
puts ntpages
|
|
100
|
+
puts "---"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
#puts response.body.to_s
|
|
104
|
+
true
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def file_info(item)
|
|
108
|
+
#url = item[:url]
|
|
109
|
+
#@request.replaceURL "#{url}/.json"
|
|
110
|
+
test = @request.copy
|
|
111
|
+
test.set_file_extension "json"
|
|
112
|
+
# puts "\n>> #{@request.url}"
|
|
113
|
+
request, response = sendRequest test
|
|
114
|
+
|
|
115
|
+
return false unless response.respond_to? :status
|
|
116
|
+
item[:info_status] = response.status
|
|
117
|
+
|
|
118
|
+
if response.content_type =~ /json/i
|
|
119
|
+
info = JSON.parse response.body.to_s
|
|
120
|
+
item[:file_info] = info
|
|
121
|
+
end
|
|
122
|
+
#@disp_queue << item
|
|
123
|
+
true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def sendRequest(request, prefs={})
|
|
127
|
+
begin
|
|
128
|
+
test_req, test_resp = self.doRequest(request, prefs)
|
|
129
|
+
return test_req, test_resp
|
|
130
|
+
rescue => bang
|
|
131
|
+
puts bang
|
|
132
|
+
puts bang.backtrace if $DEBUG
|
|
133
|
+
end
|
|
134
|
+
return nil, nil
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|