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

📄 sslsniffer.c

📁 ssl sniffer源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* we need to figure out whether its V2, V3 or V23 */        /* pull off the first three bytes */    if((bytes_read = 	utlnet_ReadnBytesFromSocket(ssl_conn->client_fd, record_hdr_buf, TLS_RECORD_HEADER_SIZE)) < 0)    {	goto end;    }                   /* first check if it's a V2 client hello */     if(IsV2ClientHello(record_hdr_buf))    {	/* read the rest of the record from the socket */	    ssl_conn->record_len = (((record_hdr_buf[0] & 0x7f) << 8) 				    | ((unsigned char) record_hdr_buf[1]))		                   + SSL2_2BYTE_RECORD_HEADER_SIZE;	if((bytes_read = ReadRecordData(ssl_conn, record_hdr_buf, TLS_RECORD_HEADER_SIZE)) < 0)	{	    goto end;	}		/* set the right values in the ssl_conn */	if(ssl_conn->record[SSL2_CLIENT_HELLO_MAJOR_VER_OFFSET] == TLS_MAJOR)	{	    ssl_conn->ssl_version = VERSION_SSL3;	}	else	{	    ssl_conn->ssl_version = VERSION_SSL2;	}	/* do the printing out */	ProcessSSLV2ClientHello(ssl_conn);	    }    else    {	/* if not ssl2, assume this is a ssl3/tls packet */		/* read the rest of the record */	ssl_conn->record_len = TwoBytesToInt(&(record_hdr_buf[TLS_RECORD_LENGTH_OFFSET]))                               + TLS_RECORD_HEADER_SIZE;	if((bytes_read = ReadRecordData(ssl_conn, record_hdr_buf, TLS_RECORD_HEADER_SIZE)) 	     < 0)	{	    goto end;	}	/* verify that the major version is right */	if(ssl_conn->record[TLS_RECORD_PROTOCOL_MAJ_VERSION_OFFSET] != TLS_MAJOR)	{	    printf("    ERR Invalid protocol version received in record header.\n");	    goto end;	}	if(ssl_conn->record[TLS_RECORD_PROTOCOL_MIN_VERSION_OFFSET] == TLS_MINOR)	{	    ssl_conn->ssl_version = VERSION_TLS;	}	else if(ssl_conn->record[TLS_RECORD_PROTOCOL_MIN_VERSION_OFFSET] == SSL_MINOR)	{	    ssl_conn->ssl_version = VERSION_SSL3;	}	else	{	    printf("    ERR Invalid protocol version received in record header.\n");	    goto end;	}	/* process it */	ProcessTLSClientHello(ssl_conn->record + TLS_RECORD_HEADER_SIZE);     }    /* flag it as having received a client hello */    ssl_conn->recv_client_hello = 1;        /* send the data over to the server, use bytes read as a return value */    bytes_read = utlnet_WritenBytesToSocket(ssl_conn->server_fd,					    ssl_conn->record, 					    ssl_conn->record_len);     end:    return bytes_read;}/*  Reads from the server socket and writes it to the client one. We  need to flip some values to do the server read and then reset them  when we are done.  returns the return code from ClientRead.*/static int ServerRead(ssl_connection *ssl_conn){    int return_val;    /* set the appropriate read and write sockets */    ssl_conn->read_fd = ssl_conn->server_fd;    ssl_conn->write_fd = ssl_conn->client_fd;    /* set the right change cipher */    ssl_conn->recv_change = 	&(ssl_conn->recv_change_cipher[SERVER_RECV_CHANGE_CIPHER]);        /* leverage client read */    return_val = ClientRead(ssl_conn);    /* revert back to the default values */     ssl_conn->recv_change = 	&(ssl_conn->recv_change_cipher[CLIENT_RECV_CHANGE_CIPHER]);     ssl_conn->read_fd = ssl_conn->client_fd;    ssl_conn->write_fd = ssl_conn->server_fd;           return return_val;}/*  Called by DoOneSSLConnection to read from the client socket within the   select loop. Reads from the client socket and writes the data to the server  socket.    It reads sockets of up to any size using dynamically allocated memory. */static intClientRead(ssl_connection *ssl_conn){   	    int bytes_read = 0;    char buf[1];    /* we process SSLV2 and TLS connections differently */    if(ssl_conn->ssl_version != VERSION_SSL2)    {	/*	  this catches the case where the client initially sends a V2 hello	  with version 3 but the server can only do V2 and hence replies in	  V2	*/	if(!ssl_conn->recv_server_hello)	{	    /* peek at the first byte to ensure that it's not a V2 server hello */	    if(utlnet_PeekAtnBytesFromSocket(ssl_conn->read_fd, buf, 1) < 0)	    {		return -1;	    }	    if(buf[0] & 0x80)	    {		ssl_conn->ssl_version = VERSION_SSL2;		return ClientRead(ssl_conn);	    }	}	/* TLS connection */	if((bytes_read = ReadOneTLSRecord(ssl_conn)) > 0)	{	    /* processes the packet */	    ProcessTLSPacketType(ssl_conn);	}    }    else    {	/* SSLV2 connection */	if((bytes_read = ReadOneSSL2Record(ssl_conn)) > 0)	{	    ProcessOneSSL2Record(ssl_conn);	}    }        /* sends it to the other end if there is something to send */    if(bytes_read > 0)    {	bytes_read = utlnet_WriteToSocket(ssl_conn->write_fd, 					  ssl_conn->record, 					  ssl_conn->record_len);    }        if(ssl_conn->record_len != 0 && ssl_conn->record != NULL)    {	free(ssl_conn->record);    }       return bytes_read;}/*  Called by ClientRead. Reads from the socket till one complete  Record has been read in and then returns the buffer.    returns the number of bytes read.*/static intReadOneTLSRecord(ssl_connection *ssl_conn){    int bytes_read;    char record_hdr_buf[TLS_RECORD_HEADER_SIZE];    short record_len;        ssl_conn->record_len = 0;    ssl_conn->record = NULL;    /* read in just the record header */    if((bytes_read = utlnet_ReadnBytesFromSocket(ssl_conn->read_fd, 						 record_hdr_buf,						 TLS_RECORD_HEADER_SIZE)) <= 0)    {	return bytes_read;    }        /* find out how big this record is and allocate mem for it */    record_len = TwoBytesToInt(&(record_hdr_buf[TLS_RECORD_LENGTH_OFFSET]));    ssl_conn->record_len = (int) record_len + TLS_RECORD_HEADER_SIZE;    return ReadRecordData(ssl_conn, record_hdr_buf, TLS_RECORD_HEADER_SIZE);}static int ReadOneSSL2Record(ssl_connection *ssl_conn){    char record_hdr_buf[SSL2_2BYTE_RECORD_HEADER_SIZE];    int bytes_read = 0;    ssl_conn->record_len = 0;    ssl_conn->record = NULL;    /* read in the first two bytes and check how long the record is */    if((bytes_read = utlnet_ReadnBytesFromSocket(ssl_conn->read_fd, 						 record_hdr_buf,						 SSL2_2BYTE_RECORD_HEADER_SIZE))        <= 0)    {	return bytes_read;    }    /* check how long header length is */    if(record_hdr_buf[0] & 0x80)    {	/* 2 bytes */	ssl_conn->ssl2_record_hdr_len = SSL2_2BYTE_RECORD_HEADER_SIZE;	ssl_conn->record_len = 	    (((((unsigned int) record_hdr_buf[0]) & 0x7f) << 8) | 	     ((unsigned char) record_hdr_buf[1]) )	    + SSL2_2BYTE_RECORD_HEADER_SIZE;    }    else    {	/* 3 bytes */	ssl_conn->ssl2_record_hdr_len = SSL2_3BYTE_RECORD_HEADER_SIZE;	ssl_conn->record_len = 	    ((((unsigned int) record_hdr_buf[0] & 0x3f) << 8) 	     | ((unsigned char) record_hdr_buf[1]))	    + SSL2_3BYTE_RECORD_HEADER_SIZE;         }    /* read the rest of the record in */    if((bytes_read = ReadRecordData(ssl_conn, 				    record_hdr_buf,				    SSL2_2BYTE_RECORD_HEADER_SIZE)) <= 0)    {	return bytes_read;    }    /* if it's padded, get the padding length */    if(ssl_conn->ssl2_record_hdr_len == SSL2_3BYTE_RECORD_HEADER_SIZE)    {	ssl_conn->ssl2_padding_len = (unsigned char) ssl_conn->record[2];    }    return bytes_read;}/*    reads the rest of the record in. usually called after having read   the record header in.   the record len of the ssl_conn should be set to the total num of   bytes to be read including the previously read bytes before calling   this function.   returns the number of bytes read.*/static int ReadRecordData(ssl_connection *ssl_conn, 			  char *prev_read_buf, 			  int num_prev_read_bytes){    int bytes_read;    ssl_conn->record = (char *) utl_GetMem(ssl_conn->record_len);        /* copy the previous bytes over */    memcpy(ssl_conn->record, prev_read_buf, num_prev_read_bytes);        /* then read the rest of the buffer in */        if((bytes_read = 	utlnet_ReadnBytesFromSocket(ssl_conn->read_fd, 				    ssl_conn->record + num_prev_read_bytes, 				    ssl_conn->record_len - num_prev_read_bytes))        <= 0)    {	goto end;    }        return ssl_conn->record_len; end:    free(ssl_conn->record); /* cannot be null */    return bytes_read;}/* ------------------------ SSL3 / TLS ------------------------ *//*  Handles TLS packets that it reads from the socket. there might be  more than one packet in the data that it reads and so it has to  handle those cases. Also application data does not come in nice big  packets and might be passed to the proxy in fragments and we handle  that too.  Determines the kind of packet that has been sent. Handles  TLS Record Headers.  If the data is encrypted, then no further processing is done. This is   signalled by the recv_change_cipher argument  returns the content type.*/static intProcessTLSPacketType(ssl_connection *ssl_conn){    int i;    char *rec_hdr = ssl_conn->record;    char *c = (char *) rec_hdr;    /* print out protocol version */    printf("From Record Header -- Protocol Version: %d.%d\n",	   rec_hdr[1], rec_hdr[2]);        printf("                      Record Length: %d\n", 	   ssl_conn->record_len - TLS_RECORD_HEADER_SIZE);        switch( (unsigned int) rec_hdr[0])    {    case TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC:		printf("Received a CHANGE_CIPHER_SPEC packet:\n"	       "Further packets will be encrypted ... ");		/* signals that no more processing is to be done */	*(ssl_conn->recv_change) = (char) 1;	break;	    case TLS_RECORD_TYPE_ALERT:		printf("Received an ALERT packet ...\n");		/* only process if we have not received the change cipher spec */	if(!(*(ssl_conn->recv_change)))	{	    ProcessTLSAlertMessage(ssl_conn);	}	else	{	    printf("Packet is encrypted.");	}	break;	    case TLS_RECORD_TYPE_HANDSHAKE:		printf("Received a HANDSHAKE packet ...\n");	/* only process if we have not received the change cipher spec */	if(!(*(ssl_conn->recv_change)))	{	    ProcessTLSHandshakeMessage(ssl_conn);	    	}	else	{	    printf("Packet is encrypted.");	}	break;	    case TLS_RECORD_TYPE_APPLICATION_DATA:		printf("Received APPLICATION DATA packet ...\n");	if(*(ssl_conn->recv_change))	{	    printf("Packet is encrypted.");	}	break;	    default:		if(ssl_conn->recv_server_hello)	{	    printf("Received Unrecognised TLS packet, type %d\n",		   rec_hdr[0]);	    printf("First 30 bytes of data from packet\n");	    for(i = 0; i < 30; i++, c++)	    {		printf("%d ",*c);	    }	    printf("\n\n");		}	return -1;	    }    return rec_hdr[0];}/*  Takes in an alert struct and prints out the level of the alert and also  the description of the alert.*/static void ProcessTLSAlertMessage(ssl_connection *ssl_conn){    char *str;    char *alert_data = ssl_conn->record + TLS_RECORD_HEADER_SIZE;        if( (unsigned int) alert_data[0] == TLS_ALERT_LEVEL_WARNING)    {	printf("Alert Level: Warning -- ");    }    else if( (unsigned int) alert_data[0] == TLS_ALERT_LEVEL_FATAL)    {	printf("Alert Level: Fatal -- ");    }        switch( (unsigned int) alert_data[1])    {    case TLS_ALERT_TYPE_CLOSE_NOTIFY:	str = "CLOSE_NOTIFY\n"; 	break;    case TLS_ALERT_TYPE_UNEXPECTED_MESSAGE:	str = "UNEXPECTED_MESSAGE\n"; 	break;    case TLS_ALERT_TYPE_BAD_RECORD_MAC:	str = "BAD_RECORD_MAC\n"; 	break;    case TLS_ALERT_TYPE_DECRYPTION_FAILED:	str = "DECRYPTION_FAILED\n"; 	break;    case TLS_ALERT_TYPE_RECORD_OVERFLOW:	str = "RECORD_OVERFLOW\n"; 	break;    case TLS_ALERT_TYPE_DECOMPRESSION_FAILURE:	str = "DECOMPRESSION_FAILURE\n"; 	break;    case TLS_ALERT_TYPE_HANDSHAKE_FAILURE:	str = "HANDSHAKE_FAILURE\n"; 	break;    case TLS_ALERT_TYPE_BAD_CERTIFICATE:	str = "BAD_CERTIFICATE\n"; 	break;    case TLS_ALERT_TYPE_UNSUPPORTED_CERTIFICATE:	str = "UNSUPPORTED_CERTIFICATE\n"; 	break;    case TLS_ALERT_TYPE_CERTIFICATE_REVOKED:	str = "CERTIFICATE_REVOKED\n"; 	break;    case TLS_ALERT_TYPE_CERTIFICATE_EXPIRED:	str = "CERTIFICATE_EXPIRED\n"; 	break;    case TLS_ALERT_TYPE_CERTIFICATE_UNKNOWN:	str = "CERTIFICATE_UNKNOWN\n"; 	break;    case TLS_ALERT_TYPE_ILLEGAL_PARAMETER:	str = "ILLEGAL_PARAMETER\n"; 	break;    case TLS_ALERT_TYPE_UNKNOWN_CA:	str = "UNKNOWN_CA\n"; 	break;    case TLS_ALERT_TYPE_ACCESS_DENIED:	str = "ACCESS_DENIED\n"; 	break;    case TLS_ALERT_TYPE_DECODE_ERROR:	str = "DECODE_ERROR\n"; 	break;    case TLS_ALERT_TYPE_DECRYPT_ERROR:	str = "DECRYPT_ERROR\n"; 	break;    case TLS_ALERT_TYPE_EXPORT_RESTRICTION:	str = "EXPORT_RESTRICTION\n"; 	break;    case TLS_ALERT_TYPE_PROTOCOL_VERSION:	str = "PROTOCOL_VERSION\n"; 	break;    case TLS_ALERT_TYPE_INSUFFICIENT_SECURITY:	str = "INSUFFICIENT_SECURITY\n"; 	break;    case TLS_ALERT_TYPE_INTERNAL_ERROR:	str = "INTERNAL_ERROR\n"; 	break;    case TLS_ALERT_TYPE_USER_CANCELED:	str = "USER_CANCELLED\n"; 	break;    case TLS_ALERT_TYPE_NO_RENEGOTIATION:	str = "NO_RENEGOTIATION\n"; 	break;    default:	printf("No such alert code %d\n", (unsigned int) alert_data[1]);	return;    }    printf("%s\n",str);}/*  Pass in the data segment containing the handshake data extracted from  the TLS Record. Determines the type and takes the appropriate action.  Mostly just prints out the Handshake request.*/static voidProcessTLSHandshakeMessage(ssl_connection *ssl_conn){    char *cur_handshake_packet;    int bytes_processed = 0;    int total_bytes_to_process = ssl_conn->record_len - TLS_RECORD_HEADER_SIZE;    int handshake_packet_len;    /* move to the first record */    cur_handshake_packet = ssl_conn->record + TLS_RECORD_HEADER_SIZE;    /*        want to keep looping till we've processed all the handshake packets       in a single record. this deals with the multiple handshake packets       in one single record     */    while(bytes_processed < total_bytes_to_process)    {		/* process the current handshake packet */	printf("HandShake Packet Type :- ");		switch(cur_handshake_packet[0])	{	case TLS_HANDSHAKE_TYPE_HELLO_REQUEST:	    printf("Hello Request\n");	    break;	case TLS_HANDSHAKE_TYPE_CLIENT_HELLO:	    printf("SSLV3/TLS Client Hello\n");	    ProcessTLSClientHello(cur_handshake_packet);	    break;	case TLS_HANDSHAKE_TYPE_SERVER_HELLO:	    printf("Server Hello\n");	    ProcessServerHello(cur_handshake_packet, ssl_conn);	    ssl_conn->recv_server_hello = 1;	    break;	case TLS_HANDSHAKE_TYPE_CERTIFICATE:	    printf("Certificate\n");	    ProcessCertificateChain(cur_handshake_packet, ssl_conn);	    break;	case TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE:	    printf("Server Key Exchange\n");	    ProcessTLSServerKeyExchange(cur_handshake_packet, ssl_conn);	   

⌨️ 快捷键说明

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