Псс, бра­ток... слы­шал, что вин­да уже всё? Все поваль­но перехо­дят на сво­бод­ное ПО, иног­да даже оте­чес­твен­ное. Ты безопас­ник, так что иди обес­печивай безопас­ность. И вот тебе кейс: комп с «Линук­сом» и инци­дент. Или инци­ден­та не было, а про­верить, что все чис­то, надо. Зна­ешь, что делать? Если нет, сей­час рас­ска­жем. А если зна­ешь, все рав­но пог­ляди! Мы соб­рали рецеп­ты на все слу­чаи жиз­ни, а в кон­це статьи поделим­ся под­боркой полез­ных инс­тру­мен­тов.

Имен­но здесь начина­ется наша исто­рия. По усло­виям задачи рас­смат­рива­ются дис­три­бути­вы Linux на осно­ве Debian: Kali, Astra и про­чие. Нуж­но соб­рать информа­цию о хос­те, поль­зователь­ской активнос­ти, иные арте­фак­ты, которые могут при­годить­ся для ана­лиза любой по­тусто­рон­ней активнос­ти. Очень желатель­но собирать все дан­ные авто­мати­чес­ки, без исполь­зования кучи пакетов с зависи­мос­тями. Веро­ятно, ты дума­ешь, что при­дет­ся вруч­ную вби­вать все коман­ды в тер­минал, делать себе чек‑лист... Но зачем? Напишем скрип­тец на Bash и будем носить его на флеш­ке!

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

Пред­варитель­но отформа­тируй флеш­ку в NTFS, если ты будешь потом общать­ся с Windows, или в ext4, если нет. Соз­дадим фай­лик ifrit.sh (incident forensic response in terminal) и вне­сем в него пре­амбу­лу. Скрипт будет фик­сировать вре­мя запус­ка и соз­даст дирек­торию для сбо­ра фай­лов (арте­фак­тов) с машины и наших логов. Называть­ся она будет так:

<имя_хоста>_<юзер>_<дата и время>

В кон­це основной час­ти соз­даем в этой пап­ке под­каталог для будущих арте­фак­тов и раз­реша­ем его копиро­вать, затем счи­таем зат­рачен­ное вре­мя и откры­ваем пап­ку в фай­ловом менед­жере. Все свои дей­ствия будем писать в общий лог.

