当前位置:编程学习 > 网站相关 >>

网络安全:捕包只能捕获单向数据流???急

各位朋友:
  我学习捕包解析http协议。基本配置如下:                          各位请详细解析,最好拿出例子。我是初学者,很笨。
  fedora 9 linux 
  libnids libpcap libnet
  gcc 编译器
问题一:
  在应用层用libnids捕获http数据流,但是,只能捕获到服务器发给我的响应信息,而我的客户端发给服务器的请求报文却不能捕获。我不知道这是为什么?? 
  具体编码如下:(见问题后面);

问题二:
   参见http协议内容。
   charset 字符集:我如何将字符集转换,比如实体内容如果为汉语,我解析出来printf为乱码,如何将字符集转化输出不是乱码?
   content-coding 内容编码:是否是压缩的。请问如果是压缩的,解析数据包的时候,用不用解压缩?这些数据包如何解压缩呢?
   transfer-coding 传输编码  :传输编码是加密的话,如何判断用何种加密形式?解密算法一般可以从网络上下。
  chunked-body:成块传输代码:  这是怎么回事?我不明白。怎么解析这些成块代码???
问题三:
  我如何知道具体数据包里面每一个字节的格式?是否我不用知道他的具体格式,只要用 strstr函数解析就可以了???

   具体编码如下:
    
   #include <nids.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.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 parse_client_data(char content[], int number)
{
    char temp[1024];
    char str1[1024];
    char str2[1024];
    char str3[1024];
    int i;
    int k;
    int j;
    char entity_content[1024];
    if (content[0] != 'H' && content[1] != 'T' && content[2] != 'T' && content[3] != 'P')
    {
        printf("实体内容为(续):\n");
        for (i = 0; i < number; i++)
        {
            printf("%s", char_to_ascii(content[i]));
        }
        printf("\n");
    }
    else
    {
        for (i = 0; i < strlen(content); i++)
        {
            if (content[i] != '\n')
            {
                k++;
                continue;
            }
            for (j = 0; j < k; j++)
                temp[j] = content[j + i - k];
            temp[j] = '\0';
            if (strstr(temp, "HTTP"))
            {
                printf("状态行为:");
                printf("%s\n", temp);
                sscanf(temp, "%s %s %s", str1, str2);
                printf("HTTP协议为:%s\n", str1);
                printf("状态代码为:%s\n", str2);
            }
            if (strstr(temp, "Date"))
            {
                printf("当前的时间为(Date):%s\n", temp + strlen("Date:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Server"))
            {
                printf("服务器为(Server):%s\n", temp + strlen("Server:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Cache-Control"))
            {
                printf("缓存机制为(Cache-Control):%s\n", temp + strlen("Cache-Control:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Expires"))
            {
                printf("资源期限为(Expires):%s\n", temp + strlen("Expires:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Last-Modified"))
            {
                printf("最后一次修改的时间为(Last-Modified):%s\n", temp + strlen("Last-Modified:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "ETag"))
            {
                printf("Etag为(ETag):%s\n", temp + strlen("Etag:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Accept-Ranges"))
            {
                printf("Accept-Ranges(Accept-Ranges):%s\n", temp + strlen("Accept-Ranges:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Content-Length"))
            {
                printf("内容长度为(Content-Length):%s\n", temp + strlen("Content-Length:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Connection"))
            {
                printf("连接状态为(Connection):%s\n", temp + strlen("Connection:"));
                printf("%s\n", temp);
            }
            if (strstr(temp, "Content-Type"))
            {
                printf("内容类型为(Content-Type):%s\n", temp + strlen("Content-Type:"));
                printf("%s\n", temp);
            }
            /* 获取实体内容 */
            if ((content[i] == '\n') && (content[i + 1] == '\r'))
            {
                if (i + 3 == strlen(content))
                {
                    printf("无实体内容\n");
                    break;
                }
                for (j = 0; j < number - i - 3; j++)
                    entity_content[j] = content[i + 3+j];
                entity_content[j] = '\0';
                printf("实体内容为:\n");
                for (i = 0; i < j; i++)
                {
                    printf("%s", char_to_ascii(entity_content[i]));
                }
                printf("\n");
                break;
            }
            k = 0;
        }
    }
}
/* --------------------编程问答-------------------- 代码如下:接上部分

  void parse_server_data(char content[], int number)
{
    char temp[1024];
    char str1[1024];
    char str2[1024];
    char str3[1024];
    int i;
    int k;
    int j;
    char entity_content[1024];
    for (i = 0; i < strlen(content); i++)
    {
        if (content[i] != '\n')
        {
            k++;
            continue;
        }
        for (j = 0; j < k; j++)
            temp[j] = content[j + i - k];
        temp[j] = '\0';
        if (strstr(temp, "GET"))
        {
            printf("请求行为:");
            printf("%s\n", temp);
            sscanf(temp, "%s %s %s", str1, str2, str3);
            printf("使用的命令为:%s\n", str1);
            printf("获得的资源为:%s\n", str2);
            printf("HTTP协议类型为:%s\n", str3);
        }
        if (strstr(temp, "Accept:"))
        {
            printf("接收的文件包括(Accept:):%s\n", temp + strlen("Accept:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "Referer"))
        {
            printf("转移地址为(Referer):%s\n", temp + strlen("Referer:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "Accept-Language"))
        {
            printf("使用的语言为(Accept-Language):%s\n", temp + strlen("Accept-Language:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "Accept-Encoding"))
        {
            printf("接收的编码方式为(Accept-Encoding):%s\n", temp + strlen("Accept-Encoding:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "If-Modified-Since"))
        {
            printf("上次修改时间为(If-Modified-Since):%s\n", temp + strlen("If-Modified-Since:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "If-None-Match"))
        {
            printf("If-None-Match为(If-Modified-Since):%s\n", temp + strlen("If-None-Match:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "User-Agent"))
        {
            printf("用户的浏览器信息为(User-Agent):%s\n", temp + strlen("User-Agent:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "Host"))
        {
            printf("访问的主机为(Host):%s\n", temp + strlen("Host:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "Connection"))
        {
            printf("连接状态为(Connection):%s\n", temp + strlen("Connection:"));
            printf("%s\n", temp);
        }
        if (strstr(temp, "Cookie"))
        {
            printf("Cookie为(Cookie):%s\n", temp + strlen("Cookie:"));
            printf("%s\n", temp);
        }
        /* 获取实体内容 */
        if ((content[i] == '\n') && (content[i + 1] == '\r') && (content[i + 2] == '\n'))
        {
            if (i + 3 == strlen(content))
            {
                printf("无实体内容\n");
                break;
            }
            for (j = 0; j < strlen(content) - i - 3; j++)
                entity_content[j] = content[i + 3+j];
            entity_content[j] = '\0';
            printf("实体内容为:\n");
            printf("%s", entity_content);
            printf("\n");
            break;
        }
        k = 0;
    }
}
/*
=======================================================================================================================
下面是回调函数,实现对HTTP协议的分析
=======================================================================================================================
 */
void http_protocol_callback(struct tcp_stream *tcp_http_connection, void **param)
{
    char address_content[1024];
    char content[65535];
    char content_urgent[65535];
    struct tuple4 ip_and_port = tcp_http_connection->addr;
    strcpy(address_content, inet_ntoa(*((struct in_addr*) &(ip_and_port.saddr))));
    sprintf(address_content + strlen(address_content), " : %i", ip_and_port.source);
    strcat(address_content, " <----> ");
    strcat(address_content, inet_ntoa(*((struct in_addr*) &(ip_and_port.daddr))));
    sprintf(address_content + strlen(address_content), " : %i", ip_and_port.dest);
    strcat(address_content, "\n");
    if (tcp_http_connection->nids_state == NIDS_JUST_EST)
    {
        if (tcp_http_connection->addr.dest != 80)
         /* 只捕获HTTP协议数据包 */
        {
            return ;
        }
        tcp_http_connection->client.collect++; /* 浏览器接收数据 */
        tcp_http_connection->server.collect++; /* WEB服务器端接收数据 */
        printf("\n\n\n==============================================\n");
        printf("%s 建立连接...\n", address_content);
        return ;
    }
    if (tcp_http_connection->nids_state == NIDS_CLOSE)
    {
        printf("--------------------------------\n");
        printf("%s连接正常关闭...\n", address_content);
        /* 连接正常关闭 */
        return ;
    }
    if (tcp_http_connection->nids_state == NIDS_RESET)
    {
        printf("--------------------------------\n");
        printf("%s连接被RST关闭...\n", address_content);
        /* 连接被RST关闭 */
        return ;
    }
    if (tcp_http_connection->nids_state == NIDS_DATA)
    {
        struct half_stream *hlf;
        if (tcp_http_connection->client.count_new)
         /* 浏览器接收数据 */
        {
            hlf = &tcp_http_connection->client;
            /* hlft表示浏览器接收的数据 */
            strcpy(address_content, inet_ntoa(*((struct in_addr*) &(ip_and_port.saddr))));
            sprintf(address_content + strlen(address_content), ":%i", ip_and_port.source);
            strcat(address_content, " <---- ");
            strcat(address_content, inet_ntoa(*((struct in_addr*) &(ip_and_port.daddr))));
            sprintf(address_content + strlen(address_content), ":%i", ip_and_port.dest);
            strcat(address_content, "\n");
            printf("\n");
            printf("%s", address_content);
            printf("浏览器接收数据...\n");
            printf("\n");
            memcpy(content, hlf->data, hlf->count_new);
            content[hlf->count_new] = '\0';
            parse_client_data(content, hlf->count_new);
            /* 分析浏览器接收的数据 */
        }
        else
        {
            hlf = &tcp_http_connection->server;
            /* hlf表示Web服务器的TCP连接端 */
            strcpy(address_content, inet_ntoa(*((struct in_addr*) &(ip_and_port.saddr))));
            sprintf(address_content + strlen(address_content), " : %i", ip_and_port.source);
            strcat(address_content, " ----> ");
            strcat(address_content, inet_ntoa(*((struct in_addr*) &(ip_and_port.daddr))));
            sprintf(address_content + strlen(address_content), ":%i", ip_and_port.dest);
            strcat(address_content, "\n");
            printf("\n");
            printf("%s", address_content);
            printf("服务器接收数据...\n");
            printf("\n");
            memcpy(content, hlf->data, hlf->count_new);
            content[hlf->count_new] = '\0';
            parse_server_data(content, hlf->count_new);
            /* 分析WEB服务器接收的数据 */
        }
    }
    return ;
}
/*
=======================================================================================================================
主函数
=======================================================================================================================
 */
int main()
{
nids_params.device = "eth1";
    if (!nids_init())
     /* Libnids初始化 */
    {
        printf("出现错误:%s\n", nids_errbuf);
        exit(1);
    }
    nids_register_tcp(http_protocol_callback);
    /* 注册回调函数 */
    nids_run(); /* 进入循环捕获数据包状态 */

return 0;
}
补充:云计算 ,  云安全
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,