此文章是项目开发过程中遇到的关键问题,在此做记录方便日后查看。
问题详细阐述
使用C++对旁路捕获的数据包进行IP地址的匹配,随后将HTTP协议数据包和SMTP协议数据包进行分流。
问题拆解模块化
1.使用libnids对数据流进行抓取
2.首先对数据流的IP层进行解析,根据数据库的匹配规则进行IP匹配,若匹配成功则发送警报
3.然后对数据流的特征进行提取,若是HTTP协议就将数据提交给HTTP数据流处理函数进行还原,若是SMTP数据就提交给SMTP数据流处理函数进行还原
问题解决
1.进行数据抓取
由于电脑原因目前进行跳过,等换电脑了这块再进行补全。
2.对数据流进行分流
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include "nids.h"
//头文件
char sAscii_string[10000];
char* char_to_ascii(char ch){
char* pString;
sAscii_string[0] = 0;
pString = sAscii_string;
if (ch >= '!' && ch <= '~') {
*pString++ = ch;
}
else if (ch == ' '){
*pString++ = ch;
}else if (ch == '\n' || ch == '\r'){
*pString++ = ch;
}else{
*pString++ = '.';
}
*pString = '\0';
return sAscii_string;
}
bool is_http_packet(const char* data) {
const char* http_methods[] = { "GET ", "POST ", "PUT ", "DELETE ", "HEAD ", "OPTIONS ", "HTTP/1.0", "HTTP/1.1" };
for (int i = 0; i < 8; i++) {
if (strstr(data, http_methods[i]) != NULL) {
return true;
}
}
return false;
}
bool is_smtp_packet(const char* data) {
const char* smtp_keywords[] = { "220 ", "HELO", "EHLO", "MAIL FROM", "RCPT TO", "DATA" };
for (int i = 0; i < 6; i++) {
if (strstr(data, smtp_keywords[i]) != NULL) {
return true;
}
}
return false;
}
void print_string(const char* data, int length){
for (int i = 0; i < length; i++) {
printf("%s", char_to_ascii(data[i]));
}
putchar('\n');
}
void tcp_protocol_callback(struct tcp_stream *tcp_connection, void **arg) {
char address_string[1024];
char content[65535];
if (tcp_connection->nids_state == NIDS_JUST_EST) {
tcp_connection->client.collect++;
tcp_connection->server.collect++;
}else if (tcp_connection -> nids_state == NIDS_DATA) {
struct half_stream* hlf = NULL;
if (tcp_connection -> client.count_new) {
struct tuple4 ip_and_port = tcp_connection->addr;
strcpy(address_string, inet_ntoa(*((struct in_addr*)&(ip_and_port.saddr))));
sprintf(address_string + strlen(address_string), " : %i", ip_and_port.source);
strcat(address_string, "<--");
strcat(address_string, inet_ntoa(*((struct in_addr*)&(ip_and_port.daddr))));
sprintf(address_string + strlen(address_string), " : %i", ip_and_port.dest);
strcat(address_string, "\n");
printf("%s\n", address_string);
hlf = &tcp_connection->client;
} else if (tcp_connection -> server.count_new) {
struct tuple4 ip_and_port = tcp_connection->addr;
strcpy(address_string, inet_ntoa(*((struct in_addr*)&(ip_and_port.saddr))));
sprintf(address_string + strlen(address_string), " : %i", ip_and_port.source);
strcat(address_string, "-->");
strcat(address_string, inet_ntoa(*((struct in_addr*)&(ip_and_port.daddr))));
sprintf(address_string + strlen(address_string), " : %i", ip_and_port.dest);
strcat(address_string, "\n");
printf("%s\n", address_string);
hlf = &tcp_connection->server;
}
if (hlf != NULL) {
printf("------------------------------------\n");
memcpy(content, hlf->data, hlf->count_new);
content[hlf->count_new] = '\0';
if (is_http_packet(content)) {
print_string(content, hlf->count_new);
} else {
printf("This is not an HTTP packet.\n");
}
printf("------------------------------------\n");
}
}
fflush(stdout);
}
int main(int argc, char** argv){
struct nids_chksum_ctl temp;
temp.netaddr = 0;
temp.mask = 0;
temp.action = 1;
nids_register_chksum_ctl(&temp, 1);
//nids_params.device = "ens33";
if (!nids_init()){
printf("出现错误:%s\n", nids_errbuf);
exit(1);
}
nids_register_tcp((void *)tcp_protocol_callback);
nids_run();
return 0;
}
有空会对代码进行详细注释