教你使用Libnids开发包做-协议分析、网络嗅探!

Libnids是基于Libpcap和Libnet而开发的,是一个用于网络入侵检测开发的专业编程接口,利用Libndis可以构建网络入侵检测系统。

Libnids有哪些功能

分析源码会发现,Libnids的主要功能包括捕获网络数据包,IP碎片重组、TCP数据流重组以及端口扫描攻击检测、异常数据包检测等等。

这里要说一下,Libnids是基于libpcap来捕获数据包,可以设定过滤规则。对于IP碎片重组,Libnids是参考Linux内核中的IP重组而实现的。

Libnids有TCP数据流重组功能,这在一些开发包中所不具备的,在Libnids中利用TCP数据流重组,可以分析基于TCP协议的各种应用层协议。

Libnids可以做什么

对于Libnids可以用在一下这几个方面

1、网络嗅探
2、协议分析
3、入侵检测

下面对这几个方面进行简单的描述。

网络嗅探

网络嗅探可以称为网络监视,主要是检测网络信息,查看网络内容。

如果你是网络管理员,想知道网络的运行状况,想检测网络出现的状况,可以使用网络嗅探技术来实现。

对于网络非法攻击者来说,为了获取敏感信息,可以使用网络嗅探技术来实现。获取密码、用户、账户等。这些都是基于Libnids获取的,所以说Libnids是一把双刃剑。

网络协议

Libndis是在Libpcap基础上开发的,所以他具备libpcap的功能,可以实现各种协议解析。我们在利用libnids分析基于TCP协议的各种协议时,不仅可以分析各种单个TCP数据包,而且可以分析整个TCP连接过程。

入侵检测

Libnids的设计是作为入侵检测系统的一个部件设计的,它实现了入侵检测系统中非常基础的功能。例如:数据包捕获、协议分析接口等。

Libnids还准备针对入侵检测系统的特性,实现了TCP数据流的重组功能,这对于分析针对TCP协议的各种攻击是很有帮助的。

Libnids安装

我们了解libnids可以做什么以后,接下来,我们来安装Libnids开发包。由于Libnids必须支持libpcap、libnet,所以我们得安装好这两个包。这里就不多说了,这里只给安装libnids安装。

安装libnids需要四个步骤,分别是:

tar zxvf libnids-1.24.tar.gz
./configure
make
make install

首先解压缩,执行如下命令:
在这里插入图片描述
然后进入Libnids解压缩目录,执行如下配置命令:

在这里插入图片描述

执行编译命令

在这里插入图片描述
执行安装命令

在这里插入图片描述

常用的Libnids函数

基本函数

  • int nids_init (void);

此函数的功能是对Libnids进行初始化,这是所有设计基于Libnids的程序最开始调用的函数。它的主要内容包含打开网络接口、打开文件、编译过滤规则、设置过滤规则、判断网络链路类型,进行必要的初始化工作。

  • int nids_run()

此函数的功能是运行Libnids,进入循环捕获数据包状态,它实际上是调用Libpcap函数pcap_loop()来循环捕获数据包。

  • int nids_getfd()

此函数的功能是获得文件描述符号。

  • int nids_dispatch(int cnt)
    此函数的功能就是调用Libpcap中的捕获数据包函数 pcap_dispatch()

  • int nids_next()

此函数的功能是调用Libpcap中的捕获数据包函数 pcap_next()

IP常用函数

  • void nids_register_ip_frag(void (*x))

此函数的功能是注册一个能够检测所有IP数据包的回调函数,包括IP碎片。例如:

nids_register_ip_frag(ip_frag_func);
注册一个回调函数ip_frag_func定义类型如下:

void ip_frag_func(struct ip * a_packet, int len)

此函数可以检测所有IP数据包,包括IP碎片。

TCP常用函数

  • void nids_register_tcp (void (*));

此函数是注册一个TCP链接的回调函数。回调函数的定义如下:

void tcp_callback (struct tcp_stream *a_tcp, void ** this_time_not_needed)

a_tcp表示一个TCP连接的所有信息,this_time_not_needed是要传递的连接参数信息。

  • void nids_killtcp(struct tcp_stream *a_tcp)

此函数的功能是终止TCP连接,它实际上是调用Libnet的函数进行构造数据包,然后发送出去。

  • void nids_discard(struct tcp_stream * a_tcp, int num)

