Содержание статьи
/ proc. Все это требует загрузки кода в ядро, компиляции под конкретную версию и оставляет заметные следы. Но есть способ проще. Никаких модулей ядра и компиляции, только один штатный вызов mount с флагом MS_BIND.В этой статье мы:
- разберем технику сокрытия процессов через
bind;mount - воспроизведем ее руками и посмотрим, что происходит на уровне syscall, через
strace; - настроим правило
auditdдля мониторинга в реальном времени; - напишем скрипт на Python для обнаружения и раскрытия скрытых процессов.
Идея основана на статьях Стефана Бергера и Хэла Померанца.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Как работает техника
Как малварь прячет процессы? Мы часто используем ps, чтобы посмотреть, какие процессы запущены в системе. Если заглянуть чуть глубже, то можно узнать, что эта утилита смотрит информацию о процессах в /:
`root@0bc5a04d0a00:/rev# strace ps`
`...`
`openat(AT_FDCWD, "/proc", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3`
`fstat(3, {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0`
`openat(AT_FDCWD, "/proc/uptime", O_RDONLY) = 4`
`fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0`
`read(4, "75062.72 585321.72\n", 1024) = 19`
`close(4) = 0`
`mmap(NULL, 626688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7bc2598f6000`
`getdents64(3, 0x57052d78eaf0 /* 67 entries */, 32768) = 2008`
`newfstatat(AT_FDCWD, "/proc/1", {st_mode=S_IFDIR|0555, st_size=0, ...}, 0) = 0`
`openat(AT_FDCWD, "/proc/1/stat", O_RDONLY) = 4`
`read(4, "1 (bash) S 0 1 1 34816 169 41945"..., 1024) = 329`
`close(4) = 0`
`openat(AT_FDCWD, "/proc/1/status", O_RDONLY) = 4`
`read(4, "Name:\tbash\nUmask:\t0022\nState:\tS "..., 1024) = 1024`
`read(4, "0000,00000000,00000000,00000000,"..., 1024) = 417`
`close(4) = 0`
`openat(AT_FDCWD, "/proc/1/environ", O_RDONLY) = 4`
`read(4, "PATH=/usr/local/sbin:/usr/local/"..., 131072) = 110`
`read(4, "", 130962) = 0`
`close(4) = 0`
`openat(AT_FDCWD, "/proc/1/cmdline", O_RDONLY) = 4`
`read(4, "bash\0", 131072) = 5`
`read(4, "", 131067) = 0`
`close(4) = 0`
`openat(AT_FDCWD, "/proc/1/ctty", O_RDONLY) = -1 ENOENT (No such file or directory)`
`openat(AT_FDCWD, "/proc/tty/drivers", O_RDONLY) = 4`
`read(4, "/dev/tty /dev/tty "..., 9999) = 677`
`close(4) = 0`
`...`В Linux procfs — виртуальная файловая система, которая предоставляет доступ к информации ядра через обычные файловые операции. Каждый процесс представлен директорией /, внутри которой лежат файлы: stat, cmdline, comm, environ, fd/ и другие. Именно их читает ps, top, htop и любой другой инструмент мониторинга.
Главный герой сегодняшней техники — системный вызов mount:
mount(source, target, filesystemtype, mountflags, data)
Это syscall для монтирования файловой системы. Для bind используется флаг MS_BIND (0x1000).
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Оформи подписку на материалы по тегу
Если тебе интересна эта тема целиком, можно открыть доступ не к одному материалу, а ко всем платным статьям выбранного тега.
Вариант 3. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»
