Портал Belkin-labs»PHP классы»Статья
welcome!

Рутировали хостинг? А мне плевать! Я в танке!!! Детективная история по поиску php-шелла

Вот захотелось мне написать статейку с таким броским названием. Возможно я открою чей-нибудь секрет сейчас? Ну извините. Не хотел.

Предыстория вопроса

Живет где-то в России Вася. Он мой знакомый. Мы с ним по аське списываемся. Он считает себя опытным вебмастером и программистом. В один прекрасный солнечный день он вел переговоры с клиентом и в качестве примера своих умений и доблестей упоминал свое любимое детище - свой сайт, которым Вася гордился и на который возлагал некоторые надежды в будущем. И когда уже казалось, что Вася "загрузил клиента" подзавязку и выглядит в его глазах уже так круто, что дальше и некуда, от клиента приходит письмо, в котором клиент, а звали его, кстати, Николай Петрович, приводит во вложении скрин со своего собственного компьютера, где совершенно четко видно, что антивирус Касперского заблокировал сайт Васи, его гордость и надежду! Причем утверждает, что на этот сайт нельзя заходить, поскольку он угрожает "Вашему" компьютеру и всему интернету и является зараженным, а возможно даже и фишинговым и мошенническим и так далее. Каспер обычно никогда не церемонился в формулировках.

Получилась очень неприятная и конфузная картина. То есть Николай Петрович решил зайти на сайт Васи и посмотреть на столько ли Вася крут, как говорит, и натыкается вот на такую штуку. Ну стоит ли говорить, что у Васи тут же случился "бледный вид" и ему пришлось оправдываться? Некрасиво получилось? Да ужас просто!

И что же случилось?

Ну, слава Богу, клиентов в нашей жизни много и Николай Петрович не последний. Он, кстати и не делся никуда. Вася с ним успешно работает. Но сайт-то надо спасать! И Вася, очевидно бросился это делать, отложив при этом все дела и даже не пообедав.

А к слову сказать
Вася действительно неплохой программист и обладал к тому моменту некоторым опытом. То есть сайты у него вскрывали и опыт по поиску проблем у Васи был.

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

А .htaccess был у Васи тоже непростой!
Как мы уже говорили, Вася, хоть и оконфузился, но имел некий опыт и файл .htaccess он сформировал таким образом, что никакие строчки после последней не могли выполниться. И эта ссылка тоже не выполнялась. Но Каспер не стал разбираться, выполняется этот редирект или просто лежит себе на последней строчке. Он взял и заблокировал сайт.

Как же был устроен .htaccess у Васи?

Во-первых, на сайте у Васи не было адресов, заканчивающихся на ".php". Все страницы отзывались только на папки, то есть на uri вида "/folder/". Это, в свою очередь, означало, что все полезные страницы проходили ритуал переименования в этом самом .htaccess. Все переименования Вася завершал опцией [L]. Последней инструкцией файла Вася наивно поставил следующую:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ /page_for_bad_uris.php [L]

Таким образом, любая плохая и несуществующая страница, а также любой битый ури попадали на специальную страницу, которая должна была безболезненно убить все попытки навредить сайту.

Кто же заразил Васин .htaccess?

Кто-то заразил ведь? И Вася стал искать. Очень скоро он нашел неопознанный файл под названием "template.php" в своей корневой папке. Он скачал этот файл к себе на локальный диск, открыл его редактором со всеми предосторожностями и выяснил, что это так называемый php-shell. Проблема, таким образом, идентифицирована!

Что сделал Вася дальше?

А вот дальше Вася задумался. Любому полезно поставить себя на место Васи и представить себе его состояние в тот момент.

Дело в том, что Вася не использовал приемы программирования, позволяющие записать на сайт шелл. Не было в принципе у Васи в скриптах оборотов типа "include($file);". "preg_replace()" с флагом "e" он тоже в своей практике не использовал. КАК ЖЕ ЧУЖОЙ ФАЙЛ ПОПАЛ В КОРНЕВУЮ ПАПКУ САЙТА? Бедный Вася терялся в догадках.

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

Логи доступа сайта