此函数的功能是丢弃num字节TCP数据。

UDP常用函数

  • void nids_register_udp (void (*));

此函数的功能是注册一个分析UDP协议的回调函数,回调函数的类型定义如下:

  • void udp_callback(struct tuple4 * addr, char * buf, int len, struct
    ip * iph);

此回调函数中就可以对UDP数据包进行分析了。

Libnids的使用

显示tcp连接

下面我们写一个程序,显示TCP连接过程,并对它们的传输数据进行 详细的分析。

#include <sys/types.h>
#include <dnet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include <nids.h>

char ascii_string[10000];
char *char_to_ascii(char ch)
{
    char *string;
    ascii_string[0] = 0;
    string = ascii_string;
    if (isgraph(ch))
    {
        *string++ = ch;
    }
    else if (ch == ' ')
    {
        *string++ = ch;
    }
    else if (ch == '\n' || ch == '\r')
    {
        *string++ = ch;
    }
    else
    {
        *string++ = '.';
    }
    *string = 0;
    return ascii_string;
}

void tcp_protocol_callback(struct tcp_stream *tcp_connection, void **arg)
{
    int i;
    char address_string[1024];
    char content[65535];
    char content_urgent[65535];
    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");
    switch (tcp_connection->nids_state) /* 判断LIBNIDS的状态 */
    {
        case NIDS_JUST_EST:
            tcp_connection->client.collect++;
            tcp_connection->server.collect++;
            tcp_connection->server.collect_urg++;
            tcp_connection->client.collect_urg++;
            printf("%sTCP连接建立\n", address_string);
            return ;
        case NIDS_CLOSE:
            printf("--------------------------------\n");
            printf("%sTCP连接正常关闭\n", address_string);
            return ;
        case NIDS_RESET:
            printf("--------------------------------\n");
            printf("%sTCP连接被RST关闭\n", address_string);
            return ;
        case NIDS_DATA:
            {
                struct half_stream *hlf;
                if (tcp_connection->server.count_new_urg)
                {
                    printf("--------------------------------\n");
                    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, " urgent---> ");
                    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");
                    address_string[strlen(address_string) + 1] = 0;
                    address_string[strlen(address_string)] = tcp_connection->server.urgdata;
                    printf("%s", address_string);
                    return ;
                }
                if (tcp_connection->client.count_new_urg)
                {
                    printf("--------------------------------\n");
                    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, " <--- urgent ");
                    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");
                    address_string[strlen(address_string) + 1] = 0;
                    address_string[strlen(address_string)] = tcp_connection->client.urgdata;
                    printf("%s", address_string);
                    return ;
                }
                if (tcp_connection->client.count_new)
                {
                    hlf = &tcp_connection->client;
                    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("--------------------------------\n");
                    printf("%s", address_string);
                    memcpy(content, hlf->data, hlf->count_new);
                    content[hlf->count_new] = '\0';
                    printf("客户端接收数据\n");
                    for (i = 0; i < hlf->count_new; i++)
                    {
                        printf("%s", char_to_ascii(content[i]));
                    }
                    printf("\n");
                }
                else
                {

                    hlf = &tcp_connection->server;
                    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("--------------------------------\n");
                    printf("%s", address_string);
                    memcpy(content, hlf->data, hlf->count_new);
                    content[hlf->count_new] = '\0';
                    printf("服务器端接收数据\n");
                    for (i = 0; i < hlf->count_new; i++)
                    {
                        printf("%s", char_to_ascii(content[i]));
                    }
                    printf("\n");
                }
            }
        default:
            break;
    }
    return ;
}


int main(int argc ,char **argv)
{
    if (!nids_init())
     /* Libnids初始化 */
    {
        printf("出现错误:%s\n", nids_errbuf);
        exit(1);
    }
    nids_register_tcp((void*)tcp_protocol_callback);
    nids_run();
    /* Libnids进入循环捕获数据包状态 */
	return 0;
}

此程序主要分析当建立TCP数据流进行重组,显示TCP连接状态,并对TCP的传输数据进行详细分析并输出。

总结

Libnids是一个入侵检测系统开发包,可以构造入侵检测系统的基本框架,还可以用于网络监控系统,网络数据包分析系统等。

欢迎关注微信公众号【程序猿编码】,欢迎添加本人微信号(17865354792),交个朋友,咱们一起学习进步!

