
Мониторинг процессов Linux без прав root
pspy — это инструмент командной строки, предназначенный для слежки за процессами без необходимости прав root. Он позволяет видеть команды, запускаемые другими пользователями, cron-задания и т.п. по мере их выполнения. Отлично подходит для перечисления систем Linux в CTF. Также отлично демонстрирует коллегам, почему передавать секреты в качестве аргументов командной строки — плохая идея.
Инструмент собирает информацию из сканирования procfs. Наблюдатели inotify, размещённые на выбранных частях файловой системы, запускают эти сканирования, чтобы ловить короткоживущие процессы.
Загрузите инструмент на машину Linux, которую хотите проверить. Сначала получите бинарные файлы. Скачайте опубликованные бинарники здесь:
pspy32 скачатьpspy64 скачатьpspy32s скачатьpspy64s скачатьСтатически скомпилированные файлы должны работать в любой системе Linux, но они довольно большие (~4 МБ). Если размер имеет значение, попробуйте маленькие версии, которые зависят от libc и сжаты с помощью UPX (~1 МБ).
Либо используйте Go, установленный в вашей системе, либо запустите процесс сборки на основе Docker, который использовался для создания релиза.
Для последнего убедитесь, что Docker установлен, затем выполните make build-build-image для сборки Docker-образа, после чего make build для сборки бинарников с его помощью.
Вы можете запустить pspy --help, чтобы узнать о флагах и их значении.
Краткое описание выглядит так:
Настройки по умолчанию подходят для большинства применений.
Наблюдение за файлами внутри /usr наиболее важно, так как многие инструменты обращаются к библиотекам внутри него.
Некоторые более сложные примеры:
# печатать и команды, и события файловой системы, сканировать procfs каждые 1000 мс (=1 сек)
./pspy64 -pf -i 1000
# разместить наблюдатели рекурсивно в двух каталогах и нерекурсивно в третьем
./pspy64 -r /path/to/first/recursive/dir -r /path/to/second/recursive/dir -d /path/to/the/non-recursive/dir
# отключить вывод обнаруженных команд, но включить события файловой системы
./pspy64 -p=false -f
Чтобы увидеть инструмент в действии, просто склонируйте репозиторий и выполните make example (требуется Docker).
Известно, что передавать пароли в качестве аргументов командной строки небезопасно, и этот пример можно использовать для демонстрации этого.
Команда запускает контейнер Debian, в котором секретное cron-задание, выполняемое от root, меняет пароль пользователя каждую минуту.
pspy запускается на переднем плане от пользователя myuser и сканирует процессы.
Вы должны увидеть вывод, похожий на этот:
~/pspy (master) $ make example
[...]
docker run -it --rm local/pspy-example:latest
[+] cron started
[+] Running as user uid=1000(myuser) gid=1000(myuser) groups=1000(myuser),27(sudo)
[+] Starting pspy now...
Watching recursively : [/usr /tmp /etc /home /var /opt] (6)
Watching non-recursively: [] (0)
Printing: processes=true file-system events=false
2018/02/18 21:00:03 Inotify watcher limit: 524288 (/proc/sys/fs/inotify/max_user_watches)
2018/02/18 21:00:03 Inotify watchers set up: Watching 1030 directories - watching now
2018/02/18 21:00:03 CMD: UID=0 PID=9 | cron -f
2018/02/18 21:00:03 CMD: UID=0 PID=7 | sudo cron -f
2018/02/18 21:00:03 CMD: UID=1000 PID=14 | pspy
2018/02/18 21:00:03 CMD: UID=1000 PID=1 | /bin/bash /entrypoint.sh
2018/02/18 21:01:01 CMD: UID=0 PID=20 | CRON -f
2018/02/18 21:01:01 CMD: UID=0 PID=21 | CRON -f
2018/02/18 21:01:01 CMD: UID=0 PID=22 | python3 /root/scripts/password_reset.py
2018/02/18 21:01:01 CMD: UID=0 PID=25 |
2018/02/18 21:01:01 CMD: UID=??? PID=24 | ???
2018/02/18 21:01:01 CMD: UID=0 PID=23 | /bin/sh -c /bin/echo -e "KI5PZQ2ZPWQXJKEL\nKI5PZQ2ZPWQXJKEL" | passwd myuser
2018/02/18 21:01:01 CMD: UID=0 PID=26 | /usr/sbin/sendmail -i -FCronDaemon -B8BITMIME -oem root
2018/02/18 21:01:01 CMD: UID=101 PID=27 |
2018/02/18 21:01:01 CMD: UID=8 PID=28 | /usr/sbin/exim4 -Mc 1enW4z-00000Q-Mk
Сначала pspy выводит все запущенные в данный момент процессы, каждый с PID, UID и командной строкой.
Когда pspy обнаруживает новый процесс, он добавляет строку в этот журнал.
В этом примере вы видите процесс с PID 23, который, похоже, меняет пароль пользователя myuser.
Это результат работы Python-скрипта, используемого в личном crontab root /var/spool/cron/crontabs/root, который выполняет эту команду оболочки (проверьте crontab и скрипт).
Обратите внимание, что myuser не может видеть ни crontab, ни Python-скрипт.
С pspy он, тем не менее, может видеть команды.
Ниже приведён пример с машины Shrek с Hack The Box. В этом CTF-задании требуется эксплуатировать скрытое cron-задание, которое меняет владельца всех файлов в папке. Уязвимость заключается в небезопасном использовании wildcard вместе с chmod (подробности для заинтересованного читателя). Для её поиска и эксплуатации требуется немало догадок. Однако с pspy cron-задание легко найти и проанализировать:

Существуют инструменты для вывода всех процессов, выполняемых в Linux, включая завершённые. Например, forkstat. Он получает уведомления от ядра о событиях, связанных с процессами, таких как fork и exec.