watobo 0.9.8.677

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.
Files changed (260) hide show
  1. data/bin/watobo_gui.rb +39 -0
  2. data/certificates/cert.pem +19 -0
  3. data/certificates/privkey.pem +15 -0
  4. data/certificates/watobo_dh.key +5 -0
  5. data/config/datastore.yml +5 -0
  6. data/config/forwarding_proxy.yml +12 -0
  7. data/config/general.yml +4 -0
  8. data/config/gui.yml +23 -0
  9. data/config/interceptor.yml +16 -0
  10. data/config/scan_policy.yml +13 -0
  11. data/config/scanner.yml +34 -0
  12. data/icons/Add.ico +0 -0
  13. data/icons/Add_24x24.ico +0 -0
  14. data/icons/Bandwidth.ico +0 -0
  15. data/icons/Bandwidth_24x24.ico +0 -0
  16. data/icons/Mr. Bomb.ico +0 -0
  17. data/icons/Mr. Bomb_16x16.ico +0 -0
  18. data/icons/Mr. Bomb_24x24.ico +0 -0
  19. data/icons/Orange Ball.ico +0 -0
  20. data/icons/Orange Ball_16x16.ico +0 -0
  21. data/icons/Orange Ball_24x24.ico +0 -0
  22. data/icons/Pause.ico +0 -0
  23. data/icons/Play.ico +0 -0
  24. data/icons/Play_24x24.ico +0 -0
  25. data/icons/Red Ball.ico +0 -0
  26. data/icons/Red Ball_16x16.ico +0 -0
  27. data/icons/Red Ball_24x24.ico +0 -0
  28. data/icons/Run.ico +0 -0
  29. data/icons/Stop.ico +0 -0
  30. data/icons/Stop_24x24.ico +0 -0
  31. data/icons/Terminal.ico +0 -0
  32. data/icons/Transfer.ico +0 -0
  33. data/icons/Transfer_16x16.ico +0 -0
  34. data/icons/User.ico +0 -0
  35. data/icons/User_16x16.ico +0 -0
  36. data/icons/User_24x24.ico +0 -0
  37. data/icons/Web Browser.ico +0 -0
  38. data/icons/Web Browser_16x16.ico +0 -0
  39. data/icons/Write Document.ico +0 -0
  40. data/icons/Yellow Ball.ico +0 -0
  41. data/icons/Yellow Ball_16x16.ico +0 -0
  42. data/icons/Yellow Ball_24x24.ico +0 -0
  43. data/icons/advanced.ico +0 -0
  44. data/icons/advanced_16x16.ico +0 -0
  45. data/icons/advanced_24x24.ico +0 -0
  46. data/icons/applications.ico +0 -0
  47. data/icons/applications_16x16.ico +0 -0
  48. data/icons/applications_24x24.ico +0 -0
  49. data/icons/browser_16x16.ico +0 -0
  50. data/icons/browser_24x24.ico +0 -0
  51. data/icons/burn.ico +0 -0
  52. data/icons/burn_16x16.ico +0 -0
  53. data/icons/burn_24x24.ico +0 -0
  54. data/icons/calculator.ico +0 -0
  55. data/icons/calculator_24x24.ico +0 -0
  56. data/icons/cb_checked.ico +0 -0
  57. data/icons/cb_checked_orange.ico +0 -0
  58. data/icons/cb_unchecked.ico +0 -0
  59. data/icons/coin_24x24.ico +0 -0
  60. data/icons/conversation.ico +0 -0
  61. data/icons/conversation_24x24.ico +0 -0
  62. data/icons/engine.ico +0 -0
  63. data/icons/filter.ico +0 -0
  64. data/icons/folder.ico +0 -0
  65. data/icons/folder_16x16.ico +0 -0
  66. data/icons/fuzzer_16x16.ico +0 -0
  67. data/icons/fuzzer_24x24.ico +0 -0
  68. data/icons/go-down_16x16.png +0 -0
  69. data/icons/go-up_16x16.png +0 -0
  70. data/icons/help.ico +0 -0
  71. data/icons/help_16x16.ico +0 -0
  72. data/icons/help_24x24.ico +0 -0
  73. data/icons/iChat.ico +0 -0
  74. data/icons/iChat_16x16.ico +0 -0
  75. data/icons/iChat_24x24.ico +0 -0
  76. data/icons/icons.txt +3 -0
  77. data/icons/info.ico +0 -0
  78. data/icons/info_16x16.ico +0 -0
  79. data/icons/info_24x24.ico +0 -0
  80. data/icons/interceptor_24x24.ico +0 -0
  81. data/icons/lock.ico +0 -0
  82. data/icons/lock_12x12.ico +0 -0
  83. data/icons/lock_16x16.ico +0 -0
  84. data/icons/monitor.ico +0 -0
  85. data/icons/plugin.ico +0 -0
  86. data/icons/plugin_24x24.ico +0 -0
  87. data/icons/scan_16x16.png +0 -0
  88. data/icons/send.ico +0 -0
  89. data/icons/server.ico +0 -0
  90. data/icons/server_16x16.ico +0 -0
  91. data/icons/siberas_logo_x24.gif +0 -0
  92. data/icons/tag_blue_32x32.ico +0 -0
  93. data/icons/watobo-48x48.png +0 -0
  94. data/icons/watobo-logo.png +0 -0
  95. data/icons/watobo.ico +0 -0
  96. data/lib/watobo/adapters/data_store.rb +38 -0
  97. data/lib/watobo/adapters/file/file_store.rb +211 -0
  98. data/lib/watobo/adapters/session_store.rb +27 -0
  99. data/lib/watobo/adapters.rb +26 -0
  100. data/lib/watobo/config.rb +143 -0
  101. data/lib/watobo/constants.rb +92 -0
  102. data/lib/watobo/core/active_check.rb +404 -0
  103. data/lib/watobo/core/cookie.rb +69 -0
  104. data/lib/watobo/core/fuzz_gen.rb +160 -0
  105. data/lib/watobo/core/http_socket.rb +142 -0
  106. data/lib/watobo/core/interceptor.rb +729 -0
  107. data/lib/watobo/core/passive_check.rb +141 -0
  108. data/lib/watobo/core/project.rb +1058 -0
  109. data/lib/watobo/core/scanner.rb +396 -0
  110. data/lib/watobo/core/session.rb +1320 -0
  111. data/lib/watobo/core/simple_ca.rb +393 -0
  112. data/lib/watobo/core.rb +34 -0
  113. data/lib/watobo/defaults.rb +40 -0
  114. data/lib/watobo/external/diff/lcs/array.rb +42 -0
  115. data/lib/watobo/external/diff/lcs/block.rb +72 -0
  116. data/lib/watobo/external/diff/lcs/callbacks.rb +343 -0
  117. data/lib/watobo/external/diff/lcs/change.rb +190 -0
  118. data/lib/watobo/external/diff/lcs/hunk.rb +279 -0
  119. data/lib/watobo/external/diff/lcs/ldiff.rb +247 -0
  120. data/lib/watobo/external/diff/lcs/string.rb +40 -0
  121. data/lib/watobo/external/diff/lcs.rb +1124 -0
  122. data/lib/watobo/external/ntlm/ntlm.rb +797 -0
  123. data/lib/watobo/externals.rb +28 -0
  124. data/lib/watobo/framework/create_project.rb +55 -0
  125. data/lib/watobo/framework/init.rb +149 -0
  126. data/lib/watobo/framework/init_modules.rb +116 -0
  127. data/lib/watobo/framework/license_text.rb +50 -0
  128. data/lib/watobo/framework.rb +26 -0
  129. data/lib/watobo/gui/about_watobo.rb +68 -0
  130. data/lib/watobo/gui/browser_preview.rb +460 -0
  131. data/lib/watobo/gui/certificate_dialog.rb +132 -0
  132. data/lib/watobo/gui/chat_diff.rb +415 -0
  133. data/lib/watobo/gui/chatviewer_frame.rb +427 -0
  134. data/lib/watobo/gui/checkboxtree.rb +221 -0
  135. data/lib/watobo/gui/checks_policy_frame.rb +123 -0
  136. data/lib/watobo/gui/client_cert_dialog.rb +227 -0
  137. data/lib/watobo/gui/confirm_scan_dialog.rb +67 -0
  138. data/lib/watobo/gui/conversation_table.rb +386 -0
  139. data/lib/watobo/gui/conversation_table_ctrl.rb +175 -0
  140. data/lib/watobo/gui/csrf_token_dialog.rb +446 -0
  141. data/lib/watobo/gui/dashboard.rb +341 -0
  142. data/lib/watobo/gui/define_scope_frame.rb +380 -0
  143. data/lib/watobo/gui/edit_comment.rb +70 -0
  144. data/lib/watobo/gui/edit_scope_dialog.rb +69 -0
  145. data/lib/watobo/gui/finding_info.rb +212 -0
  146. data/lib/watobo/gui/findings_tree.rb +459 -0
  147. data/lib/watobo/gui/full_scan_dialog.rb +269 -0
  148. data/lib/watobo/gui/fuzzer_gui.rb +1522 -0
  149. data/lib/watobo/gui/hex_viewer.rb +106 -0
  150. data/lib/watobo/gui/interceptor_gui.rb +994 -0
  151. data/lib/watobo/gui/interceptor_settings_dialog.rb +201 -0
  152. data/lib/watobo/gui/log_viewer.rb +97 -0
  153. data/lib/watobo/gui/login_wizzard.rb +301 -0
  154. data/lib/watobo/gui/main_window.rb +1815 -0
  155. data/lib/watobo/gui/manual_request_editor.rb +1105 -0
  156. data/lib/watobo/gui/master_pw_dialog.rb +142 -0
  157. data/lib/watobo/gui/password_policy_dialog.rb +98 -0
  158. data/lib/watobo/gui/plugin/base.rb +82 -0
  159. data/lib/watobo/gui/plugin_board.rb +95 -0
  160. data/lib/watobo/gui/preferences_dialog.rb +116 -0
  161. data/lib/watobo/gui/progress_window.rb +102 -0
  162. data/lib/watobo/gui/project_wizzard.rb +369 -0
  163. data/lib/watobo/gui/proxy_dialog.rb +550 -0
  164. data/lib/watobo/gui/quick_scan_dialog.rb +242 -0
  165. data/lib/watobo/gui/request_editor.rb +480 -0
  166. data/lib/watobo/gui/save_chat_dialog.rb +158 -0
  167. data/lib/watobo/gui/scanner_settings_dialog.rb +360 -0
  168. data/lib/watobo/gui/select_chat_dialog.rb +169 -0
  169. data/lib/watobo/gui/session_management_dialog.rb +688 -0
  170. data/lib/watobo/gui/sites_tree.rb +347 -0
  171. data/lib/watobo/gui/status_bar.rb +88 -0
  172. data/lib/watobo/gui/table_editor.rb +445 -0
  173. data/lib/watobo/gui/tagless_viewer.rb +62 -0
  174. data/lib/watobo/gui/templates/plugin.rb +80 -0
  175. data/lib/watobo/gui/templates/plugin2.rb +103 -0
  176. data/lib/watobo/gui/text_viewer.rb +247 -0
  177. data/lib/watobo/gui/transcoder_window.rb +215 -0
  178. data/lib/watobo/gui/utils/gui_utils.rb +129 -0
  179. data/lib/watobo/gui/utils/init_icons.rb +106 -0
  180. data/lib/watobo/gui/utils/load_icons.rb +54 -0
  181. data/lib/watobo/gui/utils/load_plugins.rb +94 -0
  182. data/lib/watobo/gui/utils/master_password.rb +90 -0
  183. data/lib/watobo/gui/utils/save_default_settings.rb +99 -0
  184. data/lib/watobo/gui/utils/save_project_settings.rb +21 -0
  185. data/lib/watobo/gui/utils/save_proxy_settings.rb +45 -0
  186. data/lib/watobo/gui/utils/save_session_settings.rb +21 -0
  187. data/lib/watobo/gui/utils/session_history.rb +134 -0
  188. data/lib/watobo/gui/workspace_dialog.rb +89 -0
  189. data/lib/watobo/gui/www_auth_dialog.rb +348 -0
  190. data/lib/watobo/gui/xml_viewer_frame.rb +114 -0
  191. data/lib/watobo/gui.rb +139 -0
  192. data/lib/watobo/mixins/httpparser.rb +664 -0
  193. data/lib/watobo/mixins/request_parser.rb +210 -0
  194. data/lib/watobo/mixins/shapers.rb +345 -0
  195. data/lib/watobo/mixins/transcoders.rb +88 -0
  196. data/lib/watobo/mixins.rb +32 -0
  197. data/lib/watobo/utils/check_regex.rb +36 -0
  198. data/lib/watobo/utils/copy_object.rb +29 -0
  199. data/lib/watobo/utils/crypto.rb +74 -0
  200. data/lib/watobo/utils/expand_range.rb +45 -0
  201. data/lib/watobo/utils/file_management.rb +73 -0
  202. data/lib/watobo/utils/load_chat.rb +219 -0
  203. data/lib/watobo/utils/load_icon.rb +47 -0
  204. data/lib/watobo/utils/print_debug.rb +34 -0
  205. data/lib/watobo/utils/response_hash.rb +143 -0
  206. data/lib/watobo/utils/secure_eval.rb +57 -0
  207. data/lib/watobo/utils/text2request.rb +96 -0
  208. data/lib/watobo/utils.rb +32 -0
  209. data/lib/watobo.rb +76 -0
  210. data/modules/active/Apache/mod_status.rb +123 -0
  211. data/modules/active/Flash/crossdomain.rb +102 -0
  212. data/modules/active/directories/dirwalker.rb +89 -0
  213. data/modules/active/discovery/fileextensions.rb +151 -0
  214. data/modules/active/discovery/http_methods.rb +135 -0
  215. data/modules/active/domino/domino_db.lst +164 -0
  216. data/modules/active/domino/domino_db.rb +128 -0
  217. data/modules/active/fileinclusion/lfi_simple.rb +134 -0
  218. data/modules/active/jboss/jboss_basic.rb +119 -0
  219. data/modules/active/sap/business_objects.rb +73 -0
  220. data/modules/active/sap/its_commands.rb +101 -0
  221. data/modules/active/sap/its_service_parameter.rb +105 -0
  222. data/modules/active/sap/its_services.rb +103 -0
  223. data/modules/active/sap/its_xss.rb +98 -0
  224. data/modules/active/sqlinjection/sql_boolean.rb +262 -0
  225. data/modules/active/sqlinjection/sqli_simple.rb +205 -0
  226. data/modules/active/xss/xss_simple.rb +179 -0
  227. data/modules/passive/cookie_options.rb +97 -0
  228. data/modules/passive/cookie_xss.rb +85 -0
  229. data/modules/passive/detect_code.rb +89 -0
  230. data/modules/passive/detect_fileupload.rb +80 -0
  231. data/modules/passive/detect_infrastructure.rb +98 -0
  232. data/modules/passive/detect_one_time_tokens.rb +86 -0
  233. data/modules/passive/dirindexing.rb +81 -0
  234. data/modules/passive/disclosure_emails.rb +82 -0
  235. data/modules/passive/disclosure_ipaddr.rb +87 -0
  236. data/modules/passive/filename_as_parameter.rb +85 -0
  237. data/modules/passive/form_spotter.rb +75 -0
  238. data/modules/passive/hotspots.rb +86 -0
  239. data/modules/passive/in_script_parameter.rb +92 -0
  240. data/modules/passive/multiple_server_headers.rb +98 -0
  241. data/modules/passive/possible_login.rb +134 -0
  242. data/modules/passive/redirect_url.rb +88 -0
  243. data/modules/passive/redirectionz.rb +96 -0
  244. data/modules/passive/xss_dom.rb +91 -0
  245. data/plugins/catalog/catalog.ico +0 -0
  246. data/plugins/catalog/catalog.rb +726 -0
  247. data/plugins/catalog/db_tests +6483 -0
  248. data/plugins/catalog/db_variables +29 -0
  249. data/plugins/filefinder/dbs/hbci.db +12 -0
  250. data/plugins/filefinder/filefinder.rb +602 -0
  251. data/plugins/sslchecker/cli/sslchecker_cli.rb +21 -0
  252. data/plugins/sslchecker/gui/cipher_table.rb +260 -0
  253. data/plugins/sslchecker/gui/gui.rb +245 -0
  254. data/plugins/sslchecker/gui/sslchecker.rb +26 -0
  255. data/plugins/sslchecker/icons/green_16x16.ico +0 -0
  256. data/plugins/sslchecker/icons/grey_16x16.ico +0 -0
  257. data/plugins/sslchecker/icons/red_16x16.ico +0 -0
  258. data/plugins/sslchecker/icons/sslchecker.ico +0 -0
  259. data/plugins/sslchecker/lib/check.rb +117 -0
  260. metadata +317 -0
