xplico中使用ndpi進行協議識別
阿新 • • 發佈:2019-02-02
0x01 緣由
有人通過github找我瞭解xplico,一直沒有好好解答他的問題,於是想著手寫這麼一篇簡單文章。
0x02 介紹
做協議識別:1、特徵碼
2、埠
3、正則
詳細介紹,傳送:http://www.sdnlab.com/17449.html
0x03 xplico的使用
在tTcp_garbage.c \Udp_analysis.c 中使用,一般是將tcp層資料傳給ndpi,使用是要在配置檔案中進行配置;
/* nDPI library */ #include "ndpi_main.h" #include "ndpi_api.h" .... .... //申請記憶體 static void *nDPImalloc(unsigned long size) { return malloc(size); } //釋放記憶體 static void nDPIfree(void *freeable) { free(freeable); } static void nDPIPrintf(u_int32_t protocol, void *id_struct, ndpi_log_level_t log_level, const char *format, ...) { return; } //匹配 static ndpi_protocol nDPIPacket(packet *pkt, struct ndpi_flow_struct *l7flow, struct ndpi_id_struct *l7src, struct ndpi_id_struct *l7dst, bool ipv4) { void *data; size_t offset, size; ftval voffset; const pstack_f *ip; unsigned long when; ndpi_protocol l7prot_id; if (ipv4) { ip = ProtStackSearchProt(pkt->stk, ip_id); ProtGetAttr(ip, ip_offset_id, &voffset); offset = voffset.uint32; data = pkt->raw + offset; size = pkt->raw_len - offset; } else { ip = ProtStackSearchProt(pkt->stk, ipv6_id); ProtGetAttr(ip, ipv6_offset_id, &voffset); offset = voffset.uint32; data = pkt->raw + offset; size = pkt->raw_len - offset; } when = pkt->cap_sec; when = when * NDPI_TICK_RES; when += pkt->cap_usec/1000; /* (1000000 / NDPI_TICK_RES) */ pthread_mutex_lock(&ndpi_mux); /** * Processes one packet and returns the ID of the detected protocol. * This is the MAIN PACKET PROCESSING FUNCTION. * * @par ndpi_struct = the detection module * @par flow = pointer to the connection state machine * @par packet = unsigned char pointer to the Layer 3 (IP header) * @par packetlen = the length of the packet * @par current_tick = the current timestamp for the packet * @par src = pointer to the source subscriber state machine * @par dst = pointer to the destination subscriber state machine * @return the detected ID of the protocol * */ l7prot_id = ndpi_detection_process_packet(ndpi, l7flow, data, size, when, l7src, l7dst); pthread_mutex_unlock(&ndpi_mux); return l7prot_id; } packet *TcpGrbDissector(int flow_id) { char *l7prot_type; struct ndpi_flow_struct *l7flow; struct ndpi_id_struct *l7src, *l7dst; ndpi_protocol l7prot_id .... .... if (stage != 4 && (l7prot_type == NULL || l7prot_id.master_protocol == NDPI_PROTOCOL_HTTP) && l7flow != NULL) { if (TcpGrbClientPkt(priv, pkt)) { //做匹配 l7prot_id = nDPIPacket(pkt, l7flow, l7src, l7dst, ipv4); } else { l7prot_id = nDPIPacket(pkt, l7flow, l7dst, l7src, ipv4); } if (l7prot_id.protocol != NDPI_PROTOCOL_UNKNOWN) { stage++; //根據id獲取名字 l7prot_type = ndpi_protocol2name(ndpi, l7prot_id, buff, TCP_CFG_LINE_MAX_SIZE); } } .... .... } int DissectInit(void) { char tmp_dir[256]; unsigned short i; /*協議掩碼*/ NDPI_PROTOCOL_BITMASK all; .... .... /* ndpi */ pthread_mutex_init(&ndpi_mux, NULL); /*初始化,返回一個初始化檢測模組*/ ndpi = ndpi_init_detection_module(NDPI_TICK_RES, nDPImalloc, nDPIfree, nDPIPrintf); if (ndpi == NULL) { LogPrintf(LV_ERROR, "nDPi initializzation failed"); return -1; } /* enable all protocols */ NDPI_BITMASK_SET_ALL(all); //設定協議掩碼 ndpi_set_protocol_detection_bitmask2(ndpi, &all); //得到id結構的大小,用於動態申請ndpi_id_struct ndpi_proto_size = ndpi_detection_get_sizeof_ndpi_id_struct(); //得到flow結構的大小,用於動態申請ndpi_flow_struct ndpi_flow_struct_size = ndpi_detection_get_sizeof_ndpi_flow_struct(); return 0; }
0x04 xplico中的使用例子
./xplico -l -c ./config/xplico_dpi.cfg -m pcap -f eyou.pcap
輸出結果:
13:59:00 [tcp-grb]{9969}-DEBUG: DST: 172.16.2.54:56051 l7prot_type HTTP //新增的輸出 13:59:00 [tcp-grb]{9969}-DEBUG: TCP->HTTP garbage... bye bye fid:9969 count:2 13:59:00 [tcp-grb]{9966}-DEBUG: TCP->Unknown garbage... bye bye fid:9966 count:2 13:59:00 [udp-grb]{9958}-DEBUG: DST: 239.255.255.250:1900 l7prot_type HTTP 13:59:00 [tcp-grb]{9894}-DEBUG: TCP->HTTP garbage... bye bye fid:9894 count:103