Продолжая
разговор о применении DTrace для исследования безопасности системы, поговорим о перехвате паролей* и просто строковых данных приложений, проследим за тем, что делает тот или иной пользователь, и за тем, какие файлы и кто создает в любимой хакерами директории /tmp.
Все знают, что с помощью сниффера можно перехватывать пароли, передаваемые открытым текстом - это телнет, почта и т.д. Посмотрим, что мы можем получить, используя вот такую небольшую программку Dtrace - testsnoop.d:
#!/usr/sbin/dtrace -s
/* Save syscall entry info */
syscall:::entry
/execname == $$1/
{
/* set start details */
self->start = timestamp;
self->arg0 = arg0;
self->arg1 = arg1;
self->arg2 = arg2;
}
/* Print data */
syscall::write:return,
syscall::pwrite:return,
syscall::*read*:return
/self->start/
{
printf("%s(0x%X, \"%S\", 0x%X)\t\t = %d\n",probefunc,self->arg0,
stringof(copyin(self->arg1,self->arg2)),self->arg2,(int)arg0);
self->arg0 = arg0;
self->arg1 = arg1;
self->arg2 = arg2;
}
Запустим ее, к примеру с параметром in.ftpd:
# dtrace -s testsnoop.d in.ftpd
Попробуем теперь зайти с другой консоли на сервер по ftp. Смотрим на вывод нашего скрипта. Оп-па,
а вот и пароль:
...
17 15 write:return write(0x6, "pupkin\0", 0x174) = 372
17 15 write:return write(0x1, "230 User pupkin logged in.\r\n\0", 0x1C) = 28
17 13 read:return read(0x0, "SYST\r\uperpupkin\r\n\0", 0x2000) = 6
17 15 write:return write(0x1, "215 UNIX Type: L8 Version: SUNOS\r\n\0", 0x22) = 34
^C
Правда, в данном случае, у пароля недостает первой буквы s (пароль - superpupkin). Теперь попробуем
с командой su:
# dtrace -s testsnoop.d su
В другом окне набираем su, затем пароль root, предположим для примера, root2007 (надеюсь у вас не такие простые пароли) и наблюдаем за выводом dtrace:
...
14 1599 write:return write(0x2, "Password: 12782::::::\nsimon:o3QK...
pupkin:0vKlw.P65sCNg:12822::::::\nivanov:37a12Xw6IiWgU:12856::::...
lena:Mm.rI4zqLGwyQ:12940::::::\npetya:meRzfd.yg/K4.:13010::::::\nrod...
doris:mPgprlAdOTDPs:13405", 0xA) = 10
1 1597 read:return read(0x4, "r\0", 0x1) = 1
1 1597 read:return read(0x4, "o\0", 0x1) = 1
1 1597 read:return read(0x4, "o\0", 0x1) = 1
1 1597 read:return read(0x4, "t\0", 0x1) = 1
1 1597 read:return read(0x4, "2\0", 0x1) = 1
1 1597 read:return read(0x4, "0\0", 0x1) = 1
1 1597 read:return read(0x4, "0\0", 0x1) = 1
1 1597 read:return read(0x4, "7\0", 0x1) = 1
1 1597 read:return read(0x4, "\n\0", 0x1) = 1
1 1599 write:return write(0x2, "\n\0", 0x1) = 1
^C
Вот и пароль root!
А как с перехватом паролей ssh, слабо? Brendan Gregg дает нам эту возможность с помощью скрипта
sshkeysnoop.d. Запустите в одном окне
скрипт, а в другом - соединение ssh c этой же машины на любой хост. Вывод dtrace:
# ./sshkeysnoop.d
UID PID PPID TYPE TEXT
100 9651 8600 cmd ssh -l pupkin myhost
100 9651 8600 key s
100 9651 8600 key u
100 9651 8600 key p
100 9651 8600 key e
100 9651 8600 key r
100 9651 8600 key p
100 9651 8600 key u
100 9651 8600 key p
100 9651 8600 key k
100 9651 8600 key i
100 9651 8600 key n
100 9651 8600 key
100 9651 8600 key -
...
Вот вам и ssh. Впрочем, надо заметить, это не какая-то дырка в ssh, скорее это преимущества пользователя root - пароли исходящих ssh-соединений можно получить и при помощи truss:
# ps -ef | grep ssh
root 23787 24089 0 10:34:17 ? 0:00 /usr/lib/ssh/sshd
pupkin 24567 21007 0 10:45:22 pts/3 0:00 ssh -l pupkin myhost
root 19678 1 0 10:34:16 ? 0:00 /usr/lib/ssh/sshd
root 23734 22115 0 10:12:38 pts/2 0:00 grep ssh
# truss -p 24567
read(4, 0x08046D6C, 1) (sleeping...)
read(4, " s", 1) = 1
read(4, " u", 1) = 1
read(4, " p", 1) = 1
read(4, " e", 1) = 1
read(4, " r", 1) = 1
read(4, " p", 1) = 1
read(4, " u", 1) = 1
...
read(4, "\n", 1) = 1
write(4, "\n", 1) = 1
ioctl(4, TCSETSF, 0x08046CF8) = 0
А как узнать, какие команды и какой вывод от них получает пользователь pupkin? Заходим на сервер в одной консоли:
myhost:~$ ssh server
Password:
Last login: Thu May 31 10:09:41 2007 from 192.168.1.16
Welcome to SunServer!
pupkin@server:~$ echo $$
4148
pupkin@server:~$ who am i
а в другой получаем вывод от скрипта shellsnoop, запущенного с параметром 4148 (скрипт входит в состав DTtraceToolkit):
# ./shellsnoop -p 4148
PID PPID CMD DIR TEXT
4148 4146 bash R w
4148 4146 bash W w
4148 4146 bash R h
4148 4146 bash W h
4148 4146 bash R o
4148 4146 bash W o
4148 4146 bash R
4148 4146 bash W
4148 4146 bash R a
4148 4146 bash W a
4148 4146 bash R m
4148 4146 bash W m
4148 4146 bash R
4148 4146 bash W
4148 4146 bash R i
4148 4146 bash W i
4148 4146 bash R
4148 4146 bash W
4148 4146 bash W
4148 4146 bash W pupkin@server:~$
5200 4148 who W pupkin pts/3 May 31 10:10 (192.168.1.16)
Так при помощи DTrace можно отследить всю деятельность любого пользователя в системе.
Предположим, мы хотим отслеживать, кто и какие файлы создает в директории /tmp (скрипт tmpsnoop.d):
#!/usr/sbin/dtrace -qs
dtrace:::BEGIN
{
printf("\tPID\tCMD\tFILE\n");
}
syscall::open:entry, syscall::open64:entry,syscall::creat:entry,
syscall::creat64:entry
{
self->traceme = 1;
self->path = copyinstr(arg0);
}
syscall::open:return, syscall::open64:return,syscall::creat:return,
syscall::creat64:return
{
self->traceme = 0;
self->path = "";
}
fbt:tmpfs:tmp_create:entry
/self->traceme == 1 && self->path != ""/
{
printf("\t%d\t%s\t%s\n", curpsinfo->pr_uid, execname, self->path);
}
Запускаем скрипт и в другой консоли создаем файл backdoor в /tmp:
# dtrace -s tmpsnoop.d
dtrace: script 'test.d' matched 10 probes
CPU ID FUNCTION:NAME
6 1 :BEGIN PID CMD FILE
20 22303 tmp_create:entry 100 touch /tmp/backdoor
0 22303 tmp_create:entry 0 cron /tmp/croutDDAxabyFa
^C
Как видите, DTrace может значительно облегчить жизнь администратора системы в которой необходимо
отслеживать работу разных пользователей.
* Примечание:
Данная статья рассматривает перехват паролей лишь с точки зрения проверки операционной системы на безопасность.