How to Make a Simple UDP_Flooder in C pt2
Alright so last time I gave you a homework assignment. This week we're gonna look at my version of the UDP-Flooder.
It can be found here.
Alright, I assume you've written yours or at least attempted to.
First let's take a look at the struct used in this program
This struct is used to store the port and ipadress.
It has 3 members:
in-port sin-port is the port, we'll use a function to assign the value.
struct in-addr sin-addr is the IP adress, it is a struct, we'll not go into detail about this struct, since we'll use a function to assign the values of it.
sin-zero is used to make sockaddr-in the size of sockaddr. This is important so we can typecast sockaddr-in as sockaddr.
Notice the arithmics used for the size of the array sin-zero.
It is convention to use memset() to zero out sin-zero, however this will not be needed in this UDP-Flooder.
Now let's look at the functions used in this program.
Check man 2 socket if you haven't already
This is what creates a socket. It returns a socketdescriptor which is comparable to the file descriptor.
Takes 3 arguments:
- int domain
- int type
- int protocol
domain is used to specify a communication domain.
Most used are AF INET, AF INET6 for internet sockets.
These represent IPv4 and IPv6 respectively.
type is used to specify whether you are using SOCK STREAM ,
SOCK DGRAM, SOCK RAW, or something else.
The first two are standard in TCP and UDP respectively.
The third one will be discussed in the next part of this serie ;)
protocol is used to specify the protocol you are using. It depends on the type what the numbers mean. Check out /usr/include/netinet/in.h for a full list.
For a this UDP Flooder I have used AF INET, SOCK DGRAM and IPPROTO UDP.
Used to return the size of a variable or datatype in bytes. Useful for function's that take the size of a certain variable or datatype as an argument.
Takes two arguments:
- const char address (POINTER)
- struct in addr inp (POINTER)
The const char address is a string in the format of an ip adress, for example: "127.0.0.1", in this program I've used argv1 as argument.
the struct serv.sin-addr is where the value will be stored.
The program will take adress as argument, convert it into computer readable, and store that in serv.sin-addr
Notice that I use &serv.sin-addr in the function. This is the memory address of serv.sin-addr, so it can be used as the argument struct in addr inp of function inet-aton().
Takes one argument, hostshort.
Used to change hostbyte order to network byte order.
With host byte order is meant, the byte order that your machine uses.
This can be either Little Endian or Big Endian. Google this if you want to know more about this, what is important, is that the (inter)net uses Big Endian, and in networking is called network byte order.
So what this program does, is check what your machine uses, Big Endian convert Little Endian, convert it to Big Endian if needed, and finally return the value as uint16-t.
Alright, this function is what actually sends the packet.
It takes 6 arguments:
- int socket
- const void message (POINTER)
- size-t length
- int flags
- const struct sockaddr dest-addr (POINTER)
- socklen-t dest-len
So socket, will be the socket descriptor returned by socket().
message is a pointer to the message, can also give it a string.
size-t length is the length of the message, I just put 2 here since the message is of no importance in this flooder and I just made it as short as possible.
int flags Used to set flags, check the man page, 0 for no flags.
const struct sockaddr dest-addr(POINTER) Alright, as I said in the sockaddr-in part, sockaddr-in has the same size as sockaddr.
I will not go into detail about the differences between these two, but keep just remember that sockaddr-in is used for internet socket and sockaddr is used for general purpose sockets.
Because sockaddr-in has the same size as sockaddr and the members of sockaddr-in and sockaddr start with the same two members, the struct serv of type sockaddr-in, can be typecasted as sockaddr (Remember serv is stored in memory and the members are right next to each other).
Because it needed a pointer I just did &serv.
socklen-t dest-len This is the sizeof the sockaddr-in struct, I did sizeof(serv), but you might as well do sizeof(sockaddr-in). It's just that this seems a better conventions.
This was the easiest part, I even gave it away in the pseudo code.
I assigned the ipaddr outside the for loop and the portaddr inside the for loop to make it reassign every cycle. Then each cycle it sends the message.
Well most OS'es nowadays are protected against this attack by limeting the max rate at which the OS will send ICMP packets.
Alternatively you can use a Firewall to block the UDP packets, so they will never reach the target.
So next tutorial we'll be making a UDP-Flooder with forged source IP, this is a bit header, as you need to forge the datagram.
Hope you liked it.