C中的数据包嗅探器适用于所有VM

时间:2015-11-19 23:01:32

标签: c linux ubuntu packet-capture packet-sniffers

我有3个代表客户端/服务器/攻击者的Ubuntu VM。我创建了一个在TCP中连接客户端和服务器的应用程序,我在攻击者机器中有一个数据包嗅探器。但是,代码只设法嗅探来自攻击者计算机的数据包,它无法检测客户端/服务器连接。我尝试了Wireshark,它捕获了它们之间的连接。您认为问题是什么?

我正在使用Virtual Box并且网络已被桥接。 这是代码

#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>


pcap_t* handle; 
int linkhdrsize; 
char filter[256];

/* - Packet Capture function - */
pcap_t* packet_capture(char* device, const char* bpfstr)
{
char errorbuffer[PCAP_ERRBUF_SIZE];
pcap_t* handle;
uint32_t source_ip, netmask;
struct bpf_program bpf;

if((handle=pcap_open_live(device,BUFSIZ,1,0,errorbuffer)) == NULL){
printf("pcap_open_live(): %s\n", errorbuffer);
return NULL;
}

if(pcap_lookupnet(device, &source_ip, &netmask, errorbuffer) <0)
{
printf("pcap_lookupnet: %s\n", errorbuffer);
return NULL;
}

if (pcap_compile(handle, &bpf, (char*)filter, 0, netmask))
{
printf("pcap_compile(): %s\n", pcap_geterr(handle));
return NULL;
}
if (pcap_setfilter(handle, &bpf) < 0)
{
printf("pcap_setfilter(): %s\n", pcap_geterr(handle));
return NULL;
}

return handle;
}

/* - Capture Loop function - */

void capture_loop(pcap_t* handle, pcap_handler func)
{
int linktype;
if((linktype = pcap_datalink(handle))<0)
{
printf("pcap_datalink(): %s\n", pcap_geterr(handle));
}
if(linktype==DLT_EN10MB)
linkhdrsize=14;
else
printf("Unsupported datalink (%d)\n", linktype);
if (pcap_loop(handle, 0, func, 0) < 0)
printf("pcap_loop failed: %s\n", pcap_geterr(handle));
}

/* - Parsing function - */

void parse_packet(u_char *user, struct pcap_pkthdr *packethdr, u_char *packetptr)
{
struct ip* ip_header;
struct tcphdr* tcp_header;
char ip_header_info[256], source_ip[256], destination_ip[256];
unsigned short id, seq;
packetptr += linkhdrsize;
ip_header = (struct ip*)packetptr;
strcpy(source_ip, inet_ntoa(ip_header->ip_src));
strcpy(destination_ip, inet_ntoa(ip_header->ip_dst));
packetptr += 4*ip_header->ip_hl;
if((ip_header->ip_p)==IPPROTO_TCP)
    {
        tcp_header = (struct tcphdr*)packetptr;
        printf("TCP  %s:%d -> %s:%d\n", source_ip, ntohs(tcp_header->source),
               destination_ip, ntohs(tcp_header->dest));
        printf("%c%c%c%c%c%c Seq: 0x%x Ack: 0x%x Win: 0x%x TcpLen: %d\n",
               (tcp_header->urg ? 'U' : '*'),
               (tcp_header->ack ? 'A' : '*'),
               (tcp_header->psh ? 'P' : '*'),
               (tcp_header->rst ? 'R' : '*'),
               (tcp_header->syn ? 'S' : '*'),
               (tcp_header->fin ? 'F' : '*'),
               ntohl(tcp_header->seq), ntohl(tcp_header->ack_seq),
               ntohs(tcp_header->window), 4*tcp_header->doff);
}
printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n");
}
void bailout(int signo)
{
    struct pcap_stat stats;

    if (pcap_stats(handle, &stats) >= 0)
    {
        printf("%d packets received\n", stats.ps_recv);
        printf("%d packets dropped\n\n", stats.ps_drop);
    }
    pcap_close(handle);
    exit(0);
}
/* - Main function - */
int main()
{
char interface[256]="eth0"; 
char filter[256]="tcp"; 
int packets=0;

if(( handle=packet_capture(interface,filter)) != NULL)
{
signal(SIGINT, bailout);
signal(SIGTERM, bailout);
signal(SIGQUIT, bailout);
capture_loop(handle,(pcap_handler)parse_packet);
bailout(0);
}
exit(0);
}

1 个答案:

答案 0 :(得分:1)

您使用的是模拟局域网。行为将根据VM桥架构是模拟交换机还是集线器而改变:

  • 集线器会将收到的数据包发送到所有输出端口
  • 交换机将定位与其ARP表中引用的目标IP地址相关联的MAC地址

关于&#34;混杂模式&#34;在评论中提到:AFAIK,它只允许网卡查看它收到的数据包(在物理链路上),即使它们没有发送到它(例如,在集线器的cas中,它接收发送到的数据包)一个不同的MAC地址)。

在您的情况下,网卡只会看到:

  • 数据包地址为其MAC地址
  • 从网卡发送给任何收件人的数据包
  • 已发送到广播的数据包(MAC / IP)

要让攻击者VM能够查看所有数据包,您必须:

  • 在路由模式下使用它作为默认网关(将看到所有数据包)
  • 欺骗对方主机的MAC地址(如Cain所做的)

基本上,你正试图在C中编写一个light-Wireshark / TCPdump,如果你看看它们的功能,你会发现它们不会比我上面描述的更多。< / p>