提取ssl握手原始信息(去除一些字段)

This commit is contained in:
崔一鸣
2020-02-06 23:35:38 +08:00
parent 01c884dffb
commit 01d5c4c872
7 changed files with 828 additions and 5 deletions

View File

@@ -1,8 +1,8 @@
{
"host": "192.168.40.133",
"username": "root",
"password": "111111",
"remotePath": "/root/cuiyiming/FeatureExtract",
"host": "123.57.35.217",
"username": "cuiyiming",
"password": "070708",
"remotePath": "/data/cuiyiming/GradProj/FeatureExtract",
"protocol": "sftp",
"port": 22,
"fileNameEncoding": "utf8",

View File

@@ -5,4 +5,11 @@ target_link_libraries(stmstat MESA_prof_load MESA_field_stat cjson)
add_library(sslstat SHARED src/sslstat_entry.cpp)
target_include_directories(sslstat PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
target_link_libraries(sslstat MESA_prof_load MESA_field_stat cjson)
target_link_libraries(sslstat MESA_prof_load MESA_field_stat cjson)
add_library(sslparse SHARED src/sslparse_entry.cpp src/ssl_utils.cpp src/base64.cpp)
target_include_directories(sslparse PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
target_link_libraries(sslparse MESA_prof_load MESA_field_stat cjson)
add_executable(test_base64 src/base64.cpp)
target_include_directories(test_base64 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include)

View File

@@ -0,0 +1,2 @@
unsigned int b64_encode(const unsigned char* in, unsigned int in_len, unsigned char* out);
unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out);

View File

@@ -0,0 +1,143 @@
/*
base64.c - by Joe DF (joedf@ahkscript.org)
Released under the MIT License
See "base64.h", for more information.
Thank you for inspiration:
http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode
*/
#include "base64.h"
#include <stdio.h>
#include <algorithm>
//Base64 char table - used internally for encoding
unsigned char b64_chr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int b64_int(unsigned int ch) {
// ASCII to base64_int
// 65-90 Upper Case >> 0-25
// 97-122 Lower Case >> 26-51
// 48-57 Numbers >> 52-61
// 43 Plus (+) >> 62
// 47 Slash (/) >> 63
// 61 Equal (=) >> 64~
if (ch==43)
return 62;
if (ch==47)
return 63;
if (ch==61)
return 64;
if ((ch>47) && (ch<58))
return ch + 4;
if ((ch>64) && (ch<91))
return ch - 'A';
if ((ch>96) && (ch<123))
return (ch - 'a') + 26;
return 0;
}
/*
unsigned int b64e_size(unsigned int in_size) {
// size equals 4*floor((1/3)*(in_size+2));
int i, j = 0;
for (i=0;i<in_size;i++) {
if (i % 3 == 0)
j += 1;
}
return (4*j);
}
*/
unsigned int b64d_size(unsigned int in_size) {
return ((3*in_size)/4);
}
unsigned int b64_encode(const unsigned char* in, unsigned int in_len, unsigned char* out) {
unsigned int i=0, j=0, k=0, s[3];
for (i=0;i<in_len;i++) {
s[j++]=*(in+i);
if (j==3) {
out[k+0] = b64_chr[ (s[0]&255)>>2 ];
out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ];
out[k+2] = b64_chr[ ((s[1]&0x0F)<<2)+((s[2]&0xC0)>>6) ];
out[k+3] = b64_chr[ s[2]&0x3F ];
j=0; k+=4;
}
}
if (j) {
if (j==1)
s[1] = 0;
out[k+0] = b64_chr[ (s[0]&255)>>2 ];
out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ];
if (j==2)
out[k+2] = b64_chr[ ((s[1]&0x0F)<<2) ];
else
out[k+2] = '=';
out[k+3] = '=';
k+=4;
}
out[k] = '\0';
return k;
}
unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out) {
unsigned int i=0, j=0, k=0, s[4];
for (i=0;i<in_len;i++) {
s[j++]=b64_int(*(in+i));
if (j==4) {
out[k+0] = ((s[0]&255)<<2)+((s[1]&0x30)>>4);
if (s[2]!=64) {
out[k+1] = ((s[1]&0x0F)<<4)+((s[2]&0x3C)>>2);
if ((s[3]!=64)) {
out[k+2] = ((s[2]&0x03)<<6)+(s[3]); k+=3;
} else {
k+=2;
}
} else {
k+=1;
}
j=0;
}
}
return k;
}
int test(){
unsigned char in_buff[100] = "ab\0d\0fghi";
unsigned char out_buff[100];
unsigned char *in = in_buff;
unsigned char *out = out_buff;
int in_len = 10;
int out_len = b64_encode(in, in_len, out);
printf("encode: out_len = %d\n", out_len);
for(int i = 0; i < out_len; i++){
printf("%c ", out[i]);
}
printf("\n");
std::swap(in, out);
in_len = out_len;
out_len = b64_decode(in, in_len, out);
printf("decode: out_len = %d\n", out_len);
for(int i = 0; i < out_len; i++){
printf("%c ", out[i]);
}
printf("\n");
return 0;
}
int main(){
test();
}