Ну и конечно Вася полез в логи доступа сайта. В логах он довольно быстро нашел обращения к файлу "template.php". Но как ни старался, он не смог найти больше ничего подозрительного. Может быть смотрел невнимательно? Тогда он стал изучать все файлы логов за последние 7 дней (больше просто не было). Причем каждый файл был в районе 100 мегабайт в объеме (у Васи довольно популярный сайт). После исключительно внимательного изучения логов Вася сделал следующие выводы.

  1. Вася так и не нашел ни одного следа того, как файл "template.php" оказался у него на сайте в корневой папке.
  2. Вася обнаружил, что обращения к файлу template.php шли и идут довольно часто. Причем с разных IP-адресов. С адресов, условно 178-х шли безобидные GET запросы без параметров, а вот с (условно) 46-го шла уже реальная атака по протоколу POST. Причем посты в лог не записываются и что там было, можно только догадываться, хотя это и не так важно в конце концов. При этом 178-е адреса были "замазаны" поганой своей спаммерской деятельностью, а 46-й был чистенький и находился в Германии. Что значит замазаны? Вася любит, ценит и пользуется сайтом projecthoneypot.org. То есть любил он иногда взять какой-нибудь надоедливый айпишник и зайти на проект по ссылочке, для примера, "http://www.projecthoneypot.org/ip_91.200.13.87". Там он частенько видел, что IP запятнал себя в противоправной деятельности, а бывало, что зайдешь, и ничего. По мнению экспертов вполне безобидный адресочек. Вот как этот, например, "http://www.projecthoneypot.org/ip_62.80.189.130". А пометить бы этот айпишник можно было, ибо он запрашивал с Васиного сайта такие адреса, которые добропорядочный IP запрашивать совсем не должен был бы.

И вот в итоге сложилось у Васи ощущение, что файла "template.php" сначала не было, а потом, вдруг, он появился и после нескольких безобидных и пустых, но уже успешных GET запросов произошла атака. Ключевым является слово "вдруг". А вот между запросами, где файла нет и запросом, где он есть, не было ничего подозрительного.

Что же предпринял Вася в такой непонятной ситуации?

Ну очевидно, Вася был сильно озадачен. Для начала он написал письмо в поддержку хостинга. Поддержка его не поддержала и в положение его входить не захотела. У Васи сложилось даже впечатление, что мудрые и многоопытные администраторы популярного хостинга за вполне лояльными и культурными отписками просто посмеялись над ним, типа "Программировать научись, валенок!" Но может быть это Васе только так казалось, ибо в тот момент его вера в свои способности была довольно сильно уязвлена. Слава Богу, Вася был еще и достаточно мудрый, чтобы не полезть в бутылку, и вообще он не любил действовать на "горячую голову", и это его много раз выручало и оберегало от неприятных ситуаций.

И, поскольку Васе делать больше было нечего, а он действительно не знал, что ему еще сделать и проверить, он решил ждать. Но он решил не просто ждать! Он решил подготовиться! В частности он вышел на меня и все мне рассказал (почему я и оказался в курсе всей этой истории) и мы вместе стали думать, как обезопаситься или по крайней мере вооружиться.

Как мы ждали очередного нападения

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

А еще мы сделали лог постов. Причем всех. К тому же их не должно было быть слишком много. Сделали таблицу в базе данных и скидывали туда все сведения по пост-запросу, да и сами посты до кучи. А заодно уж и сессию с куками тоже стали записывать.

И вот через 3 недели мы дождались! Пошли пустые GET запросы на файл "template.php" со 178-х адресов. Причем, заметьте, как только 46-й робот определил, что шелл с сайта пропал, он сам тоже пропал и не появлялся 3 недели. А потом, как по волшебству, Васе пришло письмо "счастья", в котором скрипт проверки папок радостно сообщил, что на сайте появился файл "template.php" и разом посыпались изменения файлов ".htaccess". Когда мы с Васей полезли в наши новые логи, возбуждению просто не было предела. Я думал, что сердце просто выпрыгнет из груди. Вася потом признался мне, что испытал что-то похожее.

