Class: Watobo::Session
- Inherits:
-
Object
- Object
- Watobo::Session
- Includes:
- Constants, Subscriber
- Defined in:
- lib/watobo/core/session.rb
Overview
:nodoc: all
Direct Known Subclasses
ActiveCheck, Gui::ManualRequestSender, Gui::SaveChatDialog::Sender
Constant Summary collapse
- @@settings =
Hash.new
- @@proxy =
Hash.new
- @@session_lock =
Mutex.new
- @@login_mutex =
Mutex.new
- @@login_cv =
ConditionVariable.new
- @@login_in_progress =
false
Constants included from Constants
Constants::AC_GROUP_APACHE, Constants::AC_GROUP_DOMINO, Constants::AC_GROUP_ENUMERATION, Constants::AC_GROUP_FILE_INCLUSION, Constants::AC_GROUP_FLASH, Constants::AC_GROUP_GENERIC, Constants::AC_GROUP_JBOSS, Constants::AC_GROUP_JOOMLA, Constants::AC_GROUP_SAP, Constants::AC_GROUP_SQL, Constants::AC_GROUP_TYPO3, Constants::AC_GROUP_XSS, Constants::AUTH_TYPE_BASIC, Constants::AUTH_TYPE_DIGEST, Constants::AUTH_TYPE_NONE, Constants::AUTH_TYPE_NTLM, Constants::AUTH_TYPE_UNKNOWN, Constants::CHAT_SOURCE_AUTO_SCAN, Constants::CHAT_SOURCE_FUZZER, Constants::CHAT_SOURCE_INTERCEPT, Constants::CHAT_SOURCE_MANUAL, Constants::CHAT_SOURCE_MANUAL_SCAN, Constants::CHAT_SOURCE_PROXY, Constants::CHAT_SOURCE_UNDEF, Constants::DEFAULT_PORT_HTTP, Constants::DEFAULT_PORT_HTTPS, Constants::FINDING_TYPE_HINT, Constants::FINDING_TYPE_INFO, Constants::FINDING_TYPE_UNDEFINED, Constants::FINDING_TYPE_VULN, Constants::FIRST_TIME_FILE, Constants::GUI_REGULAR_FONT_SIZE, Constants::GUI_SMALL_FONT_SIZE, Constants::ICON_PATH, Constants::LOG_DEBUG, Constants::LOG_INFO, Constants::SCAN_CANCELED, Constants::SCAN_FINISHED, Constants::SCAN_PAUSED, Constants::SCAN_STARTED, Constants::TE_CHUNKED, Constants::TE_COMPRESS, Constants::TE_DEFLATE, Constants::TE_GZIP, Constants::TE_IDENTITY, Constants::TE_NONE, Constants::VULN_RATING_CRITICAL, Constants::VULN_RATING_HIGH, Constants::VULN_RATING_INFO, Constants::VULN_RATING_LOW, Constants::VULN_RATING_MEDIUM, Constants::VULN_RATING_UNDEFINED
Instance Method Summary collapse
- #addProxy(prefs = nil) ⇒ Object
-
#doRequest(request, opts = {}) ⇒ Object
+++ doRequest(request) +++ + function:.
- #get_settings ⇒ Object
- #getProxy(site = nil) ⇒ Object
-
#initialize(session_id = nil, prefs = {}) ⇒ Session
constructor
INITIALIZE.
- #readHTTPBody(socket, response, request, prefs = {}) ⇒ Object
- #runLogin(chat_list, prefs = {}) ⇒ Object
-
#sendHTTPRequest(request, prefs = {}) ⇒ Object
sendHTTPRequest returns Socket, ResponseHeader.
- #sessionSettings ⇒ Object
- #setSIDCache(new_cache = {}) ⇒ Object
- #sidCache ⇒ Object
Methods included from Subscriber
#clearEvents, #notify, #subscribe
Constructor Details
#initialize(session_id = nil, prefs = {}) ⇒ Session
INITIALIZE
Possible preferences: :proxy => ‘127.0.0.1:port’ :valid_sids => Hash.new, :sid_patterns => [], :logout_signatures => [], :update_valid_sids => false, :update_sids => false, :update_contentlength => true
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/watobo/core/session.rb', line 465 def initialize( session_id=nil, prefs={} ) @event_dispatcher_listeners = Hash.new # @session = {} session = nil session = ( session_id.is_a? Fixnum ) ? session_id : session_id.object_id session = Digest::MD5.hexdigest(Time.now.to_f.to_s) if session_id.nil? @sid_cache = Watobo::SIDCache.acquire(session) unless @@settings.has_key? session @@settings[session] = { :logout_signatures => [], :logout_content_types => Hash.new, :update_valid_sids => false, :update_sids => false, :update_otts => false, :update_session => true, :update_contentlength => true, :login_chats => [], :www_auth => Hash.new, :client_certificates => {}, :proxy_auth => Hash.new } end @session = @@settings[session] # shortcut to settings @session.update prefs # @valid_csrf_tokens = Hash.new addProxy( prefs[:proxy] ) if prefs.is_a? Hash and prefs[:proxy] @socket = nil @ctx = OpenSSL::SSL::SSLContext.new() @ctx.key = nil @ctx.cert = nil # TODO: Implement switches for URL-Encoding (http://www.blooberry.com/indexdot/html/topics/urlencoding.htm) # TODO: Implement switches for Following Redirects # TODO: Implement switches for Logging, Debugging, ... end |
Instance Method Details
#addProxy(prefs = nil) ⇒ Object
428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
# File 'lib/watobo/core/session.rb', line 428 def addProxy(prefs=nil) proxy = nil unless prefs.nil? proxy = Proxy.new(prefs) # proxy.setCredentials(prefs[:credentials]) unless prefs[:credentials].nil? unless prefs[:site].nil? @@proxy[prefs[:site]] = proxy return end end @@proxy[:default] = proxy end |
#doRequest(request, opts = {}) ⇒ Object
+++ doRequest(request) +++ + function:
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
# File 'lib/watobo/core/session.rb', line 309 def doRequest(request, opts={} ) begin ott_cache = Watobo::OTTCache.acquire(request) @session.update opts # puts "[doRequest] #{@session.to_yaml}" # puts "#[#{self.class}]" + @session[:csrf_requests].first.object_id.to_s # unless @session[:csrf_requests].empty? or @session[:csrf_patterns].empty? unless Watobo::OTTCache.requests(request).empty? or @session[:update_otts] == false Watobo::OTTCache.requests(request).each do |req| copy = Watobo::Request.new YAML.load(YAML.dump(req)) #updateCSRFToken(csrf_cache, copy) ott_cache.update_request(copy) socket, csrf_request, csrf_response = sendHTTPRequest(copy, opts) next if socket.nil? # puts "= Response Headers:" # puts csrf_response # puts "===" #update_sids(csrf_request.host, csrf_response.headers) @sid_cache.update_sids(csrf_request.site, csrf_response.headers) if @session[:update_sids] == true next if socket.nil? # p "*" # csrf_response = readHTTPHeader(socket) readHTTPBody(socket, csrf_response, csrf_request, opts) # response = Response.new(csrf_response) next unless csrf_response.has_body? csrf_response.unchunk! csrf_response.unzip! @sid_cache.update_sids(csrf_request.site, [csrf_response.body]) if @session[:update_sids] == true # updateCSRFCache(csrf_cache, csrf_request, [csrf_response.body]) if csrf_response.content_type =~ /text\// ott_cache.update_tokens( [csrf_response.body]) if csrf_response.content_type =~ /text\// # socket.close closeSocket(socket) end #p @session[:csrf_requests].length #updateCSRFToken(csrf_cache, request) ott_cache.update_request(request) end socket, request, response = sendHTTPRequest(request, opts) if socket.nil? return request, response #return request, nil end @sid_cache.update_sids(request.site, response.headers) if @session[:update_sids] == true if @session[:follow_redirect] # puts response.status if response.status =~ /^30(1|2|8)/ #response.extend Watobo::Mixin::Parser::Web10 #request.extend Watobo::Mixin::Shaper::Web10 loc_header = response.headers("Location:").first new_location = loc_header.gsub(/^[^:]*:/,'').strip unless new_location =~ /^http/ if new_location =~ /^\// new_location = request.proto + "://" + request.site + new_location else new_location = request.proto + "://" + request.site + "/" + request.dir + "/" + new_location.sub(/^[\.\/]*/,'') end end notify(:follow_redirect, new_location) nr = Watobo::Request.new YAML.load(YAML.dump(request)) # create GET request for new location nr.replaceMethod("GET") nr.removeHeader("Content-Length") nr.removeBody() nr.replaceURL(new_location) socket, request, response = sendHTTPRequest(nr, opts) if socket.nil? #return nil, request return request, response end end end readHTTPBody(socket, response, request, opts) unless response.body.nil? @sid_cache.update_sids(request.site, [response.body]) if @session[:update_sids] == true and response.content_type =~ /text\// end #socket.close closeSocket(socket) rescue => bang # puts "! Error in doRequest" puts "! Module #{Module.nesting[0].name}" puts bang puts bang.backtrace if $DEBUG @lasterror = bang # raise # ensure end #response.extend Watobo::Mixin::Parser::Web10 # resp = Watobo::Response.new(response) response.unchunk! response.unzip! return Request.new(request), response end |
#get_settings ⇒ Object
443 444 445 |
# File 'lib/watobo/core/session.rb', line 443 def get_settings @@settings end |
#getProxy(site = nil) ⇒ Object
447 448 449 450 451 452 |
# File 'lib/watobo/core/session.rb', line 447 def getProxy(site=nil) unless site.nil? return @@proxy[site] unless @@proxy[site].nil? end return @@proxy[:default] end |
#readHTTPBody(socket, response, request, prefs = {}) ⇒ Object
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
# File 'lib/watobo/core/session.rb', line 510 def readHTTPBody(socket, response, request, prefs={}) clen = response.content_length data = "" begin if response.is_chunked? Watobo::HTTPSocket.readChunkedBody(socket) { |c| data += c } elsif clen > 0 # puts "* read #{clen} bytes for body" Watobo::HTTPSocket.read_body(socket, :max_bytes => clen) { |c| data += c break if data.length == clen } elsif clen < 0 # puts "* no content-length information ... mmmmmpf" # eofcount = 0 Watobo::HTTPSocket.read_body(socket) do |c| data += c end end response.push data unless data.empty? unless prefs[:ignore_logout]==true or @session[:logout_signatures].empty? notify(:logout, self) if loggedOut?(response) end @sid_cache.update_sids(request.site, response) if prefs[:update_sids] == true return true rescue => e puts "! Could not read response" puts e # puts e.backtrace end return false end |
#runLogin(chat_list, prefs = {}) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/watobo/core/session.rb', line 19 def runLogin(chat_list, prefs={}) #puts @session.object_id @@login_mutex.synchronize do begin @@login_in_progress = true login_prefs = Hash.new login_prefs.update prefs dummy = {:ignore_logout => true, :update_sids => true, :update_session => true, :update_contentlength => true} login_prefs.update dummy puts "! Start Login ..." if $DEBUG unless chat_list.empty? # puts login_prefs.to_yaml chat_list.each do |chat| puts "! LoginRequest: #{chat.id}" if $DEBUG test_req = chat.copyRequest request, response = doRequest(test_req, login_prefs) end else puts "! no login script configured !" end rescue => bang puts "!ERROR in runLogin" puts bang.backtrace if $DEBUG ensure @@login_in_progress = false @@login_cv.signal end end end |
#sendHTTPRequest(request, prefs = {}) ⇒ Object
sendHTTPRequest returns Socket, ResponseHeader
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/watobo/core/session.rb', line 56 def sendHTTPRequest(request, prefs={}) begin @lasterror = nil response_header = nil site = request.site # proxy = getProxy(site) proxy = Watobo::ForwardingProxy.get(site) unless proxy.nil? host = proxy.host port = proxy.port else host = request.host port = request.port end # check if hostname is valid and can be resolved hostip = IPSocket.getaddress(host) # update current preferences, prefs given here are stronger then global settings! current_prefs = Hash.new [:update_session, :update_sids, :update_contentlength, :ssl_cipher, :www_auth, :client_certificates, :egress_handler ].each do |k| current_prefs[k] = prefs[k].nil? ? @session[k] : prefs[k] end @sid_cache.update_request(request) if current_prefs[:update_session] == true #--------------------------------------- # request.removeHeader("^Proxy-Connection") #if not use_proxy # request.removeHeader("^Connection") #if not use_proxy # !!! # remove Accept-Encoding header # otherwise we won't get the content-length information for pass-through feature request.removeHeader("^Accept-Encoding") # If-Modified-Since: Tue, 28 Oct 2008 11:06:43 GMT # If-None-Match: W/"3975-1225192003000" # request.removeHeader("^If-") # puts # request.each do |line| # puts line.unpack("H*") #end #puts if current_prefs[:update_contentlength] == true and request.has_body? then #puts request.body.unpack("H*")[0] #puts (request.body.unpack("H*")[0].length / 2).to_s request.fix_content_length() #puts "New: #{request.content_length}" #puts request.body.encoding #puts "--" end # # Engress Handler unless current_prefs[:egress_handler].nil? unless current_prefs[:egress_handler].empty? h = Watobo::EgressHandlers.create current_prefs[:egress_handler] unless h.nil? h.execute request end end end #request.add_header("Via", "Watobo") if use_proxy #puts request # puts "==============" rescue SocketError puts "!!! unknown hostname #{host}" puts request.first return nil, "WATOBO: Could not resolve hostname #{host}", nil rescue => bang puts bang puts bang.backtrace if $DEBUG end begin unless proxy.nil? # connection requires proxy # puts "* use proxy #{proxy.name}" # check for regular proxy authentication if request.is_ssl? socket, response_header = sslProxyConnect(request, proxy, current_prefs) return socket, response_header, error_response("Could Not Connect To Proxy: #{proxy.name} (#{proxy.host}:#{proxy.port})\n", "#{response_header}") if socket.nil? if current_prefs[:www_auth].has_key?(site) case current_prefs[:www_auth][site][:type] when AUTH_TYPE_NTLM # puts "* found NTLM credentials for site #{site}" socket, response_header = wwwAuthNTLM(socket, request, current_prefs[:www_auth][site]) else puts "* Unknown Authentication Type: #{current_prefs[:www_auth][site][:type]}" end else data = request.join + "\r\n" unless socket.nil? socket.print data response_header = readHTTPHeader(socket, current_prefs) end end return socket, Request.new(request), Response.new(response_header) end # puts "* doProxyRequest" socket, response_header = doProxyRequest(request, proxy, current_prefs) # puts socket.class return socket, response_header, error_response("Could Not Connect To Proxy: #{proxy.name} (#{proxy.host}:#{proxy.port})\n", "#{response_header}") if socket.nil? return socket, Request.new(request), Response.new(response_header) else # direct connection to host tcp_socket = nil # timeout(6) do #puts "* no proxy - direct connection" tcp_socket = TCPSocket.new( host, port ) #optval = [1, 5000].pack("I_2") #tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval #tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) #tcp_socket.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1 tcp_socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) tcp_socket.sync = true socket = tcp_socket if request.is_ssl? ssl_prefs = {} ssl_prefs[:ssl_cipher] = current_prefs[:ssl_cipher] if current_prefs.has_key? :ssl_cipher #if current_prefs.has_key? :client_certificates # if current_prefs[:client_certificates].has_key? request.site # puts "* use ssl client certificate for site #{request.site}" if $DEBUG # ssl_prefs[:ssl_client_cert] = current_prefs[:client_certificates][request.site][:ssl_client_cert] # ssl_prefs[:ssl_client_key] = current_prefs[:client_certificates][request.site][:ssl_client_key] # end #end unless Watobo::ClientCertStore.get(site).nil? # puts "* using client cert for site #{site}" client_cert = Watobo::ClientCertStore.get(site) ssl_prefs[:client_certificate] = client_cert end # need hostname for SNI (Server Name Indication) # http://en.wikipedia.org/wiki/Server_Name_Indication ssl_prefs[:hostname] = host socket = sslConnect(tcp_socket, ssl_prefs) # puts "SSLSocket " + (socket.nil? ? "NO" : "OK") return nil, request, [] if socket.nil? end #puts socket.class # remove URI before sending request but cache it for restoring request uri_cache = nil uri_cache = request.removeURI #if proxy.nil? # request.addHeader("Proxy-Connection", "Close") unless proxy.nil? # request.set_header("Accept-Encoding", "gzip;q=0;identity; q=0.5, *;q=0") #don't want encoding # request.set_header("Connection", "close") unless request.has_header?("Upgrade") if current_prefs[:www_auth].has_key?(site) case current_prefs[:www_auth][site][:type] when AUTH_TYPE_NTLM # puts "* found NTLM credentials for site #{site}" socket, response_header = wwwAuthNTLM(socket, request, current_prefs[:www_auth][site]) request.restoreURI(uri_cache) else puts "* Unknown Authentication Type: #{current_prefs[:www_auth][site][:type]}" end else # puts "========== Add Headers" request.set_header("Connection", "close") #if not use_proxy data = request.join unless request.has_body? data << "\r\n" unless data =~ /\r\n\r\n$/ end # puts "\n*** SENDING ..." # puts data # if request.has_body? # puts request.body.length # bhex = request.body.unpack("H*")[0] # puts bhex # puts bhex.length # end #puts "= SESSION =" #puts data #puts data.unpack("H*")[0]#.gsub(/0d0a/,"0d0a\n") # puts "---" unless socket.nil? socket.print data socket.flush response_header = readHTTPHeader(socket, current_prefs) end # RESTORE URI FOR HISTORY/LOG request.restoreURI(uri_cache) end return socket, Watobo::Request.new(request), Watobo::Response.new(response_header) end rescue Errno::ECONNREFUSED response = error_response "connection refused (#{host}:#{port})" puts response socket = nil rescue Errno::ECONNRESET response = error_response "connection reset (#{host}:#{port})" socket = nil rescue Errno::ECONNABORTED response = error_response "connection aborted (#{host}:#{port})" socket = nil rescue Errno::EHOSTUNREACH response = error_response "host unreachable (#{host}:#{port})" socket = nil rescue Timeout::Error #request = "WATOBO: TimeOut (#{host}:#{port})\n" response = error_response "TimeOut (#{host}:#{port})" socket = nil rescue Errno::ETIMEDOUT puts "TimeOut (#{host}:#{port})" response = error_response "TimeOut (#{host}:#{port})" socket = nil rescue Errno::ENOTCONN puts "!!!ENOTCONN" rescue OpenSSL::SSL::SSLError response = error_response "SSL-Error", $!.to_s + "<br>" + $!.backtrace.join("<br>") socket = nil rescue => bang response = error_response "ERROR:", "#{bang}\n#{bang.backtrace}" socket = nil puts bang puts bang.backtrace if $DEBUG end #puts response return socket, request, response end |
#sessionSettings ⇒ Object
50 51 52 |
# File 'lib/watobo/core/session.rb', line 50 def sessionSettings() @@settings end |
#setSIDCache(new_cache = {}) ⇒ Object
302 303 304 |
# File 'lib/watobo/core/session.rb', line 302 def setSIDCache(new_cache = {} ) @session[:valid_sids] = new_cache if new_cache.is_a? Hash end |
#sidCache ⇒ Object
297 298 299 300 |
# File 'lib/watobo/core/session.rb', line 297 def sidCache() #puts @project @session[:valid_sids] end |