View File

@@ -0,0 +1,641 @@
#include "base_utils.h"
#include "ssl_utils.h"
#include "MESA/stream_inc/stream_base.h"
#include "MESA/stream_inc/stream_rawpkt.h"
#include "cjson/cJSON.h"
#include "openssl/x509.h"
#include "base64.h"
#include <algorithm>
#define STREAM_PACKET_COUNT_MAX 10000
#define TLS_MESSAGE_LEN_MAX 20000
void *g_logger = NULL;
FILE *g_fp = NULL;
struct tls_message_type{
int message_type;
int content_type;
int handshake_type;
const char *name;
};
struct tls_message_type g_tls_types[] = {
{0, 22, 0, "hello_request_RESERVED"},
{1, 22, 1, "client_hello"},
{2, 22, 2, "server_hello"},
{3, 22, 3, "hello_verify_request_RESERVED"},
{4, 22, 4, "new_session_ticket"},
{5, 22, 5, "end_of_early_data"},
{6, 22, 6, "hello_retry_request_RESERVED"},
{7, 22, 8, "encrypted_extensions"},
{8, 22, 11, "certificate"},
{9, 22, 12, "server_key_exchange_RESERVED"},
{10, 22, 13, "certificate_request"},
{11, 22, 14, "server_hello_done_RESERVED"},
{12, 22, 15, "certificate_verify"},
{13, 22, 16, "client_key_exchange_RESERVED"},
{14, 22, 20, "finished"},
{15, 22, 21, "certificate_url_RESERVED"},
{16, 22, 22, "certificate_status_RESERVED"},
{17, 22, 23, "supplemental_data_RESERVED"},
{18, 22, 24, "key_update"},
{19, 22, 25, "compressed_certificate"},
{20, 22, 254, "message_hash"},
{21, 20, 0, "change_cipher_spec"},
{22, 21, 0, "alert"},
{23, 23, 0, "application_data"},
{24, 24, 0, "heartbeat"},
{25, 25, 0, "tls12_cid"},
{26, 22, -1, "handshake_unknown"},
};
struct tls_message_detail{
int type;
int len;
unsigned char buff[TLS_MESSAGE_LEN_MAX];
int buff_len;
};
struct tls_filtered_message{
unsigned char buff[TLS_MESSAGE_LEN_MAX];
int buff_len;
};
struct pkt_parsed_info{
addr_type_t addr_type;
union{
struct iphdr *v4;
struct ip6_hdr *v6;
}iphdr;
uint16_t iphdr_len;
uint16_t ip_totlen;
struct tcphdr *tcphdr;
uint16_t tcphdr_len;
char *data;
uint16_t data_len;
};
struct pme_info{
int _errno;
char sip[INET_ADDRSTRLEN];
int sport;
char dip[INET_ADDRSTRLEN];
int dport;
struct ssl_chello chello;
struct tls_message_detail cur_c2s_tls;
struct tls_message_detail cur_s2c_tls;
struct tls_filtered_message message_client_hello;
struct tls_filtered_message message_client_hello_no_extensions;
struct tls_filtered_message message_server_hello;
struct tls_filtered_message message_server_hello_no_extensions;
struct tls_filtered_message message_certificate;
struct tls_filtered_message message_certificate_no_serial;
int has_fin_rst;
};
int ipv4_header_parse(const void *a_packet, struct pkt_parsed_info* pktinfo){
if(a_packet == NULL){
return -1;
}
pktinfo->addr_type = ADDR_TYPE_IPV4;
pktinfo->iphdr.v4 = (struct iphdr*)a_packet;
pktinfo->iphdr_len = pktinfo->iphdr.v4->ihl * 4;
pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v4->tot_len);
pktinfo->tcphdr = (struct tcphdr*)((char*)pktinfo->iphdr.v4 + pktinfo->iphdr_len);
pktinfo->tcphdr_len = pktinfo->tcphdr->doff * 4;
pktinfo->data = (char*)pktinfo->tcphdr + pktinfo->tcphdr_len;
pktinfo->data_len = pktinfo->ip_totlen - pktinfo->iphdr_len - pktinfo->tcphdr_len;
/*
struct iphdr *_iphdr = pktinfo->iphdr.v4;
int ttl = _iphdr->ttl;
int ipid = ntohs(_iphdr->id);
printf("ipv4: ipid = %02x, ttl = %d, data_len = %d\n", ipid, ttl, pktinfo->data_len);
*/
return 0;
}
int chello_packet_parse(struct pme_info *pmeinfo, struct pkt_parsed_info *pktinfo){
enum chello_parse_result chello_status = CHELLO_PARSE_INVALID_FORMAT;
char *buff = pktinfo->data;
int len = pktinfo->data_len;
ssl_chello_parse(&(pmeinfo->chello), (const unsigned char*)buff, len, &chello_status);
if(chello_status != CHELLO_PARSE_SUCCESS){
LOG_ERROR(g_logger, "Error: chello parse failed\n");
return -1;
}
return 0;
}
int get_tls_message_type(int content_type, int handshake_type){
int type_count = sizeof(g_tls_types) / sizeof(struct tls_message_type);
for(int i = 0; i < type_count; i++){
if(g_tls_types[i].content_type == content_type && g_tls_types[i].handshake_type == handshake_type){
return i;
}
}
if(content_type == 22){
return type_count - 1;
}
return -1;
}
int client_server_hello_get(unsigned char *buff, int len, struct pme_info *pmeinfo, int type){
char buff1[TLS_MESSAGE_LEN_MAX];
int i = 0, len1 = 0;
memcpy(buff1 + len1, buff + i, 6);
i += 6;
len1 += 6;
//random
i += 32;
//session_id
int session_id_len = (uint8_t)buff[i];
i += (1 + session_id_len);
//cipher suites: type = 1, client hello; type = 2, server hello
if(type == 1){
int cipher_suites_len = (uint16_t)(buff[i] << 8) + (uint8_t)buff[i + 1];
memcpy(buff1 + len1, buff + i, 2 + cipher_suites_len);
i += (2 + cipher_suites_len);
len1 += (2 + cipher_suites_len);
}
if(type == 2){
memcpy(buff1 + len1, buff + i, 2);
i += 2;
len1 += 2;
}
//compression methods
int compression_methods_len = (uint8_t)buff[i];
memcpy(buff1 + len1, buff + i, 1 + compression_methods_len);
i += (1 + compression_methods_len);
len1 += (1 + compression_methods_len);
int extensions_index = len1;
//extensions
int extensions_len = (uint16_t)(buff[i] << 8) + (uint8_t)buff[i + 1];
memcpy(buff1 + len1, buff + i, 2);
i += 2;
len1 += 2;
int i1 = i;
for(; i + 3 < i1 + extensions_len;){
int type = (uint16_t)(buff[i] << 8) + (uint8_t)buff[i + 1];
int extension_len = (uint16_t)(buff[i + 2] << 8) + (uint8_t)buff[i + 3];
if(type == 21){
i += (4 + extension_len);
continue;
}
memcpy(buff1 + len1, buff + i, 4 + extension_len);
i += (4 + extension_len);
len1 += (4 + extension_len);
}
if(len1 > len){
return -1;
}
if(type == 1){
memcpy(pmeinfo->message_client_hello.buff, buff1, len1);
pmeinfo->message_client_hello.buff_len = len1;
memcpy(pmeinfo->message_client_hello_no_extensions.buff, buff1, extensions_index);
pmeinfo->message_client_hello_no_extensions.buff_len = extensions_index;
}
if(type == 2){
memcpy(pmeinfo->message_server_hello.buff, buff1, len1);
pmeinfo->message_server_hello.buff_len = len1;
memcpy(pmeinfo->message_server_hello_no_extensions.buff, buff1, extensions_index);
pmeinfo->message_server_hello_no_extensions.buff_len = extensions_index;
}
return 0;
}
int client_hello_get(struct pme_info* pmeinfo, unsigned char *buff, int len){
int ret = client_server_hello_get(buff, len, pmeinfo, 1);
if(ret < 0){
LOG_ERROR(g_logger, "Invalid client hello");
return -1;
}
/*
printf("client_hello, buff_len = %d\n", pmeinfo->message_client_hello.buff_len);
for(int i = 0; i < pmeinfo->message_client_hello.buff_len; i++){
printf("%02x ", (uint8_t)pmeinfo->message_client_hello.buff[i]);
}
printf("\n");
printf("client_hello_no_extensions, buff_len = %d\n", pmeinfo->message_client_hello_no_extensions.buff_len);
for(int i = 0; i < pmeinfo->message_client_hello_no_extensions.buff_len; i++){
printf("%02x ", (uint8_t)pmeinfo->message_client_hello_no_extensions.buff[i]);
}
printf("\n");
*/
return 0;
}
int server_hello_get(struct pme_info* pmeinfo, unsigned char *buff, int len){
int ret = client_server_hello_get(buff, len, pmeinfo, 2);
if(ret < 0){
LOG_ERROR(g_logger, "Invalid server hello");
return -1;
}
/*
printf("server_hello, buff_len = %d\n", pmeinfo->message_server_hello.buff_len);
for(int i = 0; i < pmeinfo->message_server_hello.buff_len; i++){
printf("%02x ", (uint8_t)pmeinfo->message_server_hello.buff[i]);
}
printf("\n");
printf("server_hello_no_extensions, buff_len = %d\n", pmeinfo->message_server_hello_no_extensions.buff_len);
for(int i = 0; i < pmeinfo->message_server_hello_no_extensions.buff_len; i++){
printf("%02x ", (uint8_t)pmeinfo->message_server_hello_no_extensions.buff[i]);
}
printf("\n");
*/
return 0;
}
int get_public_key(X509 *cert, unsigned char *public_key){
//printf("call get_public_key\n");
int public_key_len = 0;
EVP_PKEY *pkey = X509_get_pubkey(cert);
if(pkey == NULL){
return -1;
}
unsigned char *p = NULL;
public_key_len = i2d_PUBKEY(pkey, &p);
public_key_len -= 24;
memcpy(public_key, p + 24, public_key_len);
/*
printf("public_key_len = %d\n", public_key_len);
for(int i = 0; i < public_key_len; i++){
printf("%02x ", public_key[i]);
}
printf("\n");
*/
EVP_PKEY_free(pkey);
return public_key_len;
}
int find_sub_block(unsigned char *s1, int len1, unsigned char *s2, int len2){
for(int i = 0; i + len2 < len1; i++){
int j;
for(j = 0; j < len2; j++){
if(s1[i + j] != s2[j]){
break;
}
}
if(j == len2){
return i;
}
}
return -1;
}
int strip_data_from_buff(unsigned char *input, int input_len, int begin, int end, unsigned char *output){
int output_len = 0;
memcpy(output + output_len, input, begin);
output_len += begin;
memcpy(output + output_len, input + end, input_len - end);
output_len += (input_len - end);
return output_len;
}
int strip_encrypted_data(unsigned char *input, int input_len, unsigned char *output){
int encrypted_data_begin = input_len - 24;
int encrypted_data_end = input_len;
return strip_data_from_buff(input, input_len, encrypted_data_begin, encrypted_data_end, output);
}
int strip_public_key(X509 *cert, unsigned char *input, int input_len, unsigned char *output){
unsigned char public_key[TLS_MESSAGE_LEN_MAX];
int public_key_len = get_public_key(cert, public_key);
if(public_key_len < 0){
return -1;
}
int public_key_begin = find_sub_block(input, input_len, public_key, public_key_len);
//printf("public key begin = %d\n", public_key_begin);
if(public_key_begin < 0){
return -1;
}
int public_key_end = public_key_begin + public_key_len;
return strip_data_from_buff(input, input_len, public_key_begin, public_key_end, output);
}
int get_serial_number(X509 *cert, unsigned char *serial_number){
ASN1_INTEGER *serial = X509_get_serialNumber(cert);
BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL);
int len = BN_num_bytes(bn);
BN_bn2bin(bn, serial_number);
/*
printf("serial number len = %d\n", len);
for(int i = 0; i < len; i++){
printf("%02x ", serial_number[i]);
}
printf("\n");
*/
return len;
}
int strip_serial_number(X509 *cert, unsigned char *input, int input_len, unsigned char *output){
unsigned char serial_number[TLS_MESSAGE_LEN_MAX];
int serial_number_len = get_serial_number(cert, serial_number);
if(serial_number_len < 0){
return -1;
}
int serial_number_begin = find_sub_block(input, input_len, serial_number, serial_number_len);
//printf("serial number begin = %d\n", serial_number_begin);
if(serial_number_begin < 0){
return -1;
}
int serial_number_end = serial_number_begin + serial_number_len;
return strip_data_from_buff(input, input_len, serial_number_begin, serial_number_end, output);
}
int certificate_get(struct pme_info* pmeinfo, unsigned char *buff, int len){
//printf("call certificate_get\n");
if(10 > len){
return -1;
}
int cert_len = (buff[7] << 16) + (buff[8] << 8) + buff[9];
int i = 10;
if(i + cert_len > len){
return -1;
}
unsigned char cert_buff[TLS_MESSAGE_LEN_MAX];
memcpy(cert_buff, buff + i, cert_len);
const unsigned char *p = cert_buff;
X509 *cert = d2i_X509(NULL, &p, cert_len);
if(cert == NULL){
return -1;
}
unsigned char buff1[TLS_MESSAGE_LEN_MAX];
unsigned char *input = cert_buff;
int input_len = cert_len;
unsigned char *output = buff1;
int output_len = 0;
output_len = strip_public_key(cert, input, input_len, output);
std::swap(output, input);
input_len = output_len;
output_len = strip_encrypted_data(input, input_len, output);
if(output_len >= 0){
memcpy(pmeinfo->message_certificate.buff, output, output_len);
pmeinfo->message_certificate.buff_len = output_len;
}
std::swap(output, input);
input_len = output_len;
output_len = strip_serial_number(cert, input, input_len, output);
if(output_len >= 0){
memcpy(pmeinfo->message_certificate_no_serial.buff, output, output_len);
pmeinfo->message_certificate_no_serial.buff_len = output_len;
}
X509_free(cert);
return 0;
}
int tls_header_parse(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_parsed_info *pktinfo){
int i = 0, len = pktinfo->data_len;
int curdir = stream->curdir;
struct tls_message_detail *cur_tls = NULL;
if(curdir == 1){
cur_tls = &(pmeinfo->cur_c2s_tls);
}
if(curdir == 2){
cur_tls = &(pmeinfo->cur_s2c_tls);
}
int cp_len = 0;
while(i < len){
if(cur_tls->buff_len < 5){
cp_len = MIN(5 - cur_tls->buff_len, len - i);
memcpy(cur_tls->buff + cur_tls->buff_len, pktinfo->data + i, cp_len);
cur_tls->buff_len += cp_len;
i += cp_len;
if(cur_tls->buff_len < 5){
break;
}
}
int content_type = cur_tls->buff[0];
if(content_type == 0x16){
if(cur_tls->buff_len < 6){
cp_len = MIN(1, len - i);
memcpy(cur_tls->buff + cur_tls->buff_len, pktinfo->data + i, cp_len);
cur_tls->buff_len += cp_len;
i += cp_len;
if(cur_tls->buff_len < 6){
break;
}
}
}
int handshake_type = 0;
if(content_type == 0x16){
handshake_type = cur_tls->buff[5];
}
int message_type = get_tls_message_type(content_type, handshake_type);
cur_tls->type = message_type;
cur_tls->len = (uint16_t)(cur_tls->buff[3] << 8) + (uint8_t)cur_tls->buff[4];
if(message_type < 0){
LOG_ERROR(g_logger, "message_type unknown, content_type = %d, handshake_type = %d", content_type, handshake_type);
memset(cur_tls, 0, sizeof(*cur_tls));
break;
}
cp_len = MIN(cur_tls->len + 5 - cur_tls->buff_len, len - i);
//client hello, server hello, certificate
if(message_type == 1 || message_type == 2 || message_type == 8){
memcpy(cur_tls->buff + cur_tls->buff_len, pktinfo->data + i, cp_len);
}
cur_tls->buff_len += cp_len;
i += cp_len;
if(cur_tls->len + 5 == cur_tls->buff_len){
if(message_type == 1 || message_type == 2 || message_type == 8){
switch (message_type){
case 1:
client_hello_get(pmeinfo, cur_tls->buff + 5, cur_tls->len);
break;
case 2:
server_hello_get(pmeinfo, cur_tls->buff + 5, cur_tls->len);
break;
case 8:
certificate_get(pmeinfo, cur_tls->buff + 5, cur_tls->len);
break;
default:
break;
}
}
memset(cur_tls, 0, sizeof(*cur_tls));
}
}
return 0;
}
int packet_need_filter(struct pkt_parsed_info *pktinfo){
struct iphdr *_iphdr = pktinfo->iphdr.v4;
int ttl = _iphdr->ttl;
if(ttl == 70 || ttl == 75){
//printf("packet_need_filter: ret = 1, ttl = %d\n", ttl);
return 1;
}
int data_len = pktinfo->data_len;
if(data_len == 0){
//printf("packet_need_filter: ret 1, data_len = %d\n", data_len);
return 1;
}
return 0;
}
char pending_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_parsed_info *pktinfo){
//printf("call pending_opstate\n");
struct tcphdr *_tcphdr = pktinfo->tcphdr;
if(_tcphdr->fin || _tcphdr->rst){
pmeinfo->has_fin_rst = 1;
}
struct stream_tuple4_v4 *tuple4 = stream->addr.tuple4_v4;
inet_ntop(AF_INET, &(tuple4->saddr), pmeinfo->sip, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(tuple4->daddr), pmeinfo->dip, INET_ADDRSTRLEN);
pmeinfo->sport = ntohs(tuple4->source);
pmeinfo->dport = ntohs(tuple4->dest);
if(packet_need_filter(pktinfo) == 1){
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
int ret = chello_packet_parse(pmeinfo, pktinfo);
if(ret < 0){
pmeinfo->_errno = -1;
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
tls_header_parse(stream, pmeinfo, pktinfo);
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
char data_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_parsed_info *pktinfo){
struct tcphdr *_tcphdr = pktinfo->tcphdr;
if(_tcphdr->fin || _tcphdr->rst){
pmeinfo->has_fin_rst = 1;
}
if(packet_need_filter(pktinfo) == 0){
tls_header_parse(stream, pmeinfo, pktinfo);
}
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
void time_tostring(struct timeval tv, char *buf, int buflen){
char tmbuf[64];
time_t nowtime;
struct tm *nowtm;
nowtime = tv.tv_sec;
//printf("nowtime = %lld\n", nowtime);
nowtm = localtime(&nowtime);
strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", nowtm);
snprintf(buf, buflen, "%s.%06ld", tmbuf, tv.tv_usec);
return;
}
void print_tls_message(struct tls_filtered_message *message, const char *name){
int len = message->buff_len;
printf("%s: len = %d, data = \n", name, len);
for(int i = 0; i < len; i++){
printf("%02x ", message->buff[i]);
}
printf("\n");
}
void cjson_add_tls_message(cJSON *log_obj, struct tls_filtered_message *message, const char *tls_message_name){
//print_tls_message(message, tls_message_name);
unsigned char out_buff[TLS_MESSAGE_LEN_MAX];
int out_len = b64_encode((const unsigned char*)message->buff, message->buff_len, out_buff);
if(out_len > 0){
memcpy(message->buff, out_buff, out_len);
message->buff_len = out_len;
cJSON *tls_message = cJSON_CreateObject();
cJSON_AddStringToObject(tls_message, "data", (char*)message->buff);
cJSON_AddNumberToObject(tls_message, "len", message->buff_len);
cJSON_AddItemToObject(log_obj, tls_message_name, tls_message);
}
return;
}
void output_result(struct pme_info *pmeinfo){
if(pmeinfo->has_fin_rst == 0){
printf("not have fin or rst\n");
return;
}
cJSON *log_obj = cJSON_CreateObject();
cJSON_AddStringToObject(log_obj, "sip", pmeinfo->sip);
cJSON_AddNumberToObject(log_obj, "sport", pmeinfo->sport);
cJSON_AddStringToObject(log_obj, "dip", pmeinfo->dip);
cJSON_AddNumberToObject(log_obj, "dport", pmeinfo->dport);
cJSON_AddStringToObject(log_obj, "proto", "tcp");
cjson_add_tls_message(log_obj, &(pmeinfo->message_client_hello), "client_hello");
cjson_add_tls_message(log_obj, &(pmeinfo->message_client_hello_no_extensions), "client_hello_no_extensions");
cjson_add_tls_message(log_obj, &(pmeinfo->message_server_hello), "server_hello");
cjson_add_tls_message(log_obj, &(pmeinfo->message_server_hello_no_extensions), "server_hello_no_extensions");
cjson_add_tls_message(log_obj, &(pmeinfo->message_certificate), "certificate");
cjson_add_tls_message(log_obj, &(pmeinfo->message_certificate_no_serial), "certificate_no_serial");
char *log_msg = cJSON_PrintUnformatted(log_obj);
//printf("%s\n\n", log_msg);
fputs(log_msg, g_fp);
fputs("\n", g_fp);
cJSON_Delete(log_obj);
cJSON_free(log_msg);
}
char close_opstate(struct streaminfo *stream, struct pme_info *pmeinfo, struct pkt_parsed_info *pktinfo, const void *a_packet){
if(a_packet != NULL){
struct tcphdr *_tcphdr = pktinfo->tcphdr;
if(_tcphdr->fin || _tcphdr->rst){
pmeinfo->has_fin_rst = 1;
}
if(packet_need_filter(pktinfo) == 0){
tls_header_parse(stream, pmeinfo, pktinfo);
}
}
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
void pme_info_destroy(struct pme_info *pmeinfo){
FREE(&pmeinfo);
pmeinfo = NULL;
}
extern "C" char sslparse_entry(struct streaminfo *stream, void** pme, int thread_seq, const void* a_packet){
//printf("call sslparse_entry\n");
char ret;
struct pme_info *pmeinfo = *(struct pme_info **)pme;
//printf("pmeinfo = %p, opstate = %d, a_packet = %p\n", pmeinfo, stream->opstate, a_packet);
if(a_packet == NULL && stream->opstate != OP_STATE_CLOSE){
return APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
struct pkt_parsed_info pktinfo;
memset(&pktinfo, 0, sizeof(pktinfo));
ipv4_header_parse(a_packet, &pktinfo);
switch(stream->opstate){
case OP_STATE_PENDING:
//printf("call pending\n");
pmeinfo = ALLOC(struct pme_info, 1);
*pme = pmeinfo;
ret = pending_opstate(stream, pmeinfo, &pktinfo);
break;
case OP_STATE_DATA:
//printf("call data\n");
ret = data_opstate(stream, pmeinfo, &pktinfo);
break;
case OP_STATE_CLOSE:
//printf("call close\n");
ret = close_opstate(stream, pmeinfo, &pktinfo, a_packet);
break;
default:
break;
}
if((ret & APP_STATE_DROPME)){
if(pmeinfo->_errno >= 0){
output_result(pmeinfo);
}
pme_info_destroy(pmeinfo);
}
return ret;
}
extern "C" int sslparse_init(){
char *log_path = (char*)"./ssl_parse_stat.log";
int log_level = 10;
g_logger = MESA_create_runtime_log_handle(log_path, log_level);
g_fp = fopen("./ssl_parse_stat.txt", "a+");
return 0;
}
extern "C" void sslparse_destroy(){
}

View File

@@ -3,6 +3,36 @@
include(ExternalProject)
include(ExternalProject)
### OpenSSL 1.1.1
ExternalProject_Add(OpenSSL PREFIX openssl
URL ${CMAKE_CURRENT_SOURCE_DIR}/openssl-1.1.1.tar.gz
URL_MD5 d65944e4aa4de6ad9858e02c82d85183
CONFIGURE_COMMAND ./Configure enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers linux-x86_64 --prefix=<INSTALL_DIR> --openssldir=<INSTALL_DIR>/lib/ssl
enable-ec_nistp_64_gcc_128 no-shared
BUILD_COMMAND ${MAKE_COMMAND}
INSTALL_COMMAND make install_sw
BUILD_IN_SOURCE 1)
ExternalProject_Get_Property(OpenSSL INSTALL_DIR)
set(OPENSSL_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include)
set(OPENSSL_LINK_DIRECTORIES ${INSTALL_DIR}/lib)
set(OPENSSL_PKGCONFIG_PATH ${INSTALL_DIR}/lib/pkgconfig/)
file(MAKE_DIRECTORY ${INSTALL_DIR}/include)
add_library(openssl-crypto-static STATIC IMPORTED GLOBAL)
add_dependencies(openssl-crypto-static OpenSSL)
set_property(TARGET openssl-crypto-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libcrypto.a)
set_property(TARGET openssl-crypto-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include)
add_library(openssl-ssl-static STATIC IMPORTED GLOBAL)
add_dependencies(openssl-ssl-static OpenSSL)
set_property(TARGET openssl-ssl-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libssl.a)
set_property(TARGET openssl-ssl-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include)
### cJSON: 注意: -DCMAKE_POSITION_INDEPENDENT_CODE=ON
ExternalProject_Add(cJSON PREFIX cJSON
URL ${CMAKE_CURRENT_SOURCE_DIR}/cJSON-1.7.7.tar.gz

Binary file not shown.