From ccbf88f5a34e989f98e244bb2e0d12aff92ec6ce Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sat, 14 Mar 2009 05:06:13 +0000 Subject: [PATCH] Fixes TCP socket evasion (max_send_size and send_delay) git-svn-id: file:///home/svn/framework3/trunk@6340 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/exploit/tcp.rb | 111 ++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/lib/msf/core/exploit/tcp.rb b/lib/msf/core/exploit/tcp.rb index 9cd9d861b0..20179838aa 100644 --- a/lib/msf/core/exploit/tcp.rb +++ b/lib/msf/core/exploit/tcp.rb @@ -1,47 +1,39 @@ module Msf -# this module provides instance methods to be used in overloading to do single byte sending of data -module SmallSend - def write(buf, opts = {}) - warn "smallsend write" - - tsent = 0; bidx = 0 - - if self._send_size == nil or self._send_size == 0 - self._send_size = 1 - end +module EvasiveTCP + attr_accessor :_send_size, :_send_delay, :evasive - while (bidx < buf.length) - str = buf[bidx, _send_size] - sent = super(str, opts) - bidx += sent if sent > 0 - tsent += sent - - if self.is_a?(SlowSend) - sleep(self._send_delay) - else - sleep(0) + def denagle + begin + setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + rescue ::Exception + end + end + + def write(buf, opts={}) + + return super(buf, opts) if not @evasive + + ret = 0 + idx = 0 + len = @_send_size || buf.length + + while(idx < buf.length) + + if(@_send_delay and idx > 0) + select(nil, nil, nil, @_send_delay) end - end + + pkt = buf[idx, len] - return tsent + res = super(pkt, opts) + flush() + + idx += len + ret += res if res + end + ret end - - attr_accessor :_send_size -end - -# this module provides instance mehtods to be used in overloading of Socket to insert delays inbetween each write -module SlowSend - def write(buf, opts = {}) - warn 'slowsend write' - if !self.is_a?(SmallSend) - sleep(_send_delay) - end - response = super(buf, opts) - return response - end - - attr_accessor :_send_delay end ### @@ -103,8 +95,7 @@ module Exploit::Remote::Tcp }) # enable evasions on this socket - # XXX implement evasions!!!! - # evasions(nsock) + set_tcp_evasions(nsock) # Set this socket to the global socket as necessary self.sock = nsock if (global) @@ -115,6 +106,29 @@ module Exploit::Remote::Tcp return nsock end + # Enable evasions on a given client + def set_tcp_evasions(socket) + + if( datastore['TCP::max_send_size'] == 0 and datastore['TCP::send_delay'] == 0) + return + end + + return if socket.respond_to?('evasive') + + socket.extend(EvasiveTCP) + + if ( datastore['TCP::max_send_size'] > 0) + socket._send_size = datastore['TCP::max_send_size'] + socket.denagle + socket.evasive = true + end + + if ( datastore['TCP::send_delay'] > 0) + socket._send_delay = datastore['TCP::send_delay'] + socket.evasive = true + end + end + def handler(nsock = self.sock) # If the handler claims the socket, then we don't want it to get closed # during cleanup @@ -377,23 +391,6 @@ module Exploit::Remote::TcpServer end end - # Enable evasions on a given client - def evasions(socket) - # XXX - oooogly - return if socket.instance_variables.member?('@tcp_evasion') - - if !socket.is_a?(SmallSend) and datastore['TCP::max_send_size'] > 0 - socket.extend(SmallSend) - socket._send_size = datastore['TCP::max_send_size'] - end - - if !socket.is_a?(SlowSend) and datastore['TCP::send_delay'] > 0 - socket.extend(SlowSend) - socket._send_delay = datastore['TCP::send_delay'] - end - socket.instance_eval('@tcp_evasion = 1') - end - # # Returns the local host that is being listened on. #