Trong một số trường hợp, chúng ta cần cấu hình Wireshark để chỉ bắt một phần dữ liệu mà nó nhìn thấy khi đi qua interface:
- Khi có lượng dữ liệu lớn đang chạy qua interface và ta chỉ muốn bắt các dữ liệu cần thiết.
- Khi muốn bắt dữ liệu chỉ đi vào và ra khỏi một server cụ thể trên một VLAN.
- Khi muốn bắt dữ liệu chỉ từ một ứng dụng hoặc các ứng dụng cụ thể (ví dụ nghi ngờ có vấn đề DNS trong mạng và chỉ muốn phân tích các truy vấn và phản hồi DNS tới và từ internet).
Các bạn xem thêm [Master Wireshark] Phần 1: Nên đặt Wireshark ở đâu trong mạng?.
Cấu hình Capture Filter
Để cấu hình bộ lọc bắt gói tin, nhấp vào nút Capture options, nằm ở vị trí thứ tư từ bên trái như hình bên dưới:
Cửa sổ Wireshark – Capture Interfaces xuất hiện. Chúng ta nhập filter vào ô khoanh đỏ.
Bộ lọc bắt gói tin được tạo thành từ một chuỗi biểu thức lọc. Biểu thức này chọn các gói tin sẽ được bắt cũng như các gói tin sẽ bị bỏ qua. Biểu thức lọc bao gồm một hoặc nhiều yếu tố cơ bản. Yếu tố cơ bản thường bao gồm một định danh (tên hoặc số) kèm theo một hoặc nhiều qualifiers. Có ba loại qualifiers khác nhau:
- Loại (type): Các qualifier này xác định loại dữ liệu mà định danh (tên hoặc số) liên quan đến. Các loại có thể là host cho tên máy chủ hoặc địa chỉ, net cho mạng, port cho port TCP/UDP, ….
- Hướng (dir): Xác định hướng truyền dẫn cụ thể. Ví dụ, src chỉ ra nguồn, dst chỉ ra đích, ….
- Giao thức (proto): Đây là các qualifier giới hạn kết quả lọc cho một giao thức cụ thể. Ví dụ, ether cho Ethernet, ip cho giao thức internet, arp cho giao thức phân giải địa chỉ MAC, …
Các định danh là những điều kiện thực sự, có thể là địa chỉ IP như 10.0.0.1, số port 53 hoặc địa chỉ mạng 192.168.1 (đây là một định danh cho mạng 192.168.1.0/24). Ví dụ, trong bộ lọc tcp dstport 135
, chúng ta có:
dst
là dir qualifierport
là type qualifiertcp
là proto qualifier
Cấu hình Ethernet Filter
Các bộ lọc cơ bản ở tầng 2 (Layer 2) bao gồm:
ether host <Ethernet host>
: Để lấy địa chỉ Ethernet của một máy (Ethernet host)ether dst <Ethernet host>
: Để lấy địa chỉ đích Ethernet của gói tin (Ethernet destination address)ether src <Ethernet host>
: Để lấy địa chỉ nguồn Ethernet của gói tin (Ethernet source address)ether broadcast
: Để bắt các gói tin phát sóng (broadcast) trên Ethernetether multicast
: Để bắt các gói tin đa đích (multicast) trên Ethernetether proto <protocol>
: Để lọc chỉ các gói tin thuộc một giao thức cụ thể được chỉ định trong trường giao thức (protocol identifier)vlan <vlan_id>
: Để chỉ cho qua các gói tin từ một VLAN cụ thể được chỉ định trong trường định danh (identifier field)
Để phủ định một quy tắc bộ lọc, chỉ cần gõ từ “not” hoặc “!” phía trước. Ví dụ: Not ether host <Ethernet host>
hoặc ! ether host <Ethernet host>
sẽ bắt các gói tin không phải từ/đến địa chỉ Ethernet được chỉ định trong trường định danh (identifier field).
Ở hình bên dưới, ta có một server, các PC và một router, kết nối với một switch LAN. Wireshark đang chạy trên latop được kết nối với switch LAN, với cổng mirror toàn bộ switch (đến VLAN1). Ký hiệu /24 trong sơ đồ đề cập đến mặt nạ con (subnet mask) có 24 bit, tức là 11111111.11111111.11111111.00000000 trong hệ nhị phân hoặc 255.255.255.0 trong hệ thập phân.
Cách hoạt động của bộ lọc bắt gói tin với địa chỉ nguồn và đích rất đơn giản – công cụ bắt gói tin chỉ cần so sánh điều kiện với các địa chỉ MAC thực tế. Một địa chỉ phát sóng (broadcast address) là một địa chỉ trong đó địa chỉ đích là toàn bộ 1s, tức là ff:ff:ff:ff:ff:ff:ff. Do đó, khi cấu hình một bộ lọc phát sóng, chỉ có các địa chỉ này sẽ qua bộ lọc. Địa chỉ phát sóng có thể là:
- Địa chỉ phát sóng Layer 3 IPv4 được chuyển đổi thành phát sóng Layer 2; ví dụ, gói tin IP tới 10.0.0.255 sẽ được chuyển đổi thành phát sóng Layer 2 trong trường địa chỉ MAC đích.
- Một phát sóng liên quan đến mạng; ví dụ, Giao thức Giải địa chỉ IPv4 (ARP) gửi một phát sóng như một phần của hoạt động mạng.
- Trong IPv4, một địa chỉ MAC đa đích (multicast) được truyền khi địa chỉ MAC bắt đầu bằng chuỗi 01:00:5e. Mọi gói tin có địa chỉ MAC bắt đầu bằng chuỗi này sẽ được coi là đa đích.
- Trong IPv6, một địa chỉ đa đích (multicast) được truyền khi địa chỉ MAC bắt đầu bằng chuỗi 33:33. Mọi gói tin có địa chỉ MAC bắt đầu bằng chuỗi này sẽ được coi là đa đích.
Ngoài ra, để cấu hình bộ lọc cho một VLAN cụ thể, sử dụng vlan <vlan_id>
. Để cấu hình bộ lọc trên nhiều VLAN, sử dụng vlan <vlan_id> and vlan <vlan_id> and vlan ...
Cấu hình hosts và network filters
ip
hoặcip6
: Để bắt các gói tin IP hoặc IPv6.host <host>
: Để lấy hostname hoặc IP.dst host <host>
: Để lấy hostname hoặc IP đích.src host <host>
: Để lấy hostname hoặc IP nguồn.net <net>
: Tất cả các gói tin tới hoặc từ mạng IPv4/IPv6 đã được chỉ định.dst net <net>
: Tất cả các gói tin tới mạng đích IPv4/IPv6 đã được chỉ định.src net <net>
: Tất cả các gói tin từ mạng nguồn IPv4/IPv6 đã được chỉ định.net <net> mask <subnet mask>
: Tất cả các gói tin tới/ từ mạng cụ thể. Cú pháp này không hợp lệ đối với mạng IPv6.dst net <net> mask <subnet mask>
: Tất cả các gói tin tới/ từ mạng cụ thể. Cú pháp này không hợp lệ đối với mạng IPv6.src net <net> mask <subnet mask>
: Tất cả các gói tin từ/ tới mạng cụ thể. Cú pháp này không hợp lệ đối với mạng IPv6.net <net>/<độ dài>
: Tất cả các gói tin tới/ từ mạng net với độ dài len theo bit.dst net <net>/<độ dài>
: Tất cả các gói tin tới/ từ mạng net với độ dài len theo bit.broadcast
: Tất cả các gói tin phát sóng (broadcast).multicast
: Tất cả các gói tin đa đích (multicast).ip proto <protocol code>
: Bắt gói tin khi trường giao thức IP bằng với mã xác định giao thức (protocol code). Có thể có các giao thức khác nhau như TCP (code 6), UDP (code 17), ICMP (code 1), và nhiều giao thức khác.
Hostname có thể là một IP hoặc domain liên quan đến IP này. Ví dụ host www.packtpub.com
sẽ hiển thị tất cả các gói tin tới/ từ địa chỉ IP liên quan đến trang www.packtpub.com.
Một số filter thông dụng khác:
ip multicast
: Gói tin IP multicastip broadcast
: Gói tin IP broadcastip[2:2] =<number>
: Kích thước gói tin IP (byte 3 và 4 của IP header)ip[8] ==<number>
: Giá trị TTL (byte 9 của IP header)ip[12:4] = ip[16:4]
: Địa chỉ IP nguồn bằng địa chỉ IP đích (byte 13-16 bằng byte 17-20)ip[2:2]== <number>
: Độ dài tổng của gói tin IP (byte 3 và 4 bằng number)ip[9] ==<number>
: Định danh giao thức (byte 10 bằng number)
Những filter này được giải thích thêm trong phần Configuring byte offset and payload matching filters ở sau. Nguyên tắc như hình bên dưới, là số đầu tiên trong dấu ngoặc vuông xác định có bao nhiêu byte từ đầu của header giao thức và số thứ hai chỉ ra số byte theo sau:
Cấu hình TCP/UDP và port filters
Các bộ lọc cơ bản ở tầng 4 (Layer 4) bao gồm:
port <port>
: Khi gói tin là giao thức tầng 4 như TCP hoặc UDP, bộ lọc này sẽ bắt các gói tin tới/ từ cổng được chỉ định trong trường nhận dạngdst port <port>
: Khi gói tin là giao thức tầng 4 như TCP hoặc UDP, bộ lọc này sẽ bắt các gói tin tới cổng đích được chỉ định trong trường nhận dạngsrc port <port>
: Khi gói tin là giao thức tầng 4 như TCP hoặc UDP, bộ lọc này sẽ bắt các gói tin từ cổng nguồn được chỉ định trong trường nhận dạng
Các bộ lọc port range bao gồm:
tcp portrange <p1>-<p2> hoặc udp portrange <p1>-<p2>
: Lọc các gói tin TCP hoặc UDP trong khoảng port từ p1 đến p2.tcp src portrange <p1>-<p2>
hoặcudp src portrange <p1>-<p2>
: Lọc các gói tin TCP hoặc UDP có port nguồn trong khoảng từ p1 đến p2.tcp dst portrange <p1>-<p2>
hoặcudp dst portrange <p1>-<p2>
: Lọc các gói tin TCP hoặc UDP có port đích trong khoảng từ p1 đến p2.
Ngoài ra, các cờ TCP sau đây cũng có thể được sử dụng:
tcp-urg
: Lọc các gói tin TCP với cờ ưu tiên (TCP urgent pointer flag).tcp-rst
: Lọc các gói tin TCP với cờ reset (TCP reset pointer flag).tcp-ack
: Lọc các gói tin TCP với cờ xác nhận (TCP acknowledgment pointer flag).tcp-syn
: Lọc các gói tin TCP với cờ đồng bộ (TCP sync pointer flag).tcp-psh
: Lọc các gói tin TCP với cờ đẩy (TCP push pointer flag).tcp-fin
: Lọc các gói tin TCP với cờ kết thúc (TCP finish pointer flag).
Các giao thức tầng 4, chủ yếu là TCP và UDP, là các giao thức kết nối giữa các ứng dụng cuối. Định danh của các tiến trình gửi yêu cầu và tiến trình nhận yêu cầu được gọi là số port (port numbers).
Các cờ TCP được gửi trong các gói tin nhằm thiết lập, duy trì và đóng kết nối. Một tín hiệu được đặt khi một bit cụ thể trong gói tin được đặt thành 1. Các cờ phổ biến nhất được sử dụng bao gồm:
- syn: Tín hiệu để mở kết nối.
- fin: Tín hiệu để đóng kết nối.
- ack: Tín hiệu để xác nhận dữ liệu đã nhận.
- rst: Tín hiệu để đóng kết nối ngay lập tức.
- psh: Tín hiệu để đẩy dữ liệu cho việc xử lý bởi quy trình cuối (ứng dụng).
Một số ví dụ như sau:
- Để bắt gói tin đến port 80 (HTTP), cấu hình
dst port 80
hoặcdst port http
. - Để bắt gói tin đến hoặc từ port 5060 (SIP), cấu hình
port 5060
. - Để bắt tất cả các gói tin TCP khởi đầu một kết nối (tất cả gói tin có
syn=1
), cấu hìnhtcp-syn != 0
. - Để bắt gói tin khởi đầu (cờ syn) và kết thúc (cờ fin) của tất cả các kết nối TCP, cấu hình
tcp[tcpflags] & (tcp-syn|tcp-fin) != 0
. Lưu ý rằng trongtcp[tcpflags] & (tcp-syn|tcp-fin) != 0
, đây là phép AND bit, không phải phép AND logic. Ví dụ: 010 hoặc 101 bằng 111, không phải 000. - Để bắt tất cả các gói tin TCP có cờ rst (reset) được đặt thành 1, cấu hình
tcp[tcpflags] & (tcp-rst) != 0
.
Các bộ lọc về độ dài được cấu hình như sau:
less <length>
: Chỉ bắt các gói tin có độ dài nhỏ hơn hoặc bằng giá trị length. Tương đương vớilen <= <length>
.greater <length>
: Chỉ bắt các gói tin có độ dài lớn hơn hoặc bằng giá trị length. Tương đương vớilen >= <length>
.
Khi sử dụng bộ lọc bắt gói tin, ta có thể lọc các gói tin dựa trên các ứng dụng cụ thể và cũng có thể lọc các gói tin có các cờ cụ thể.
Trong trường hợp tcp[tcpflags] & (tcp-syn|tcp-fin) != 0
, các toán tử bitwise &
và |
được sử dụng thay vì toán tử logic thông thường &&
. Sự khác biệt là &
và |
là các toán tử bitwise, có nghĩa là chúng thực hiện phép toán trên từng bit một thay vì trên toàn bộ field.
Lưu ý rằng khi sử dụng bộ lọc như tcp[tcpflags] & (tcprst) == 1
, ta có thể không nhận được kết quả. Điều này là do bộ lọc đang thực hiện phép toán AND boolean giữa trường tcpflags
và giá trị 11111111 (đại diện cho tất cả các cờ được bật), và sau đó kiểm tra xem kết quả có bằng 1 hay không. Tuy nhiên, gói tin TCP với cờ rst
được đặt thành 1 sẽ có biểu diễn nhị phân là 00000010. Vì vậy, khi ta thực hiện phép toán AND bitwise giữa 00000010 và 11111111, kết quả là 00000010, không bằng 1. Tuy nhiên, khi chúng ta viết tcp[tcpflags] & (tcp-rst) != 0
, chúng ta thực hiện phép AND bit giữa 00000010 và 11111111, kết quả lại là 00000010, không bằng 0 như đã cấu hình.
Do đó, quan trọng là hiểu tính chất bitwise của các toán tử này khi sử dụng bộ lọc bắt gói tin để đảm bảo việc lọc chính xác các gói tin dựa trên các điều kiện cờ cụ thể.
Một số tình huống gặp vấn đề (chủ yếu là trong các cuộc tấn công) bao gồm:
tcp[13] & 0x00 = 0
: Không có cờ nào được thiết lập (null scan).tcp[13] & 0x01 = 1
: Cờ fin được thiết lập và cờ ack không được thiết lập.tcp[13] & 0x03 = 3
: Cờ syn được thiết lập và cờ fin được thiết lập.tcp[13] & 0x05 = 5
: Cờ rst được thiết lập và cờ fin được thiết lập.tcp[13] & 0x06 = 6
: Cờ syn được thiết lập và cờ rst được thiết lập.tcp[13] & 0x08 = 8
: Cờ psh được thiết lập và cờ ack không được thiết lập.
Các tình huống này thường liên quan đến các hành vi tấn công và gây rối trong quá trình truyền thông TCP.
Trong sơ đồ dưới đây, ta có thể thấy cách nó hoạt động. tcp[13] là số byte tính từ đầu của header, khi các giá trị 0, 1, 3, 5, 6 và 8 liên quan đến vị trí các cờ.
Cấu hình lọc byte offset và payload filter
Nếu ta hiểu rõ các giao thức về cách hoạt động cũng như cấu trúc gói tin của chúng thì ta có thể cấu hình bộ lọc để theo dõi một chuỗi cụ thể trong các gói tin đã bắt được và lọc các gói tin dựa trên chuỗi đó.
Bộ lọc khớp chuỗi (string matching filter) kiểm tra một chuỗi cụ thể trong header của gói tin. Chúng ta có thể cấu hình chúng theo hai cách sau:
- Sử dụng cú pháp
proto [Offset:bytes]
, trong đóoffset
là số byte tính từ đầu tiên của header. Ví dụ,ip[8:1]
sẽ kiểm tra byte số 9 trong tiêu đề IP, vàtcp[8:2]
sẽ kiểm tra các byte từ 9 đến 10 trong tiêu đề TCP. - Sử dụng cú pháp
proto [byte]
, trong đóbyte
chỉ ra số byte cần kiểm tra tính từ đầu tiên của header. Ví dụ,ip[8]
cũng sẽ kiểm tra byte số 9 trong IP header.
Với bộ lọc này, chúng ta có thể tạo ra các bộ lọc khớp chuỗi cho các giao thức IP, TCP và UDP.
proto[x:y] & z = 0
: Khớp với các bit được đặt thành 0 khi áp dụng maskz
choproto[x:y]
.proto[x:y] & z != 0
: Một số bit được đặt thành 1 khi áp dụng maskz
choproto[x:y]
.proto[x:y] & z = z
: Tất cả các bit được đặt thànhz
khi áp dụng maskz
choproto[x:y]
.proto[x:y] = z
:proto[x:y]
có các bit được đặt chính xác thànhz
.
Để lọc các TCP destination port trong khoảng từ 50 đến 100, cấu hình filter như sau: (tcp[2:2] > 50 and tcp[2:2] < 100)
. Ở đây, chúng ta tính từ đầu tiên của TCP header và kiểm tra hai byte tiếp theo có giá trị nhỏ hơn 100 và lớn hơn 50.
Như kết quả bên dưới, destination port đều là 443 vì ta filter (tcp[2:2] > 440 and tcp[2:2] < 445)
.
Để kiểm tra kích thước TCP window nhỏ hơn 8192, cấu hình bộ lọc sau: tcp[14:2] < 8192
. Ở đây, chúng ta tính từ đầu tiên của tiêu đề TCP và kiểm tra hai byte tiếp theo (kích thước cửa sổ) có giá trị nhỏ hơn 8192.
- Để chỉ lấy các gói tin HTTP GET, cấu hình như sau:
tcp[((tcp[12:1] & 0xf0) >> 2):3] = 0x474554
. Ở đây,tcp[12:1] & 0xf0) >> 2
cho ra độ dài TCP header. Ngay sau đó, chúng ta kiểm tra chuỗi G, E, T (tức là lệnh HTTP GET) có giá trị hex tương ứng là 47, 45, 54 trong phần dữ liệu gói tin ngay sau TCP header. - Để lấy ra tất cả các gói tin IPv4 HTTP port 80 (tức là chỉ in ra các gói tin chứa dữ liệu, không in các gói tin chỉ gửi syn, fin hoặc ack), ta dùng filter:
tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)
. - Để in ra các gói tin khởi đầu và kết thúc (gói tin syn và fin) của mỗi TCP conversation liên quan đến một máy chủ không nằm trong mạng nội bộ:
tcp[tcpflags] & (tcpsyn|tcp-fin) != 0 and not src and dst net localnet
. - Để in ra các gói tin broadcast hoặc multicast IP không được gửi qua broadcast hoặc multicast Ethernet:
ether[0] & 1 = 0 and ip[16] >= 224
. - Để in ra tất cả các gói tin ICMP không phải là echo request/response (tức là không phải là các gói tin ping):
icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.