watobo 0.9.20 → 0.9.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGELOG.md +54 -2
  2. data/README.md +1 -1
  3. data/config/scanner.yml +1 -0
  4. data/custom-views/prettify-json.rb +19 -0
  5. data/lib/watobo/adapters/file/marshal_store.rb +297 -0
  6. data/lib/watobo/adapters.rb +2 -1
  7. data/lib/watobo/core/active_check.rb +4 -0
  8. data/lib/watobo/core/chat.rb +8 -0
  9. data/lib/watobo/core/chats.rb +2 -1
  10. data/lib/watobo/core/cookie.rb +3 -3
  11. data/lib/watobo/core/finding.rb +7 -0
  12. data/lib/watobo/core/request.rb +3 -3
  13. data/lib/watobo/core/session.rb +6 -2
  14. data/lib/watobo/framework/init_modules.rb +18 -16
  15. data/lib/watobo/gui/conversation_table.rb +13 -16
  16. data/lib/watobo/gui/conversation_table_ctrl2.rb +1 -0
  17. data/lib/watobo/gui/custom_viewer.rb +101 -76
  18. data/lib/watobo/gui/define_scope_frame.rb +44 -10
  19. data/lib/watobo/gui/edit_scope_dialog.rb +1 -1
  20. data/lib/watobo/gui/fuzzer_gui.rb +61 -23
  21. data/lib/watobo/gui/main_window.rb +1 -1
  22. data/lib/watobo/gui/scanner_settings_dialog.rb +15 -0
  23. data/lib/watobo/http/data/json.rb +6 -0
  24. data/lib/watobo/interceptor/html/favicon.ico +0 -0
  25. data/lib/watobo/interceptor/html/index.html +13 -0
  26. data/lib/watobo/interceptor/proxy.rb +70 -18
  27. data/lib/watobo/mixins/httpparser.rb +26 -16
  28. data/lib/watobo/mixins/shapers.rb +49 -5
  29. data/lib/watobo/mixins/transcoders.rb +8 -8
  30. data/lib/watobo/sockets/connection.rb +1 -1
  31. data/lib/watobo/utils/load_chat.rb +62 -0
  32. data/lib/watobo/utils/response_hash.rb +3 -3
  33. data/lib/watobo.rb +1 -1
  34. data/modules/active/cq5/cq5_default_selectors.rb +116 -0
  35. data/modules/active/cq5/cqp_user_enumeration.rb +134 -0
  36. data/modules/active/struts2/include_params_ognl.rb +1 -1
  37. data/modules/active/xml/xml_xxe.rb +6 -1
  38. data/modules/passive/disclosure_domino.rb +1 -1
  39. data/modules/passive/in_script_parameter.rb +9 -4
  40. data/plugins/aem/aem.rb +21 -0
  41. data/plugins/aem/gui/main.rb +128 -0
  42. data/plugins/aem/gui/tree_view.rb +180 -0
  43. data/plugins/aem/icons/aem.ico +0 -0
  44. data/plugins/aem/lib/agent.rb +140 -0
  45. data/plugins/aem/lib/dispatcher.rb +53 -0
  46. data/plugins/aem/lib/engine.rb +187 -0
  47. data/plugins/filefinder/dbs/cq5.db +23 -0
  48. data/plugins/filefinder/dbs/subs-big.lst +44 -44
  49. data/plugins/filefinder/filefinder.rb +4 -4
  50. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +11 -10
  51. metadata +16 -2
@@ -75,7 +75,7 @@ EOD
75
75
  tparam = Watobo::UrlParameter.new( :name => "watobo", :value => CGI::escape(test_value) )
76
76
 
77
77
  test_request.url.set tparam
78
- puts test_request.first
78
+ #puts test_request.first
79
79
 
80
80
  request, response = doRequest(test_request)
81
81
 
@@ -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
@@ -33,7 +33,7 @@ module Watobo#:nodoc: all
33
33
  )
34
34
 
35
35
 
36
- @pattern = '([\w\/\-0-9\.:]+\.nsf)'
36
+ @pattern = '([a-zA-Z\/\-0-9\.:]+\.nsf)'
37
37
  @dbs = []
38
38
  end
39
39
 
@@ -35,9 +35,11 @@ module Watobo#:nodoc: all
35
35
 
36
36
  end
37
37
 
38
- def showError(chatid, message)
39
- puts "!!! Error #{Module.nesting[0].name}"
40
- puts "Chat: [#{chatid}]"
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
- showError(chat.id, bang)
83
+
84
+ showError(chat, bang)
85
+ puts bang
86
+ puts "-- trace --"
82
87
  puts bang.backtrace
83
88
 
84
89
  end
@@ -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