CHƯƠNG 6: PACKET SNIFFING AND SPOOFING
PHẦN 1: PACKET SENDING AND RECEIVING - REVISION
1. SOCKETS - KHÁI NIỆM CƠ BẢN
Socket là gì:
- Interface giữa application và network
- Cho phép processes giao tiếp qua network
- Giống như “cửa” để gửi/nhận data
Socket Types:
- Stream Sockets (SOCK_STREAM): TCP - reliable, ordered
- Datagram Sockets (SOCK_DGRAM): UDP - unreliable, unordered
- Raw Sockets (SOCK_RAW): Direct IP access
2. SOCKET APIs - GỬI PACKETS
Các bước cơ bản để gửi packet:
A. Tạo Socket:
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
// AF_INET: IPv4
// SOCK_DGRAM: UDP
// 0: protocol (default)
B. Cấu hình địa chỉ đích:
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
dest.sin_addr.s_addr = inet_addr(ip);C. Gửi data:
sendto(sockfd, data, length, 0,
(struct sockaddr*)&dest, sizeof(dest));3. NHẬN PACKETS
Hai cách chính:
A. NORMAL SOCKET (Application Layer)
Cách hoạt động:
- Kernel demultiplex packets dựa trên port
- Chỉ nhận packets gửi đến port cụ thể
- Application chỉ thấy payload (data)
Quy trình:
- Packet arrives → Network layer
- Transport layer checks destination port
- Nếu match → copy to socket buffer
- Application reads từ socket buffer
Hạn chế:
- Chỉ nhận packets cho port đã bind
- Không thấy headers (IP, TCP/UDP)
- Không thấy packets của processes khác
B. RAW SOCKET (Lower Level)
Đặc điểm:
- Access packets ở IP layer
- Thấy toàn bộ packet (bao gồm headers)
- Requires root/administrator privileges
Tạo Raw Socket:
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
// IPPROTO_TCP: chỉ TCP packets
// IPPROTO_UDP: chỉ UDP packets
// IPPROTO_ICMP: chỉ ICMP packets
PHẦN 2: PACKET SNIFFING
1. PACKET SNIFFING LÀ GÌ?
Định nghĩa:
- Capturing and analyzing network traffic
- Đọc packets không dành cho mình
- Có thể thấy toàn bộ packet (headers + data)
Mục đích:
- Legitimate: Network monitoring, debugging, security analysis
- Malicious: Steal passwords, eavesdrop, reconnaissance
2. LÀM SAO ĐỂ SNIFF PACKETS?
Vấn đề:
- Thông thường, network card chỉ nhận packets gửi cho mình
- Packets gửi cho máy khác bị discard ở hardware level
Giải pháp: PROMISCUOUS MODE
3. PROMISCUOUS MODE
Định nghĩa:
- Network interface card (NIC) accepts ALL packets
- Không filter theo destination MAC address
- Passes tất cả packets lên OS
Kích hoạt:
// Linux
struct ifreq ifr;
ioctl(sock, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_PROMISC;
ioctl(sock, SIOCSIFFLAGS, &ifr);Lưu ý:
- Requires root privileges
- Chỉ hoạt động trên shared medium (hub, wireless)
- Không hoạt động tốt trên switched networks (switch chỉ forward packets đến đúng port)
4. RECEIVING PACKETS - RAW SOCKET
Tạo Raw Socket:
int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
// AF_PACKET: Link layer
// ETH_P_ALL: All protocols
Nhận packet:
char buffer[65536];
struct sockaddr saddr;
int saddr_len = sizeof(saddr);
recvfrom(sock, buffer, 65536, 0, &saddr, &saddr_len);Vấn đề:
- Nhận TẤT CẢ packets → quá nhiều!
- Cần filter packets quan tâm
5. BSD PACKET FILTER (BPF)
Mục đích:
- Filter packets in kernel space
- Chỉ copy packets cần thiết lên user space
- Giảm overhead, tăng hiệu suất
Cách hoạt động:
- User defines filter rules
- Kernel applies filter TRƯỚC KHI copy to user space
- Chỉ matching packets được delivered
Filter examples:
tcp and port 80: Chỉ TCP packets port 80icmp: Chỉ ICMP packetshost 192.168.1.1: Chỉ packets từ/đến IP này
Packet Flow:
WITHOUT Filter:
Network → Kernel → Copy ALL packets → User space → Filter → Process
(Slow, nhiều overhead)WITH BPF:
Network → Kernel → BPF Filter → Copy matching packets → User space → Process
(Fast, ít overhead)6. PCAP (PACKET CAPTURE) API
Định nghĩa:
- High-level library for packet capture
- Cross-platform (Linux, Windows, macOS)
- Sử dụng BPF internally
- Wireshark, tcpdump dùng PCAP
Ưu điểm:
- Dễ sử dụng hơn raw sockets
- Portable
- Built-in BPF filtering
- Handle promiscuous mode automatically
A. PCAP WORKFLOW
Các bước chính:
1. Mở network device:
char *dev = "eth0";
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
// dev: network interface
// BUFSIZ: snapshot length
// 1: promiscuous mode ON
// 1000: read timeout (ms)
2. Set filter (optional):
struct bpf_program fp;
char filter_exp[] = "tcp and port 80";
pcap_compile(handle, &fp, filter_exp, 0, PCAP_NETMASK_UNKNOWN);
pcap_setfilter(handle, &fp);3. Capture packets:
Option A: Loop callback:
pcap_loop(handle, num_packets, packet_handler, NULL);
// num_packets: số packets cần capture (-1 = infinite)
// packet_handler: callback function
Option B: Single packet:
const u_char *packet = pcap_next(handle, &header);4. Process packet trong callback:
void packet_handler(u_char *args,
const struct pcap_pkthdr *header,
const u_char *packet) {
// header: metadata (timestamp, length)
// packet: actual packet data
}5. Close:
pcap_close(handle);B. PROCESSING CAPTURED PACKETS
Packet structure:
[Ethernet Header | IP Header | TCP/UDP Header | Data]Parse Ethernet header:
struct ether_header *eth = (struct ether_header *)packet;
// eth->ether_shost: source MAC
// eth->ether_dhost: dest MAC
// eth->ether_type: protocol type
Parse IP header:
struct ip *ip_header = (struct ip*)(packet + sizeof(struct ether_header));
// ip_header->ip_src: source IP
// ip_header->ip_dst: dest IP
// ip_header->ip_p: protocol (TCP/UDP/ICMP)
Parse TCP header:
int ip_header_len = ip_header->ip_hl * 4;
struct tcphdr *tcp = (struct tcphdr*)(packet + sizeof(struct ether_header) + ip_header_len);
// tcp->th_sport: source port
// tcp->th_dport: dest port
Extract data:
int tcp_header_len = tcp->th_off * 4;
u_char *data = (u_char*)(packet + sizeof(struct ether_header) + ip_header_len + tcp_header_len);
int data_len = header->len - (sizeof(struct ether_header) + ip_header_len + tcp_header_len);7. SNIFFING USING SCAPY
Scapy là gì:
- Python library for packet manipulation
- High-level, interactive
- Rất dễ sử dụng cho sniffing và spoofing
Cài đặt:
pip install scapyBasic sniffing:
from scapy.all import *
# Sniff 10 packets
packets = sniff(count=10)
# Sniff with filter
packets = sniff(filter="tcp and port 80", count=10)
# Sniff với callback
def packet_callback(pkt):
print(pkt.summary())
sniff(prn=packet_callback, count=10)Process packet:
def process_packet(pkt):
if pkt.haslayer(IP):
ip_src = pkt[IP].src
ip_dst = pkt[IP].dst
print(f"{ip_src} -> {ip_dst}")
if pkt.haslayer(TCP):
sport = pkt[TCP].sport
dport = pkt[TCP].dport
print(f"Port: {sport} -> {dport}")
sniff(prn=process_packet, count=10)Sniff on specific interface:
sniff(iface="eth0", count=10)Get protocol info:
from scapy.all import IP, TCP
# List all fields
ls(IP)
ls(TCP)
# Get default values
IP().show()
TCP().show()PHẦN 3: PACKET SPOOFING
1. PACKET SPOOFING LÀ GÌ?
Định nghĩa:
- Creating packets with FORGED information
- Thường là forged source IP address
- Pretend to be someone else
Mục đích:
- Attack: DDoS, Man-in-the-Middle, Session hijacking
- Testing: Security testing, penetration testing
- Bypass: Firewall rules, access controls
2. TẠI SAO CẦN SPOOFING?
Normal socket KHÔNG cho phép spoof:
- OS tự động điền source IP (từ outgoing interface)
- Không thể thay đổi source IP
- Kernel kiểm soát packet construction
Raw socket CHO PHÉP spoof:
- Application tự construct toàn bộ packet
- Có thể set bất kỳ field nào (including source IP)
- Requires root privileges
3. SENDING WITHOUT SPOOFING (Normal Socket)
UDP example:
int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_port = htons(9090);
dest.sin_addr.s_addr = inet_addr("10.0.2.69");
char *data = "Hello";
sendto(sock, data, strlen(data), 0,
(struct sockaddr*)&dest, sizeof(dest));Kết quả:
- Kernel tự động set source IP = outgoing interface IP
- Source port = random ephemeral port
- KHÔNG THỂ spoof source IP!
4. SPOOFING WITH RAW SOCKETS
A. TẠO RAW SOCKET
Raw socket cho spoofing:
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
// IPPROTO_RAW: tự construct IP header
Quan trọng:
int one = 1;
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one));
// IP_HDRINCL: Báo kernel KHÔNG tự động tạo IP header
// Application sẽ tự construct
B. CONSTRUCT PACKET
Packet structure:
[IP Header] [UDP/TCP/ICMP Header] [Data]1. Construct IP Header:
struct ip ip_header;
memset(&ip_header, 0, sizeof(ip_header));
ip_header.ip_hl = 5; // Header length (5 * 4 = 20 bytes)
ip_header.ip_v = 4; // IPv4
ip_header.ip_tos = 0; // Type of service
ip_header.ip_len = sizeof(struct ip) + sizeof(struct udphdr) + data_len;
ip_header.ip_id = htons(54321); // ID
ip_header.ip_off = 0; // Fragment offset
ip_header.ip_ttl = 64; // Time to live
ip_header.ip_p = IPPROTO_UDP; // Protocol (UDP)
ip_header.ip_sum = 0; // Checksum (0 for now)
ip_header.ip_src.s_addr = inet_addr("1.2.3.4"); // SPOOFED SOURCE!
ip_header.ip_dst.s_addr = inet_addr("10.0.2.69"); // Destination
2. Construct UDP Header:
struct udphdr udp_header;
memset(&udp_header, 0, sizeof(udp_header));
udp_header.uh_sport = htons(12345); // Source port (can spoof!)
udp_header.uh_dport = htons(9090); // Dest port
udp_header.uh_ulen = htons(sizeof(struct udphdr) + data_len);
udp_header.uh_sum = 0; // Checksum (optional for UDP)
3. Assemble packet:
char packet[4096];
memset(packet, 0, 4096);
// Copy IP header
memcpy(packet, &ip_header, sizeof(struct ip));
// Copy UDP header
memcpy(packet + sizeof(struct ip), &udp_header, sizeof(struct udphdr));
// Copy data
char *data = "Spoofed packet!";
memcpy(packet + sizeof(struct ip) + sizeof(struct udphdr), data, strlen(data));4. Calculate checksums:
// IP checksum
ip_header.ip_sum = calculate_checksum((unsigned short*)&ip_header, sizeof(struct ip));
// UDP checksum (optional but recommended)
// Pseudo header + UDP header + data
5. Send packet:
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = ip_header.ip_dst.s_addr;
sendto(sock, packet, ip_header.ip_len, 0,
(struct sockaddr*)&dest, sizeof(dest));C. CHECKSUM CALCULATION
IP Checksum algorithm:
unsigned short calculate_checksum(unsigned short *buf, int len) {
unsigned long sum = 0;
while (len > 1) {
sum += *buf++;
len -= 2;
}
if (len == 1) {
sum += *(unsigned char*)buf;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
return (unsigned short)(~sum);
}Lưu ý:
- IP checksum: BẮT BUỘC (kernel có thể tính tự động nếu = 0)
- UDP checksum: Optional (có thể = 0)
- TCP checksum: BẮT BUỘC
5. SPOOFING ICMP PACKETS
ICMP structure:
struct icmp icmp_header;
icmp_header.icmp_type = 8; // Echo request
icmp_header.icmp_code = 0;
icmp_header.icmp_id = htons(1234);
icmp_header.icmp_seq = htons(1);
icmp_header.icmp_cksum = 0;
icmp_header.icmp_cksum = calculate_checksum((unsigned short*)&icmp_header,
sizeof(struct icmp));6. SPOOFING USING SCAPY
Scapy - Rất đơn giản!
Spoof ICMP:
from scapy.all import *
# Create IP layer with spoofed source
ip = IP(src="1.2.3.4", dst="10.0.2.69")
# Create ICMP layer
icmp = ICMP()
# Combine and send
send(ip/icmp)Spoof UDP:
ip = IP(src="1.2.3.4", dst="10.0.2.69")
udp = UDP(sport=12345, dport=9090)
data = Raw(load="Spoofed packet!")
send(ip/udp/data)Spoof TCP:
ip = IP(src="1.2.3.4", dst="10.0.2.69")
tcp = TCP(sport=12345, dport=80, flags="S") # SYN flag
send(ip/tcp)Ưu điểm của Scapy:
- Tự động tính checksums
- Tự động set default values
- Syntax đơn giản, dễ đọc
- Hỗ trợ nhiều protocols
PHẦN 4: SNIFFING AND THEN SPOOFING
1. KHÁI NIỆM
Mục đích:
- Sniff packets từ network
- Analyze packets
- Spoof response packets based on sniffed data
Use cases:
- Man-in-the-Middle attacks
- Session hijacking
- DNS spoofing
- ARP spoofing
2. IMPLEMENTATION - C/PCAP
Workflow:
void packet_handler(u_char *args, const struct pcap_pkthdr *header,
const u_char *packet) {
// 1. Parse sniffed packet
struct ip *ip_header = (struct ip*)(packet + sizeof(struct ether_header));
if (ip_header->ip_p == IPPROTO_UDP) {
struct udphdr *udp = (struct udphdr*)(packet + sizeof(struct ether_header)
+ ip_header->ip_hl * 4);
// 2. Analyze
printf("Sniffed UDP: %s:%d -> %s:%d\n",
inet_ntoa(ip_header->ip_src), ntohs(udp->uh_sport),
inet_ntoa(ip_header->ip_dst), ntohs(udp->uh_dport));
// 3. Spoof response
send_spoofed_packet(ip_header->ip_dst, ip_header->ip_src,
ntohs(udp->uh_dport), ntohs(udp->uh_sport));
}
}
int main() {
pcap_t *handle = pcap_open_live("eth0", BUFSIZ, 1, 1000, errbuf);
pcap_loop(handle, -1, packet_handler, NULL);
return 0;
}3. IMPLEMENTATION - SCAPY
Rất đơn giản:
Example 1: UDP Echo Response
from scapy.all import *
def spoof_reply(pkt):
if pkt.haslayer(UDP) and pkt[UDP].dport == 9090:
# Extract info from sniffed packet
src_ip = pkt[IP].src
src_port = pkt[UDP].sport
dst_ip = pkt[IP].dst
dst_port = pkt[UDP].dport
print(f"Sniffed: {src_ip}:{src_port} -> {dst_ip}:{dst_port}")
# Create spoofed response (swap src and dst)
ip = IP(src=dst_ip, dst=src_ip)
udp = UDP(sport=dst_port, dport=src_port)
data = Raw(load="Spoofed response!")
# Send spoofed packet
send(ip/udp/data, verbose=0)
print(f"Spoofed reply sent: {dst_ip}:{dst_port} -> {src_ip}:{src_port}")
# Sniff and spoof
sniff(filter="udp and port 9090", prn=spoof_reply)Example 2: ICMP Echo Reply Spoof
def spoof_icmp_reply(pkt):
if pkt.haslayer(ICMP) and pkt[ICMP].type == 8: # Echo request
# Create spoofed reply
ip = IP(src=pkt[IP].dst, dst=pkt[IP].src)
icmp = ICMP(type=0, id=pkt[ICMP].id, seq=pkt[ICMP].seq) # Echo reply
data = pkt[Raw].load if pkt.haslayer(Raw) else ""
send(ip/icmp/data, verbose=0)
print(f"Spoofed ICMP reply: {pkt[IP].dst} -> {pkt[IP].src}")
sniff(filter="icmp", prn=spoof_icmp_reply)4. SO SÁNH: SCAPY VS C
| Đặc điểm | C/Raw Sockets | Scapy |
|---|---|---|
| Độ khó | Khó, nhiều code | Dễ, ít code |
| Checksums | Manual calculation | Automatic |
| Headers | Manual construction | Automatic |
| Performance | Nhanh | Chậm hơn (Python) |
| Flexibility | Full control | High-level abstraction |
| Use case | Production, performance-critical | Testing, prototyping, learning |
Khi nào dùng C:
- Performance critical
- Production environments
- Low-level control cần thiết
Khi nào dùng Scapy:
- Testing, prototyping
- Security research
- Learning
- Quick experiments
PHẦN 5: ENDIANNESS (BYTE ORDER)
1. KHÁI NIỆM
Endianness:
- Thứ tự lưu trữ bytes trong multi-byte data types
- Ảnh hưởng đến integers, addresses, ports…
Hai loại:
A. LITTLE-ENDIAN
- Least Significant Byte (LSB) first
- Byte thấp nhất ở địa chỉ thấp nhất
- VD: Intel x86/x64
Example: 0x12345678
Memory Address: 0x00 0x01 0x02 0x03
Value: 0x78 0x56 0x34 0x12
LSB MSBB. BIG-ENDIAN
- Most Significant Byte (MSB) first
- Byte cao nhất ở địa chỉ thấp nhất
- VD: Network protocols, some ARM
Example: 0x12345678
Memory Address: 0x00 0x01 0x02 0x03
Value: 0x12 0x34 0x56 0x78
MSB LSB2. NETWORK BYTE ORDER
Quy ước:
- Network protocols sử dụng BIG-ENDIAN
- Gọi là Network Byte Order
Lý do:
- Standardization
- Interoperability giữa các systems khác nhau
- Historical reasons
3. HOST VS NETWORK BYTE ORDER
Host Byte Order:
- Byte order của máy local
- Có thể là little-endian hoặc big-endian
- VD: x86 = little-endian
Network Byte Order:
- Luôn luôn BIG-ENDIAN
Vấn đề:
- Nếu host là little-endian
- Gửi trực tiếp → receiver (big-endian network) đọc sai!
Ví dụ:
Port 80 (0x0050):
Little-endian host: 0x50 0x00
Send qua network → Network nhận: 0x5000 (port 20480!) - SAI!
Phải convert: 0x0050 → 0x00 0x50 (network byte order)4. CONVERSION FUNCTIONS
C provides conversion functions:
Host to Network:
uint16_t htons(uint16_t hostshort); // Host to Network Short (16-bit)
uint32_t htonl(uint32_t hostlong); // Host to Network Long (32-bit)
Network to Host:
uint16_t ntohs(uint16_t netshort); // Network to Host Short
uint32_t ntohl(uint32_t netlong); // Network to Host Long
Sử dụng:
// Setting port
struct sockaddr_in addr;
addr.sin_port = htons(80); // Convert port 80 to network byte order
// Setting IP (already in network byte order from inet_addr)
addr.sin_addr.s_addr = inet_addr("192.168.1.1");
// Reading received port
uint16_t received_port = ntohs(tcp_header->th_dport);5. KHI NÀO CẦN CONVERSION?
CẦN convert:
- Port numbers: Luôn luôn!
- IP addresses: Khi assign từ integer
- Packet lengths, IDs: Trong headers
KHÔNG CẦN convert:
- String IP addresses:
inet_addr()tự convert - Data/payload: Đã là bytes
- Single bytes: Chỉ 1 byte không có byte order
Ví dụ ĐÚNG:
// Port - PHẢI convert
udp_header.uh_sport = htons(12345);
// IP from integer - PHẢI convert
ip_header.ip_src.s_addr = htonl(0x01020304);
// IP from string - KHÔNG cần (inet_addr tự convert)
ip_header.ip_src.s_addr = inet_addr("1.2.3.4");
// Data - KHÔNG cần
char *data = "Hello"; // Bytes, no conversion needed
6. SCAPY VÀ ENDIANNESS
Scapy tự động handle:
# Scapy TỰ ĐỘNG convert!
tcp = TCP(sport=80, dport=12345) # No manual conversion needed
ip = IP(src="1.2.3.4") # Scapy handles itReading values:
pkt = sniff(count=1)[0]
src_port = pkt[TCP].sport # Already in host byte orderNGÂN HÀNG CÂU HỎI CHƯƠNG 6
PHẦN 1: SOCKET BASICS
Câu 1: Socket là gì?
A. Hardware component
B. Interface giữa application và network ✓
C. Protocol
D. Network cable
Câu 2: Stream Socket (SOCK_STREAM) sử dụng protocol nào?
A. UDP
B. TCP ✓
C. ICMP
D. IP
Câu 3: Datagram Socket (SOCK_DGRAM) sử dụng protocol nào?
A. TCP
B. UDP ✓
C. ICMP
D. HTTP
Câu 4: Raw Socket (SOCK_RAW) cho phép access ở layer nào?
A. Application
B. Transport
C. Network (IP) ✓
D. Physical
Câu 5: Raw socket requires gì?
A. Password
B. Root/Administrator privileges ✓
C. Special hardware
D. License key
PHẦN 2: PACKET SNIFFING
Câu 6: Packet Sniffing là gì?
A. Sending fake packets
B. Capturing and analyzing network traffic ✓
C. Blocking packets
D. Encrypting packets
Câu 7: Promiscuous Mode làm gì?
A. Chỉ nhận packets cho mình
B. NIC accepts ALL packets ✓
C. Tắt network card
D. Tăng tốc độ network
Câu 8: Promiscuous Mode hoạt động tốt trên loại network nào?
A. Shared medium (hub, wireless) ✓
B. Switched network (switch)
C. Cả hai
D. Không hoạt động
Câu 9: Promiscuous Mode requires gì?
A. Special hardware
B. Root privileges ✓
C. License
D. Không cần gì
Câu 10: Normal socket nhận packets như thế nào?
A. Tất cả packets
B. Chỉ packets gửi đến port đã bind ✓
C. Chỉ broadcast packets
D. Ngẫu nhiên
Câu 11: Normal socket có thấy packet headers không?
A. Thấy tất cả headers
B. Không, chỉ thấy payload ✓
C. Chỉ thấy IP header
D. Chỉ thấy Ethernet header
Câu 12: Raw socket có thể thấy gì? A. Chỉ payload
B. Chỉ headers
C. Toàn bộ packet (headers + payload) ✓
D. Không thấy gì
Câu 13: BPF viết tắt của gì?
A. Best Packet Filter
B. BSD Packet Filter ✓
C. Binary Packet Format
D. Basic Protocol Function
Câu 14: BPF filter packets ở đâu?
A. User space
B. Kernel space ✓
C. Hardware
D. Router
Câu 15: Mục đích chính của BPF?
A. Mã hóa packets
B. Filter packets TRƯỚC KHI copy to user space - giảm overhead ✓
C. Tăng tốc độ network
D. Compress packets
Câu 16: PCAP viết tắt của gì?
A. Protocol Capture API
B. Packet Capture API ✓
C. Port Control Application
D. Private Communication Access
Câu 17: PCAP là gì?
A. Low-level raw socket library
B. High-level library for packet capture ✓
C. Hardware device
D. Protocol
Câu 18: Tool nào sử dụng PCAP?
A. Notepad
B. Wireshark, tcpdump ✓
C. Chrome
D. Excel
Câu 19: Trong pcap_open_live(), parameter thứ 3 (= 1) nghĩa là gì?
A. Capture 1 packet
B. Promiscuous mode ON ✓
C. Timeout 1ms
D. Buffer size 1MB
Câu 20: pcap_loop() làm gì?
A. Gửi packets
B. Capture packets và call callback function cho mỗi packet ✓
C. Lọc packets
D. Đếm packets
Câu 21: Trong pcap_loop(handle, -1, callback, NULL), -1 nghĩa là gì?
A. Error
B. Infinite loop (capture forever) ✓
C. Capture 1 packet
D. No timeout
Câu 22: Packet structure thông thường?
A. [Data | Headers]
B. [Ethernet Header | IP Header | TCP/UDP Header | Data] ✓
C. [IP | Data]
D. [TCP | Data]
Câu 23: Để parse IP header từ packet, cần skip bao nhiêu bytes?
A. 0 bytes
B. sizeof(struct ether_header) bytes ✓
C. 20 bytes
D. 14 + 20 bytes
Câu 24: IP header length được tính như thế nào?
A. ip_header->ip_len
B. ip_header->ip_hl * 4 ✓
C. 20 bytes cố định
D. ip_header->ip_hl
Câu 25: TCP header offset (th_off) * 4 cho biết gì?
A. Data length
B. TCP header length in bytes ✓
C. Packet length
D. Sequence number
Câu 26: Scapy là gì?
A. C library
B. Python library for packet manipulation ✓
C. Java framework
D. Hardware tool
Câu 27: Scapy command để sniff 10 packets?
A. sniff(10)
B. sniff(count=10) ✓
C. capture(10)
D. get_packets(10)
Câu 28: Sniff packets với filter trong Scapy?
A. sniff(10, “tcp”)
B. sniff(filter=“tcp and port 80”, count=10) ✓
C. sniff(“tcp”, 10)
D. filter_sniff(“tcp”, 10)
Câu 29: Sniff với callback function trong Scapy?
A. sniff(callback=func)
B. sniff(prn=func, count=10) ✓
C. sniff(function=func)
D. sniff(process=func)
Câu 30: Check nếu packet có IP layer trong Scapy?
A. pkt.has(IP)
B. pkt.haslayer(IP) ✓
C. pkt.contains(IP)
D. IP in pkt
Câu 31: Lấy source IP từ packet trong Scapy?
A. pkt.IP.src
B. pkt[IP].src ✓
C. pkt.get_IP().src
D. pkt.source_ip
Câu 32: List all fields của IP layer trong Scapy?
A. show(IP)
B. ls(IP) ✓
C. dir(IP)
D. help(IP)
PHẦN 3: PACKET SPOOFING
Câu 33: Packet Spoofing là gì?
A. Capturing packets
B. Creating packets with FORGED information (usually source IP) ✓
C. Encrypting packets
D. Compressing packets
Câu 34: Normal socket có cho phép spoof source IP không?
A. Có
B. KHÔNG - OS tự động điền source IP ✓
C. Tùy thuộc protocol
D. Chỉ với UDP
Câu 35: Loại socket nào cho phép spoofing?
A. Stream socket
B. Datagram socket
C. Raw socket ✓
D. Normal socket
Câu 36: Tạo raw socket cho spoofing (IP level)?
A. socket(AF_INET, SOCK_RAW, 0)
B. socket(AF_INET, SOCK_RAW, IPPROTO_RAW) ✓
C. socket(AF_PACKET, SOCK_RAW, 0)
D. socket(AF_INET, SOCK_DGRAM, 0)
Câu 37: IP_HDRINCL option làm gì?
A. Include more headers
B. Báo kernel KHÔNG tự động tạo IP header - application tự construct ✓
C. Include checksum
D. Include timestamp
Câu 38: Khi spoof packets, application phải construct gì?
A. Chỉ data
B. Chỉ IP header
C. Toàn bộ packet (IP header + TCP/UDP header + data) ✓
D. Chỉ checksum
Câu 39: IP header length field (ip_hl) thường = bao nhiêu?
A. 4
B. 5 (5 * 4 = 20 bytes) ✓
C. 20
D. 10
Câu 40: IP version field (ip_v) cho IPv4?
A. 1
B. 2
C. 4 ✓
D. 6
Câu 41: IP protocol field (ip_p) = IPPROTO_UDP nghĩa là gì?
A. TCP protocol
B. UDP protocol ✓
C. ICMP protocol
D. IP protocol
Câu 42: IP TTL (Time To Live) thường set bao nhiêu?
A. 32
B. 64 ✓
C. 128
D. 255
Câu 43: IP checksum có bắt buộc không?
A. Optional
B. BẮT BUỘC (kernel có thể tự tính nếu = 0) ✓
C. Không cần
D. Tùy protocol
Câu 44: UDP checksum có bắt buộc không?
A. Bắt buộc
B. Optional (có thể = 0) ✓
C. Deprecated
D. Always required
Câu 45: TCP checksum có bắt buộc không?
A. Optional
B. BẮT BUỘC ✓
C. Không cần
D. Tùy version
Câu 46: ICMP Echo Request có type bao nhiêu?
A. 0
B. 8 ✓
C. 3
D. 11
Câu 47: ICMP Echo Reply có type bao nhiêu?
A. 0 ✓
B. 8
C. 3
D. 11
Câu 48: Spoof ICMP packet trong Scapy?
A. send(ICMP())
B. send(IP(src=“1.2.3.4”)/ICMP()) ✓
C. spoof_icmp(“1.2.3.4”)
D. ICMP.spoof()
Câu 49: Spoof UDP packet trong Scapy?
A. send(UDP())
B. send(IP(src=“1.2.3.4”)/UDP(sport=1234)/Raw(load=“data”)) ✓
C. UDP.send_spoofed()
D. spoof(UDP, “1.2.3.4”)
Câu 50: Scapy tự động tính checksums không?
A. Không
B. Có ✓
C. Tùy protocol
D. Chỉ cho IP
Câu 51: TCP SYN flag trong Scapy?
A. TCP(flags=1)
B. TCP(flags=“S”) ✓
C. TCP(syn=True)
D. TCP.SYN
Câu 52: Ưu điểm CHÍNH của Scapy so với C raw sockets?
A. Nhanh hơn
B. Dễ sử dụng, tự động checksums, syntax đơn giản ✓
C. An toàn hơn
D. Không cần root
Câu 53: Khi nào nên dùng C raw sockets thay vì Scapy?
A. Khi learning
B. Khi testing
C. Khi performance critical, production environments ✓
D. Khi prototyping
PHẦN 4: SNIFF AND SPOOF
Câu 54: Sniff and Then Spoof nghĩa là gì?
A. Sniff rồi dừng
B. Sniff packets, analyze, rồi spoof response packets ✓
C. Chỉ sniff
D. Chỉ spoof
Câu 55: Use case của Sniff and Spoof?
A. Normal communication
B. Man-in-the-Middle, Session hijacking, DNS spoofing ✓
C. File transfer
D. Web browsing
Câu 56: Trong sniff and spoof UDP, thường làm gì với src và dst?
A. Giữ nguyên
B. Swap src và dst để tạo response ✓
C. Set cả hai = 0
D. Random
Câu 57: Scapy sniff và spoof trong một command?
A. Không thể
B. sniff(prn=callback_function) - callback tự spoof ✓
C. sniff_and_spoof()
D. Phải dùng 2 commands riêng
Câu 58: ICMP Echo Reply phải có gì giống Echo Request?
A. Không cần giống
B. ID và Sequence number ✓
C. Chỉ ID
D. Chỉ Sequence
PHẦN 5: ENDIANNESS
Câu 59: Endianness là gì?
A. Encryption method
B. Thứ tự lưu trữ bytes trong multi-byte data types ✓
C. Network protocol
D. Compression algorithm
Câu 60: Little-endian lưu byte nào trước?
A. Most Significant Byte (MSB)
B. Least Significant Byte (LSB) ✓
C. Middle byte
D. Random byte
Câu 61: Big-endian lưu byte nào trước?
A. Least Significant Byte
B. Most Significant Byte (MSB) ✓
C. Last byte
D. Random byte
Câu 62: Intel x86/x64 architecture sử dụng endianness nào?
A. Big-endian
B. Little-endian ✓
C. Mixed
D. Không có
Câu 63: Network Byte Order sử dụng endianness nào?
A. Little-endian
B. Big-endian ✓
C. Tùy hệ thống
D. Random
Câu 64: Tại sao cần Network Byte Order?
A. Tăng tốc độ
B. Standardization, interoperability giữa systems khác nhau ✓
C. Bảo mật
D. Nén dữ liệu
Câu 65: htons() làm gì?
A. Host to Network String
B. Host to Network Short (16-bit) ✓
C. HTTP to Network Short
D. Hash to Network Short
Câu 66: htonl() chuyển đổi gì?
A. 8-bit
B. 16-bit
C. 32-bit (Host to Network Long) ✓
D. 64-bit
Câu 67: ntohs() làm gì?
A. Network to Host String
B. Network to Host Short (16-bit) ✓
C. New to Old Host Short
D. None to Host Short
Câu 68: Khi nào CẦN convert byte order?
A. Chỉ cho data
B. Port numbers, IP addresses (from integer), lengths, IDs ✓
C. Chỉ cho passwords
D. Không bao giờ
Câu 69: Khi nào KHÔNG CẦN convert?
A. Port numbers
B. IP from integer
C. String IP addresses (inet_addr tự convert), single bytes, data/payload ✓
D. Packet lengths
Câu 70: Set port 80 đúng cách?
A. addr.sin_port = 80;
B. addr.sin_port = htons(80); ✓
C. addr.sin_port = ntohs(80);
D. addr.sin_port = “80”;
Câu 71: inet_addr() return value đã ở byte order nào?
A. Host byte order
B. Network byte order ✓
C. Little-endian
D. Không convert
Câu 72: Scapy có cần manual byte order conversion không?
A. Luôn cần
B. KHÔNG - Scapy tự động handle ✓
C. Tùy protocol
D. Chỉ cho TCP
Câu 73: 0x12345678 trong little-endian lưu như thế nào?
A. 0x12 0x34 0x56 0x78
B. 0x78 0x56 0x34 0x12 ✓
C. 0x87 0x65 0x43 0x21
D. 0x21 0x43 0x65 0x87
Câu 74: 0x12345678 trong big-endian lưu như thế nào?
A. 0x78 0x56 0x34 0x12
B. 0x12 0x34 0x56 0x78 ✓
C. 0x87 0x65 0x43 0x21
D. 0x21 0x43 0x65 0x87
Câu 75: Port 80 (0x0050) không convert, little-endian host gửi đi sẽ bị hiểu là port nào?
A. 80
B. 5000
C. 20480 (0x5000) ✓
D. 8000
ĐÁP ÁN NHANH
1.B 2.B 3.B 4.C 5.B 6.B 7.B 8.A 9.B 10.B 11.B 12.C 13.B 14.B 15.B 16.B 17.B 18.B 19.B 20.B 21.B 22.B 23.B 24.B 25.B 26.B 27.B 28.B 29.B 30.B 31.B 32.B 33.B 34.B 35.C 36.B 37.B 38.C 39.B 40.C 41.B 42.B 43.B 44.B 45.B 46.B 47.A 48.B 49.B 50.B 51.B 52.B 53.C 54.B 55.B 56.B 57.B 58.B 59.B 60.B 61.B 62.B 63.B 64.B 65.B 66.C 67.B 68.B 69.C 70.B 71.B 72.B 73.B 74.B 75.C
BẢNG TÓM TẮT NHANH - CHƯƠNG 6
1. SOCKETS
- Stream (TCP), Datagram (UDP), Raw (IP)
- Raw socket: Requires root, full packet access
2. PACKET SNIFFING
- Promiscuous Mode: NIC accepts ALL packets (requires root)
- Works on: Shared medium (hub, wireless)
- BPF: Filter in kernel → reduce overhead
- PCAP: High-level API (Wireshark, tcpdump use it)
- Scapy:
sniff(filter="tcp", prn=callback, count=10)
3. PACKET SPOOFING
- Normal socket: CANNOT spoof (OS auto-fills src IP)
- Raw socket: CAN spoof (manual construct entire packet)
- IP_HDRINCL: Tell kernel NOT to auto-create IP header
- Scapy:
send(IP(src="fake")/UDP()/Raw())- tự động checksums!
4. CHECKSUMS
- IP: BẮT BUỘC (kernel auto if = 0)
- UDP: Optional (có thể = 0)
- TCP: BẮT BUỘC
- Scapy: Tự động tính tất cả
5. SNIFF & SPOOF
- Sniff → Analyze → Spoof response
- MITM, Session hijacking, DNS/ARP spoofing
- Scapy:
sniff(prn=spoof_callback)
6. ENDIANNESS
- Little-endian: LSB first (x86/x64)
- Big-endian: MSB first (Network Byte Order)
- htons/htonl: Host → Network
- ntohs/ntohl: Network → Host
- CẦN convert: ports, IP (from int), lengths
- KHÔNG cần: inet_addr(), data, single bytes
- Scapy: Tự động handle!
7. C VS SCAPY
| C Raw Sockets | Scapy |
|---|---|
| Khó, nhiều code | Dễ, ít code |
| Manual checksums | Auto checksums |
| Nhanh | Chậm hơn |
| Production | Testing/Learning |
CHUẨN BỊ THI: Nhớ kỹ Promiscuous Mode, BPF, PCAP workflow, Raw socket vs Normal socket, IP_HDRINCL, checksum requirements, byte order conversion (htons/ntohs), và Scapy syntax!