TCP分流模块通过流量特征识别分流数据包

此文章是项目开发过程中遇到的关键问题,在此做记录方便日后查看。

问题详细阐述

使用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;
}

有空会对代码进行详细注释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值