И что же мы обнаружили?

Самое прикольное, что мы опять не обнаружили ни-че-го. Вообще! Все то же самое. Сначала файла не было, а потом он "вдруг" появился и буквально через 15 минут после этого началась атака. И между этими событиями не было ни одного подозрительного запроса! Напомню, что мы писали и посты и куки и сессии и агенты и вообще все, до чего могли додуматься в течение 3-х недель!

Уроки, которые мы извлекли.

Ну нам показалось, что все очень грустно. Первый раз шелл просто изменил один ".htaccess" и на этом успокоился. В этот раз он стал значительно умнее. Во-первых, он не стал выжидать, пока мы его обнаружим (а мы на это надеялись). Во-вторых, он изменил все файлы ".htaccess" на Васином сайте и вдобавок поменял им доступ таким образом, что они стали доступны "только для чтения" для всех, включая владельца. А на Васином сайте оказалась такая прорва этих файлов, что просто жутко стало! Штук 50, не меньше! Сайт-то большой! В итоге у нас создалось впечатление, что скрипт стал умнее, и я вообще усомнился, что это робот. Тогда я еще сказал Васе, что если, дорогой, к тебе прицепился человек-хакер, то бороться вообще бесполезно. Опять же, тот факт, что атака идет с нормального и незапятнанного адреса, хоть и в Германии, косвенно говорит о том, что это мог быть человек.

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

Мы стали смотреть еще более внимательно и обнаружили кучу bash-скриптов в папке даже не сайта, а вообще в корневой папке хостинга. Мы написали письмо в службу поддержки и нам ответили, что не должно быть там никаких bash-скриптов, и что если они там есть, их можно удалить. Мы их, конечно, удалили и стали думать дальше. И вот тут первый раз нам пришла мысль о том, что рутирован сам хостинг, а не сайт.

Хостинг или оптимистический финал

Мы с холодной головой сочинили хорошее и доброе письмо на хостинг. Мы указали в нем все аргументы, которые были абсолютно непробиваемы. Мы очень надеялись, что нас не "пошлют". И к чести хостинга, нас не "послали". Была выдержана очень серьезная пауза в итоге которой мы получили официально звучащий ответ, в котором было указано, что поддержка вот так сразу не может выявить причину появления на нашем сайте файла "template.php" и bash-скриптов, и как только они появятся опять то, дескать, просьба сообщить, они посмотрят еще раз уже в привязке к дате. Хотя мы им и тут дали время и даже ту часть дня, когда файл появился. У нас же были подробнейшие логи!

Мы письмо прочитали, занесли руку писать ответ, и о чудо! В корневой папке хостинга опять куча bash-скриптов, но уже других и вообще похожих больше на мусор, а не на скрипты. Мы сообщили об этом в поддержку, типа чего ждать-то? На хостинге на вашем ведется вредоносная деятельность вот прямо сейчас и странно, что вы не видите.

Ответ пришел быстро. В нем не было никаких признаний, но было предложено написать заявление на перевод на другой сервер. Это предложение прозвучало примерно как признание, и Вася написал это заявление, перешел на другой сервер, и с тех пор ничего предосудительного замечено не было. Вот уже 2 года прошло. Он даже на хостинг не обиделся и менять его не стал. Говорит, с любым случиться может...

И почему же нам теперь все пофиг и "мы в танке"?

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

В чем основная сложность?

Сложность в том, что мы не знаем заранее, откуда придет атака, как будет называться файл с шеллом и в какую папку его положат. Заметьте, что даже непростой Васин ".htaccess" пропустил файл template.php просто потому, что в момент вызова он лежал на хостинге и был доступен.

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

Опять же хотелось бы, чтобы сайт сам себя защищал, без человеческого вмешательства.

Что делать, если молниеносная атака опять поменяет порядка 50 файлов ".htaccess" с заменой разрешений на доступ владельца?

Ну, ответ напрашивается. Надо хранить базу данных файлов ".htaccess" с их содержимым и местоположением, и делать скрипт по такой же молниеносной замене этих файлов нормальными непорченными копиями. Но это опять с одной стороны человеческий ресурс, а с другой временной фактор. Хорошо, кстати, что выяснилось, что Каспер так быстро не отлавливает плохие акцессы.

