amapcrap.c

来自「Ubuntu packages of security software。 相」· C语言 代码 · 共 577 行

C
577
字号
/* * AmapCrap (c) 2003 by van Hauser / THC <vh@thc.org> * http://www.thc.org * * Sends random data to silent ports to illicit a reponse. For use with amap * for protocol identification. * * Use allowed only for legal purposes. * * To compile:   cc -o amapcrap -O2 amapcrap.c * with openssl: cc -o amapcrap -O2 amapcrap.c -DOPENSSL -lssl * */#include "amap-inc.h"#include "amap.h"#define UNLIMITED   0		// dont change this#define ASCII "abcdefghijklmnopqrstuvwxyz "#ifdef OPENSSLSSL *ssl = NULL;SSL_CTX *sslContext = NULL;RSA *rsa = NULL;RSA *ssl_temp_rsa_cb(SSL * ssl, int export, int keylength){  if (rsa == NULL)    rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);  return rsa;}#endifchar *prg;int warn = 0;void help(){  printf("amapcrap v%s (c) %s by van Hauser/THC <vh@thc.org>\n\n", AMAP_VERSION, AMAP_YEAR);  printf("Syntax: %s [-S] [-u] [-m 0ab] [-M min,max] [-n connects] [-N delay] [-w delay] [-e] [-v] TARGET PORT\n\n", prg);  printf("Options:\n");  printf("    -S           use SSL after TCP connect (not usuable with -u)\n");  printf("    -u           use UDP protocol (default: TCP) (not usable with -c)\n");  printf("    -n connects  maximum number of connects (default: unlimited)\n");  printf("    -N delay     delay between connects in ms (default: 0)\n");  printf("    -w delay     delay before closing the port (default: 250)\n");  printf("    -e           do NOT stop when a response was made by the server\n");  printf("    -v           verbose mode\n");  printf("    -m 0ab       send as random crap:0-nullbytes, a-letters+spaces, b-binary\n");  printf("    -M min,max   minimum and maximum length of random crap\n");  printf("    TARGET PORT  target (ip or dns) and port to send random crap\n\n");  printf("This tool sends random data to a silent port to illicit a response, which can\n");  printf("then be used within amap for future detection. It outputs proper amap\n");  printf("appdefs definitions. Note: by default all modes are activated (0:10%%, a:40%%,\n");  printf("b:50%%). Mode 'a' always sends one line with letters and spaces which end with\n");  printf("\\r\\n. Visit our homepage at http://www.thc.org\n");  exit(-1);}int main(int argc, char *argv[]){  unsigned short int port = 0;  long int max_connects = UNLIMITED;  int sent_mode = 0, sent_mode_old = 0;  int send_nullbytes = 1;  int send_ascii = 1;  int send_binary = 1;  int send_min = 3;  int send_max = 256;  int verbose = 0;  int use_ssl = 0;  int debug = 0;  int dont_exit_when_response = 0;  long int connect_delay = 1;  long int close_delay = 250;  unsigned char *str = NULL, *str_old;  int str_len = 0, str_len_old = 0;  int i, j;  int s;  int ret;  int reads = 0;  int sock_type = SOCK_STREAM;  int sock_protocol = IPPROTO_TCP;  unsigned char buf[8196];  long int count, successful;  struct sockaddr_in target;  struct hostent *resolv;  int res = 0;#ifdef OPENSSL  int err;#endif#ifndef CYGWIN  char out[16];#endif  srand((getpid() + getuid() + getgid()) ^ time(0));  prg = argv[0];  if (argc < 2 || strncmp(argv[1], "-h", 2) == 0)    help();  while ((i = getopt(argc, argv, "M:N:SVem:n:p:uvw:")) >= 0) {    switch (i) {    case 'M':      if ((str = index(optarg, ',')) == NULL) {	fprintf(stderr,		"Error: Syntax is \"-M min,max\", e.g. \"-M 1,256\".\n");	exit(-1);      }      *str++ = 0;      send_min = atoi(optarg);      send_max = atoi(str);      if (send_min < 3 || send_max < 3 || send_min > 1024 || send_max > 1024	  || send_min > send_max) {	fprintf(stderr,		"Error: min and max values must be between 3 and 1024.\n");	exit(-1);      }      break;    case 'm':      send_nullbytes = 0;      send_ascii = 0;      send_binary = 0;      for (i = 0; i < strlen(optarg); i++)	switch (optarg[i]) {	case '0':	  send_nullbytes = 1;	  break;	case 'a':	case 'A':	  send_ascii = 1;	  break;	case 'b':	case 'B':	  send_binary = 1;	  break;	case 0:	  break;	default:	  fprintf(stderr, "Error: character for -m option unknown: %c\n",		  optarg[i]);	  exit(-1);	}      break;    case 'N':      connect_delay = atol(optarg);      break;    case 'w':      close_delay = atol(optarg);      break;    case 'e':      dont_exit_when_response = 1;      break;    case 'u':      sock_type = SOCK_DGRAM;      sock_protocol = IPPROTO_UDP;      break;    case 'v':      verbose++;      break;    case 'V':      debug = 1;      break;    case 'n':      max_connects = atol(optarg);      break;    case 'S':      use_ssl = 1;#ifndef OPENSSL      fprintf(stderr,	      "Error: Not compiled with openssl support, use -DOPENSSL -lssl\n");      exit(-1);#endif      break;    case 'p':      if (atoi(optarg) < 1 || atoi(optarg) > 65535) {	fprintf(stderr, "Error: port must be between 1 and 65535\n");	exit(-1);      }      port = atoi(optarg) % 65536;      break;    default:      fprintf(stderr, "Error: unknown option -%c\n", i);      help();    }  }  if ((optind + 1 != argc && port > 0) && (optind + 2 != argc && port == 0)) {    fprintf(stderr,	    "Error: target missing or too many commandline options!\n");    exit(-1);  }  if (atoi(argv[argc - 1]) < 1 || atoi(argv[argc - 1]) > 65535) {    fprintf(stderr, "Error: port must be between 1 and 65535\n");    exit(-1);  }  port = atoi(argv[argc - 1]) % 65536;  if ((resolv = gethostbyname(argv[argc - 2])) == NULL) {    fprintf(stderr, "Error: can not resolve target\n");    exit(-1);  }  memset(&target, 0, sizeof(target));  memcpy(&target.sin_addr.s_addr, resolv->h_addr, 4);  target.sin_port = htons(port);  target.sin_family = AF_INET;  if (connect_delay > 0)    connect_delay = connect_delay * 1000;	/* ms to microseconds */  else    connect_delay = 1;  if (close_delay > 0)    close_delay = close_delay * 1000;	/* ms to microseconds */  else    close_delay = 1;  for (i = 3; i < 4096; i++)    close(i);  printf("# Starting AmapCrap on %s port %d\n",#ifdef CYGWIN	 inet_ntoa((struct in_addr) target.sin_addr), port);#else         inet_ntop(AF_INET, &target.sin_addr, (char *) &out, sizeof(out)), port);#endif  (void) setvbuf(stdout, NULL, _IONBF, 0);  printf("# Writing a \"+\" for every 10 connect attempts\n# ");  ret = 0;  count = 0;  successful = 0;  i = 1;  s = -1;  res = 1;  if (use_ssl) {#ifdef OPENSSL    SSL_load_error_strings();    SSLeay_add_ssl_algorithms();    // context: ssl2 + ssl3 is allowed, whatever the server demands    if ((sslContext = SSL_CTX_new(SSLv23_method())) == NULL) {      if (verbose) {	err = ERR_get_error();	fprintf(stderr, "SSL: Error allocating context: %s\n",		ERR_error_string(err, NULL));      }      res = -1;    }    // set the compatbility mode    SSL_CTX_set_options(sslContext, SSL_OP_ALL);    // we set the default verifiers and dont care for the results    (void) SSL_CTX_set_default_verify_paths(sslContext);    SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);    SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);#endif  }  str = malloc(send_max);  str_old = malloc(send_max);  while (count < max_connects || max_connects == UNLIMITED) {    if (ret >= 0) {      if ((s = socket(AF_INET, sock_type, sock_protocol)) < 0) {	perror("Error");	exit(-1);      } else {	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));      }    }    if (s >= 0) {      ret = connect(s, (struct sockaddr *) &target, sizeof(target));      if (use_ssl && ret >= 0) {#ifdef OPENSSL	if ((ssl = SSL_new(sslContext)) == NULL) {	  if (verbose) {	    err = ERR_get_error();	    fprintf(stderr, "Error preparing an SSL context: %s\n",		    ERR_error_string(err, NULL));	  }	  ret = -1;	} else	  SSL_set_fd(ssl, s);	if (ret >= 0 && SSL_connect(ssl) <= 0) {	  printf("ERROR %d\n", SSL_connect(ssl));	  if (verbose) {	    err = ERR_get_error();	    fprintf(stderr, "Could not create an SSL session: %s\n",		    ERR_error_string(err, NULL));	  }	  ret = -1;	}	if (debug)	  fprintf(stderr, "SSL negotiated cipher: %s\n", SSL_get_cipher(ssl));#endif      }      count++;      if (ret >= 0) {	successful++;	warn = 0;// begin string generation	if (str_len > 0) {	  str_len_old = str_len;	  memcpy(str_old, str, str_len_old);	  sent_mode_old = sent_mode;	}	j = 0;	while (j == 0) {	  i = (int) (100.0 * rand() / (RAND_MAX + 1.0));	  if (i < 11 && send_nullbytes) {	    sent_mode = 0;	    j = 1;	  }	  if (i >= 11 && i < 50 && send_ascii) {	    sent_mode = 1;	    j = 1;	  }	  if (i >= 50 && send_binary) {	    sent_mode = 2;	    j = 1;	  }	}	str_len =	  send_min +	  (int) ((1.0 * (send_max + 1 - send_min)) * rand() /		 (RAND_MAX + 1.0));	switch (sent_mode) {	case 0:	  memset(str, 0, str_len);	  break;	case 1:	  for (i = 0; i < str_len - 2; i++)	    str[i] =	      ASCII[(unsigned char) (1.0 * (1 + strlen(ASCII)) * rand() /				     (RAND_MAX + 1.0)) % strlen(ASCII)];	  str[str_len - 2] = '\r';	  str[str_len - 1] = '\n';	  break;	case 2:	  for (i = 0; i < str_len; i++)	    str[i] =	      (unsigned char) (256.0 * rand() / (RAND_MAX + 1.0)) % 256;	  break;	default:	  fprintf(stderr, "Error: memory corrupted (1)\n");	  exit(-1);	}	if (verbose > 1 || debug)	  printf(" %d:%d ", sent_mode, str_len);// end string generation	if (use_ssl) {#ifdef OPENSSL	  SSL_write(ssl, str, str_len);#endif	} else {	  if (write(s, str, str_len) < 0) {	    perror("\n\nError");	    if (ret == -1 && str_len > 0) {	      printf		("\n# Service seems to have crashed from the following trigger:\n");	      if (sent_mode == 1) {		printf("PROTOCOL_CRASH::%s:1:\"",		       sock_type == SOCK_DGRAM ? "udp" : "tcp");		for (i = 0; i < str_len; i++)		  switch (str[i]) {		  case '\t':		    printf("\\t");		    break;		  case '\n':		    printf("\\n");		    break;		  case '\r':		    printf("\\r");		    break;		  default:		    printf("%c", str[i]);		  }		printf("\"");	      } else {		printf("PROTOCOL_CRASH::%s:1:0x",		       sock_type == SOCK_DGRAM ? "udp" : "tcp");		for (i = 0; i < str_len; i++) {		  printf("%c",			 str[i] / 16 >			 9 ? str[i] / 16 + 87 : str[i] / 16 + 48);		  printf("%c",			 str[i] % 16 >			 9 ? str[i] % 16 + 87 : str[i] % 16 + 48);		}	      }	      printf("\n\n");	    }	    exit(-1);	  }	}	if (close_delay > 0)	  usleep(close_delay);	fcntl(s, F_SETFL, O_NONBLOCK);	errno = 0;	if (use_ssl) {#ifdef OPENSSL	  reads = SSL_read(ssl, buf, sizeof(buf));#endif	} else {	  reads = read(s, buf, sizeof(buf));	}	if (reads < 0 && errno == ECONNREFUSED && sock_type == SOCK_DGRAM) {	  perror("\n\nError");	  if (str_len_old > 0) {	    printf	      ("\n# Service seems to have crashed from the following trigger:\n");	    if (sent_mode_old == 1) {	      printf("PROTOCOL_CRASH::%s:1:\"",		     sock_type == SOCK_DGRAM ? "udp" : "tcp");	      for (i = 0; i < str_len_old; i++)		switch (str_old[i]) {		case '\t':		  printf("\\t");		  break;		case '\n':		  printf("\\n");		  break;		case '\r':		  printf("\\r");		  break;		default:		  printf("%c", str_old[i]);		}	      printf("\"");	    } else {	      printf("PROTOCOL_CRASH::%s:1:0x",		     sock_type == SOCK_DGRAM ? "udp" : "tcp");	      for (i = 0; i < str_len_old; i++) {		printf("%c",		       str_old[i] / 16 >		       9 ? str_old[i] / 16 + 87 : str_old[i] / 16 + 48);		printf("%c",		       str_old[i] % 16 >		       9 ? str_old[i] % 16 + 87 : str_old[i] % 16 + 48);	      }	    }	    printf("\n\n");	  }	  exit(-1);	}	if (reads > 0) {// output function	  printf("\n\n# Put this line into appdefs.trig:\n");	  if (sent_mode == 1) {	    printf("PROTOCOL_NAME::%s:0:\"",		   sock_type == SOCK_DGRAM ? "udp" : "tcp");	    for (i = 0; i < str_len; i++)	      switch (str[i]) {	      case '\t':		printf("\\t");		break;	      case '\n':		printf("\\n");		break;	      case '\r':		printf("\\r");		break;	      default:		printf("%c", str[i]);	      }	    printf("\"");	  } else {	    printf("PROTOCOL_NAME::%s:0:0x",		   sock_type == SOCK_DGRAM ? "udp" : "tcp");	    for (i = 0; i < str_len; i++) {	      printf("%c",		     str[i] / 16 > 9 ? str[i] / 16 + 87 : str[i] / 16 + 48);	      printf("%c",		     str[i] % 16 > 9 ? str[i] % 16 + 87 : str[i] % 16 + 48);	    }	  }	  printf("\n\n# Put this line into appdefs.resp:\n");	  j = 0;	  i = 0;	  while (j == 0 && i < reads) {	    if (!isprint(buf[i]) && !isspace(buf[i]))	      j = 1;	    i++;	  }	  if (j) {	    printf("PROTOCOL_NAME::%s::0x",		   sock_type == SOCK_DGRAM ? "udp" : "tcp");	    for (i = 0; i < reads; i++) {	      printf("%c",		     buf[i] / 16 > 9 ? buf[i] / 16 + 87 : buf[i] / 16 + 48);	      printf("%c",		     buf[i] % 16 > 9 ? buf[i] % 16 + 87 : buf[i] % 16 + 48);	    }	    printf("\n\n");	  } else {	    printf("PROTOCOL_NAME::%s::\"",		   sock_type == SOCK_DGRAM ? "udp" : "tcp");	    for (i = 0; i < reads; i++)	      switch (buf[i]) {	      case '\t':		printf("\\t");		break;	      case '\n':		printf("\\n");		break;	      case '\r':		printf("\\r");		break;	      default:		printf("%c", buf[i]);	      }	    printf("\"\n\n");	  }// output function end	  if (!dont_exit_when_response)	    exit(0);	}#ifdef OPENSSL	if (use_ssl)	  SSL_shutdown(ssl);#endif	close(s);	if (connect_delay > 0)	  usleep(connect_delay);      } else {	perror("\n\nError");	if (ret == -1 && str_len > 0) {	  printf	    ("\n# Service seems to have crashed from the following trigger:\n");	  if (sent_mode == 1) {	    printf("PROTOCOL_CRASH::%s:1:\"",		   sock_type == SOCK_DGRAM ? "udp" : "tcp");	    for (i = 0; i < str_len; i++)	      switch (str[i]) {	      case '\t':		printf("\\t");		break;	      case '\n':		printf("\\n");		break;	      case '\r':		printf("\\r");		break;	      default:		printf("%c", str[i]);	      }	    printf("\"");	  } else {	    printf("PROTOCOL_CRASH::%s:1:0x",		   sock_type == SOCK_DGRAM ? "udp" : "tcp");	    for (i = 0; i < str_len; i++) {	      printf("%c",		     str[i] / 16 > 9 ? str[i] / 16 + 87 : str[i] / 16 + 48);	      printf("%c",		     str[i] % 16 > 9 ? str[i] % 16 + 87 : str[i] % 16 + 48);	    }	  }	  printf("\n\n");	}	exit(-1);      }      if (count % 10 == 0)	printf("+");    } else      close(s);  }  printf("\ndone\n");  return 0;			// not reached}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?