Всем привет! В свободное от не-работы время я CTO собственной компании (DigitalWand), и как следствие – чем мне только ни приходится заниматься! И вот недавно один из наших клиентов посетовал на проблемы в своей внутренней кухне: мол, вирус положил внутренние сервисы, включая git и площадки для разработки. И тут мне вспомнилась собственная аналогичная проблема, которая произошла год тому назад. Вот эту страшилку и хотел бы рассказать. Думаю, будет полезна как начинающим сисадминам и девопсам, так и вообще людям, которые каким-то боком с линуксовыми серверами связаны.
Об атаках на сервера вообще
Прежде всего оговорюсь, что я не являюсь каким-либо узкоспециализированным экспертом в области безопасности, ну и даже просто мой уровень DevOps / Sysadmin оставляет желать лучшего. Так, нахватался знаний по ходу дела. Да и потом, когда возникает ситуация «никто кроме нас» - уже не вариант отмахиваться, мол, не мой профиль…
Мотивы
По моим наблюдениям, сервера и сайты совершенно разных компаний постоянно «утюжат» робо-хакеры в поисках дыры, через которую можно пролезть. Так что даже если конкретно сегодня вы уверены, что всё идеально настроили и ваша система как неприступная цитадель – не переживайте, пройдёт месяц, другой, вы поставите себе какой-то новый софт, подкрутите конфиги, пропустите обновление – и вот уже «входная дверь» для зловреда открыта, осталось только дождаться, когда он её найдёт.
Большинство зловредов, с которыми я сталкивался – относительно безобидные в том плане что не ставят перед собой цели украсть данные, шифровать диски, вымогать деньги и т.п. Наоборот, чаще всего они занимаются массовыми почтовыми рассылками или пытаются майнить на свободных ресурсах ваших серверов. И не привлекать к себе лишнего внимания. Так что, возможно, ваша система полна такими «невидимыми сусликами», а вы просто об этом не знаете. Заражают и работают такие зловреды тоже, как правило, в автоматическом режиме – если бы был за ними живой человек-оператор, заинтересованный в том, чтобы гарантированно вас уничтожить, то шансов вылечиться было бы значительно меньше.
Симотомы
Как опознать заражение «невооруженным глазом»? Прежде всего, ваш хостинг-провайдер может выслать вам через техподдержку уведомление о подозрительном траффике, и разбор этой проблемы не стоит откладывать в долгий ящик. Второй момент: вы можете заметить периодическую недоступность ранее стабильно работавших сервисов, замедление открытия сайтов на хостинге, на дисках может начать заканчиваться место без особой причины. Если заметили что-то такое – это в целом повод заглянуть на сервер, открыть монитор процессов и хотя бы поверхностно посмотреть, а что это такое сейчас грузит систему? Сколько времени работает процесс, кто его создал, на что даёт нагрузку: диск, процессор или сеть? Знаете ли вы, что это за процесс? Какую функцию он выполняет? А нужны ли вашей инфраструктуре эти функции? Что будет, если процесс положить – перезапустится ли он сам через какое-то время, перестанет ли в вашей системе при этом работать какая-то важная функция?
Надо понимать, что название процесса не будет говорить само за себя, типа exploit.sh или virus.bin. Вероятнее всего это будет либо случайный набор букв, либо название продублирует имя какого-то существующего полезного сервиса.
Лечение
Как вылечиться от такого вторжения? Тут всё индивидуально, прям универсального решения нет. Могу наверняка сказать только то, что просто остановить процессы и удалить вызвавшие их файлы может быть недостаточно. Даже, скорее всего, это и не произведёт особого эффекта: вероятно, «зловред» где-то в системе уже успел прописать скрипт своего самовосстановления, и через какое-то время проявит себя снова. Так что нужно тщательно проверить все операции, исполняемые по таймеру, несколько дней внимательно понаблюдать за происходящим. Ну и поставить обновления, конечно.
Наш случай
А теперь, собственно, что случилось конкретно у нас и как мы от этого вылечились. Далее будет довольно много технических деталей, и без них тут никак – иначе не получится в полной мере оценить всё коварство и изящество, с которым подходят к взлому.
Первый звоночек, что что-то идёт не так – посыпались письма с ошибками с зараженных серверов. При этом ошибки слал не наш мониторинг, а простые внутрисистемные уведомления о том, что команда в консоли завершилась с ошибкой и т.п. И падали они не на специальный ящик, а на какие-то несуществующие – благо, у нас была настроена специальная почта, на которую собирались все сообщения, отправленные на несуществующий ящик. Вот пример:
Я был на куче созвонов и забил. Так бы и лег спокойно спать, если бы dev сервер не лёг раньше меня. За вечер нам с админом удалось кое-что раскопать, но по итогу сервера на ночь вообще отключили (хорошо, что мы могли себе это позволить!)
Итак, характерные черты "заразы":
Она удаляет содержимое crontab и прописывает туда запуск своих скриптов
Она прописывает запуск своих скриптов при запуске системы, в /etc/rc.d
Пишет в hosts какие‑то домены про блокчейн
Сносит все iptables, ищет и удаляет точечно какие‑то программы, которые, видимо, потенциально могут помешать работе «вируса» или обнаружить его.
Запускает кучу инстансов какого‑то процесса bbp, причем новые инстансы будут появляться быстрее, чем удаляешь их руками.
Все файлы, перечисленные выше, также пополняются новыми записями непрерывно. То есть вручную удалять бессмысленно, скрипт успевает генерить мусор быстрее, как ни крути.
Создаёт пользователя под благовидным логином system и выдаёт ему права на sudo
Как оказалось, в заражении участвуют несколько скриптов, и бинарный файл в этой посылке счастья всего один… но, похоже, именно он и получает рут-доступ, используя какие-то системные уязвимости.
В общем, я делал несколько подходов к очищению, и несколько раз казалось, что система уже свободна от вирусов, но минут через 20 он снова появлялся… Пришлось внимательно читать скрипты вируса, благо это простой bash. По итогу сформировал вот такую инструкцию для "борьбы":
Во-первых, не надо пытаться убить процессы. Это бессмысленно, новые всё равно вылезут.
service crond stop - всё равно кронтаб весь перетёрт
chattr -ia /var/spool/cron/root после чего можно удалить мусор из крона
удалил пользователя system
прописал exit 0 в файл /etc/rc.local
chattr +i /etc/rc.local
убил процессы eid2jfhp4j (или похожие, со странным рандомным именем)
rm -rf /tmp/bbp; touch /tmp/bbp; chattr -i /tmp
rm -rf /opt/bbp; touch /opt/bbp; chattr +i /opt/bbp
rm -rf /var/tmp/bbp; touch /var/tmp/bbp; chattr -i /var/tmp/bbp
useradd system --shell=/bin/false --no-create-home - скрипт в вирусе пытается создать системного пользователя. Но не проверяет его наличие. Так что если нет уверенности, что машина полностью "обеззаражена" - лучше создать этого юзера самому, и сразу кастрировать его по правам.
-
зачистил /etc/hosts от вот этого:
добавил туда 127.0.0.1 privatekeysweeper.cf
chattr +i /etc/hosts
переименовать команду ssh - для уверенности, что другие машины не будут заражены.
План, признаюсь, не вполне точный: в тот момент очень много приходилось ориентироваться по ситуации, список действия я уже восстанавливал постфактум.
Принцип действия
Вирус состоит из нескольких bash скриптов. Неплохо отрефакторенных, кстати говоря - для баша! ???? Каждый скрипт так или иначе пытается скачать и запустить бинарный файл bbp. И скачивает он его с сайта privatekeysweeper.cf . Поэтому уже простая запись 127.0.01 privatekeysweeper.cf позволяет остановить вторжение. К тому же вирус не перетирает hosts, а дополняет его, так что даже если он уже запущен - против записи в hosts ничего не сможет сделать.
После запуска bbp в систему начинают попадать и другие bash скрипты, которые уже уверенно выполняют операции с уровнем доступа рута, удаляют неугодный софт, прописывают свой запуск где только можно, ещё и ставят проверку в цикл, что их никто не удалил…
В целом ничего особенного, но есть тут изюминка…
Один кусок кода сканирует домашние папки всех пользователей. Собирает оттуда пути до приватных ключей пользователя и адреса, сохранённые в known_hosts. После чего в бесконечном цикле начинает выполнять команду ssh, пытаясь выполнить скачивание и запуск bbp на удалённой машине из known_hosts… Таким образом, под заражение попадают не просто операционки, физически располагающиеся на одной железке, а вообще любые системы, с которых когда-либо делалась связь по ssh и в которых есть уязвимость, позволяющая получить рут-привилегии. Именно поэтому, зачистив одну систему от вируса, можно минут через -дцать увидеть, что на неё снова всё вернулось…. Если не прописать адрес в hosts, конечно. И не удалить ssh везде, где он не нужен.
Потому что обновление софта - дело долгое, и пока апдейты качаются - эксплойт качается тоже ????
Вот как выглядела картина по заапущенным процессам на зараженной машине, характерные черты:
-
Толпа ssh подключений с целью заразить другие машины:
-
Отголосок bash скрипта, запускающего ssh в цикле:
-
Попытка вируса размножиться через cron:
Счастливый конец
По итогу, от вредоноса мы очистились. Разорванные связи между серверами восстановили. Удалённые файлы восстановили из бэкапов.
На время неработоспособности серверов часть проектов разработчики подняли локально, для особо критичных оперативно купили недорогой хостинг с ежедневной оплатой, и временно развернулись там. По итогу вред был нанесён больше моральный, чем материальный, и компания в целом это пережила спокойно. За исключением, конечно, двух жестко не выспавшихся человек: меня и админа.
По итогу мы обновили софт на наших серверах, в том числе пакет polkit
, через уязвимость в котором, предположительно, эксплойт к нам и попал. Но и тут есть интересное: на момент заражения на серверах все security-обновления были честно установлены. Как видно, это ещё не гарантия того, что всё будет гладко.
Мораль
Как видно, вопросы информационной безопасности актуальны, даже если ты «неуловимый Джо», которого специально никто не ловит. И просто выполнить формальные шаги типа «обновиться» - порой недостаточно для спокойного сна. Поэтому думать о безопасности стоит не только в том ключе «а что я сделал, чтобы мне не поломали сервера?», но и в ключе «а что я буду делать, когда их поломают, а данные удалят?». Сэкономите если не на деньгах, то уж на нервных клетках – точно.
Комментарии (15)
3ycb
16.06.2023 08:46в том числе пакет, через уязвимость в котором, предположительно, эксплойт к нам и попал
Блин, столько букв, а конкретно не назвали.
ASGAlex Автор
16.06.2023 08:46Сейчас уже сложно раскопать, переписка сгинула в слаке :-( в тикетной системе мы это не фиксировали уже, не до бюрократии было.
Должен сказать, что конкретный пакет - это лишь наше предположение, просто нагуглили его в репортах об уязвимостях, которые показались нам похожими на то, что произошло с нами.
CORAM
16.06.2023 08:46Не совсем понял из статьи, на какой должности работает автор? Разработчик и по совместительству DevOps?
ASGAlex Автор
16.06.2023 08:46СТО - это типа такой чел, который отвечает за всю техническую стратегию работы компании, большой пафосный дядька ????
Вообще, "исходно", я разработчик.
Naves
16.06.2023 08:46+2Если вы предполагаете, что получили рута, то только отключение машины от сети, и полная переустановка.
Пока вы там боролись со скриптами, скорее всего в систему уже поставили перекомпиленный ssh-server и все ваши пароли, если вы их использовали, уже отправились куда-надо. Еще говорят, что если подключиться к такой зараженной машине с пробросом ssh-ключа через -A, то и приватный ключ может утечь.
У вас root был получен, в данном случае самое правильное действие сжечь все.
Странно, что ни вы, ни ваш админ не знают этих базовых правил безопасности в 2023 году.
Далее.
>Собирает оттуда пути до приватных ключей пользователя и адреса, сохранённые в known_hosts.
Ваши разработчики же не хранят ключи на серверах? Да? (картинка со Скайуокером)
А еще если разработчики используют docker, то считайте, что у них есть есть root на сервере, потому что docker run -ti --rm -v /:/tmp bash bash
Неоднократно видел, как кто-то ставил какой-либо portainer на сервер, а потом там волшебным образом появлялся очередной контейнер с -v /:/tmp
anzay911
AppArmor или SELinux сами себя не настроят.
3ycb
Ткните пожалуйста носом в хорошее руководство для настройки AppArmor для чайников.
Я не настоящий сварщик, перечитал кучу руководств и рекомендаций по AppArmor, но не въезжаю в одну вещь. При включении AppArmor, по умолчанию, все можно. Это сбивает с толку. Я думал, что по аналогии с файрволом, когда он включен, без настроек, то все запрещено и надо открывать нужные порты. А тут(AppArmor), откуда я знаю, какой бинарь(как у автора статьи, bbp) меня заразит? А когда уже заразит, будет поздно пить боржоми. Разъясните этот нюанс.
anzay911
Да вроде нормальная родная документация.
https://gitlab.com/apparmor/apparmor/-/wikis/Documentation
Самый простой путь - отпрофилировать обычное поведение бинарника или скрипта (задействовав все возможное сценарии, даже вызов справки) с помощью aa-genprof, применить, допилить напильником, если что-то отломалось и допиливать до тех пор, пока бинарник не перестанет ругаться.
3ycb
Я понимаю, что я ламер и вопросы соответствующие. Но… Это самый простой путь закончить жизнь самоубийством. :) Я должен все известные и неизвестные мне бинарники и скрипты в системе отпрофилировать? А как же, те бинарники и скрипты, которыми система еще не заражена?
anzay911
Зачем все? Только те, за которые тревожно. Как минимум, из списка netstat -plut
И можно быть обладателем самой большой коллекции заразы, но chmod лучше любого профиля.
3ycb
А чтоб я так знал, за что мне тревожно. Я как дилетант и ненастоящий сварщик, естественно, не чувствую нюансы и актуальные возможные опасности.
Спасибо за какую никакую конкретику. А как максимум? Вот я и прошу, где бы почитать дельные советы и рекомендации с конкретикой базового(и чуть выше) уровня? А не тупо выжимки из родного мануала.
Все предусмотреть невозможно. Как бы в данном конкретном случае, как у автора статьи, AppArmor помог бы? Можно простейший пример, пожалуйста?