Очень полезен отбор плохих IP и создание базы данных наглых агентов. Такую базу всегда будет полезно иметь. Опять же она крайне полезна для проведения различных регулярных действий на сайте. Лично мне видится, что нагрузка спаммерских заходов выгоднее, чем использование cron-а, который не на всех хостингах работает.

Что решили сделать в итоге?

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

Хорошая идея? Дерзайте, дорогие программеры! Вариантов ее воплощения много. Мы с Васей не претендуем на лучшее решение. Только на одно из возможных. Вот, как мы сделали.

Мы дали всем php-скриптам особый префикс. Какой? Да любой! Например, "my_super_secret_long_script_prefix_". После этого мы поместили в ".htaccess" на место самого первого переименования следующее:

RewriteCond %{REQUEST_URI} !my_super_secret_long_script_prefix_.*\.php
RewriteRule [^/]*\.php /my_super_secret_long_script_prefix_proxy.php [L]

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

RewriteCond %{REQUEST_URI} !my_prefix1_.*\.php
RewriteCond %{REQUEST_URI} !my_prefix2_.*\.php
RewriteRule [^/]*\.php /my_prefix1_proxy.php [L]

Вот и все. Любой посторонний файл (злоумышленник вряд ли догадается, какой у нас префикс) попадает на страницу /my_prefix1_proxy.php, где спокойно анализируется, записывается для истории и умирает.

Но этот метод не поможет от реально человеческой атаки на хостинг. Но все равно, есть надежда на то, что атака несколько задержится. Даже человек сразу технологию не просечет. Ему нужно отвлечься и разобраться, что надо префикс вставить и по префиксу обращаться. Хотя чего ее просекать? Вот она! Описана! И на этот случай у нас есть система выявления и учета вредоносных айпишников и анализ появления новых файлов на сайте. То есть об атаке мы узнаем в течение ну часа, ну максимум двух.

Зато против роботизированной атаки она сработает на ура и даст достаточно времени для того, чтобы не спеша принять меры. А поскольку этот метод совершенно не нагружает сервер, то вообще странно, что он не используется при изготовлении движков. То есть до снабжения префиксами таблиц баз данных все додумались, а до снабжения префиксами скриптовых файлов додуматься на столько тяжело? Странно все это и похоже на заговор! Шучу ;)

И не забывайте, что можно ведь идею и развить! Например, раз в сутки менять все префиксы. Что, очень трудно такой скрипт сделать? Ничуть!

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

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

Ну и хотелось бы закончить на оптимистической ноте.

Будем надеяться, что случаи с рутированием хостингов, все-таки, не частые и являются форс-мажором. Вот Вася, например, надеется. Я тоже.

Печатается с разрешения Васи.
Дмитрий Белкин.

Статья создана 05.02.2014
Похожие материалы - отбираем по ключевым словам

Обсуждение

Может я чего и не знаю, но файл .htacess не отдается в текстовом виде, по этому Каспер просканировать его не может... но может я просто не все знаю.

Каспер использует базы плохих сайтов, как они туда попадают вопрос отдельный. Но вот в базу каспера сайт попал и Каспер его блокирует. На другом компе сайт не блокируется так как нет каспера. а отсыл может быть скрытый.

Комментировал lasjfdlasdf
06.02.2014 (11:16)
Да, Антон! Подумав, я прихожу к выводу, что ты прав. Скорее всего Каспер не мог получить этот файл для чтения и анализа (хотя чем черт не шутит). Я тоже не знаю, как работает Каспер. Видимо у него есть роботы, сканирующие сайты. Вполне возможно, что и у Васи что-то делалось и строчка его, все-таки, выполнялась. Но с другой стороны, Вася работает на Линуксе. Если бы сайт у него не работал, он сразу бы это увидел. Но он не увидел. То есть сайт загружался, и все с виду было правильно. Но это было давно и вот так сразу цепь событий уже не восстановить.
Дмитрий Белкин