2

I have 3 Ubuntu VM that represent client/server/attacker. I created an application that connect client and server in TCP and I have a packet sniffer in the attacker machine. However, the code only manage to sniff packet going from the attacker machine only, it can't detect the client/server connection. I tried the Wireshark, and it captured the connection between them. What do you think the problem is?

I'm using Virtual Box and the network is bridged. this is the code

#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);
}
Arwa
  • 23
  • 6
  • Not sure what you mean, but wouldn't it be correct behaviour a VM cannot sniff trafic of two other VMs? – too honest for this site Nov 19 '15 at 23:06
  • @Olaf but the other two VM uses the same network, wouldn't that mean the attacker if he sniffed the network, he should be able to find their packets as well? – Arwa Nov 19 '15 at 23:12
  • Depends on if the network code is emulating an ethernet switch (vs a hub). In that case then the packets from client <-> server will be point-to-point. These days (usually) an attacker configuration needs to be a waypoint in the packet routing topology. – par Nov 19 '15 at 23:15
  • Did you put the interface into promiscuous mode inside the attacker VM (not sure if libpcap does that for you)? – FatalError Nov 19 '15 at 23:18
  • As the VMs are all running on the same host it also might be the case that the kernel routing strategy is simply directing packets internally from one localhost socket to another. In that case you wouldn't see any packets between the client/server either. – par Nov 19 '15 at 23:22
  • @par If it as you said, will Wireshark be able to capture them? because it did. – Arwa Nov 19 '15 at 23:31
  • @FatalError I put it from the Network Sitting form VB, promiscuous mode: Allow all. – Arwa Nov 19 '15 at 23:35
  • @Arwa: To clarify, you're saying you ran Wireshark inside the attacker VM and saw the stream? Also, I think you'ed need to enable promiscuous mode inside the guest to see frames that aren't addressed to you (assuming there are any, see lansus' answer). – FatalError Nov 20 '15 at 00:01
  • @FatalError No, I was running the Wireshark on the host machine. I tried it in attacker VM and it didn't capture anything. Also, I have enabled the promiscuous mode in all the VM, still nothing – Arwa Nov 20 '15 at 13:17

1 Answers1

1

You are on an emulated LAN. The behavior will change depending on whether the VM bridge architecture emulates a switch or a hub:

  • The hub will send the recived packets to all output ports
  • The switch will target the MAC address associated with the target's IP address referred in its ARP table

Regarding the "promiscuous mode" mentioned in the comments: AFAIK, it only enables the network card to look at the packets it receives (on the physical link) even if they are not addressed to it (in the cas of a hub for example, where it receives packets sent to a different MAC address).

In your case, the network card will only see :

  • packets address to its MAC address
  • packets sent from the network card to any recipient
  • packets that have been sent to broadcast (MAC/IP)

To enable your attacker VM to see ALL the packets, you must either :

  • Use it as the default gateway in routing mode (will see all the packets)
  • Spoof each other host's MAC address (like Cain does)

Basically, you are trying to write a light-Wireshark/TCPdump in C, and if you take a look at their capabilities, you'll see they won't do more than what I described above.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53
Iansus
  • 198
  • 1
  • 12
  • Thank you, for the solution provided I tried deleting and adding the attacker IP as the default gateway by this command: route add default gw x.x.x.x. However, the internet went off and the Wireshark didn't capture anything at all. – Arwa Nov 20 '15 at 13:23