#!/bin/bash
# IFRIT. Stands for: Incident Forensic Response In Terminal =)
# Использование: chmod a+x ./ifrit.sh && ./ifrit.sh
# Фиксируем текущую дату
start=`date +%s`
# Проверка, что мы root
[[ $UID == 0 || $EUID == 0 ]] || (
echo "Current user:"
# «Без root будет бедная форензика»
echo $(id -u -n)
)
echo "Наш sudo-юзер:"
echo $SUDO_USER
# Делаем директорию для сохранения всех результатов (если не указан аргумент скрипта)
if [ -z $1 ]; then
part1=$(hostname) # Имя хоста
echo "Наш хост: $part1"
time_stamp=$(date +%Y-%m-%d-%H.%M.%S) # Берем дату и время
curruser=$(whoami) # Текущий юзер
saveto="./${part1}_${curruser}_$time_stamp" # Имя директории
else
saveto=$1
fi
# Создаем директорию и переходим в нее
mkdir -pv $saveto
cd $saveto
# Создаем вложенную директорию для триаж-файлов
mkdir -p ./artifacts
# Начинаем писать лог в файл
{
<основной код проверок>
# Пример команды в формате:
# <команда> >> <тематический файл>
# Сведения о релизе ОС, например из файла os-release
# Аналоги: cat /usr/lib/os-release или lsb_release
cat /etc/*release
# Список всех запущенных процессов вывод в тематический файл test
ps aux >> test
...
# Завершающая часть после выполнения необходимых команд
# Для выходной директории даем права всем на чтение и удаление
chmod -R ugo+rwx ./../$saveto
end=`date +%s`
echo ENDED! Execution time: `expr $end - $start` seconds.
echo "Проверяй директорию ${saveto}!"
# Открываем директорию в файловом менеджере работает не во всех дистрибутивах. В Astra также можно использовать команду fly-fm
xdg-open .
} |& tee ./console_log # Наш лог-файл

По­доб­ные скрип­ты обыч­но либо пишут всё в один общий лог или в мно­жес­тво малень­ких фай­лов, либо пыта­ются как‑то сис­темати­зиро­вать свой вывод, раз­мещая рядом архи­вец с соч­ными дан­ными. Мы выберем пос­ледний вари­ант, но об этом даль­ше.

В лис­тингах мы ука­зыва­ем толь­ко коман­ду, для эко­номии пишем в ком­мента­рии, что она дела­ет, а ее резуль­тат выводим в один из темати­чес­ких фай­лов, нап­ример >> case1.log (тоже опус­каем эту часть в лис­тингах). В реаль­ном скрип­те рекомен­дуем каж­дую коман­ду соп­ровож­дать выводом ее наз­вания и соп­роводи­тель­ной информа­ции, что­бы было понят­но, что про­исхо­дит:

# Выводим текущий этап в консоль
echo "Название модуля"
# Выводим текущий этап в профильный лог
echo "Название модуля" >> <тематический файл>
# Выводим результат работы команды в профильный лог
<выполняемая команда> >> <тематический файл>
# Вставляем пустую строку в файл для удобочитаемости и разделения результатов отдельных команд
echo -e "\n" >> <тематический файл>
 

Сбор данных о хосте

Для начала зафик­сиру­ем базовую информа­цию о хос­те и ОС и запишем в файл host_info. Вдруг машин мно­го и в будущем нуж­но будет их раз­личать. Скрипт сто­ит запус­кать от рута для мак­сималь­но под­робно­го вывода команд. Там, где это абсо­лют­но необ­ходимо, мы будем начинать коман­ду с sudo.

# Начинаем писать файл host_info. Далее вывод каждой команды здесь подразумевает в конце добавление ">> host_info", для краткости опустим это
echo -n > host_info
date # Фиксируем текущую дату и время
hostname # Пишем имя хоста
who am i # и юзера, от имени которого запустили скрипт
ip addr # Информация о текущем IP-адресе
uname -a # На каких ОС и ядре мы находимся
# Получим список живых пользователей. Зачастую мы хотим просто посмотреть реальных пользователей, у которых есть каталоги, чтобы в них порыться. Запишем имена в переменную для последующей эксплуатации
ls /home
# Исключаем папку lost+found
users=`ls /home -I lost*`
echo $users
# Раскомментируй следующую строчку, чтобы сделать паузу и что-нибудь скушать. Затем нажми Enter, чтобы продолжить
# read -p "Press [Enter] key to continue fetch..."

Ба­зовая информа­ция об активнос­ти — вклю­чении, вык­лючении, уров­не заряда батареи ноут­бука (вдруг при­годит­ся). Как‑то раз машину вклю­чили спе­циаль­но для меня впер­вые за пять лет.

# Текущее время работы системы, количество залогиненных пользователей, средняя загрузка системы за 1, 5 и 15 мин
uptime
# Список последних входов в систему с указанием даты (/var/log/lastlog)
lastlog
# Список последних залогиненных юзеров (/var/log/wtmp), их сессий, ребутов и включений и выключений
last -Faiwx
# Информация о текущей учетной записи и ее членстве в группах
id
for name in $(ls /home) # ...и обо всех остальных
# Здесь же можно использовать и нашу переменную $users
do
id $name
done
# Проверимся на руткиты, иногда помогает
chkrootkit 2>/dev/null
# Здесь можно встретить информацию в виде dat-файлов о состоянии батареи ноутбука, включая процент зарядки, расход и состояние отключения батарейки и ее заряда
cat /var/lib/upower/* 2>/dev/null
 

Кейс 1. Кто косячит?

Кто‑то из поль­зовате­лей занима­ется непот­ребс­тва­ми на работе. То Steam уста­новит, то в ЖЖ напишет трак­тат. Поп­робу­ем его опре­делить сво­ими силами.

 

Шаг 1. Копаемся в файловой системе

Нуж­но спер­ва пос­мотреть активность в стан­дар­тных поль­зователь­ских дирек­тори­ях. Это самый быс­трый и прос­той спо­соб най­ти тех, кто не уби­рает за собой. Здесь мы дела­ем поиск сра­зу для всех домаш­них катало­гов, что тре­бует при­виле­гий супер­поль­зовате­ля. Если ты про­веря­ешь толь­ко одно­го текуще­го юзе­ра, вмес­то /home/* в коман­дах ниже можешь написать ~/.

# В этих каталогах можно поискать последние пользовательские документы и файлы, что позволит узнать, какие документы открывал пользователь и что качал из интернета
sudo ls -la /home/*/Downloads/ 2>/dev/null
sudo ls -la /home/*/Загрузки/ 2>/dev/null
sudo ls -la /home/*/Documents/ 2>/dev/null
sudo ls -la /home/*/Документы/ 2>/dev/null
sudo ls -la /home/*/Desktop/ 2>/dev/null
sudo ls -la /home/*/Рабочий\ стол/ 2>/dev/null
# Составляем список файлов в корзине
sudo ls -laR /home/*/.local/share/Trash/files 2>/dev/null
# Для рута тоже на всякий случай
sudo ls -laR /root/.local/share/Trash/files 2>/dev/null
# Кешированные изображения могут помочь понять, какие программы использовались
sudo ls -la /home/*/.thumbnails/

В резуль­тате ты можешь най­ти приз­наки ска­чива­ния фай­лов, докумен­тов, при­ложе­ний. В кор­зине могут остать­ся уда­лен­ные серии сери­алов или еще что‑то в этом духе.

По­лез­но быва­ет про­шер­стить катало­ги на наличие фай­лов с иско­мым кон­тентом или тер­мином. Нап­ример, поп­робу­ем поис­кать все фай­лы с упо­мина­нием сло­ва «тер­менвокс» (пред­положим, юзер писал чер­новик в тек­сто­вом фай­ле перед пуб­ликаци­ей в ЖЖ) и выведем по две строч­ки свер­ху и сни­зу от него для понима­ния кон­тек­ста упот­ребле­ния.

# Ищем в домашних пользовательских папках
grep -A2 -B2 -rn 'терменвокс' --exclude="*ifrit.sh" --exclude-dir=$saveto /home/* 2>/dev/null >> ioc_word_info

Мож­но поис­кать все фай­лы с инте­ресу­ющим нас рас­ширени­ем. Одна­ко эта коман­да может выпол­нять­ся очень дол­го.

sudo find /root /home -type f -o -name \*.jpg -o -name \*.doc -o -name \*.xls -o -name \*.csv -o -name \*.odt -o -name \*.ppt -o -name \*.pptx -o -name \*.ods -o -name \*.odp -o -name \*.mbox -o -name \*.eml 2>/dev/null >> interes_files_info

По­лез­но пос­тро­ить тай­млайн фай­лов в домаш­них катало­гах с датами изме­нения и сох­ранить его в CSV. Тай­млайн может помочь впос­ледс­твии понять, в какой момент что‑то пош­ло не так, какие фай­лы, ког­да и где соз­давались.

echo "[BUILDING SACRED TIMELINE!]"
echo -n >> timeline_file
echo "file_location_and_name, date_last_Accessed, date_last_Modified, date_last_status_Change, owner_Username, owner_Groupname,sym_permissions, file_size_in_bytes, num_permissions" >> timeline_file
echo -n >> timeline_file
sudo find /home /root -type f -printf "%p,%A+,%T+,%C+,%u,%g,%M,%s,%m\n" 2>/dev/null >> timeline_file #
 

Шаг 2. Приложения

Те­перь пос­мотрим на спис­ки при­ложе­ний. Для начала гля­нем, что у нас вооб­ще уста­нов­лено в сис­теме помимо стан­дар­тных вещей. Сле­дует про­верить, какие бра­узе­ры, мес­сен­дже­ры и поч­товые сер­веры исполь­зуют­ся, — вдруг через них совер­шались недоб­рые дела? Это в будущем может при­годить­ся ана­лити­кам при рас­сле­дова­нии инци­ден­та.

Ра­зуме­ется, мож­но и прос­то про­бежать­ся по знач­кам на рабочем сто­ле. Здесь мы при­водим коман­ды и пап­ки, куда дан­ные прог­раммы могут писать полез­ную инфу, нап­ример хра­нить базы, пароли, исто­рию и про­чие све­дения.

# Firefox, артефакты: ~/.mozilla/firefox/*, ~/.mozilla/firefox/* и ~/.cache/mozilla/firefox/*
firefox --version 2>/dev/null
# Firefox, альтернативная проверка
dpkg -l | grep firefox
# Thunderbird. Можно при успехе просмотреть содержимое каталога командой ls -la ~/.thunderbird/*, поискать календарь, сохраненную переписку
thunderbird --version 2>/dev/null
# Chromium. Артефакты: ~/.config/chromium/*
chromium --version 2>/dev/null
# Google Chrome. Артефакты можно брать из ~/.cache/google-chrome/* и ~/.cache/chrome-remote-desktop/chrome-profile/
chrome --version 2>/dev/null
# Opera. Артефакты: ~/.config/opera/*
opera --version 2>/dev/null
# Brave. Артефакты: ~/.config/BraveSoftware/Brave-Browser/*
brave --version 2>/dev/null
# Бета Яндекс-браузера для Linux. Артефакты: ~/.config/yandex-browser-beta/*
yandex-browser-beta --version 2>/dev/null
# Мессенджеры
# Signal
signal-desktop --version 2>/dev/null
# Viber
viber --version 2>/dev/null
# WhatsApp
whatsapp-desktop --version 2>/dev/null
# Telegram
tdesktop --version 2>/dev/null
# Zoom
# Также можно проверить каталог: ls -la ~/.zoom/*
zoom --version 2>/dev/null
# Steam
# Можешь проверить и каталог: ls -la ~/.steam
steam --version 2>/dev/null
# Discord
discord --version 2>/dev/null
# Dropbox
dropbox --version 2>/dev/null
# И артефакты в ~/.dropbox
# Яндекс Диск
yandex-disk --version 2>/dev/null
# Ищем установленные торрент-клиенты
apt list --installed | grep torrent 2>/dev/null
# Иные специфичные приложения
docker --version 2>/dev/null # Docker
# Артефакты Docker: /var/lib/docker/containers/*/
containerd --version 2>/dev/null
# Артефакты containerd : /etc/containerd/* и /var/lib/containerd/

Ес­ли у тебя есть спи­сок при­ложе­ний, зап­рещен­ных в орга­низа­ции, мож­но хра­нить его в отдель­ном тек­сто­вом фай­ле, гре­пать их отту­да или исполь­зовать однос­троч­ники. Нап­ример:

dpkg -l | grep -f blacklisted_apps.txt
apt list --installed | grep 'torrent\|viber'

Еще мож­но на вся­кий слу­чай выписать все пакеты, уста­нов­ленные в сис­теме. Тут мы при­водим коман­ды для раз­ных пакет­ных менед­жеров, не толь­ко для стан­дар­тных в Debian.

# Список всех установленных пакетов APT; также попробуй dpkg -l
apt list --installed 2>/dev/null
# Следующая команда позволяет получить список пакетов, установленных вручную
apt-mark showmanual 2>/dev/null
apt list --manual-installed | grep -F \[installed\] 2>/dev/null
# Как вариант, можешь написать aptitude search '!~M ~i' или aptitude search -F %p '~i!~M'
# Для openSUSE, ALT, Mandriva, Fedora, Red Hat, CentOS
rpm -qa --qf "(%{INSTALLTIME:date}): %{NAME}-%{VERSION}\n" 2>/dev/null
# Для Fedora, Red Hat, CentOS
yum list installed 2>/dev/null
# Для Fedora
dnf list installed 2>/dev/null
# Для Arch
pacman -Q 2>/dev/null
# Для openSUSE
zypper info 2>/dev/null

При сбо­ре дан­ных еще мож­но вытянуть вся­кие шту­ки типа бра­узер­ных баз, где хра­нят­ся нас­трой­ки, пароли, зак­ладки и исто­рия посеще­ний. А так­же нас­трой­ки поч­товых кли­ентов и перепис­ки в них. Учти, что копиро­вание таких фай­лов обыч­но тре­бует опре­делен­ных прав в сис­теме. Пред­став­ленные ниже пап­ки при­ложе­ний будут сущес­тво­вать, толь­ко если эти при­ложе­ния запус­кались и исполь­зовались.

# Создаем папку для сохранения профиля
mkdir -p ./artifacts/mozilla
# Банально воруем профиль «Файрфокса» для последующих опытов анализа закладок, истории, сохраненных кредов
sudo cp -r /home/*/.mozilla/firefox/ ./artifacts/mozilla
mkdir -p ./artifacts/gchrome
# Google Chrome
sudo cp -r /home/*/.config/google-chrome* ./artifacts/gchrome
mkdir -p ./artifacts/chromium
# Chromium
sudo cp -r /home/*/.config/chromium ./artifacts/chromium

На этом эта­пе мы успешно пос­мотре­ли, чем поль­зователь занимал­ся, какие у него есть при­ложе­ния, и выг­рузили бра­узер­ные арте­фак­ты. Потом отту­да мож­но будет получить исто­рию посеще­ний и сох­ранен­ные кре­ды.

 

Шаг 3. Виртуальный нарушитель

Са­мый хит­рый спо­соб наруше­ний — гадить из вир­туалок или вин­довых при­ложе­ний, раз­верну­тых в Wine. Коман­ды ниже могут помочь най­ти уста­нов­ленные там прог­раммы и пос­мотреть их нас­трой­ки. Тоже запус­каем от рута.

# Список приложений, установленных в Winetricks
winetricks list-installed 2>/dev/null
# Параметры Winetricks
winetricks settings list 2>/dev/null
# Смотрим файлы в вайновском Program Files
ls -la /home/*/.wine/drive_c/program_files 2>/dev/null
ls -la /home/*/.wine/drive_c/Program 2>/dev/null
ls -la /home/*/.wine/drive_c/Program\ Files/ 2>/dev/null
ls -la /home/*/.wine/drive_c/Program/ 2>/dev/null

По­лез­но и пос­мотреть, не затеря­лись ли VirtualBox или QEMU.

# Проверяем, установлена ли VirtualBox
apt list --installed | grep virtualbox 2>/dev/null
# А вот так можем посмотреть логи QEMU, в том числе и об активности виртуальных машин
cat ~/.cache/libvirt/qemu/log/* 2>/dev/null

Для ана­лиза вир­туаль­ных машин их при­дет­ся вклю­чать и смот­реть вруч­ную или выг­ружать их дис­ки для даль­нейше­го ана­лиза ути­лита­ми типа Autopsy.

 

Шаг 4. Любители консоли

Смот­реть пос­леднюю активность поль­зовате­ля — это наша пер­вооче­ред­ная обя­зан­ность. Не забыва­ем, что, кро­ме обыч­ных гра­фичес­ких юзе­ров, у нас есть root, от име­ни которо­го отдель­ные лич­ности любят ста­вить пакеты через тер­минал и тво­рить про­чие безоб­разия. Впе­ред! Нач­нем с исто­рии команд в кон­соли.

# Дефолтная команда
history
# Выводим историю консольных команд
cat ~/.history 2>/dev/null
# Аналог команды history, выводит список последних команд, выполненных текущим пользователем в терминале
fc -l 1 2>/dev/null
# История команд Python, здесь тоже что-то может встретиться
cat ~/.python_history

Ин­терес­но, какие при­ложе­ния ста­вил и уда­лял юзер перед нашей про­вер­кой?

echo "[History installed grep install /var/log/dpkg.log]"
# История установки пакетов. Также можно грепать в файлах /var/log/dpkg.log*, например
grep "install " /var/log/dpkg.log
# История установки пакетов в архивных логах. Для поиска во всех заархивированных логах исправь dpkg.log на *
zcat /var/log/dpkg.log.gz | grep "install "
# Обновления пакетов
grep "upgrade " /var/log/dpkg.log
# Лог удаленных пакетов
grep "remove " /var/log/dpkg.log
# Тут может быть инфа о последних установленных приложениях
cat /var/log/apt/history.log

Так­же в поис­ках уста­нов­ленных при­ложе­ний мож­но пос­мотреть сле­дующие фай­лы:

  • /var/log/dpkg.log*;
  • /var/log/apt/history.log*;
  • /var/log/apt/term.log*;
  • /var/lib/dpkg/status.

Иног­да ты при­ходишь про­верять комп и перед тобой девс­твен­но чис­тый Linux. Воз­можно, от тебя скры­ли основную рабочую ось?

# Вывод содержимого загрузочного меню, то есть список ОС
sudo awk -F' '/menuentry / {print $2}' /boot/grub/grub.cfg 2>/dev/null
# Проверим, не завалялись ли рядом еще загрузочные ОС
sudo os-prober

Под­ведем про­межу­точ­ные ито­ги. Мы получи­ли пред­став­ление о пос­ледних поль­зователь­ских дей­стви­ях с фай­лами и в тер­минале, о работе с гра­фичес­кими при­ложе­ниями. Заг­лянули в кор­зину. Пос­тро­или тай­млайн фай­ловых изме­нений в основных домаш­них катало­гах. Про­чека­ли наличие вир­туалок и пор­тирован­ных при­ложе­ний, в которых тоже мож­но мно­го чего нат­ворить. Это­го дос­таточ­но для вос­ста­нов­ления дей­ствий обыч­ного юзе­ра. Теперь перей­дем к более спе­цифич­ным кей­сам.

 

Кейс 2. Зафиксировано обращение к Tor

Тре­вога, тре­вога! Кто‑то (или что‑то) с рабоче­го компь­юте­ра под­клю­чил­ся к Tor. Есть IP хос­та, с которо­го пред­положи­тель­но было обра­щение, IP целево­го узла Tor и дата. Резуль­таты будем писать в файл network.

 

На том ли мы хосте?

Про­верим, что мы на машине с IP источни­ка под­клю­чения:

# Сетевое имя текущего хоста
cat /etc/hostname
# Информация о сетевых адаптерах. Аналоги: ip l и ifconfig -a
ip a 2>/dev/null
# Список известных хостов, он же локальный DNS
cat /etc/hosts
# Проверяем наличие интернета, а заодно и записываем внешний IP-адрес
wget -O- https://api.ipify.org 2>/dev/null | tee -a network

Ес­ли в сети исполь­зует­ся DHCP, мож­но пос­мотреть сле­дующие фай­лы:

# База аренд DHCP-сервера (файлы dhcpd.leases). Гламурный аналог утилита dhcp-lease-list
cat /var/lib/dhcp/* 2>/dev/null
# Основные конфиги DHCP-сервера (можно сразу убрать из вывода все строки, начинающиеся с комментариев, и посмотреть именно актуальный конфиг, если тебе это надо, конечно)
cat /etc/dhcp/* | grep –vE ^ 2>/dev/null
# В логах смотрим инфу о назначенном адресе по DHCP
sudo journalctl | grep " lease"
# При установленном NetworkManager
sudo journalctl | grep "DHCP"
Пример вывода информации об адресе DHCP из журнала
При­мер вывода информа­ции об адре­се DHCP из жур­нала

Ес­ли мы на подоз­рева­емой машине, то дви­гаем­ся даль­ше.

 

Текущие соединения и логи

Не­обхо­димо пос­мотреть, нет ли сре­ди активных под­клю­чений соеди­нений с IP-адре­сом Tor.

# Сохраняем текущую ARP-таблицу. Аналог: arp -e
sudo ip n 2>/dev/null
# Банальный принт таблицы маршрутизации. Аналог: route
sudo ip r 2>/dev/null
# Активные сетевые процессы и сокеты с адресами. Эти же ключи сработают для утилиты ss ниже
netstat -anp 2>/dev/null
# Актуальная альтернатива netstat, выводит имена процессов (если запуск с sudo) с текущими TCP/UDP-соединениями
sudo ss -tupln

Сре­ди активных соеди­нений мы ничего подоз­ритель­ного не уви­дели. При­дет­ся обра­щать­ся к логам и кон­фигам. Коман­ды, при­веден­ные ниже, мы поза­имс­тво­вали у спе­циалис­тов Цен­тро­бан­ка (из стан­дарта ИББС-1.3-2016, при­ложе­ние В).

Мы будем искать информа­цию (в том чис­ле в сис­темных логах) о сетях, к которым под­клю­чалась опе­раци­онка. Для всех команд нуж­ны пра­ва супер­поль­зовате­ля. Вывод же мож­но нап­равлять в отдель­ный файл network_list.

# Незамысловатый карвинг из логов сетевых соединений
sudo journalctl -u NetworkManager | grep -i "connection '"
sudo journalctl -u NetworkManager | grep -i "address" # адресов
sudo journalctl -u NetworkManager | grep -i wi-fi # подключений-отключений Wi-Fi
sudo journalctl -u NetworkManager | grep -i global -A2 -B2 # подключений к интернету
# Сети Wi-Fi, к которым подключались
sudo grep psk= /etc/NetworkManager/system-connections/* 2>/dev/null
# Альтернатива
sudo cat /etc/NetworkManager/system-connections/* 2>/dev/null
# Забираем конфигурацию iptables
sudo iptables-save 2>/dev/null
sudo iptables -n -L -v --line-numbers
# Список правил файрвола nftables
sudo nft list ruleset

До­пол­нитель­ные коман­ды, тре­бующие sudo:

# Конфигурация беспроводных сетей
sudo iwconfig 2>/dev/null
# Процессы, прослушивающие порты
sudo lsof -i
# Информация о DHCP-действиях на хосте
sudo journalctl | grep -i dhcpd

А вот эта коман­да покажет количес­тво полу­откры­тых соеди­нений:

netstat -tan | grep -i syn | wc -l

Ес­ли соеди­нений мно­го, мож­но пред­положить, что на хост про­води­лась ата­ка SYN flood.

Мы выяс­нили текущую кон­фигура­цию сети, соб­рали некото­рую исто­рию под­клю­чений и получи­ли нас­трой­ки фай­рво­ла. Кста­ти, часть вре­доно­сов прос­то обыч­но или целиком сно­сят фай­рвол (ник­то не заметит, ведь у Linux быва­ет аптайм по пол­года и боль­ше), или откры­вают и изме­няют пор­ты для сво­ей работы.

 

Разные приемы

Про­верим логи с регуляр­кой на более‑менее валид­ный IP-адрес:

sudo journalctl | grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|
sudo [01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' | sort |uniq

Или можешь поп­робовать такой вари­ант:

grep -r -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9
][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' /var/log | sort | uniq

К сожале­нию, иссле­дуемый хост все это вре­мя был под­клю­чен к одной сети. Исполь­зуя соб­ранные дан­ные из кей­са 1, мы уста­нови­ли, что в день под­клю­чения было активно два при­ложе­ния: Firefox и qBittorrent. В /var/log не было ничего инте­рес­ного. Зато в заг­рузках обна­ружи­ли ска­чан­ный в тот же день тор­рент‑файл и сам спи­рачен­ный кон­тент. Что же делать? В тех слу­чаях, ког­да ты не зна­ешь, куда при­ложе­ние пишет лог, быва­ет полез­но греп­нуть кон­крет­ный IP-адрес...

# Ищем айпишник среди данных приложений
grep -A2 -B2 -rn '66.66.55.42' --exclude="*ifrit.sh" --exclude-dir=$saveto /usr /etc 2>/dev/null >> IP_info

И еще — сла­бый, но рабочий спо­соб искать логи где‑то еще. Из‑за того что жур­налы могут иметь вари­ации типа -log. *.log, log1 и так далее, будет мно­го лож­ных сра­баты­ваний. Лег­че будет потом находить логи кон­крет­ных при­ложе­ний.

sudo find /root /home /bin /etc /lib64 /opt /run /usr -type f -name \*log* 2>/dev/null >> int_files_info

В резуль­тате ана­лиза мы обна­ружи­ли файл, содер­жащий логи ска­чива­ния это­го тор­рента:

/home/user/.local/share/qBittorrent/logs/qbittorrent.log

Вре­мя работы тор­рент‑кли­ента в логе точ­но сов­падало с обра­щени­ем к Tor. Запус­каем ска­чива­ние это­го тор­рента на стен­де, и фай­рвол немед­ленно ловит айпиш­ник ноды Tor. Таким обра­зом вос­ста­нови­лась пол­ная кар­тинка событий. Кто‑то ска­жет, что прос­то повез­ло. Спо­рить не будем. В самых запущен­ных слу­чаях мож­но поис­кать в домаш­нем катало­ге все фай­лы, изме­нен­ные за опре­делен­ный вре­мен­ной интервал:

find ~/ -type f -newermt "2023-02-24 00:00:11" \! -newermt "2023-02-24 00:53:00" –ls
 

Кейс 3. Майнер

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

# Выводим список залогиненных юзеров
w
# Список запущенных приложений
lsof -w /dev/null
# Список всех запущенных процессов, лучше класть в отдельный файлик
ps -l
# Список всех запущенных процессов ver. 2
ps aux
# Гламурный вывод дерева процессов
pstree -Aup
# Вывод информации о текущих альтернативных задачах в screen
screen -ls 2>/dev/null
# Вывод выполняющихся фоновых задач. Можешь проверить, открыв приложение из терминала, затем нажми в терминале ctrl + z. Командой fg ты возобновишься к последней такой отложенной задаче, а fg 1 к первой. Не злоупотребляй
jobs
# Текстовый вывод аналога виндового диспетчера задач
top -bcn1 -w512

Сом­нитель­ный про­цесс иног­да мож­но най­ти, прос­то гля­нув вывод ps (при­мер из бло­га Tenable).

10601 pts/18 Sl+ 14:25 | | _ /usr/lib/jvm/java-8-openjdk- …
10716 pts/18 S+ 0:20 | | _ /tmp/konL6821804046402511623.exe
29565 pts/18 S+ 0:00 | | | _ /bin/sh -c /bin/sh
29566 pts/18 S+ 0:00 | | | _ /bin/sh
10718 pts/18 S+ 0:00 | | _ /tmp/konL6369286348563749691.exe

В дан­ном слу­чае все как раз нес­ложно. Дос­таточ­но вбить коман­ду htop, опре­делить PID про­цес­са, который боль­ше всех пожира­ет ресур­сы (нап­ример, гру­зит про­цес­сор на 100%), и убить его коман­дой kill -9 <твой PID>. Так­же прис­мотрись к про­цес­сам, стар­товав­шим из пап­ки /tmp/ или дру­гой ано­маль­ной дирек­тории.

 

Практический разбор

Ис­поль­зуя коман­ду top -bcn1 -w512, мы получи­ли сле­дующий вывод.

Вывод информации о процессах
Вы­вод информа­ции о про­цес­сах

Не­кий firefoxier пот­ребля­ет 100% CPU. Най­дем обжо­ру. Зная PID (62147), получим путь к исполня­емо­му фай­лу, потом можем сдам­пить его, уда­лить или прос­то гор­дить­ся собой:

sudo ls -la /proc/62147/exe
Вывод информации по подозрительному PID
Вы­вод информа­ции по подоз­ритель­ному PID
# Убиваем процесс
sudo kill -9 62147
# Удаляем исполняемый файл
sudo rm /usr/bin/firefoxier

Ус­пех! В прос­тей­шем слу­чае еди­нора­зово­го слу­чай­ного запус­ка это поз­волит хотя бы нор­маль­но работать с хос­том даль­ше. Здесь мы не рас­смат­рива­ем самопо­рож­дающий­ся вре­донос и пути его про­ник­новения и зак­репле­ния в сис­теме.

Ес­ли тебе попал­ся серь­езный про­тив­ник, то пос­ле уста­нов­ки рут­кита про­цес­сы не будут отоб­ражать­ся в спис­ке. Одна­ко в дан­ном слу­чае про­цесс май­нера запус­тился без зак­репле­ния, а поль­зовате­лю дос­тупно объ­ясни­ли, почему не сто­ит запус­кать что попало.

Для переда­чи в SOC соберем базовый три­аж, добавив полез­ную коман­ду в наш скрипт. Три­аж, если по‑прос­тому, — это ког­да ты при­шел на мес­то кибер­прес­тупле­ния и тебе нуж­но быс­тро обна­ружить и соб­рать клю­чевую информа­цию о хос­те. Нап­ример, если ты заранее зна­ешь, что прес­тупник исполь­зовал бра­узер Firefox, то в пер­вую оче­редь получи арте­фак­ты бра­узе­ра, потом логи и осталь­ное — в зависи­мос­ти от зоны инте­ресов.

tar -zc -f ./artifacts/VAR_LOG1.tar.gz /var/log/ 2>/dev/null # Запаковываем все логи в архив

Де­таль­но ана­лизи­ровать и раз­бирать логи мы тут не будем, это отдель­ная тема. Нап­ример, в логах Apache сто­ит гре­пать все стро­ки User-Agent кли­ентов, которые под­клю­чались к тво­ему хос­ту.

Во­обще, в любой непонят­ной ситу­ации гре­пай. Есть ошиб­ки — гре­пай error или fail. Зна­ешь проб­лемную служ­бу — гре­пай по ее наз­ванию или час­ти. Показа­лось, что есть под­клю­чения со сто­рон­них IP-адре­сов? Смот­ри кейс 2 и гре­пай. Пом­ни, grep — твой ключ к успе­ху!

 

Кейс 4. Съемные носители

Поль­зовате­ли обо­жают совать вся­кое барах­ло в пор­ты рабоче­го компь­юте­ра. Нап­ример, флеш­ки с филь­мами, а в запущен­ных слу­чаях — Wi-Fi-адап­теры. Поэто­му есть смысл искать сле­ды этих жут­ких наруше­ний. Вот как пос­мотреть спи­сок железа (отпра­вим в темати­чес­кий лог dev_info):

# Вывод инфо о PCI-шине
lspci
# Вывод инфо о подключенных USB-устройствах
lsusb
# Вывод инфо о блочных устройствах
lsblk
# cat /sys/bus/pci/devices/*/*
# Информация о текущих и ранее установленных Bluetooth-устройствах
ls -laR /var/lib/bluetooth/ 2>/dev/null
# Список Bluetooth-устройств
bt-device -l 2>/dev/null
# Список Bluetooth-устройств mk. III
hcitool dev 2>/dev/null
# Ищем другие сообщения, связанные c железом, очевидно, с sudo
sudo journalctl| grep -i 'PCI|ACPI|Plug' 2>/dev/null
# Пытаемся выявить подключение/отключение сетевого кабеля (адаптера) в логах
sudo journalctl | grep "NIC Link is" 2>/dev/null
# Открытие/закрытие крышки ноутбука
sudo journalctl | grep "Lid" 2>/dev/null
 

Пример usbrip

Ин­терес­нее все­го, конеч­но, пос­мотреть, что там с флеш­ками. Для Linux есть отличная ути­лита usbrip (написан­ная на­шим авто­ром. — При­меч. ред.), под­робную инс­трук­цию к ней можешь гля­нуть на Kali.tools. Уста­нав­лива­ем и запус­каем:

usbrip events history

Вы­бира­ем вывод в тер­минал (жмем Enter). Выводит­ся вся дос­тупная информа­ция по каж­дому носите­лю на осно­ве логов, вклю­чая дату пос­ледне­го отсо­еди­нения устрой­ства и серий­ник (у нас usbrip почему‑то вывел далеко не все серий­ники, хотя в логах они про­писы­вались). Для прос­мотра в виде таб­лицы пиши

usbrip events history -et
Вывод информации по USB-носителям из утилиты usbrip
Вы­вод информа­ции по USB-носите­лям из ути­литы usbrip
 

Самогреп

Что­бы ничего не уста­нав­ливать и смот­реть логи самос­тоятель­но, можешь вос­поль­зовать­ся вот такой коман­дой (без grep жиз­ни нет, пом­нишь?):

sudo journalctl -o short-iso-precise | grep -iw usb

Вы­вод тебя впе­чат­лит сво­им выда­ющим­ся объ­емом. Давай опти­мизи­руем зат­раты челове­ко‑часов и нап­равим вывод в фай­лы:

# Информация о USB-шине и подключенных устройствах
lsusb
cat /var/log/messages | grep -i usb 2>/dev/null
# Подключенные в текущей сессии USB-устройства у Linux аптайм обычно большой, может, прокатит
sudo dmesg | grep -i usb 2>/dev/null
# Usbrip делает то же самое, но потом обрабатывает данные и делает красиво
sudo journalctl | grep -i usb

Для более деталь­ной информа­ции будем искать серий­ники кон­крет­ных носите­лей и выводить строч­ки рядом с ними:

cat /var/log/syslog* | grep -i usb | grep -A1 -B2 -i SerialNumber: >> usb_list_file
cat /var/log/messages* | grep -i usb | grep -A1 -B2 -i SerialNumber: 2>/dev/null >> usb_list_file
# Как ты понимаешь, устройства в текущей сессии имеет смысл собирать, только если система давно не перезагружалась
sudo dmesg | grep -i usb | grep -A1 -B2 -i SerialNumber: >> usb_list_file
sudo journalctl | grep -i usb | grep -A1 -B2 -i SerialNumber: >> usb_list_file

Бла­года­ря выводу пос­ледней коман­ды мы обна­ружи­ли под­клю­чение сто­рон­него устрой­ства — флеш­ки. Пос­коль­ку такой серий­ник не чис­лился в спис­ках отде­ла безопас­ности, поль­зователь получил по лик­безу вне оче­реди.

Вывод информации о USB-носителях из системного журнала
Вы­вод информа­ции о USB-носите­лях из сис­темно­го жур­нала
 

Кейс 5. Закрепленная малварь и IOC

Это уже более серь­езный кейс, для нас­тоящих геро­ев Threat Hunting. Допус­тим, ты хочешь про­верить, нет ли на хос­те мар­керов ком­про­мета­ций, то есть IOC (indicators of compromise). В демонс­тра­цион­ных целях давай поищем фай­лы, наличие которых ука­зыва­ет на воз­можное зараже­ние «Ши­шигой» или RotaJakiro.

# Первые 18 файлов указывают на возможную активность Shishiga
# Последние четыре возможные локации RotaJakiro
FILES="/etc/rc2.d/S04syslogd
/etc/rc3.d/S04syslogd
/etc/rc4.d/S04syslogd
/etc/rc5.d/S04syslogd
/etc/init.d/syslogd
/bin/syslogd
/etc/cron.hourly/syslogd
/tmp/drop
/tmp/srv
$HOME/.local/ssh.txt
$HOME/.local/telnet.txt
$HOME/.local/nodes.cfg
$HOME/.local/check
$HOME/.local/script.bt
$HOME/.local/update.bt
$HOME/.local/server.bt
$HOME/.local/syslog
$HOME/.local/syslog.pid
/bin/systemd/systemd-daemon
/usr/lib/systemd/systemd-daemon
$HOME/.dbus/sessions/session-dbus
$HOME/.gvfsd/.profile/gvfsd-helper"
counter=0;
for f in $FILES
do
if [ -e $f ]
then
# Если нашли файл из запретного списка, алертим и увеличиваем счетчик
$counter=$counter +1;
echo "Shishiga or RotaJakiro Marker-file found: " $f
fi
done
# Если счетчик не 0, то тревожно
if [ $counter -gt 0 ]
then
# Выводим алерт, что нашли нехорошие IOC
echo "Shishiga or RotaJakiro IOC Markers found!!"
fi

Но на самом деле такой самопал и спи­сок айоков будет тяжело отсле­живать и пра­вить, поэто­му лег­че юзать готовые тул­зы типа YARA-ска­неров или «Фен­рира», который тоже написан на Bash и тре­бует на вход толь­ко спи­сок фай­лов с айока­ми.

Все это акту­аль­но и для поис­ка аген­тов C2-сер­веров. Таких аген­тов для Linux есть уже не один десяток. К сожале­нию, часть их детек­тиру­ется толь­ко при ана­лизе тра­фика (по стро­кам User-Agent или отпе­чат­кам JA3/JARM), и без спе­циаль­ных тулз или отдель­ных СЗИ нам тут не обой­тись. Для локаль­ного ана­лиза в таком слу­чае пот­ребу­ется уста­нов­ка от­дель­ных ути­лит и соз­дание дам­па тра­фика (tcpdump).

 

Анализ мест для закрепления

Вмес­то это­го давай поищем ано­малии в типич­ных мес­тах зак­репле­ния и авто­запус­ка прог­рамм. Начина­ющие хакеры так и гуг­лят: how autostart program linux. Поч­ти все коман­ды из спис­ка ниже рекомен­дуем запус­кать через sudo.

# Аналог планировщика на основе системных таймеров
systemctl list-timers
# Более подробный вывод с примечаниями
systemctl status *timer
# Текущий статус служб и сервисов. Аналог в некоторых дистрибутивах: chkconfig --list или просто вывод всех доступных сервисов systemctl -all
sudo systemctl status –-all
# Закрепление в виде сервиса. Делаешь скрипт сервисом вот и закрепился
systemctl list-unit-files --type=service
# Легаси-вариант, статус работы всех служб
sudo service --status-all 2>/dev/null
# Вывод конфигураций всех сервисов
cat /etc/systemd/system/*.service
# Список запускаемых сервисов, например ssh, networking, anacron
ls -la /etc/init 2>/dev/null
# Сценарии запуска и остановки демонов в ОС можно поискать в конфигах специфические артефакты
ls -la /etc/init.d 2>/dev/null

При подоз­рении, что вре­донос все еще работа­ет:

# Следующая команда выводит огромный список всех открытых файлов в системе с указанием процессов, перенаправим в отдельный файл. Полезно, если вредонос активничает на компе
lsof >> lsof_file
# Вывод активных модулей, которые пытались загрузиться в память
systemctl list-units
# Все модули с указанием текущего состояния файлов модулей; можно отдельно посмотреть модули ядра: cat /etc/modules.conf и cat /etc/modprobe.d/*
systemctl list-unit-files
 

Эмуляция C2 через cron

Пла­ниров­щик задач cron — доволь­но палев­ное мес­то. Для эму­ляции ано­маль­ной активнос­ти соз­дадим задачу на запуск пин­га нашего C&C-сер­вера (возь­мем прос­той — DNS canary token). Задача будет запус­кать­ся пос­ле ребута раз в 100 с.

Добавление задачи в cron
До­бав­ление задачи в cron

Пос­ле перезаг­рузки получа­ем алерт, то есть механизм рабочий. Давай сооб­разим, какие коман­ды понадо­бят­ся для про­вер­ки схо­жих с cron мест залега­ния мал­вари.

Канарейка получила отстук
Ка­нарей­ка получи­ла отстук

До­бав­ляем коман­ды в скрипт:

# Вывод запланированных задач текущего юзера
crontab -l
# Вывод запланированных задач для всех юзеров
sudo for user in $(ls /home/); do echo $user; crontab -u $user -l; done
# Планировщик задач. Автозагрузка неплохое место для закрепления вредоноса в системе
ls -la /etc/cron*
# В том числе файлы cron.daily|hourly|monthly|weekly и список пользователей
cat /etc/cron*/*
# Вывод запланированных задач
cat /etc/crontab
# Лог планировщика
cat /var/log/cron.log*
# Чтение сообщений об ошибках от планировщика заданий cron
sudo cat /var/mail/root 2>/dev/null
 

Изысканные локации

Не кро­ном еди­ным, мож­но пос­мотреть задачи в бэк­гра­унде и сооб­щения о выпол­нении задач.

# Вывод jobs
cat /var/spool/at/*
# Файлы deny|allow со списками юзеров, которым разрешено в cron или jobs
cat /etc/at.*
# Вывод задач Anacron
cat /var/spool/anacron/cron.*
# Вывод задач в бэкграунде
ls -la /var/spool/cron/atjobs 2>/dev/null
cat /var/spool/cron/** # и их конфигов
for usa in $users
do
# Проверяем сообщения
cat /var/mail/$usa 2>/dev/null
done

Поль­зователь­ские скрип­ты в авто­запус­ке:

# /etc/rc.local legacy-скрипт, который выполняется перед логоном
cat /etc/rc*/*
cat /etc/rc.d/*

Су­ровые при­виле­гиро­ван­ные вре­доно­сы не стес­няют­ся про­писать­ся че­рез GRUB. Мож­но прос­мотреть заг­рузчик на пред­мет стран­ных конс­трук­ций, в пер­вую оче­редь нас инте­ресу­ют прог­раммы, которые запус­кают­ся пос­ле окон­чания заг­рузки ядра (конс­трук­ции вида init=...). Для изу­чения под­робнос­тей заг­рузим спи­сок всех раз­делов и их иден­тифика­торов (UUID) из fstab.

Смот­рим нас­трой­ки GRUB. В некото­рых дис­три­бути­вах путь /boot/grub2:

sudo cat /boot/grub/grub.cfg 2>/dev/null

Файл fstab содер­жит информа­цию о фай­ловых сис­темах и устрой­ствах хра­нения, могут попасть­ся и спис­ки шиф­рован­ных томов, а иног­да кре­ды или пути к ним.

cat /etc/fstab 2>/dev/null
 

Любителям графики

Рас­смот­рим авто­заг­рузку гра­фичес­ких при­ложе­ний. При ее нас­трой­ке ты можешь добавить триг­геры на вход и выход поль­зовате­лей, перезаг­рузку сис­темы. Нап­ример, что­бы при вхо­де сра­зу откры­вал­ся бра­узер и мес­сен­джер. В нашем «злом» демо будем запус­кать бра­узер и одновре­мен­но откры­вать порт для ком­муника­ции с С2-сер­вером мал­вари.

Изменение параметров запуска программы
Из­менение парамет­ров запус­ка прог­раммы

Сох­раним и про­верим. Пос­ле логона запус­тился бра­узер и открыл­ся порт.

Проверка выполнения после изменения параметров запуска
Про­вер­ка выпол­нения пос­ле изме­нения парамет­ров запус­ка

В тек­сто­вые кон­фиги таких авто­заг­рузоч­ных фай­лов мож­но про­писать выпол­нение про­изволь­ной коман­ды (параметр Exec).

Чтение конфига запуска программы
Чте­ние кон­фига запус­ка прог­раммы

Уч­тем про­вер­ку таких фай­лов в скрип­те — мало ли, кто или что в них мог­ло про­писать­ся:

# Автозагрузка графических приложений (файлы с расширением .desktop)
ls -la /etc/xdg/autostart/* 2>/dev/null
# Для быстрого просмотра всех выполняемых команд через автозапуски
cat /etc/xdg/autostart/* | grep "Exec="
# Автозагрузка в GNOME и KDE
cat ~/.config/autostart/*.desktop 2>/dev/null

При ана­лизе выпол­няемых команд обра­щай вни­мание на катало­ги /usr/bin. Извес­тная хох­ма: вре­доно­сы иног­да пере­име­новы­вают себя в wget или curl для мас­киров­ки.

 

Файлы настроек

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

По­мимо это­го, кон­фиги шел­ла — одно из излюблен­ных мест для зак­репле­ния вре­доно­сов в сис­теме. Нап­ример, могут соз­давать­ся под­дель­ные обо­лоч­ки или при запус­ке тер­минала будут авто­мати­чес­ки исполнять­ся коман­ды.

Агент питонов­ско­го C2-сер­вера Ares мож­но поис­кать и прос­то в домаш­них катало­гах в виде скры­той пап­ки:

ls -la /home/$name/.ares.
# Если мы рут, запишем все параметры из скрытых файлов его домашнего каталога, включая файл history с историей команд, различные конфиги шелла и другие ништяки
sudo cat /root/.* 2>/dev/null
# То же самое для каждого юзера, у которого есть домашний каталог
for name in $(ls /home)
do
# У юзеров обычно больше интересных скрытых файлов, включая параметры профиля, шелла
cat /home/$name/.* 2>/dev/null
done
if [ -e "/etc/profile" ] ; then
# Получаем настройки профиля Bash по умолчанию
cat /etc/profile 2>/dev/null
fi
# Сохраняем пути к исполняемым файлам шеллов список доступных в системе шеллов
cat /etc/shells 2>/dev/null

По­пуляр­но зак­репле­ние мал­вари в связ­ке с началом и завер­шени­ем сес­сий Bash. Сто­ит поль­зовате­лю открыть тер­минал — и вре­донос запус­кает­ся. Еще забав­нее, ког­да админ реша­ет, что пос­ле годово­го аптай­ма мож­но и перезаг­рузить­ся, и, ког­да сес­сия завер­шится, сра­баты­вает вре­донос­ный агент. В общем, здесь тебе и авто­выпол­нение команд, и заведе­ние али­асов (вво­дишь sudo, а выпол­няет­ся rm -rf /home/ почему‑то). Крат­ко оста­новим­ся на некото­рых добыва­емых таким обра­зом инте­рес­ных фай­лах из домаш­них катало­гов:

  • .*profile — забира­ем фай­лы дефол­тных кон­фигура­ций шел­ла, нап­ример .bash_profile. Впи­сан­ные в эти фай­лы коман­ды выпол­няют­ся при каж­дом запус­ке интер­пре­тато­ра;
  • .*history — берем исто­рию команд всех поль­зовате­лей в тер­минале (если она есть);
  • .bashrc — парамет­ры Bash при запус­ке инте­рак­тивно­го шел­ла и выпол­нение команд;
  • .bash_login — парамет­ры запус­ка тер­минала, выпол­нение команд;
  • .bash_logout — парамет­ры выхода из тер­минала, выпол­нение команд;
  • .bash_history — исто­рия команд в Bash;
  • .zshrc — парамет­ры запус­ка ZSH, если он уста­нов­лен;
  • .zsh_history — исто­рия команд ZSH;
  • .history — в некото­рых дис­три­бути­вах тут может быть исто­рия команд.

Тща­тель­но изу­чи фай­лы .bashrc (или rc-фай­лы дру­гих шел­лов), соб­ранные выше. Пос­коль­ку в них про­писа­ны коман­ды, выпол­няемые при ини­циали­зации сес­сии тер­минала, они будут авто­мати­чес­ки запус­кать­ся. Вот тебе при­мер для реали­зации такой инъ­екции:

chmod u+x ~/.hidden/fakesudo
echo "alias sudo=~/.hidden/fakesudo" >> ~/.bashrc

Еще рут­кит может исполь­зовать пере­опре­деле­ния фун­кций через LD_PRELOAD (см. статью «Соз­даем userland-рут­киты в Linux с помощью LD_PRELOAD») и про­писы­вание в фай­ле .bashrc строч­ки такого типа:

export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libgtk3-nocsd.so.0
 

Профильное закрепление

Чек­нем выпол­няемые при каж­дом вхо­де поль­зовате­ля в сис­тему сце­нарии.

# Получаем стандартные параметры пользовательских профилей, выполняемых при входе в систему
cat /etc/profile 2>/dev/null
echo "[Profile parameters: cat /etc/profile.d/*]"
# Дополнительные параметры запуска профиля, включая специфические приложения
cat /etc/profile.d/*

Мож­но сде­лать скрипт /etc/profile.d/evil.sh при­мер­но такого содер­жания:

#!/bin/bash
TEST=$(cat /etc/passwd)
PENTEST=$(ping -c 1 cundcserver.server)
export $TEST
export $PENTEST

В качес­тве C&C-сер­вера исполь­зуем Canary token. Ког­да юзер вхо­дит в тер­минал, при­лета­ет алерт, а в текущих перемен­ных появ­ляют­ся резуль­таты (мож­но про­верить коман­дой set | grep TEST).

Заполняемые переменные при входе в систему
За­пол­няемые перемен­ные при вхо­де в сис­тему

По­это­му добавим в скрипт выг­рузку перемен­ных:

set # Переменные шелла
env # Глобальные переменные ОС
printenv # Все текущие переменные среды
# Или strings /proc/<подозрительный PID>/environ вывод переменных конкретного процесса
cat /proc/$$/environ
 

Триаж артефактов

В завер­шение работы с этим кей­сом стри­ажим фай­лы, которые могут помочь вирус­ным ана­лити­кам при раз­боре полетов. Такую выг­рузку целесо­образно про­водить толь­ко в запущен­ных слу­чаях, плюс может пот­ребовать­ся внеш­ний хард. Про­бежим­ся по всем поль­зователь­ским пап­кам и соберем ниш­тяки. Нач­нем с рута:

# Создаем папку для сохранения пользовательских данных
mkdir -p ./artifacts/share_root
# Копируем их
sudo cp -r /root/.local/share ./artifacts/share_root 2>/dev/null
# Туда может попасть корзина со всем содержимым, поэтому лучше удалить находящиеся в ней файлы (если, конечно, ты не ищешь ее то, что в ней находится)
rm -r ./artifacts/share_root/Trash/files 2>/dev/null
# Создаем папку для конфигов рута
mkdir -p ./artifacts/config_root
# Параметры суперпользователя
sudo cp -r /root/.config ./artifacts/config_root 2>/dev/null
# Посмотреть сохраненные параметры пользовательских сессий
sudo cp -R /root/.cache/sessions ./artifacts/config_root 2>/dev/null

Для юзе­ров собира­ем в цик­ле ров­но то же самое, соз­давая пап­ки с арте­фак­тами с хос­та для каж­дого юзе­ра:

# Создаем папку для конфигураций юзеров
mkdir -p ./artifacts/config_user
for usa in $users
do
mkdir -p ./artifacts/share_user/$usa
cp -r /home/$usa/.local/share ./artifacts/share_user/$usa 2>/dev/null # Включая файл recently-used.xbel, в котором записана информация о запуске последних графических приложений, корзина с ее содержимым и файлы keyrings
rm -r ./artifacts/share_user/$usa/Trash 2>/dev/null
rm -r ./artifacts/share_user/$usa/share/Trash/files 2>/dev/null
mkdir -p ./artifacts/cache_user/$usa
# Если стоит GNOME
cp -r /home/$usa/.cache/tracker/ ./artifacts/cache_user/$usa 2>/dev/null
cp -r /home/$usa/.local/share/tracker/data/ ./artifacts/cache_user/$usa 2>/dev/null
cat /home/$usa/.local/share/gnome-shell 2>/dev/null
# Если стоит FreeDesktop, можно посмотреть корзину тут
cat /home/$usa/.local/share/Trash/info/*.trashinfo
ls -laR /home/$usa/.local/share/Trash/files/*
# Также собираем конфигурации приложений каждого юзера:
mkdir -p ./artifacts/config_user/$usa
cp -r /home/$usa/.config ./artifacts/config_user/$usa 2>/dev/null
# Сохраненные пользовательские сессии
cp -R ~/.cache/sessions ./artifacts/config_user/$usa 2>/dev/null
done

В самом кон­це не забыва­ем заар­хивиро­вать все най­ден­ные арте­фак­ты:

echo Packing artifacts...
tar --remove-files -zc -f ./artifacts.tar.gz artifacts 2>/dev/null

Го­тово! На выходе ты получа­ешь пап­ку со все­ми резуль­татами, соб­ранны­ми арте­фак­тами и кон­фигами с ана­лизи­руемо­го хос­та. Тут спе­циаль­но не при­водят­ся резуль­таты работы каж­дой коман­ды, ведь если тебе инте­рес­но, то сам пос­мотришь.

 

Кейс 6. Удаленное проникновение

Есть подоз­рение, что у нас в сис­теме появил­ся нез­ваный уда­лен­ный гость. Давай про­верим, так ли это.

# Получим список пользователей
if uname -a | grep astra ;
# Это вариант запроса для Astra Linux. В других дистрибутивах getent в наших тестах выполнялся бесконечно
then
getent passwd {1000..60000} >/dev/null 2>&1
# Сравним с выводом через awk
eval getent passwd {$(awk '/^UID_MIN/ {print $2}' /etc/login.defs)..$(awk '/^UID_MAX/ {print $2}' /etc/login.defs)} | cut -d: -f1
fi
# Однако зачастую мы хотим просто посмотреть реальных пользователей, у которых есть каталоги, где можно порыться. Запишем в переменную для последующей эксплуатации
ls /home
# Исключаем папку lost+found
users=`ls /home -I lost*`
echo $users

При­берем к рукам информа­цию о вхо­дах в сис­тему, гля­нем основные парамет­ры юзе­ров, узна­ем, кто из них может адми­нить.

# Список последних загрузок ОС
sudo journalctl --list-boots 2>/dev/null
if [ -e /var/log/btmp ]
then
# Неудачные попытки входа в систему
lastb 2>/dev/null
fi
if [ -e /var/log/wtmp ]
then
# Лог логинов и бутов
last -f /var/log/wtmp
fi
# Получаем список привилегированных sudo-юзеров
sudo cat /etc/sudoers 2>/dev/null
cat /etc/passwd 2>/dev/null # Почему бы и нет?
# Юзеры с пустым паролем
sudo cat /etc/shadow | awk -F":" '($2 == "") {print $1}' 2>/dev/null

Од­на из так­тик зак­репле­ния дос­тупа — это сох­ранение клю­чей SSH. Выг­рузка арте­фак­тов и нас­тро­ек SSH помога­ет выявить под­клю­чения к хос­ту по сох­ранен­ным откры­тым клю­чам или отпе­чат­кам дру­гих хос­тов. Иног­да мож­но най­ти при­ват­ные клю­чи хос­та, что потом поз­волит изу­чить исхо­див­шие от него под­клю­чения. Это при­годит­ся при рас­сле­дова­нии слож­ных инци­ден­тов с мас­совыми под­клю­чени­ями.

Смот­реть сто­ит фай­лы authorized_keys и known_hosts, а так­же сами фай­лы клю­чей, генери­руемые ути­литой ssh-keygen или ско­пиро­ван­ные внеш­ним хос­том через ssh-copy-id. Спро­сим у рута и у всех поль­зовате­лей, что у них есть на этот счет:

cat /root/.ssh/* 2>/dev/null
for name in $(ls /home)
do
cat /home/$name/.ssh/* 2>/dev/null
done

Ес­ли получен­ные клю­чи не при­над­лежат извес­тным сис­темам, это может быть пло­хой новостью. Так­же про­верим попыт­ки уда­лен­ного вхо­да через SSH:

sudo journalctl _SYSTEMD_UNIT=sshd.service | grep "error" 2>/dev/null

Вхо­ды в сис­тему по SSH можешь пос­мотреть через lastlog, но полез­но и пог­репать логи и кон­фиги:

sudo journalctl | grep ssh # или sshd
# Ищем ошибки аутентификации
sudo journalctl | grep ssh | grep -i -A2 -B2 fail
Ошибки подключения по SSH из журналов
Ошиб­ки под­клю­чения по SSH из жур­налов
 

Файловые аномалии

Не забудь пос­мотреть кон­фиг для общих папок: вдруг есть откры­тая шара, через которую и про­изво­дили пенет­рацию?

cat /etc/samba/smb.conf # Конфиг
cat /var/log/samba/*.log # Логи
# Можно дополнительно проверить список текущих общих папок
cat /var/lib/samba/usershares/*
# Проверим и в списке монтируемых папок
mount -l

Да­лее нуж­но поис­кать все фай­лы, у которых нет вла­дель­ца или груп­пы, — это харак­терно при уда­лен­ном про­ник­новении на хост и работе через реверс‑шел­лы. Опять же для демонс­тра­ции ищем толь­ко в домаш­них катало­гах.

# При поиске вредоносов рекомендуется искать файлы без владельца
sudo find /root /home -nouser 2>/dev/null
# Или без группы
sudo find /root /home -nogroup 2>/dev/null

Спе­цы CERT Societe Generale так­же рекомен­дуют сле­дующие коман­ды:

# Конкурирующая команда для поиска файлов с SUID и GUID
find / -uid 0 \( -perm -4000 -o -perm 2000 \) -print
# Поиск файлов с нехарактерными названиями, например начинающихся на точку, две точки или пробел
find / -name " *" -print # find / -name ". *" -print
find / -name ".. *" -print
# Поиск больших файлов (больше 10 Мбайт)
find / -size +10M
# Поиск процессов, инициированных удаленными файлами
lsof +L1
 

Логи и сетка

Для поряд­ка стри­ажим логи, прос­то выведем их в файл:

# Вывод всех системных логов. Может быть полезно погрепать специфичные службы и сервисы, ошибки и саксессы
sudo journalctl >> journalctlfile

В нас­трой­ках сети мож­но пос­мотреть сос­тояние фай­рво­ла. Нап­ример, наличие в исто­рии команд, которы­ми его отклю­чали (ufw disable или iptables -F), может намек­нуть, что в сис­теме про­исхо­дило что‑то нехоро­шее. Еще в исто­рии мож­но поис­кать такие коман­ды, свя­зан­ные с отклю­чени­ем сер­висов защиты:

service stop apparmor
systemctl disable apparmor
# Просмотр конфигов PAM
cat /etc/pam*/*

Ес­ли есть подоз­рение, что где‑то спря­талась мал­варь, то на рабочем хос­те мож­но через iptables бло­киро­вать обра­щения с извес­тны­ми непоря­доч­ными юзе­раген­тами, нап­ример Ares:

# Блочим обращения от сервера… при условии, что мы сами не сервер и что это не SSL
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "python-requests/" -j DROP
 

Выводы

Мы намерен­но не собира­ем дамп памяти, пос­коль­ку он, конеч­но, инте­ресен при работе с заражен­ной вре­доно­сом‑шиф­роваль­щиком машиной, но момен­таль­но на мес­те его про­ана­лизи­ровать слож­но.

Ес­ли у тебя более серь­езные подоз­рения на вре­донос (где твой анти­вирус?), то не забудь прос­канить YARA-пра­вила­ми (под­робнее о них — в статье «Yara. Пишем пра­вила, что­бы искать мал­варь и не толь­ко») или пос­мотреть в sigma rules. Для поис­ка арте­фак­тов так­же есть полез­ный сбор­ник с под­дер­жкой нес­коль­ких ОС: Digital Forensics Artifacts Repository (часть арте­фак­тов мы пред­ста­вили здесь).

Со­вер­шенс­тво­вать эту под­борку команд мож­но бес­конеч­но, а на сле­дующем шаге по‑хороше­му сле­дует реали­зовать обра­бот­ку соб­ранных дан­ных для их про­вер­ки на соот­ветс­твие compliance. Но это уже будет сов­сем дру­гой уро­вень!

Ес­ли ты счи­таешь, что мы что‑то забыли или упус­тили, не будь тер­пилой и раз­неси нас в ком­мента­риях! Будем вмес­те собирать полез­ные при­емы.

 

Дополнительная литература

Ре­сур­сы и статьи о зак­репле­нии при ата­ках на Linux:

 

Скрипты и утилиты

  • Со­бирать арте­фак­ты из скрип­тов на Python поможет ресурс FastIR Collector Linux и его нас­ледник fastir_artifacts.
  • На чис­том шел­ле: ста­рень­кий LINReS, LIRES и све­жень­кий unix_collector.
  • На нечис­том (с зависи­мос­тями и дру­гими скрип­тами): набор Forensics and Ediscovery Scripts, IR_Detect, NBTempo, IR_Tool, ir-rescue, ir-triage-toolkit, очень сим­патич­ный UAC.
  • Для Windows можешь пос­мотреть inquisitor — он бли­зок к нашему скрип­ту по прин­ципу, толь­ко тащит за собой кучу сто­рон­них portable-прог­рамм. Так­же полез­но гля­нуть KAPE.
  • Су­щес­тву­ют готовые ути­литы для три­ажа, работа­ющие по прин­ципу «ска­чал, запус­тил, радуй­ся». Нап­ример, CyLR и varc. Пер­вый полезен для сбо­ра логов и информа­ции из сис­темных дирек­торий. Вто­рая приб­луда собира­ет дам­пы про­цес­сов и дан­ные из вре­мен­ных и поль­зователь­ских катало­гов. Если исполь­зовать эти ути­литы вмес­те, то поч­ти нет шан­са что‑то про­пус­тить.
  • Для повыше­ния содер­жатель­нос­ти логов рекомен­дуем защит­никам нас­тро­ить auditd, да и потес­тить Sysmon для Linux не помеша­ет.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    5 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии