Описание. Кандидат BSDA должен уметь использовать программы входящие в состав BSD, а так же сторонние программы, для определения того, какие порты в системе открыты, и какие порты видны через брандмауэр.
Практика. netstat(1), services(5)
,
fstat(1); sockstat(1) и
сторонное продукты nmap и
lsof.
Как было показано выше (см. Раздел 6.1.2.3, «Работающие интернет сервисы и открытые сокеты»), команда netstat(1) пригодна для того, чтобы определить открытые tcp/udp соединения и их состояние. Другим средством для определения состояния файлов и сокетов являются команды fstat(1) и sockstat(1). Первая позволяет понять какие файловые дескрипторы какими пользователями открыты, вторая перечисляет открытые сокеты.
Жизнедеятельность всех программ выполняемых в пространстве
пользователя может быть отслежена при помощи обращения к
устройствам /dev/mem
и
/dev/kmem
, предоставляющим информацию
непосредственно из ядра системы. Файловой системы
/proc
в системах BSD
нет. (Если она нужна для совместимости с какими-то программами,
её можно специально смонтировать, при условии, что в ядре
имеется поддержка PROCFS.) Программы
fstat(1) и sockstat(1)
берут информацию из упомянутых устройств.
В некоторых случаях названия протоколов употребляются символьные
(вроде ssh
, imap
), в других случаях явно номера
портов (22
, 143
). Соответствие символьных названий
протоколов и их номеров указано в файле
/etc/services
.
Команда fstat(1) выводит информацию обо всех открытых файловых дескрипторах. С её помощью можно получить информацию обо всех запущенных программах, так как каждая из них имеет по нескольку открытых файловых дескрипторов или сокетов, даже если в данный момент она не выполняет никакой работы. Пример, приведённый ниже, сильно урезан, так как всего в выводе команды fstat(1) было более семисот строк.
$
fstat > fstat-output$
cat fstat-output USER CMD PID FD MOUNT INUM MODE SZ|DV R/W emin fstat 84130 root / 2 drwxr-xr-x 512 r emin fstat 84130 wd /usr 5958657 drwxr-xr-x 2048 r emin fstat 84130 text /usr 447995 -r-xr-sr-x 14716 r emin fstat 84130 0 /dev 68 crw--w---- ttyp0 rw emin fstat 84130 1 /usr 5958902 -rw-r--r-- 0 w emin fstat 84130 2 /dev 68 crw--w---- ttyp0 rw emin fstat 84130 3 /dev 20 crw-r----- mem r emin fstat 84130 4 /dev 21 crw-r----- kmem r emin fstat 84130 5 / 8381 -rw-r--r-- 40960 r ...... root getty 633 root / 2 drwxr-xr-x 512 r root getty 633 wd / 2 drwxr-xr-x 512 r root getty 633 text /usr 565434 -r-xr-xr-x 21016 r root getty 633 0 /dev 39 crw------- ttyv7 rw root getty 633 1 /dev 39 crw------- ttyv7 rw root getty 633 2 /dev 39 crw------- ttyv7 rw ...... root getty 626 root / 2 drwxr-xr-x 512 r root getty 626 wd / 2 drwxr-xr-x 512 r root getty 626 text /usr 565434 -r-xr-xr-x 21016 r root getty 626 0 /dev 32 crw------- ttyv0 rw root getty 626 1 /dev 32 crw------- ttyv0 rw root getty 626 2 /dev 32 crw------- ttyv0 rw ...... root devd 242 root / 2 drwxr-xr-x 512 r root devd 242 wd / 2 drwxr-xr-x 512 r root devd 242 text / 112 -r-xr-xr-x 281208 r root devd 242 0 /dev 8 crw-rw-rw- null rw root devd 242 1 /dev 8 crw-rw-rw- null rw root devd 242 2 /dev 8 crw-rw-rw- null rw root devd 242 3 /dev 5 crw------- devctl r root devd 242 4* local stream c1089000 root adjkerntz 179 root / 2 drwxr-xr-x 512 r root adjkerntz 179 wd / 2 drwxr-xr-x 512 r root adjkerntz 179 text / 117 -r-xr-xr-x 6912 r root adjkerntz 179 0 - - bad - root adjkerntz 179 1 - - bad - root adjkerntz 179 2 - - bad - root init 1 root / 2 drwxr-xr-x 512 r root init 1 wd / 2 drwxr-xr-x 512 r root init 1 text / 47 -r-x------ 485892 r
Прежде всего, конечно, отметилась сама программа
fstat(1). Видно, что от имени
пользователя
а если в pipe, то вывод будет выглядеть так:
Видно, что fstat(1) открыл pipe с
номерами сокетов
Вернёмся к примеру. Второй файловый дескриптор направлен,
как видно, на консоль ttyp0 (Это поток
Дескрипторы 3 и 4 общаются с устройствами
Перед перечнем файловых дескрипторов с номерами, мы видим
три строки (самые первые) с отметками в поле файлового
дескриптора
Зная точку монтирования и номер inod можно найти к чему
относятся приведённые значения
Синтаксис программы find(1) обсуждается в Раздел 7.6, «Поиск файла по заданным атрибутам». Команда lsof(1), обсуждающаяся ниже, печатает в выводе не только номера inod, но и имена файлов, которые она берёт из кеша ядра. | |
Здесь, для примера, приведены записи о 8-ми экземплярах
команды getty(8), которые открыты на
терминалах ttyv0 —ttyv7 и ждут логина пользователя. (Мы
прошли на машину по ssh(1), поэтому ни
один из терминалов неиспользован).
| |
В конце приведены сведения о процессе init(8) — родительском процессе для всех прочих процессов. |
Программа sockstat(1) предоставляет информацию о сокетах, как сетевых, так и сокетах доступных в виде файлов.
$
sockstat
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
emin sshd 84087 3 stream -> ??
emin sshd 84087 4 tcp4 xxx.yyy.zzz.180:22 xyz.yzx.zxy.yxz:56325
root sshd 84084 4 tcp4 xxx.yyy.zzz.180:22 xyz.yzx.zxy.yxz:56325
root sshd 84084 5 stream -> ??
dovecot imap-login 72803 0 tcp4 *:143 *:*
dovecot imap-login 72803 3 stream -> ??
dovecot imap-login 72803 8 stream -> /var/run/dovecot/login/default
dovecot imap-login 63557 0 tcp4 *:143 *:*
dovecot imap-login 63557 3 stream -> ??
dovecot imap-login 63557 8 stream -> /var/run/dovecot/login/default
dovecot imap-login 59983 0 tcp4 *:143 *:*
dovecot imap-login 59983 3 stream -> ??
dovecot imap-login 59983 8 stream -> /var/run/dovecot/login/default
www httpd 58349 3 tcp4 *:80 *:*
www httpd 58348 3 tcp4 *:80 *:*
www httpd 58347 3 tcp4 *:80 *:*
www httpd 46549 3 tcp4 *:80 *:*
www httpd 11184 3 tcp4 *:80 *:*
www httpd 81458 3 tcp4 *:80 *:*
www httpd 32934 3 tcp4 *:80 *:*
root dovecot-au 53422 0 stream -> ??
root dovecot-au 53422 3 stream /var/run/dovecot/login/default
root dovecot-au 53422 7 stream /var/run/dovecot/login/default
root dovecot-au 53422 8 stream /var/run/dovecot/login/default
root dovecot-au 53422 9 stream /var/run/dovecot/login/default
root dovecot 53421 5 tcp4 *:143 *:*
root dovecot 53421 6 dgram -> /var/run/logpriv
root dovecot 53421 9 stream /var/run/dovecot/login/default
root dovecot 53421 10 stream -> ??
root dovecot 53421 11 stream -> ??
root dovecot 53421 13 stream -> ??
root dovecot 53421 14 stream /var/run/dovecot/auth-worker.53422
root dovecot 53421 15 stream -> ??
www httpd 39377 3 tcp4 *:80 *:*
mysql mysqld 636 3 tcp4 *:3306 *:*
mysql mysqld 636 4 stream /tmp/mysql.sock
www httpd 612 3 tcp4 *:80 *:*
www httpd 609 3 tcp4 *:80 *:*
www httpd 606 3 stream /var/run/cgisock.536
root httpd 536 3 tcp4 *:80 *:*
root cron 499 6 dgram -> /var/run/logpriv
smmsp sendmail 484 3 dgram -> /var/run/log
root sendmail 480 3 dgram -> /var/run/logpriv
root sendmail 480 4 tcp4 *:25 *:*
root sendmail 480 5 tcp4 *:587 *:*
root sshd 475 3 tcp4 *:22 *:*
root ntpd 454 3 dgram -> /var/run/logpriv
root ntpd 454 4 udp4 *:123 *:*
root ntpd 454 5 udp4 xxx.yyy.zzz.180:123 *:*
root ntpd 454 6 udp4 172.16.0.1:123 *:*
root ntpd 454 7 udp4 127.0.0.1:123 *:*
daemon rpc.lockd 409 3 udp4 *:901 *:*
daemon rpc.lockd 409 4 tcp4 *:803 *:*
daemon rpc.lockd 409 5 dgram -> /var/run/logpriv
daemon rpc.lockd 409 7 udp4 *:797 *:*
_pflogd pflogd 402 5 stream -> ??
root pflogd 400 4 stream -> ??
root pflogd 400 5 dgram -> /var/run/logpriv
root rpc.lockd 390 3 udp4 *:901 *:*
root rpc.lockd 390 4 tcp4 *:803 *:*
root rpc.lockd 390 5 dgram -> /var/run/logpriv
root rpc.lockd 390 6 udp4 *:720 *:*
root rpc.lockd 390 7 udp4 *:797 *:*
root rpc.statd 385 4 udp4 *:743 *:*
root rpc.statd 385 5 tcp4 *:966 *:*
root rpc.statd 385 6 dgram -> /var/run/logpriv
root nfsd 375 3 tcp4 *:2049 *:*
root mountd 373 4 udp4 *:891 *:*
root mountd 373 5 tcp4 *:925 *:*
root rpcbind 351 5 stream /var/run/rpcbind.sock
root rpcbind 351 6 dgram -> /var/run/logpriv
root rpcbind 351 7 udp4 *:111 *:*
root rpcbind 351 8 udp4 *:796 *:*
root rpcbind 351 9 tcp4 *:111 *:*
bind named 279 3 dgram -> /var/run/logpriv
bind named 279 20 udp4 xxx.yyy.zzz.180:53 *:*
bind named 279 21 tcp4 xxx.yyy.zzz.180:53 *:*
bind named 279 22 udp4 172.16.0.1:53 *:*
bind named 279 23 tcp4 172.16.0.1:53 *:*
bind named 279 24 udp4 127.0.0.1:53 *:*
bind named 279 25 tcp4 127.0.0.1:53 *:*
bind named 279 26 udp4 *:59517 *:*
bind named 279 27 tcp4 127.0.0.1:953 *:*
root syslogd 264 3 dgram /var/run/log
root syslogd 264 4 dgram /var/run/logpriv
root syslogd 264 5 dgram /var/run/log
root syslogd 264 6 dgram /var/named/var/run/log
root syslogd 264 7 udp4 *:514 *:*
root devd 242 4 stream /var/run/devd.pipe
Здесь запись типа xxx.yyy.zzz.180:53
означает, что система слушает интерфейс с адресом IP
xxx.yyy.zzz.180, порт 53 (из файла
/etc/services
узнаём, что это сервер DNS).
Запись типа *:22
означает, что на
22-м порту запущен демон sshd.
Вот некоторые полезные опции данной команды:
-l
-c
-4
, -6
-n
-u
-p 21-23,25,80,110
Аналогичную информацию можно получить при анализе вывода программы netstat(1). См. Раздел 6.1.2, «netstat(1)» и Раздел 6.1.2.3, «Работающие интернет сервисы и открытые сокеты».
Это тоже очень полезная программа, которая умеет рассказывать об открытых сокетах, сетевых соединениях и открытых файлах. Данная программа не входит в состав BSD, а доступна исключительно ввиде стороннего продукта (порта или пакета).
С опцией -i
она может рассказать об открытых
интернет-соединениях:
$
lsof -i -n | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
syslogd 306 root 5u IPv4 0xc18cc708 0t0 UDP *:syslog
ntpd 439 root 4u IPv4 0xc18cc654 0t0 UDP *:ntp
ntpd 439 root 5u IPv4 0xc18cc5a0 0t0 UDP 192.168.0.4:ntp
ntpd 439 root 6u IPv4 0xc18cc4ec 0t0 UDP 192.168.0.6:ntp
ntpd 439 root 7u IPv4 0xc18cc438 0t0 UDP 127.0.0.1:ntp
sshd 470 root 3u IPv4 0xc18fade0 0t0 TCP *:ssh (LISTEN)
sendmail 476 root 4u IPv4 0xc18fac24 0t0 TCP 127.0.0.1:smtp (LISTEN)
mysqld 570 mysql 3u IPv4 0xc18fa8ac 0t0 TCP *:3306 (LISTEN)
mysqld 570 mysql 3u IPv4 0xc18fa8ac 0t0 TCP *:3306 (LISTEN)
Здесь в скобках показано состояние соединения TCP (расшифровку см. выше). Сделав поиск по слову ESTABLISHED мы можем узнать соединения, по которым в данный момент могут передаваться данные:
$
lsof -i -n | grep ESTABLISHED | head
sshd 53540 root 4u IPv4 0xc28ae1bc 0t0 TCP xxx.yyy.zzz.xyz:ssh->xxx.yyy.zzz.zyx:52954 (ESTABLISHED)
sshd 53542 emin 4u IPv4 0xc28ae1bc 0t0 TCP xxx.yyy.zzz.xyz:ssh->xxx.yyy.zzz.zyx:52954 (ESTABLISHED)
httpd 47448 www 66u IPv4 0xc1f296f0 0t0 TCP xxx.yyy.zzz.xyz:http->**************:31825 (ESTABLISHED)
httpd 51286 www 66u IPv4 0xc2407378 0t0 TCP xxx.yyy.zzz.xyz:http->***********:2381 (ESTABLISHED)
httpd 51314 www 66u IPv4 0xc21c3534 0t0 TCP xxx.yyy.zzz.xyz:http->*************:11009 (ESTABLISHED)
httpd 51316 www 66u IPv4 0xc1b6dde0 0t0 TCP xxx.yyy.zzz.xyz:http->************:3664 (ESTABLISHED)
httpd 52426 www 66u IPv4 0xc2407a68 0t0 TCP xxx.yyy.zzz.xyz:http->************:10555 (ESTABLISHED)
httpd 53595 www 66u IPv4 0xc208ec24 0t0 TCP xxx.yyy.zzz.xyz:http->*************:55420 (ESTABLISHED)
httpd 53666 www 66u IPv4 0xc43adde0 0t0 TCP xxx.yyy.zzz.xyz:http->**************:3339 (ESTABLISHED)
httpd 53778 www 66u IPv4 0xc1fa8534 0t0 TCP xxx.yyy.zzz.xyz:http->*************:33735 (ESTABLISHED)
Следующий скрипт отслеживает количество соединений с web-сервером apache, и печатает статистику, по которой можно установить с какого IP пришло слишком много запросов.
#!/bin/sh while : do echo "========== `/bin/date` ==========" /usr/local/bin/lsof -i -n |\ /usr/bin/awk '/^httpd.*ESTABLISHED/{print $9}' |\ /usr/bin/sed 's/.*->\([0-9.]*\):.*/\1/' |\ /usr/bin/sort | /usr/bin/uniq -c | /usr/bin/sort -n -k1,1 /bin/sleep 5 done
Ту же задачу, впрочем, можно решить и при помощи команды netstat(1):
#!/bin/sh while : do echo "========== `/bin/date` ==========" /usr/bin/netstat -n | /usr/bin/awk '/62\.117\.108\.4\.80 .*ESTABLISHED/{print $5}' |\ /usr/bin/sed 's/\.[0-9]*$//' |\ /usr/bin/sort | /usr/bin/uniq -c | /usr/bin/sort -n -k1,1 /bin/sleep 5 done
Без опции -i
программа
lsof(1) выводит информацию об открытых
файлах. Вывод её несколько удобнее, чем у программы
fstat(1), так как включает в себя не только
номера inod'ов, но и имена файлов, которые она берёт из кеша
ядра.
Программа nmap(1) сканирует порты, доступные на системе, иногда позволяет по fingerprint'у определить тип операционной системы на изучаемой системе:
$
nmap scanme.nmap.org
Starting Nmap 4.00 ( http://www.insecure.org/nmap/ ) at 2006-03-24 18:56 MSK
Interesting ports on scanme.nmap.org.48.153.217.205.in-addr.arpa (205.217.153.62):
(The 1660 ports scanned but not shown below are in state: filtered)
PORT STATE SERVICE
22/tcp open ssh
25/tcp closed smtp
53/tcp open domain
70/tcp closed gopher
80/tcp open http
113/tcp closed auth
135/tcp open msrpc
136/tcp open profile
137/tcp open netbios-ns
138/tcp open netbios-dgm
139/tcp open netbios-ssn
445/tcp open microsoft-ds
Nmap finished: 1 IP address (1 host up) scanned in 258.100 seconds
Программа nmap(1) имеет различные опции указывающие каким образом она должна смотреть открыт ли порт. Разумеется программа эта может быть использована как во благо (тестирование своего собственного брандмауэра), так и во вред. Тем более администратор должен знать о её возможностях.
По умолчанию программа занимается тем, что по очереди перебирает
порты и посылает по ним SYN пакеты, а в ответ на SYN/ACK пакет
высылается пакет RST (см. Раздел B.1.4.3, «TCP»).
Возможны и другие способы сканирования, путём отсылки ACK
пакетов, UDP пакетов и др. Всё это подробным образом освещяется
в справочной странице по nmap(1). По
необъяснимой для меня причине столь разрушительная программа в
портах FreeBSD устанавливается так, что
запустить её может кто угодно. На мой взгляд, первое, что должен
выполнить администратор после установки такой программы, это
команду: chmod 500
/usr/local/bin/nmap
. Я конечно понимаю, что
пользователь всё равно может собрать её локально, но зачем же
его к этому подталкивать? Это я понять немогу.
В следующем разделе я расскажу о неменее разрушительной программе hping(8), которая, почему-то не входит в курс BSDA.