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

📄 sslsniffer.c

📁 ssl sniffer源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  public value.*/static void ProcessTLSClientKeyExchange(char *buffer, ssl_connection *ssl_conn){    char *ptr = buffer + TLS_HANDSHAKE_HEADER_SIZE;    int i;     unsigned int len = ThreeBytesToInt(buffer+1);    unsigned int byte = 0;          switch(ssl_conn->keyxchange_alg)    {    case RSA:        printf("Length of RSA Encrypted PreMaster Secret -- %d bytes\n",len);      	printf("RSA Encrypted PreMaster Secret --\n  0x");	/* 1 for first byte specifying type and 3 for length field */	for(i = 0, ptr += 4; i < len; i++, ptr++)	{	    byte = 0; memcpy(&byte, ptr, 1);	    printf("%2.2x", byte);			}	printf("\n");	break;    case DH:        if(!len)	{	    ExtractParams(ptr,"DH public value");	}	else	{	    printf("DH public key is implicit in client certificate\n");	}	break;    default:        printf("Unable to process Client Key Exchange %d\n", ssl_conn->keyxchange_alg);    }}/* ---------------------------- SSL2 -------------------------------- */static int ProcessOneSSL2Record(ssl_connection *ssl_conn){    /* print out protocol version */    printf("Protocol Version: SSLV2\n");    printf("From Record Header -- Record Length: %d\n", 	   ssl_conn->record_len - ssl_conn->ssl2_record_hdr_len );    /* print out padding length if record was padded */    if(ssl_conn->ssl2_record_hdr_len == SSL2_3BYTE_RECORD_HEADER_SIZE)    {	printf("                      Padding Length: %d\n",	       ssl_conn->ssl2_padding_len);    }    /*        the packet is encrypted. we cannot even parse to determine the       content type     */    if(ssl_conn->ssl2_packets_encrypted)    {	printf("Packet is encrypted.\n");	return 1;    }    switch(ssl_conn->record[ssl_conn->ssl2_record_hdr_len])    {    case SSL2_MT_CLIENT_MASTER_KEY:	ProcessSSLV2ClientMasterKey(ssl_conn);		/* all further packets will be encrypted */	ssl_conn->ssl2_packets_encrypted = 1;	break;    case SSL2_MT_CLIENT_HELLO:	/* this should never be called though */	ProcessSSLV2ClientHello(ssl_conn);	break;      case SSL2_MT_SERVER_HELLO:               /* 	   check if we should expect a client master key packet next by	   looking at the resume hit char	*/	if(ssl_conn->record[ssl_conn->ssl2_record_hdr_len + 1] != 0)	{      	    /* since the session id hit, all further packets will be encrypted */            ssl_conn->ssl2_packets_encrypted = 1;	}	ProcessSSLV2ServerHello(ssl_conn);	break;    case SSL2_MT_ERROR:        ProcessSSLV2Error(ssl_conn);	break;/*  these are all sent encrypted. since we are only parsing in this  version, we cannot do anything since we don't even know the kind of  packet this is    case SSL2_MT_CLIENT_FINISHED:        ProcessSSLV2ClientFinished(ssl_conn);	break;    case SSL2_MT_SERVER_VERIFY:	break;    case SSL2_MT_SERVER_FINISHED:	break;    case SSL2_MT_REQUEST_CERTIFICATE:	break;    case SSL2_MT_CLIENT_CERTIFICATE:        ProcessSSLV2ClientCertificate(ssl_conn);	break;*/    default:        printf("Received Unknown packet type.\n");	return -1;    }        //printf("\n");    return 1;}/*     Processes the client master key packet.*/static voidProcessSSLV2ClientMasterKey(ssl_connection *ssl_conn){    unsigned short clear_key_data_len = 0;    unsigned short encrypted_key_data_len = 0;    unsigned short key_arg_data_len = 0;    char *record = ssl_conn->record;    printf("Received Client Master Key Packet --\n");    printf("Cipher Suite --\n");        ProcessSSLV2OneCipherSuite(record[1], record[2], record[3]);    clear_key_data_len = 	(((unsigned short) record[4]) << 8) | ((unsigned char) record[5]);    encrypted_key_data_len = 	(((unsigned short) record[6]) << 8) | ((unsigned char) record[7]);    key_arg_data_len = 	(((unsigned short) record[8]) << 8) | ((unsigned char) record[9]);    printf("Clear Key Data Length     -- %hu\n", clear_key_data_len);    printf("Encrypted Key Data Length -- %hu\n", encrypted_key_data_len);    printf("Key Arg Data Length -- %hu\n", encrypted_key_data_len);    printf("All further packets will be encrypted.\n");}/*  Examines the bytes given and prints out the cipher suite that is being   used. This is used when a SSLV2 client hello is being processed.*/static voidProcessSSLV2OneCipherSuite(char byte1, char byte2, char byte3){    char unknown = 0;    if(byte1 == 0x00) /* TLS Ciphers used */    {	ProcessTLSCipherSuite(byte2,byte3);	return;    }        printf("  Hex Code:");    utl_PrintCharAsHex(byte1);    utl_PrintCharAsHex(byte2);    utl_PrintCharAsHex(byte3);    printf("\n  Type: ");        switch((unsigned char) byte1)    {          case 0x01:	if(byte3 == (char) 0x80)	{	    printf("RSA with 128 bit RC4 and hash function MD5\n");	}	else 	{	    unknown = 1; 	}	break;    case 0x02:	if(byte3 == (char) 0x80)	{	    printf("RSA Export with 40 bit RC4 and hash function MD5\n");	}	else 	{	    unknown = 1; 	}	break;    case 0x03:	if(byte3 == (char) 0x80)	{	    printf("RSA with 128 bit RC2 CBC and hash function MD5\n");	}	else 	{	    unknown = 1; 	}	break;    case 0x04:	if(byte3 == (char) 0x80)	{	    printf("RSA Export with 40 bit RC2 and hash function MD5\n");	}	else 	{	    unknown = 1; 	}	break;    case 0x05:	if(byte3 == (char) 0x80)	{	    if(byte2 == (char) 0x00)	    {		printf("RSA with 128 bit IDEA CBC and hash function MD5\n");	    }	    else	    {		printf("RSA with 128 bit IDEA CBC and hash function SHA\n");	    }	}	else 	{	    unknown = 1; 	}	break;    case 0x06:	if(byte3 == (char) 0x40)	{	    printf("RSA with 64 bit DES CBC and hash function MD5\n");	}	else 	{	    unknown = 1; 	}	break;    case 0x07:	if(byte3 == (char) 0xC0)	{	    if(byte2 == (char) 0x00)	    {		printf("RSA with 192 bit 3DES EDE CBC and hash function MD5\n");	    }	    else	    {		printf("RSA with 192 bit 3DES EDE CBC and hash function SHA\n");	    }	}	else 	{	    unknown = 1; 	}	break;    case 0xff:	if(byte3 == 0x00)	{	    printf("RSA with 64 bit DES CFB with hash function MD5\n");	}	else	{	    printf("No Cipher Suite\n");	}	break;    default:	unknown = 1;    }        if(unknown)    {	printf("Unknown SSLV2 cipher used\n");    }}/*  Processes the SSLV2 Client Hello message. This message is only sent by  clients that support both TLS1.0 and SSLV2. Appendix E RFC 2246.    Assumes that the buffer points to the record type which is 2 bytes  after the start of the packet. -- not any more.  Now assumes starts at record beginning.*/static void ProcessSSLV2ClientHello(ssl_connection *ssl_conn){       char *buffer = 	    ssl_conn->record + SSL2_2BYTE_RECORD_HEADER_SIZE; /* skip over record */    short cipher_spec_len = 	    TwoBytesToInt(&(buffer[SSL2_CLIENT_HELLO_CIPHER_SPEC_LEN_OFFSET]));    short session_id_len = 	    TwoBytesToInt(&(buffer[SSL2_CLIENT_HELLO_SESSION_ID_LEN_OFFSET]));    short challenge_len = 	    TwoBytesToInt(&(buffer[SSL2_CLIENT_HELLO_CHALLENGE_LEN_OFFSET]));    char *ptr;    int session_id_offset = 	    cipher_spec_len + SSL2_CLIENT_HELLO_CIPHER_SPEC_OFFSET;    int i;    unsigned int byte;    printf("Received SSLV2 Client Hello ...\n");    printf("\nFrom Client Hello -- Protocol Version: %d.%d\n",	   buffer[1], buffer[2]);        printf("Session ID Length -- %hd bytes\n", session_id_len);    printf("Session ID --\n");    for(i = 0, ptr = buffer + session_id_offset; 	i < session_id_len; 	i++, ptr++)    {	byte = 0;	memcpy(&byte, ptr, 1);	printf("%.2x", byte);    }        ProcessSSLV2CipherSuiteData(buffer + SSL2_CLIENT_HELLO_CIPHER_SPEC_OFFSET,				cipher_spec_len);    printf("Challenge Length -- %hd bytes\n", challenge_len);}/*  Processes all the cipher suite data*/static void ProcessSSLV2CipherSuiteData(char *cipher_suite_data, 			    unsigned short data_len){    int i;    char *ptr;    printf("Cipher Suite Length %hd bytes ... number of cipher suites %d\n",	   data_len, data_len / SSL2_ONE_CIPHER_SUITE_LEN);    printf("Cipher Suite List is -- \n");    for(i = 0, ptr = cipher_suite_data; 	i < data_len; 	i += SSL2_ONE_CIPHER_SUITE_LEN, ptr += SSL2_ONE_CIPHER_SUITE_LEN)    {	ProcessSSLV2OneCipherSuite(ptr[0], ptr[1], ptr[2]);          }}/*    Checks if the record hdr is a v2 client hello.  we don't have to   worry about the padding byte because a client hello is always in   plain text.*/static intIsV2ClientHello(char *record_hdr){    return((record_hdr[0] & 0x80) && 	   (record_hdr[SSL2_MSG_TYPE_OFFSET] == SSL2_MT_CLIENT_HELLO));              }/*    prints out the relevant information for a server hello*/static void ProcessSSLV2ServerHello(ssl_connection *ssl_conn){    char session_id_hit = 0;    char certificate_type;    unsigned short server_version;    unsigned short certificate_len;    unsigned short cipher_spec_len;    unsigned short connection_id_len;    char *record_data = ssl_conn->record + ssl_conn->ssl2_record_hdr_len;    char *cert_data = record_data + SSL2_SERVER_HELLO_CERT_DATA_OFFSET;    char *cipher_spec_data;    X509 *cert;    printf("Received Server Hello Packet --\n");       /* first pull out all the data */    session_id_hit = record_data[1];    certificate_type = record_data[2];    server_version = ((unsigned short) (record_data[3] << 8)) |  	             ((unsigned char) record_data[4]);    certificate_len = ((unsigned short) (record_data[5] << 8)) | 	              ((unsigned char) record_data[6]);    cipher_spec_len = ((unsigned short) (record_data[7] << 8)) | 	              ((unsigned char) record_data[8]);    connection_id_len = ((unsigned short) (record_data[9] << 8)) | 	                ((unsigned char) record_data[10]);    cipher_spec_data = cert_data + certificate_len;    printf("Server version is %hu\n", server_version);        if(session_id_hit)    {        printf("Session ID matched previous session - SSL2 Resume\n"	       "All further packets will be encrypted\n");	return; /* all the other fields will be empty */    }    else    {        printf("Session ID did not match any previous session - No Resume\n");    }        /*        it appears that V2 doesn't seem to support the chain the same way        as TLS. In fact, it doesn't seem to support any chains at all.       ProcessCertificateChain(cert_data, ssl_conn);    */    /* extract and print out the cert */    cert = d2i_X509(NULL, (unsigned char **) &cert_data, certificate_len);    ProcessCertificate(cert);    ProcessSSLV2CipherSuiteData(cipher_spec_data, cipher_spec_len);    printf("Connection ID len is %hu\n", connection_id_len);    }/*    prints out the relevant information for a server hello*/static void ProcessSSLV2Error(ssl_connection *ssl_conn){    char *record_data = ssl_conn->record + ssl_conn->ssl2_record_hdr_len;    unsigned short error_code;    printf("Received SSLV2 Error -- \n");	       error_code = (record_data[1] << 8) | ((unsigned char) record_data[2]);    printf("Error Code is %hu -- ", error_code);    switch(error_code)    {    case SSL2_PE_NO_CIPHER:        printf("No common ciphers supported.\n");	break;    case SSL2_PE_NO_CERTIFICATE:        printf("No certificate sent by client.\n");	break;    case SSL2_PE_BAD_CERTIFICATE:        printf("Bad certificate sent.\n");	break;	        case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:        printf("Unsupported certificate type.\n");	break;	        default:        printf("Unknown error.\n");	break;	    	        }}#if 0/*    Since we are only parsing it and it is sent encrypted, we can't do    very much here*/static voidProcessSSLV2ClientFinished(ssl_connection *ssl_conn){    printf("Received SSLV2 Client Finished -- \n"	   "Packet is encrypted\n");}/*    Since we are only parsing it and it is sent encrypted, we can't do    very much here*/static voidProcessSSLV2ClientCertificate(ssl_connection *ssl_conn){    printf("Received SSLV2 Client Certificate --\n"	   "Packet is encrypted\n\n");}#endif/* --------------------- UTILITIES ---------------------------------- *//*  A wrapper for close that does some error checking.*/void CloseSocket(int sock){  if(close(sock) < 0 )    {            perror("Close socket error");      exit(FAILURE);    }}/*  used for converting the short in 2 byte length fields to an  int. returns the value as a short in the host byte order.  can't dereference a short directly because it might not be word  aligned.*/shortTwoBytesToInt(char *buffer){    int i;      char *temp;    short len = 0;        /* get the length of the message */    temp = (char *) &len;    for(i = 0; i < 2; i++) /* 2 is the size of the length field */    {	memcpy(&(temp[i]), buffer + i, 1);    }        return ntohs(len);}/*  used for converting the 3 byte field in the handshake packet that  represents the length of the packet to an int*/unsigned intThreeBytesToInt(char *buffer){    int i;      char *temp;    unsigned int len = 0;        /* get the length of the message */    temp = (char *) &len;    for(i = 0; i < 3; i++) /* 3 is the size of the length field */    {	memcpy(&(temp[i]), buffer + 2 - i, 1);    }        return len;}

⌨️ 快捷键说明

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