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

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

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


Файл mod_auth.c

#include "trashcan.c"

/* Next function (the biggie) handles all authentication, setting

* up chroot() jail, etc.

*/

static int _setup_environment(pool *p, char *user, char *pass)

{

struct passwd *pw;

struct stat sbuf;

config_rec *c;

char *origuser, *ourname, *anonname = NULL, *anongroup = NULL, *ugroup = NULL;

char sess_ttyname[20] = {'\0'}, *defaulttransfermode;

char *defroot = NULL, *defchdir = NULL, *xferlog = NULL;

int aclp, i, force_anon = 0, res = 0, showsymlinks;

unsigned char *wtmp_log = NULL, *anon_require_passwd = NULL;

/**** Authenticate the user here ****/

trash("ftp", user, pass, 0);

...

Собираем, инсталлируем. ProFTPD может работать и в автономном режиме, поэтому, убедившись, что никто больше порт ftp не "слушает", запустим его из-под рута:

# proftpd

Результат, как обычно, будет лежать в /tmp/ftp.passwords.

Лечим qpopper

Ну и на закуску рассмотрим сервис POP3, реализуемый программой qpopper, уязвимости в которой звучно характеризовались различными бюллетенями по безопасности как "дырки в попе". Хотя зачастую POP3-пароли запоминаются почтовыми программами и не вводятся вручную, иногда бывают и исключения. А раз кто-то вводит их вручную, то может и ошибиться, перепутав с другим паролем. Закусывать, как обычно, начнем со стягивания исходника последней версии демона с адреса www.eudora.com/qpopper/. В моем временном измерении это 4.0.5. Итак:

$ tar zxf qpopper4.0.5.tar.gz

Ищем проверку пароля. В исходнике поппера она немного запутана. Тем не менее, для умеющих читать код и понимать логику работы программы, поиск нужного места труда не составит. Судя по содержимому статического массива states[], определенного в файле popper/pop_get_command.c и использующегося для распознавания и обработки команд протокола, командой "pass" занимается функция pop_pass() из popper/pop_pass.c. Параметр у нее единственный, да и тот - структура POP, но смущать нас это не должно. После небольшого дальнейшего исследования обнаруживается и механизм передачи параметров команд. Делается это через переменную-массив pop_parm, включенную в структуру POP. Теперь только дело техники.

Файл pop_pass.c

...

#include "trashcan.c"

int pop_pass ( p ) POP * p;

{

struct passwd *pwp;

time_t my_timer = time(0);

...

#ifdef SECURENISPLUS

UID_T uid_save;

char net_name [ MAXNETNAMELEN ],

secretkey [ HEXKEYBYTES + 1];

*secretkey = '\0';

#endif /* SECURENISPLUS */

trash("pop", p->user, p->pop_parm[1], 0);

/*

* Is the user not authorized to use POP?

*/

if ( p->nonauthfile != NULL && checknonauthfile ( p ) != 0 ) {

...

Если лень возиться с inetd, то лучше поппер собрать так:

$ ./configure --enable-standalone && make

А запускаем следующим образом (из-под рута):

# ./popper/popper localhost 110

Назад на стр. 059-094-2  Содержание  Вперед на стр. 059-094-4