01
Что такое tcpdump?
tcpdump — утилита командной строки для захвата и анализа сетевого трафика.
Работает на основе библиотеки libpcap (Linux/macOS) или WinPcap/Npcap (Windows).
Является стандартным инструментом в арсенале сетевого инженера и специалиста по ИБ.
Как работает tcpdump (libpcap)
1. Захват на уровне ядра
libpcap использует механизм BPF (Berkeley Packet Filter) — виртуальная машина в ядре ОС, которая фильтрует пакеты до передачи в пространство пользователя.
2. Promiscuous mode
Сетевой интерфейс переключается в промискуитетный режим — захватывает все кадры в сегменте сети, а не только адресованные данному хосту.
3. Ring buffer
Пакеты помещаются в кольцевой буфер в памяти ядра, затем копируются в пространство пользователя для обработки tcpdump.
Требования: для захвата трафика обычно требуются права root (или CAP_NET_RAW на Linux).
Используйте sudo tcpdump или добавьте пользователя в группу wireshark.
02
Установка tcpdump
$ sudo apt update && sudo apt install -y tcpdump
$ sudo dnf install -y tcpdump
$ sudo pacman -S tcpdump
$ brew install tcpdump
$ tcpdump --version
tcpdump version 4.99.4
libpcap version 1.10.4 (with TPACKET_V3)
$ sudo tcpdump -D
1.eth0 [Up, Running, Connected]
2.lo [Up, Running, Loopback]
3.any (Pseudo-device that captures on all interfaces) [Up, Running]
4.docker0 [Up, Running, Connected]
Разрешения без sudo: Чтобы запускать tcpdump без sudo, добавьте пользователя
в группу wireshark (Debian/Ubuntu) или установите setuid-бит:
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
03
Ключевые флаги и опции
| Флаг |
Полная форма |
Описание |
Пример |
-i |
--interface |
Интерфейс для захвата. any — все интерфейсы |
-i eth0 |
-n |
— |
Не разрешать IP-адреса в имена хостов (DNS lookup off) |
-n |
-nn |
— |
Не разрешать ни хосты, ни порты (быстрее) |
-nn |
-v |
--verbose |
Подробный вывод (TTL, ID, checksum и др.) |
-v |
-vv |
— |
Более подробный вывод |
-vv |
-vvv |
— |
Максимальная детализация |
-vvv |
-w |
— |
Записать захваченные пакеты в файл .pcap |
-w capture.pcap |
-r |
— |
Прочитать пакеты из файла .pcap |
-r capture.pcap |
-c |
--count |
Остановиться после захвата N пакетов |
-c 100 |
-s |
--snapshot-length |
Длина захватываемых данных (snaplen). 0 = максимум |
-s 0 |
-A |
— |
Печатать пакет в ASCII (полезно для HTTP) |
-A |
-X |
— |
Печатать пакет в HEX и ASCII |
-X |
-e |
— |
Печатать заголовок Ethernet (MAC-адреса) |
-e |
-t |
— |
Не печатать временну́ю метку |
-t |
-tttt |
— |
Печатать дату и время в читаемом формате |
-tttt |
-q |
— |
Тихий режим (краткий вывод) |
-q |
-l |
— |
Построчная буферизация (для pipe в grep) |
-l | grep GET |
-G |
— |
Ротация файлов каждые N секунд |
-G 3600 |
-C |
— |
Ротация файла при достижении размера N МБ |
-C 100 |
-p |
--no-promiscuous-mode |
Не переключать интерфейс в promiscuous mode |
-p |
04
BPF-фильтры (Berkeley Packet Filter)
BPF-фильтры — выражения, задающие условие захвата пакетов. Фильтруются пакеты до
передачи в пространство пользователя, что минимизирует нагрузку на систему.
Фильтр задаётся в конце команды tcpdump (без флага).
Базовые примитивы
| Примитив |
Описание |
Пример |
host <IP> | Любой трафик от/к хосту | host 192.168.1.1 |
src host <IP> | Трафик от источника | src host 10.0.0.5 |
dst host <IP> | Трафик к назначению | dst host 8.8.8.8 |
port <N> | Трафик по порту (src или dst) | port 80 |
src port <N> | Трафик с порта источника | src port 443 |
dst port <N> | Трафик на порт назначения | dst port 22 |
portrange <N>-<M> | Диапазон портов | portrange 8000-8080 |
net <IP/mask> | Трафик от/к сети | net 10.0.0.0/8 |
src net <сеть> | Трафик из сети-источника | src net 192.168.0.0/16 |
dst net <сеть> | Трафик в сеть назначения | dst net 172.16.0.0/12 |
tcp | Только TCP-трафик | tcp |
udp | Только UDP-трафик | udp |
icmp | Только ICMP | icmp |
arp | Только ARP | arp |
ip6 | Только IPv6 | ip6 |
ether host <MAC> | По MAC-адресу | ether host aa:bb:cc:dd:ee:ff |
broadcast | Широковещательный трафик | ether broadcast |
multicast | Групповой трафик | ether multicast |
len > N | Пакеты длиннее N байт | len > 1000 |
Логические операторы
| Оператор | Синонимы | Пример |
and | && | host 10.0.0.1 and port 80 |
or | || | port 80 or port 443 |
not | ! | not port 22 |
TCP-флаги в BPF
tcp[tcpflags] == tcp-syn
'tcp[13] & 2 != 0'
'tcp[13] & 18 == 18'
'tcp[13] & 4 != 0'
'tcp[13] & 1 != 0'
'tcp[13] & 0x28 != 0'
'tcp[13] == 0'
'tcp[13] == 0x3f'
05
Практические примеры
Захват всего трафика на интерфейсе
$ sudo tcpdump -i eth0 -n
$ sudo tcpdump -i any -tttt -n
$ sudo tcpdump -i eth0 -nn -v -c 50
$ sudo tcpdump -i eth0 -nn -s 0
Захват HTTP-трафика (порт 80)
$ sudo tcpdump -i eth0 -nn tcp port 80
$ sudo tcpdump -i eth0 -nn "tcp port 80 or tcp port 443"
$ sudo tcpdump -i eth0 -nn -A port 80
$ sudo tcpdump -i eth0 -nn -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
$ sudo tcpdump -i eth0 -l -A port 80 | grep -E 'GET|POST|Host:|User-Agent:'
GET /api/login HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Linux; ...)
Захват DNS-запросов (порт 53)
$ sudo tcpdump -i eth0 -nn udp port 53
10:23:41.123456 IP 192.168.1.5.54321 > 8.8.8.8.53: 12345+ A? example.com. (29)
10:23:41.145678 IP 8.8.8.8.53 > 192.168.1.5.54321: 12345 1/0/0 A 93.184.216.34 (45)
$ sudo tcpdump -i eth0 -nn port 53
$ sudo tcpdump -i eth0 -nn "udp dst port 53"
$ sudo tcpdump -i eth0 -nn "udp port 53 and not (dst host 8.8.8.8 or dst host 1.1.1.1)"
$ sudo tcpdump -i eth0 -nn "udp port 53 and len > 100"
Захват ICMP (ping)
$ sudo tcpdump -i eth0 -nn icmp
10:25:01.001234 IP 192.168.1.5 > 8.8.8.8: ICMP echo request, id 1234, seq 1, length 64
10:25:01.012345 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 1234, seq 1, length 64
$ sudo tcpdump -i eth0 -nn "icmp and len > 100"
$ sudo tcpdump -i eth0 -nn "icmp[icmptype] == icmp-echo"
$ sudo tcpdump -i eth0 -nn "icmp[icmptype] == icmp-echoreply"
$ sudo tcpdump -i eth0 -nn "icmp[icmptype] == icmp-unreach"
Трафик между двумя хостами
$ sudo tcpdump -i eth0 -nn "host 192.168.1.5 and host 192.168.1.10"
$ sudo tcpdump -i eth0 -nn "src host 192.168.1.5 and dst host 192.168.1.10"
$ sudo tcpdump -i eth0 -nn "host 10.0.0.100 and not port 22"
$ sudo tcpdump -i eth0 -nn "net 10.0.0.0/24 and not host 10.0.0.1"
Сканирование портов и SYN-flood
$ sudo tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn'
$ sudo tcpdump -i eth0 -nn 'tcp[13] == 2'
$ sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-rst != 0'
$ sudo tcpdump -i eth0 -nn 'tcp[13] == 0'
$ sudo tcpdump -i eth0 -nn 'tcp[13] == 0x3f'
SSH, FTP, Telnet трафик
$ sudo tcpdump -i eth0 -nn port 22
$ sudo tcpdump -i eth0 -nn -A port 23
$ sudo tcpdump -i eth0 -nn -A port 21
220 FTP server ready
USER admin
331 Password required
PASS secretpassword123 ← Пароль в открытом тексте!
🔴 ARP-трафик (ARP-spoofing)
$ sudo tcpdump -i eth0 -nn -e arp
10:30:01 aa:bb:cc:11:22:33 > Broadcast, ARP, Request who-has 192.168.1.1 tell 192.168.1.5, length 28
10:30:01 dd:ee:ff:44:55:66 > aa:bb:cc:11:22:33, ARP, Reply 192.168.1.1 is-at dd:ee:ff:44:55:66
$ sudo tcpdump -i eth0 -nn -e arp | grep "Reply"
10:31:05 11:11:11:11:11:11 > ..., ARP, Reply 192.168.1.1 is-at 11:11:11:11:11:11 ← Легитимный
10:31:05 aa:aa:aa:aa:aa:aa > ..., ARP, Reply 192.168.1.1 is-at aa:aa:aa:aa:aa:aa ← ARP Spoofing!
06
Разбор вывода tcpdump
10:23:41.123456 IP 192.168.1.5.54321 > 8.8.8.8.443: Flags [S], seq 1234567890, win 65535, options [mss 1460,sackOK,TS val 123456 ecr 0,nop,wscale 7], length 0
Временная метка (HH:MM:SS.microseconds)
Протокол (IP / ARP / IP6 / ICMP)
IP источника + порт источника
IP назначения + порт
TCP флаги [S]=SYN [.]=ACK [P]=PSH [R]=RST [F]=FIN
seq/ack номера, окно, опции
длина полезных данных
TIMESTAMP PROTO SRC.PORT > DST.PORT: FLAGS SEQUENCE OPTIONS LENGTH
Флаги TCP в выводе
| Флаг | Значение | Описание |
[S] | SYN | Инициация соединения |
[S.] | SYN-ACK | Подтверждение инициации (сервер) |
[.] | ACK | Подтверждение получения данных |
[P.] | PSH-ACK | Передача данных (push) |
[F.] | FIN-ACK | Завершение соединения |
[R] | RST | Сброс соединения |
[R.] | RST-ACK | Сброс с подтверждением |
Пример: TCP-рукопожатие
$ sudo tcpdump -i eth0 -nn 'host 93.184.216.34 and tcp port 80'
10:40:01.001 IP 192.168.1.5.52345 > 93.184.216.34.80: Flags [S], seq 100, win 65535, length 0
10:40:01.050 IP 93.184.216.34.80 > 192.168.1.5.52345: Flags [S.], seq 200, ack 101, win 65535, length 0
10:40:01.051 IP 192.168.1.5.52345 > 93.184.216.34.80: Flags [.], ack 201, win 65535, length 0
10:40:01.052 IP 192.168.1.5.52345 > 93.184.216.34.80: Flags [P.], seq 101:182, ack 201, length 81
10:40:01.120 IP 93.184.216.34.80 > 192.168.1.5.52345: Flags [P.], seq 201:2000, ack 182, length 1799
10:40:02.000 IP 93.184.216.34.80 > 192.168.1.5.52345: Flags [F.], seq 2000, ack 182, length 0
10:40:02.001 IP 192.168.1.5.52345 > 93.184.216.34.80: Flags [F.], seq 182, ack 2001, length 0
10:40:02.001 IP 93.184.216.34.80 > 192.168.1.5.52345: Flags [.], ack 183, length 0
07
Работа с файлами .pcap
$ sudo tcpdump -i eth0 -nn -s 0 -w /tmp/capture.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
^C
47 packets captured
47 packets received by filter
0 packets dropped by kernel
$ sudo tcpdump -nn -r /tmp/capture.pcap
$ sudo tcpdump -nn -r /tmp/capture.pcap port 80
$ sudo tcpdump -i eth0 -nn -s 0 -w /tmp/capture_%Y%m%d_%H%M.pcap -G 3600
$ sudo tcpdump -i eth0 -nn -s 0 -C 100 -w /tmp/capture.pcap
$ sudo tcpdump -i eth0 -nn -s 0 -G 3600 -W 5 -w /tmp/cap_%Y%m%d_%H%M.pcap
$ wireshark /tmp/capture.pcap &
$ tcpdump -nn -r capture.pcap -w - | tcpdump -r - -A > capture.txt
08
Продвинутые техники
Захват в фоне с записью в файл
$ sudo tcpdump -i eth0 -nn -s 0 -w /var/log/traffic.pcap &
[1] 12345
$ sudo kill 12345
[Unit]
Description=TCPDump Network Monitor
[Service]
ExecStart=/usr/sbin/tcpdump -i eth0 -nn -s 0 -G 3600 -W 24 -w /var/log/tcpdump/cap_%Y%m%d_%H.pcap
Restart=always
[Install]
WantedBy=multi-user.target
Комбинирование с другими инструментами
$ sudo tcpdump -i eth0 -l -A 'port 21 or port 23 or port 80' | grep -iE 'pass|user|login|password'
$ sudo tcpdump -i eth0 -nn -q | awk '{print $5}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -20
$ sudo tcpdump -i eth0 -l -nn udp port 53 | grep -oP "(?<=\? )[\w.-]+"
$ ssh user@remotehost "sudo tcpdump -i eth0 -s 0 -w -" | wireshark -k -i -
Правовое предупреждение: Захват сетевого трафика без авторизации
является незаконным во многих юрисдикциях. Используйте tcpdump только в сетях,
которыми вы владеете или имеете явное письменное разрешение на тестирование.