Packet Sniffing and Spoofing PDF
Packet Sniffing and Spoofing PDF
2. Source ip : 10.0.2.7
Destination ip : 10.0.2.8
We can observe from the below screenshots that 10 ICMP packets sent from 10.0.2.7
to 10.0.2.8 are sniffed.
Problem 1 :
Here are few steps to the sequence of library calls essential for sniffer programs :
1. Setting up device : pcap sets the device on its own. If this fails, it saves the error
message into errbuf. pcap_lookupdev(errbuf) can be used to find a device to sniff on.
2. Opening the device for sniffing : pcap uses pcap_open_live() to open session on a
device we will be sniffing on. The format of the statement is as follows :
pcap_t*pcap_open_live(char *device, int snaplen, int promise, int to_ms,
char*ebuf)
- Char *device : specify the device we want to sniff on.
- Snaplen : max number of bytes to be captured by pcap.
- Promise : specify if promiscuous mode is on or not.
- To_ms : read time in milliseconds.
- char*ebuf : stores error messages.
4. Sniffing :
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) is used to capture a single
packet at a time.
- pcap_t *p : session handler
- Struct pcap_pkthdr*h : a pointer to a structure that holds general information
about the packet.
- The function returns a u_char pointer to the packet that is described by this
structure.
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) is used to
enter a loop that waits for n number of packets to be sniffed before being done.
- pcap_t*p : session handle.
- int cnt : number of packets that should be sniffed before returning. Negative value
will sniff until an error occurs.
- pcap_handler callback : name of callback function.
- U_char *user : NULL in many situations.
5. Close the sniffing session : pcap_close() is used to close the sniffing session.
Problem 2 :
When sniffex is run without root privileges, it says that we don’t have permission to capture on
that device. Pcap needs root permissions to run sniffex because it has to access the network
interface card. pcap_lookupdev() in the sniffex program fails as it is looking for the interface to
sniff on and this requires root access.
Promiscuous Mode On :
When promiscuous mode is on, the sniffer can only sniff the packets which are sent to the
device running the sniffer code and not the packets that are sent to some other device.
When promiscuous mode is off, the machine running the sniffer code can sniff all the packets in
the network.
Task 1.2 B : Writing Filters
User establishes a telnet connection to host 10.0.2.8. The credentials for the host are entered
by the user and this is seen in plaintext in the attacker’s terminal because he is running the
sniffer program with filter set to port 23. Telnet connection runs on port 23. When we sniff telnet
connections, the entire traffic is displayed in plaintext with filter set to port 23.
Task 2 : Spoofing
Attacker IP : 10.0.2.6
Source IP : 10.0.2.7
Destination IP : 10.0.2.8
Spoofing program is run on the attacker machine. An UDP packet is created where
some of the header field values like source IP, destination IP, source and destination
are specified explicitly. Here, source IP is given as 10.0.2.7. So, even though the packet
is being sent from 10.0.2.6, it seems that the packet is being received from 10.0.2.7.
UDP Header
IP Header
Running the spoofing program
Code ( sniffex.c )
#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* Ethernet header */
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
/* IP header */
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
/* TCP header */
typedef u_int tcp_seq;
struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS
(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
void
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
void
print_payload(const u_char *payload, int len);
void
print_hex_ascii_line(const u_char *payload, int len, int offset);
void
print_app_banner(void);
void
print_app_usage(void);
/*
* app name/banner
*/
void
print_app_banner(void)
{
return;
}
/*
* print help text
*/
void
print_app_usage(void)
{
return;
}
/*
* print data in rows of 16 bytes: offset hex ascii
*
* 00000 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1..
*/
void
print_hex_ascii_line(const u_char *payload, int len, int offset)
{
int i;
int gap;
const u_char *ch;
/* offset */
printf("%05d ", offset);
/* hex */
ch = payload;
for(i = 0; i < len; i++) {
printf("%02x ", *ch);
ch++;
/* print extra space after 8th byte for visual aid */
if (i == 7)
printf(" ");
}
/* print space to handle line less than 8 bytes */
if (len < 8)
printf(" ");
printf("\n");
return;
}
/*
* print packet payload data (avoid printing binary data)
*/
void
print_payload(const u_char *payload, int len)
{
if (len <= 0)
return;
return;
}
/*
* dissect/print packet
*/
void
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
int size_ip;
int size_tcp;
int size_payload;
/* determine protocol */
switch(ip->ip_p) {
case IPPROTO_TCP:
printf(" Protocol: TCP\n");
break;
case IPPROTO_UDP:
printf(" Protocol: UDP\n");
return;
case IPPROTO_ICMP:
printf(" Protocol: ICMP\n");
return;
case IPPROTO_IP:
printf(" Protocol: IP\n");
return;
default:
printf(" Protocol: unknown\n");
return;
}
/*
* OK, this packet is TCP.
*/
/*
* Print payload data; it might be binary, so don't just
* treat it as a string.
*/
if (size_payload > 0) {
printf(" Payload (%d bytes):\n", size_payload);
print_payload(payload, size_payload);
}
return;
}
print_app_banner();
/* cleanup */
pcap_freecode(&fp);
pcap_close(handle);
printf("\nCapture complete.\n");
return 0;
}