@@ -0,0 +1,1105 @@
1
+ # .
2
+ # manual_request_editor.rb
3
+ #
4
+ # Copyright 2012 by siberas, http://www.siberas.de
5
+ #
6
+ # This file is part of WATOBO (Web Application Tool Box)
7
+ # http://watobo.sourceforge.com
8
+ #
9
+ # WATOBO is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation version 2 of the License.
12
+ #
13
+ # WATOBO is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with WATOBO; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # .
22
+ module Watobo
23
+ module Gui
24
+
25
+ class RequestBuilder < FXVerticalFrame
26
+
27
+ def subscribe(event, &callback)
28
+ (@event_dispatcher_listeners[event] ||= []) << callback
29
+ end
30
+
31
+ def clearEvents(event)
32
+ @event_dispatcher_listener[event].clear
33
+ end
34
+
35
+ def setRequest(request)
36
+ begin
37
+ @text_edit.setText(request)
38
+ @parm_table.setRequest(request)
39
+
40
+ if request.is_a? Array
41
+ text = "#{request.first}"
42
+ else
43
+ text = request.slice(/.* HTTP\/\d\.\d/)
44
+ end
45
+ #text.gsub!(/\?.*/,"")
46
+ #text.gsub!(/ HTTP\/.*/,"")
47
+ @req_line.setText(text.strip)
48
+ rescue => bang
49
+ puts bang
50
+ # puts bang.backtrace if $DEBUG
51
+ # puts request
52
+ # puts "== EOE =="
53
+ end
54
+ end
55
+
56
+ def highlight(pattern)
57
+ @text_edit.highlight(pattern)
58
+ end
59
+
60
+ def rawRequest
61
+ case @tab.current
62
+ when 0
63
+ @text_edit.rawRequest
64
+ when 1
65
+ @parm_table.rawRequest
66
+ end
67
+ end
68
+
69
+ def parseRequest
70
+
71
+ case @tab.current
72
+ when 0
73
+
74
+ @text_edit.parseRequest
75
+ when 1
76
+
77
+ @parm_table.parseRequest
78
+ end
79
+ end
80
+
81
+ def initialize(owner, opts)
82
+ super(owner,opts)
83
+
84
+ @event_dispatcher_listeners = Hash.new
85
+
86
+ @tab = FXTabBook.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
87
+
88
+ FXTabItem.new(@tab, "Text", nil)
89
+ frame = FXVerticalFrame.new(@tab, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
90
+ @text_edit = Watobo::Gui::RequestEditor.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
91
+
92
+ @text_edit.subscribe(:error) { |msg| notify(:error, msg) }
93
+
94
+ FXTabItem.new(@tab, "Table", nil)
95
+ frame = FXVerticalFrame.new(@tab, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
96
+ frame = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
97
+ @req_line = FXText.new(frame, :opts => LAYOUT_FILL_X|TEXT_FIXEDWRAP)
98
+ @req_line.visibleRows = 1
99
+ @req_line.backColor = @req_line.parent.backColor
100
+ @req_line.disable
101
+ @parm_table = TableEditor.new(frame, :opts => FRAME_SUNKEN|TABLE_COL_SIZABLE|TABLE_ROW_SIZABLE|LAYOUT_FILL_X|LAYOUT_FILL_Y|TABLE_READONLY|LAYOUT_SIDE_TOP, :padding => 2)
102
+ # setup message chain
103
+ @parm_table.subscribe(:hotkey_ctrl_enter){ notify(:hotkey_ctrl_enter) }
104
+ @text_edit.subscribe(:hotkey_ctrl_enter){ notify(:hotkey_ctrl_enter) }
105
+
106
+ end
107
+
108
+ private
109
+
110
+ def notify(event, *args)
111
+ if @event_dispatcher_listeners[event]
112
+ @event_dispatcher_listeners[event].each do |m|
113
+ m.call(*args) if m.respond_to? :call
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ class SelectionInfo < FXVerticalFrame
120
+ def update(info)
121
+ begin
122
+ @hid_label.text = info[:hid] || "-"
123
+ @url_label.text = info[:url] || "-"
124
+ @length_label.text = info[:length] || "-"
125
+ @status_label.text = info[:status] || "-"
126
+
127
+ rescue => bang
128
+ puts "!!! Could not update SelectionInfo"
129
+ puts bang
130
+ end
131
+ end
132
+
133
+ def clear()
134
+ @hid_label.text = "-"
135
+ @url_label.text = "-"
136
+ @length_label.text = "-"
137
+ @status_label.text = "-"
138
+ end
139
+
140
+ def initialize(owner, opts)
141
+ super(owner, opts)
142
+ frame = FXHorizontalFrame.new(self, :opts => FRAME_NONE|LAYOUT_FILL_X, :padding => 0)
143
+ FXLabel.new(frame, "History-ID: ")
144
+ @hid_label = FXLabel.new(frame, " - ")
145
+
146
+ frame = FXHorizontalFrame.new(self, :opts => FRAME_NONE|LAYOUT_FILL_X, :padding => 0)
147
+ FXLabel.new(frame, "URL: ")
148
+ @url_label = FXLabel.new(frame, " - ")
149
+
150
+ frame = FXHorizontalFrame.new(self, :opts => FRAME_NONE|LAYOUT_FILL_X, :padding => 0)
151
+ FXLabel.new(frame, "Length: ")
152
+ @length_label = FXLabel.new(frame, " - ")
153
+
154
+ frame = FXHorizontalFrame.new(self, :opts => FRAME_NONE|LAYOUT_FILL_X, :padding => 0)
155
+ FXLabel.new(frame, "Status: ")
156
+ @status_label = FXLabel.new(frame, " - ")
157
+ end
158
+ end
159
+
160
+ class HistoryItem
161
+
162
+ attr :request
163
+ attr :response
164
+ attr :raw_request
165
+ def initialize(request, response, raw_request)
166
+ @request = request
167
+ @response = response
168
+ @raw_request = raw_request
169
+ end
170
+ end
171
+
172
+ class HistoryButton < FXVerticalFrame
173
+ attr :item
174
+ def reset()
175
+ self.backColor = @backColor
176
+ end
177
+
178
+ def highlight()
179
+ self.backColor = FXColor::Red
180
+ end
181
+
182
+ def update(history_item)
183
+ @button.text = history_item.id.to_s
184
+ #@button.text = "Huhule"
185
+ #puts "!update Button #{@button}"
186
+ @button.update()
187
+ @item = history_item
188
+ end
189
+
190
+ def initialize(owner, text, target, opts)
191
+ super(owner, opts)
192
+ @item = nil
193
+ @backColor = self.backColor
194
+
195
+ @button = FXButton.new(self, text, nil, target, DiffFrame::ID_HISTORY_BUTTON, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
196
+
197
+ end
198
+ end
199
+
200
+ class HistorySlider < FXScrollWindow
201
+ def update(history)
202
+ @history = history
203
+ reset()
204
+ history.length.times do |i|
205
+ begin
206
+
207
+ @buttons[i].update(history[i])
208
+ rescue => bang
209
+ puts bang
210
+ end
211
+ end
212
+ end
213
+
214
+ def getItem(id)
215
+ item = nil
216
+ @history.each do |h|
217
+ item = h if h.id == id
218
+ break if item
219
+ end
220
+ return item
221
+ end
222
+
223
+ def reset()
224
+ @buttons.each do |b|
225
+ b.reset()
226
+ end
227
+
228
+ end
229
+
230
+ def initialize(owner, target, history_size, opts)
231
+ @size = history_size
232
+ @buttons = []
233
+ @history = []
234
+ super(owner, opts)
235
+ frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_Y|LAYOUT_FILL_X, :padding => 0)
236
+ @size.times do |i|
237
+ @buttons.push HistoryButton.new(frame, 'empty', target, :opts => FRAME_NONE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 50, :height => 50)
238
+ end
239
+ end
240
+ end
241
+
242
+ class DiffFrame < FXVerticalFrame
243
+ include Responder
244
+
245
+ ID_HISTORY_BUTTON = FXMainWindow::ID_LAST
246
+ def onHistoryButton(sender, sel, event)
247
+ @history_slider.reset()
248
+ sender.parent.backColor = FXColor::Red
249
+ @slider_selection = sender.parent.item
250
+ end
251
+
252
+ def updateHistory(history)
253
+ @slider_selection = nil
254
+ @history = history
255
+ # @history_slider.update(history)
256
+ updateHistoryTable()
257
+ # updateSelections()
258
+ end
259
+
260
+ def onTableClick(sender,sel,item)
261
+ begin
262
+
263
+ row = item.row
264
+ @historyTable.selectRow(row, false)
265
+ hi = @historyTable.getRowText(row).to_i - 1
266
+
267
+ if @first_selection and @second_selection
268
+ @first_selection = nil
269
+ @second_selection = nil
270
+ end
271
+
272
+ if !@first_selection
273
+ @first_selection = @history[hi]
274
+ else
275
+ @second_selection = @history[hi]
276
+ end
277
+
278
+ updateSelection()
279
+
280
+ rescue => bang
281
+ puts "!!!ERROR: onTableClick"
282
+ puts bang
283
+ puts "!!!"
284
+
285
+ end
286
+ end
287
+
288
+ def initHistoryTable()
289
+ @historyTable.clearItems()
290
+ @historyTable.setTableSize(0, 3)
291
+
292
+ @historyTable.setColumnText( 0, "STATUS" )
293
+ @historyTable.setColumnText( 1, "LENGTH" )
294
+ @historyTable.setColumnText( 2, "URL" )
295
+
296
+ @historyTable.rowHeader.width = 50
297
+ @historyTable.setColumnWidth(0, 100)
298
+
299
+ @historyTable.setColumnWidth(1, 100)
300
+ @historyTable.setColumnWidth(2, 200)
301
+
302
+ end
303
+
304
+ def updateHistoryTable()
305
+ begin
306
+ @historyTable.clearItems()
307
+ initHistoryTable()
308
+
309
+ @history.each do |h|
310
+ lastRowIndex = @historyTable.getNumRows
311
+ @historyTable.appendRows(1)
312
+ @historyTable.setRowText(lastRowIndex, (@history.index(h) + 1 ).to_s)
313
+ @historyTable.setItemText(lastRowIndex, 0, h.response.status) if h.response.respond_to? :status
314
+ @historyTable.setItemText(lastRowIndex, 1, h.response.join.length.to_s)
315
+ @historyTable.setItemText(lastRowIndex, 2, h.request.url) if h.request.respond_to? :url
316
+ 3.times do |i|
317
+ i = @historyTable.getItem(lastRowIndex, i)
318
+ i.justify = FXTableItem::LEFT unless i.nil?
319
+ end
320
+ end
321
+ rescue => bang
322
+ puts bang
323
+ end
324
+
325
+ end
326
+
327
+ def updateSelection()
328
+ @first_sel_info.clear()
329
+ @second_sel_info.clear()
330
+
331
+ if @first_selection
332
+
333
+ @first_sel_info.update( :url => @first_selection.request.url,
334
+ :hid => (@history.index(@first_selection) + 1).to_s,
335
+ :status => @first_selection.response.status,
336
+ :length => @first_selection.response.join.length.to_s)
337
+
338
+ end
339
+
340
+ if @second_selection
341
+ @second_sel_info.update( :url => @second_selection.request.url,
342
+ :hid => (@history.index(@second_selection) + 1).to_s,
343
+ :status => @second_selection.response.status,
344
+ :length => @second_selection.response.join.length.to_s)
345
+
346
+ end
347
+ end
348
+
349
+ def getDiffChats()
350
+ first = nil
351
+ second = nil
352
+ begin
353
+ case @first_chat_dt.value
354
+ when 0
355
+
356
+ when 1
357
+
358
+ end
359
+
360
+ rescue
361
+
362
+ return first, second
363
+ end
364
+ end
365
+
366
+ def initialize(owner, opts)
367
+ super(owner, opts)
368
+
369
+ @history_size = 10
370
+ @history = []
371
+ @slider_selection = nil
372
+ @first_selection = nil
373
+ @second_selection = nil
374
+
375
+ FXMAPFUNC(SEL_COMMAND, DiffFrame::ID_HISTORY_BUTTON, 'onHistoryButton')
376
+
377
+ frame = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN)
378
+ # frame_left = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH, :width => 70, :padding => 0)
379
+ # @history_slider = HistorySlider.new(frame_left, self, @history_size, opts)
380
+
381
+ frame_right = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
382
+ sunken = FXVerticalFrame.new(frame_right, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
383
+ @historyTable = FXTable.new(sunken, :opts => FRAME_SUNKEN|TABLE_COL_SIZABLE|TABLE_ROW_SIZABLE|LAYOUT_FILL_X|LAYOUT_FILL_Y|TABLE_READONLY|LAYOUT_SIDE_TOP, :padding => 2)
384
+ initHistoryTable()
385
+
386
+ @historyTable.connect(SEL_COMMAND, method(:onTableClick))
387
+
388
+ first_chat_gb = FXGroupBox.new(frame_right, "First Chat", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
389
+ @first_sel_info = SelectionInfo.new(first_chat_gb, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
390
+ second_chat_gb = FXGroupBox.new(frame_right, "Second Chat", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
391
+ @second_sel_info = SelectionInfo.new(second_chat_gb, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
392
+
393
+ diff_button = FXButton.new(frame_right, "Diff it!", nil, nil, 0, :opts => LAYOUT_FILL_X|FRAME_RAISED|FRAME_THICK)
394
+
395
+ diff_button.connect(SEL_COMMAND) {
396
+ # new, orig = getDiffChats()
397
+ if @first_selection and @second_selection then
398
+ first_request = Watobo::Utils.copyObject(@first_selection.request)
399
+ first_response = Watobo::Utils.copyObject(@first_selection.response)
400
+ second_request = Watobo::Utils.copyObject(@second_selection.request)
401
+ second_response = Watobo::Utils.copyObject(@second_selection.response)
402
+
403
+ orig = Watobo::Chat.new(first_request, first_response, :id => 0)
404
+ new = Watobo::Chat.new(second_request, second_response, :id => 0)
405
+ project = nil
406
+ diffViewer = ChatDiffViewer.new(FXApp.instance, project, orig, new)
407
+ diffViewer.create
408
+ diffViewer.show(Fox::PLACEMENT_SCREEN)
409
+ end
410
+ }
411
+ end
412
+ end
413
+
414
+ #
415
+ class ManualRequestSender < Watobo::Session
416
+ def initialize(project)
417
+ @project = project
418
+ super(project.object_id, project.getScanPreferences())
419
+
420
+ end
421
+
422
+ def sendRequest(new_request, prefs)
423
+ id = 0
424
+ if prefs[:run_login ] == true
425
+ runLogin(@project.getLoginChats(), prefs)
426
+ end
427
+ #if prefs[:update_session ] == true and
428
+ unless prefs[:update_csrf_tokens] == true
429
+ prefs[:csrf_requests] = []
430
+ prefs[:csrf_patterns] = []
431
+ end
432
+
433
+ new_request.extend Watobo::Mixin::Parser::Web10
434
+ new_request.extend Watobo::Mixin::Shaper::Web10
435
+ begin
436
+ test_req, test_resp = self.doRequest(new_request, prefs)
437
+ test_req.extend Watobo::Mixin::Parser::Url
438
+ test_req.extend Watobo::Mixin::Parser::Web10
439
+ test_resp.extend Watobo::Mixin::Parser::Web10
440
+ return test_req,test_resp
441
+ rescue => bang
442
+ puts bang
443
+ puts bang.backtrace if $DEBUG
444
+ end
445
+ return nil, nil
446
+
447
+ end
448
+ end
449
+
450
+ #
451
+ #--------------------------------------------------------------------------------------------
452
+ #
453
+ class ManualRequestEditor < FXDialogBox
454
+
455
+ include Watobo::Constants
456
+ include Watobo::Gui::Icons
457
+
458
+ include Responder
459
+ # ID_CTRL_S = ID_LAST
460
+ # ID_LAST = ID_CTRL_S + 1
461
+ def subscribe(event, &callback)
462
+ (@event_dispatcher_listeners[event] ||= []) << callback
463
+ end
464
+
465
+ def openCSRFTokenDialog(sender, sel, item)
466
+ csrf_dlg = CSRFTokenDialog.new(self, @project, @chat)
467
+ if csrf_dlg.execute != 0 then
468
+ csrf_ids = csrf_dlg.getTokenScriptIds()
469
+ csrf_patterns = csrf_dlg.getTokenPatterns()
470
+
471
+ # puts csrf_ids.to_yaml
472
+ # puts "= = ="
473
+ # puts csrf_patterns.to_yaml
474
+
475
+ @project.setCSRFRequest(@original_request, csrf_ids, csrf_patterns)
476
+
477
+ @csrf_requests = []
478
+ csrf_ids.each do |id|
479
+ chat = @project.getChat(id)
480
+ @csrf_requests.push chat.copyRequest
481
+ end
482
+
483
+ # save settings
484
+ # saveProjectSettings(@active_project)
485
+ # saveSessionSettings(@active_project)
486
+ end
487
+ end
488
+
489
+ def clearEvents(event)
490
+ @event_dispatcher_listener[event].clear
491
+ end
492
+
493
+ def notify(event, *args)
494
+ if @event_dispatcher_listeners[event]
495
+ @event_dispatcher_listeners[event].each do |m|
496
+ m.call(*args) if m.respond_to? :call
497
+ end
498
+ end
499
+ end
500
+
501
+ def onRequestReset(sender,sel,item)
502
+ @req_builder.setRequest(@original_request)
503
+ end
504
+
505
+ # def onShowPreview(sender, sel, item)
506
+ #@interface.showPreview(request, response)
507
+ # end
508
+
509
+ def logger(message)
510
+ @log_viewer.log( LOG_INFO, message )
511
+ puts "[#{self.class.to_s}] #{message}"
512
+ end
513
+
514
+
515
+
516
+ def addHistoryItem(request, response, raw_request)
517
+ @history.push HistoryItem.new(request, response, eval(YAML.load(YAML.dump(raw_request.inspect))))
518
+
519
+ @history.shift if @history.length > @history_size
520
+
521
+ @diff_frame.updateHistory(@history)
522
+ end
523
+
524
+ def onBtnQuickScan(sender, sel, item)
525
+ dlg = Watobo::Gui::QuickScanDialog.new(self, @project, :target_chat => @chat, :enable_one_time_tokens => @updateCSRF.checked?)
526
+ scan_chats = []
527
+ if sender.text =~ /Cancel/i
528
+ @scanner.cancel() if @scanner
529
+ logger("QuickScan canceled by user")
530
+ @pbar.progress = 0
531
+ sender.text = "QuickScan"
532
+ return
533
+ end
534
+
535
+ if dlg.execute != 0 then
536
+ scan_modules = []
537
+ sender.text = "Cancel"
538
+ quick_scan_options = dlg.options
539
+ # puts quick_scan_options.to_yaml
540
+
541
+ if quick_scan_options[:use_orig_request] == true then
542
+ req = @original_request
543
+ else
544
+ req = @req_builder.parseRequest()
545
+ end
546
+
547
+ scan_chats.push Chat.new(req, [""], :id => @chat.id, :run_passive_checks => false)
548
+ end
549
+
550
+ unless scan_chats.empty? then
551
+ # we only need array of selected class names
552
+ scan_modules = dlg.selectedModules().map{ |m| m.class.to_s }
553
+ acc = @project.active_checks.select do |ac|
554
+ scan_modules.include? ac.class.to_s
555
+ end
556
+
557
+ scan_prefs = @project.getScanPreferences
558
+ # we don't want logout detection during a QuickScan
559
+ # TODO: let this decide the user!
560
+ scan_prefs[:logout_signatures] = [] if quick_scan_options[:detect_logout] == false
561
+ # scan_prefs[:csrf_requests] = @project.getCSRFRequests(@original_request) if quick_scan_options[:update_csrf_tokens] == true
562
+ scan_prefs[:run_passive_checks] = false
563
+
564
+ # logging required ?
565
+
566
+ if quick_scan_options[:enable_logging] and quick_scan_options[:scanlog_name]
567
+ scan_prefs[:scanlog_name] = quick_scan_options[:scanlog_name]
568
+ end
569
+
570
+ if $DEBUG
571
+ puts "* creating scanner ..."
572
+ puts quick_scan_options.to_yaml
573
+ puts "- - - - - - - - -"
574
+ puts scan_prefs.to_yaml
575
+ end
576
+
577
+ @scanner = Watobo::Scanner2.new(scan_chats, acc, @project.passive_checks, scan_prefs)
578
+
579
+ @pbar.total = @scanner.numTotalChecks
580
+ @pbar.progress = 0
581
+ @pbar.barColor = FXRGB(255,0,0)
582
+
583
+ @scanner.subscribe(:progress) { |m|
584
+ # print "="
585
+ @pbar.increment(1)
586
+ }
587
+
588
+
589
+ @scanner.subscribe(:new_finding) { |f|
590
+ @project.addFinding(f)
591
+ }
592
+
593
+ csrf_requests = []
594
+
595
+ if quick_scan_options[:update_csrf_tokens] == true
596
+ @project.getCSRFRequestIDs(req).each do |id|
597
+ chat = @project.getChat(id)
598
+ csrf_requests.push chat.copyRequest
599
+ end
600
+ puts "* Got No CSRF Requests!!" if csrf_requests.empty?
601
+ end
602
+
603
+ run_prefs = {
604
+ :update_sids => @updateSID.checked?,
605
+ :update_session => @updateSession.checked?,
606
+ :csrf_requests => csrf_requests,
607
+ :csrf_patterns => scan_prefs[:csrf_patterns],
608
+ :www_auth => scan_prefs[:www_auth],
609
+ :follow_redirect => quick_scan_options[:follow_redirect],
610
+ }
611
+
612
+ logger("Scan Started ...")
613
+
614
+ Thread.new(run_prefs) { |rp|
615
+
616
+ # puts "* starting scanner ..."
617
+ # puts run_prefs.to_yaml
618
+
619
+ @scanner.run( rp )
620
+
621
+ logger("Scan finished!")
622
+ @pbar.total = 0
623
+ @pbar.progress = 0
624
+ @pbar.barColor = 'grey'
625
+ sender.text = "QuickScan"
626
+ }
627
+ end
628
+
629
+ # return 0
630
+
631
+ end
632
+
633
+ def onBtnSendClick(sender,sel,item)
634
+ sendManualRequest()
635
+ end
636
+
637
+ def onPreviewClick(sender,sel,item)
638
+ @request_viewer.setText('')
639
+ new_request = @req_builder.parseRequest
640
+ # puts "new request: #{new_request}"
641
+ @request_viewer.setText(new_request)
642
+ @tabBook.current = 1
643
+ end
644
+
645
+ def showHistory(dist=0, pos=nil)
646
+ if @history.length > 0
647
+
648
+ current_pos = @history_pos_dt.value
649
+ new_pos = current_pos + dist
650
+ new_pos = 1 if new_pos <= 0
651
+ new_pos = @history.length if new_pos > @history.length
652
+
653
+ @req_builder.setRequest(@history[new_pos-1].raw_request)
654
+ @req_builder.highlight("(%%[^%]*%%)")
655
+
656
+ @response_viewer.setText(@history[new_pos-1].response)
657
+
658
+ @history_pos_dt.value = new_pos
659
+ @history_pos.handle(self, FXSEL(SEL_UPDATE, 0), nil)
660
+ return new_pos
661
+ end
662
+ return 0 if dist == 0 and not pos
663
+ end
664
+
665
+ def initialize(owner, project, chat)
666
+ begin
667
+ # Invoke base class initialize function first
668
+
669
+ super(owner, "Manual Request Toolkit", :opts => DECOR_ALL,:width=>850, :height=>600)
670
+
671
+ @event_dispatcher_listeners = Hash.new
672
+
673
+ @request_sender = ManualRequestSender.new(project)
674
+ @request_sender.subscribe(:follow_redirect){ |loc| logger( "follow redirect -> #{loc}")}
675
+ @responseFilter = FXDataTarget.new("")
676
+
677
+ @chat = chat
678
+
679
+ @original_request = chat.copyRequest
680
+
681
+ @project = project
682
+
683
+ @csrf_requests = []
684
+
685
+ @tselect = ""
686
+ @sel_pos = ""
687
+ @sel_len = ""
688
+
689
+ @last_request = []
690
+ @last_response = []
691
+
692
+ @history_size = 10
693
+ @history = []
694
+ @counter = 0
695
+
696
+ @scanner = nil
697
+
698
+ @new_response = nil
699
+ @new_request = nil
700
+
701
+ @update_lock = Mutex.new
702
+
703
+ # shortcuts here
704
+ #FXMAPFUNC(SEL_COMMAND, ID_CTRL_S, :on_ctrl_s)
705
+ #accelTable.addAccel(fxparseAccel("Ctrl+S"), self, FXSEL(SEL_COMMAND, ID_CTRL_S))
706
+
707
+ # @scanlog_dir = @project.scanLogDirectory()
708
+
709
+ self.icon = ICON_MANUAL_REQUEST
710
+
711
+ # Construct some hilite styles
712
+ hs_red = FXHiliteStyle.new
713
+ hs_red.normalForeColor = FXRGBA(255,255,255,255) # FXColor::Red
714
+ hs_red.normalBackColor = FXRGBA(255,0,0,1) # FXColor::White
715
+ hs_red.style = FXText::STYLE_BOLD
716
+
717
+ mr_splitter = FXSplitter.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL|SPLITTER_REVERSED|SPLITTER_TRACKING)
718
+ # top = FXHorizontalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_SIDE_BOTTOM)
719
+ top_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM,:height => 500)
720
+ top_splitter = FXSplitter.new(top_frame, LAYOUT_FILL_X|SPLITTER_HORIZONTAL|LAYOUT_FILL_Y|SPLITTER_TRACKING)
721
+
722
+ log_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,:height => 100)
723
+
724
+ #LAYOUT_FILL_X in combination with LAYOUT_FIX_WIDTH
725
+
726
+ req_editor = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FIX_WIDTH|LAYOUT_FILL_Y|FRAME_GROOVE,:width=>400, :height=>500)
727
+
728
+ req_edit_header = FXHorizontalFrame.new(req_editor, :opts => LAYOUT_FILL_X)
729
+
730
+ #req_viewer = FXVerticalFrame.new(req_editor, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
731
+
732
+ @req_builder = RequestBuilder.new(req_editor, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding=>0)
733
+ @req_builder.subscribe(:hotkey_ctrl_s) {
734
+ simulatePressSendBtn()
735
+ sendManualRequest()
736
+ }
737
+ @req_builder.subscribe(:hotkey_ctrl_enter) {
738
+ simulatePressSendBtn()
739
+ sendManualRequest()
740
+ }
741
+
742
+ @req_builder.subscribe(:error) { |msg| logger(msg)}
743
+
744
+ @req_builder.setRequest(@original_request)
745
+
746
+ history_navigation = FXHorizontalFrame.new(req_edit_header, :opts => FRAME_NONE)
747
+ FXLabel.new(history_navigation, "History:", :opts => LAYOUT_CENTER_Y )
748
+ hback = FXButton.new(history_navigation, "<", nil, nil, 0, FRAME_RAISED|FRAME_THICK)
749
+ @history_pos_dt = FXDataTarget.new(0)
750
+ @history_pos = FXTextField.new(history_navigation, 2, @history_pos_dt, FXDataTarget::ID_VALUE, :opts => LAYOUT_FILL_X|FRAME_GROOVE|FRAME_SUNKEN)
751
+ @history_pos.justify = JUSTIFY_RIGHT
752
+ @history_pos.handle(self, FXSEL(SEL_UPDATE, 0), nil)
753
+
754
+ hback.connect(SEL_COMMAND){ showHistory(-1)}
755
+ hnext = FXButton.new(history_navigation, ">", nil, nil, 0, FRAME_RAISED|FRAME_THICK)
756
+ hnext.connect(SEL_COMMAND){ showHistory(1)}
757
+
758
+ menu = FXMenuPane.new(self)
759
+ FXMenuCommand.new(menu, "-> GET").connect(SEL_COMMAND, method(:trans2Get))
760
+ FXMenuCommand.new(menu, "-> POST").connect(SEL_COMMAND, method(:trans2Post))
761
+ # FXMenuCommand.new(menu, "POST <=> GET").connect(SEL_COMMAND, method(:switchMethod))
762
+
763
+ req_reset_button = FXButton.new(req_edit_header, "Reset", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT|LAYOUT_FILL_Y)
764
+ req_reset_button.connect(SEL_COMMAND, method(:onRequestReset))
765
+
766
+ # Button to pop menu
767
+ FXMenuButton.new(req_edit_header, "&Transform", nil, menu, (MENUBUTTON_DOWN|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_RIGHT|LAYOUT_FILL_Y))
768
+
769
+ # req_reset_button = FXButton.new(request_frame, "POST -> GET", nil, nil, 0, FRAME_RAISED|FRAME_THICK)
770
+ # req_reset_button.connect(SEL_COMMAND, method(:switchMethod))
771
+
772
+ #request_frame = FXHorizontalFrame.new(req_edit_header, :opts => FRAME_GROOVE|LAYOUT_RIGHT)
773
+ # FXLabel.new(request_frame, "Request:", :opts => LAYOUT_CENTER_Y )
774
+
775
+ frame = FXHorizontalFrame.new(req_editor, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM, :padding => 0)
776
+ req_options = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
777
+ #eq_options = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM)
778
+
779
+ #opt = FXGroupBox.new(req_options, "Request Options", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
780
+
781
+ @settings_tab = FXTabBook.new(req_options, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
782
+
783
+ resp_tab = FXTabItem.new(@settings_tab, "Request Options", nil)
784
+ opt= FXVerticalFrame.new(@settings_tab, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
785
+
786
+ # opt = FXVerticalFrame.new(frame,:opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
787
+ # btn = FXVerticalFrame.new(frame,:opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
788
+ #FXCheckButton.new(rob, "URL Encoding", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
789
+ @updateContentLength = FXCheckButton.new(opt, "Update Content-Length", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
790
+ @updateContentLength.checkState = true
791
+
792
+ @followRedirect = FXCheckButton.new(opt, "Follow Redirects", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
793
+ @followRedirect.checkState = false
794
+
795
+ @logChat = FXCheckButton.new(opt, "Log Chat", nil, 0,
796
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
797
+ @logChat.checkState = false
798
+
799
+ # scan_tab = FXTabItem.new(@settings_tab, "QuickScan Options", nil)
800
+ sess_tab = FXTabItem.new(@settings_tab, "Session Settings", nil)
801
+ session_frame = FXVerticalFrame.new(@settings_tab, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
802
+
803
+ @updateSID = FXCheckButton.new(session_frame, "Update SID Cache", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
804
+ @updateSID.checkState = false
805
+
806
+ @updateSession = FXCheckButton.new(session_frame, "Update Session", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
807
+ @updateSession.checkState = true
808
+ @updateSession.connect(SEL_COMMAND) do |sender, sel, item|
809
+ @runLogin.enabled = @updateSession.checked?
810
+ end
811
+
812
+ @runLogin = FXCheckButton.new(session_frame, "Run Login", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
813
+ @runLogin.checkState = false
814
+
815
+ csrf_frame = FXHorizontalFrame.new(session_frame,:opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP, :padding => 0)
816
+ @updateCSRF = FXCheckButton.new(csrf_frame, "Update One-Time-Tokens", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
817
+ @updateCSRF.checkState = false
818
+ @csrf_settings_btn = FXButton.new(csrf_frame, "O-T-T Settings")
819
+ @csrf_settings_btn.connect(SEL_COMMAND, method(:openCSRFTokenDialog))
820
+
821
+ @updateCSRF.connect(SEL_COMMAND) do |sender, sel, item|
822
+ if @updateCSRF.checked? then
823
+ @csrf_settings_btn.enable
824
+ else
825
+ @csrf_settings_btn.disable
826
+ end
827
+ end
828
+
829
+ ##################################################
830
+
831
+ ##################################################
832
+
833
+ button_frame = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LAYOUT_RIGHT, :width => 100)
834
+ send_frame = FXVerticalFrame.new(button_frame, :opts => LAYOUT_FILL_Y|LAYOUT_FILL_X, :padding => 2)
835
+ send_frame.backColor = FXColor::Red
836
+ #btn_send = FXButton.new(frame, "\nSEND", ICON_SEND_REQUEST, nil, 0, :opts => ICON_ABOVE_TEXT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LAYOUT_RIGHT, :width => 100)
837
+ @btn_send = FXButton.new(send_frame, "\nSEND", ICON_SEND_REQUEST, nil, 0, :opts => ICON_ABOVE_TEXT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_FILL_X|LAYOUT_RIGHT)
838
+ btn_prev = FXButton.new(button_frame, "preview >>", nil, nil, 0, :opts => LAYOUT_FILL_X|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT)
839
+ btn_prev.connect(SEL_COMMAND,method(:onPreviewClick))
840
+
841
+ frame = FXHorizontalFrame.new(req_editor, :opts => LAYOUT_FILL_X|FRAME_GROOVE)
842
+
843
+ btn_quickscan = FXButton.new(frame, "QuickScan", nil, nil, 0, FRAME_RAISED|FRAME_THICK)
844
+ btn_quickscan.connect(SEL_COMMAND, method(:onBtnQuickScan))
845
+ @pbar = FXProgressBar.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK|PROGRESSBAR_HORIZONTAL)
846
+ #@pbar.create
847
+ @pbar.connect(SEL_CHANGED) {
848
+ print ":"
849
+ }
850
+ @pbar.progress = 0
851
+ @pbar.total = 0
852
+ @pbar.barColor=0
853
+ @pbar.barColor = 'grey' #FXRGB(255,0,0)
854
+
855
+ # TODO: Implement font sizing
856
+ #@req_builder.font = FXFont.new(app, "courier" , 14, :encoding=>FONTENCODING_ISO_8859_1)
857
+
858
+ result_viewer = FXVerticalFrame.new(top_splitter, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE|LAYOUT_FIX_WIDTH, :width => 400)
859
+
860
+ # log_viewer = FXVerticalFrame.new(bottom_frame, :opts => LAYOUT_FILL_X|FRAME_GROOVE|LAYOUT_BOTTOM)
861
+
862
+ @tabBook = FXTabBook.new(result_viewer, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
863
+
864
+ resp_tab = FXTabItem.new(@tabBook, "Response", nil)
865
+ frame = FXVerticalFrame.new(@tabBook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
866
+ @response_viewer = Watobo::Gui::ResponseViewer.new(frame, LAYOUT_FILL_X|LAYOUT_FILL_Y)
867
+ #@response_viewer.ma
868
+ @response_viewer.max_len = 0
869
+
870
+ options = FXHorizontalFrame.new(frame, :opts => LAYOUT_FILL_X)
871
+ frame = FXHorizontalFrame.new(options, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN)
872
+ frame.backColor = FXColor::White
873
+ label = FXLabel.new(frame, "MD5: ", :opts => LAYOUT_FILL_Y|JUSTIFY_CENTER_Y)
874
+ label.backColor = FXColor::White
875
+ @responseMD5 = FXLabel.new(frame, "-N/A-", :opts => LAYOUT_FILL_Y|JUSTIFY_CENTER_Y)
876
+ @responseMD5.backColor = FXColor::White
877
+
878
+ browser_button = FXButton.new(options, "Browser-View", ICON_BROWSER_MEDIUM, nil, 0, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
879
+ browser_button.connect(SEL_COMMAND) {
880
+ begin
881
+ if @last_request and @last_response then
882
+ #@interface.openBrowser(@last_request, @last_response)
883
+ notify(:show_browser_preview, @last_request, @last_response)
884
+ end
885
+ rescue => bang
886
+ puts bang
887
+
888
+ end
889
+ }
890
+
891
+ req_tab = FXTabItem.new(@tabBook, "Request", nil)
892
+ @request_viewer = Watobo::Gui::RequestViewer.new(@tabBook, FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
893
+
894
+ diff_tab = FXTabItem.new(@tabBook, "Differ", nil)
895
+
896
+ @diff_frame = DiffFrame.new(@tabBook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
897
+
898
+ # log_frame_header = FXHorizontalFrame.new(log_frame, :opts => LAYOUT_FILL_X)
899
+ # FXLabel.new(log_frame_header, "Logs:" )
900
+
901
+ log_text_frame = FXVerticalFrame.new(log_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
902
+ @log_viewer = LogViewer.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
903
+ #--------------------------------------------------------------------------------
904
+
905
+ @btn_send.connect(SEL_COMMAND, method(:onBtnSendClick))
906
+
907
+ add_update_timer(50)
908
+
909
+ rescue => bang
910
+ puts bang
911
+ puts bang.backtrace if $DEBUG
912
+ end
913
+
914
+ end
915
+
916
+ private
917
+
918
+ def add_update_timer(ms)
919
+ @update_timer = FXApp.instance.addTimeout( ms, :repeat => true) {
920
+ @update_lock.synchronize do
921
+ unless @new_response.nil?
922
+
923
+ @response_viewer.setText @new_response
924
+
925
+ if @logChat.checked? == true
926
+
927
+ chat = Watobo::Chat.new(@new_request, @new_response, :source => CHAT_SOURCE_MANUAL, :run_passive_checks => false)
928
+
929
+ notify(:new_chat, chat)
930
+ end
931
+
932
+
933
+ unless @new_request.nil? then
934
+ @request_viewer.setText @new_request
935
+
936
+ @response_viewer.setText(@new_response, :filter => true)
937
+ @responseMD5.text = @new_response.contentMD5
938
+
939
+ addHistoryItem(@new_request, @new_response, @req_builder.rawRequest)
940
+
941
+ @history_pos_dt.value = @history.length
942
+ @history_pos.handle(self, FXSEL(SEL_UPDATE, 0), nil)
943
+ # puts @req_builder.rawRequest
944
+ else
945
+ logger("ERROR: #{@last_response.first}");
946
+ @responseMD5.text = "- N/A -"
947
+ end
948
+
949
+ @new_request = nil
950
+ @new_response = nil
951
+
952
+ end
953
+ end
954
+
955
+ }
956
+ end
957
+
958
+ def sendManualRequest
959
+ @request_viewer.setText('')
960
+ @response_viewer.setText('')
961
+ new_request = @req_builder.parseRequest
962
+
963
+ if new_request.nil?
964
+ logger("Could not send request!")
965
+ return false
966
+ end
967
+
968
+
969
+ if @updateCSRF.checked?
970
+ @csrf_requests = []
971
+ @project.getCSRFRequestIDs(new_request).each do |id|
972
+ chat = @project.getChat(id)
973
+ @csrf_requests.push chat.copyRequest
974
+
975
+ end
976
+ end
977
+
978
+ prefs = {:run_login => @updateSession.checked? ? @runLogin.checked? : false,
979
+ :update_session => @updateSession.checked?,
980
+ :update_contentlength => @updateContentLength.checked?,
981
+ :update_csrf_tokens => @updateCSRF.checked?,
982
+ :csrf_requests => @csrf_requests,
983
+ :csrf_patterns => @project.getCSRFPatterns(),
984
+ :update_sids => @updateSID.checked?,
985
+ :follow_redirect => @followRedirect.checked?
986
+ }
987
+
988
+ prefs.update @project.getScanPreferences
989
+ # puts "=== Scan Preferences"
990
+ # puts prefs.to_yaml
991
+
992
+ @request_thread = Thread.new(new_request, prefs) { |nr, p|
993
+ #nr = new_request
994
+ #p = prefs
995
+
996
+ begin
997
+ logger("send request")
998
+ # puts p.to_yaml
999
+ last_request, last_response = @request_sender.sendRequest(nr, p )
1000
+
1001
+ logger("got answer")
1002
+
1003
+ if @logChat.checked? == true
1004
+ logger("log chat")
1005
+ chat = Watobo::Chat.new(last_request, last_response, :source => CHAT_SOURCE_MANUAL, :run_passive_checks => false)
1006
+ notify(:new_chat, chat)
1007
+ end
1008
+
1009
+
1010
+ #puts "finished (#{last_response.status})"
1011
+ # puts last_request.url
1012
+ # puts last_response.status
1013
+
1014
+
1015
+ =begin
1016
+ if last_request and p[:follow_redirect] == true and last_response.status =~ /302/
1017
+ if @logChat.checked? == true
1018
+ chat = Watobo::Chat.new(last_request, last_response, :source => CHAT_SOURCE_MANUAL, :run_passive_checks => false)
1019
+ notify(:new_chat, chat)
1020
+ end
1021
+ # puts "* Following redirect"
1022
+
1023
+ loc_header = last_response.headers("Location:").first
1024
+ new_location = loc_header.gsub(/^[^:]*:/,'').strip
1025
+ unless new_location =~ /^http/
1026
+ new_location = last_request.proto + "://" + last_request.site + "/" + last_request.dir + "/" + new_location.sub(/^[\.\/]*/,'')
1027
+ end
1028
+ logger("follow redirect: #{new_location}")
1029
+ # create GET request for new location
1030
+ nr.replaceMethod("GET")
1031
+ nr.removeHeader("Content-Length")
1032
+ nr.removeBody()
1033
+ nr.replaceURL(new_location)
1034
+ # puts nr.first
1035
+ last_request, last_response = @request_sender.sendRequest(nr, p )
1036
+ logger("got answer")
1037
+ end
1038
+ =end
1039
+ @new_request = last_request
1040
+ @new_response = last_response
1041
+
1042
+ rescue => bang
1043
+ puts bang
1044
+
1045
+ end
1046
+ }
1047
+
1048
+ end
1049
+
1050
+ def trans2Get(sender, sel, item)
1051
+ request = @req_builder.parseRequest
1052
+ return nil if request.nil?
1053
+ @project.extendRequest(request)
1054
+
1055
+ # puts sender.methods.sort
1056
+ # puts sel
1057
+ # puts item
1058
+
1059
+ if request.method =~ /POST/i
1060
+ request.setMethod("GET")
1061
+ request.removeHeader("Content-Length")
1062
+ data = request.data
1063
+ # puts "Data: "
1064
+ # puts data
1065
+ request.appendQueryParms(data)
1066
+ request.setData('')
1067
+ end
1068
+ @req_builder.setRequest(request)
1069
+ end
1070
+
1071
+ def trans2Post(sender, sel, item)
1072
+ request = @req_builder.parseRequest
1073
+ return nil if request.nil?
1074
+ @project.extendRequest(request)
1075
+
1076
+ # puts sender.methods.sort
1077
+ # puts sel
1078
+ # puts item
1079
+ if request.method =~ /GET/i
1080
+ request.setMethod("POST")
1081
+ request.addHeader("Content-Length", "0")
1082
+ data = request.query
1083
+ request.setData(data)
1084
+ request.removeUrlParms()
1085
+
1086
+ end
1087
+ @req_builder.setRequest(request)
1088
+ end
1089
+
1090
+ def simulatePressSendBtn()
1091
+ Thread.new{
1092
+ @btn_send.state = STATE_DOWN
1093
+ sleep 0.1
1094
+ @btn_send.state = STATE_UP
1095
+ }
1096
+ end
1097
+
1098
+ def hide()
1099
+ @scanner.cancel() if @scanner
1100
+ self.destroy
1101
+ end
1102
+
1103
+ end
1104
+ end
1105
+ end