协议分析绝对有用 配合原书使用效果更好 《网络安全开发包详解》——前言 随着网络技术的飞速发展,网络安全问题变得日益严重,对网络安全的研究也越来越重要。在网络安全领域,有很多网络安全技术,如防火墙、入侵检测、安全扫描、网络嗅探协议分析、流量统计、网络管理以及蜜罐技术等,无论是研究这些技术的原理,还是直接使用这些技术来设计网络安全系统,都会遇到它们的程序设计与开发问题。例如,在研究这些技术的时候,通常要根据研究的理论来设计一个模型,以此模型来验证技术的正确性和性能;还有就是直接运用成熟的网络安全技术来设计一个应用系统,其中常见的有:防火墙系统(如Netfilter,pktfilter等),入侵检测系统(如Snort等),网络安全扫描系统(如Nmap,Nessus等),网络嗅探器(如Tcpdump/Windump,Sniffer等),网络协议分析系统(如Ethereal,Ettercap等),蜜罐系统(如H Honeyd)等。 无论是作为研究的模型还是成熟的应用系统,它们的设计和实现都离不开一些网络安全操作,其中一些操作是很基本的,使用频繁,而且很多都是底层操作,如网络地址的操作、网络接口的操作、数据包的捕获、数据包的构造、数据包的发送等。还有一些操作比较复杂,如流量的统计、路由的管理、ARP缓存的配置、防火墙的管理和配置等。这些操作都会在开发模型或应用系统时碰到,如果这些功能都已经实现,就只需调用它们,这样会大大提高开发的效率,从而降低成本,节省时间和精力。 为了实现这一目标,人们开发了关于这些操作的专用网络安全开发包。网络安全开发包是指用于网络安全研究和开发的一些专业开发函数库,它的主要作用是实现网络安全研究和开发的基本功能,为研究者和开发者进一步研究和开发网络安全提供编程接口,使网络开发人员能够忽略网络底层细节的实现,从而专注于程序本身具体功能的设计与开发。使用它们,会大大加快程序设计的速度。由于这些开发包已经经过时间的考验,非常稳定,使用它们也会提高程序的稳定性。利用它们,网络安全开发者可以很方便地编写出具有结构化强、健壮性好、可移植性高等特点的网络安全应用程序。网络安全开发包实现的都是某一种或某一类网络安全技术,都是经过很多网络安全研究和开发者的长期研究而形成的,人们的不断测试和使用使它们逐渐成熟起来,在实际应用中得到了深入推广。 网络安全开发包有很多种,功能也大不相同,其中比较著名、应用广泛、最具代表性的开发包有以下几种: · 网络数据包捕获开发包Libpcap; · Windows网络数据包捕获开发包WinPcap; · 网络数据包构造和发送开发包Libnet; · 网络入侵检测开发包Libnids; · 通用网络安全开发包Libdnet。 这些著名的网络安全开发包与上述网络安全技术密切相关,它们在网络安全领域得到了广泛的应用。这些网络安全开发包实现了一些网络安全技术,并为其他网络安全技术的开发打下坚实的基础,因而对于研究网络安全技术和开发网络安全应用程序是很有帮助的。 本书对上述网络安全开发包进行了详细讨论,详细阐述开发包的原理、数据结构、输出函数和使用方法。 本书的特点如下: ·介绍当今最著名的网络安全开发包,包括Libpcap,WinPcap,Libnet,Libdnet和Libndis等,全部以最新版本进行介绍。 · 讲解详细、透彻,对每个网络安全开发包的数据结构、输出函数以及使用方法都进行了详细阐述,特别对其使用方法进行了深入而细致的讨论。 · 针对每个网络安全开发包,提供了丰富的例程,每个程序短小精悍,都有全部源代码(需要这些源代码电子文档的读者,请与作者或本书责任编辑联系),对程序都了详细注解,对其编译过程和运行结果都进行了详细分析。 在本书的编写过程中,得到了很多朋友的帮助,在此对他们表示真挚的感谢。同时也感谢我的亲人,他们的支持和理解是我创作的动力。 由于作者水平有限,再加上网络安全技术的发展十分迅速,书中难免有不妥和错误之处,恳请广大读者赐。读者可以通过E-mail与作者联系。E-mail:securitybook@163.com(作者);zhangls@phei.com.cn(责任编辑) 刘文涛 2005年7月于武汉
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值