Как взламывают веб сервера

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

Онлайн-курс по устройству компьютерных сетей

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

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

Вирус на linux сервере

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

Вирус в docker контейнере

Все понятно. На сервере стоит Docker. В нем контейнер Postgres. Вирус сидит в контейнере. Иду смотреть, как запущен контейнер. Ничуть не удивлен тем, что он смотрит напрямую в инет.

Postgres на внешнем интерфейсе

Дальше решил проверить, с какими параметрами он запущен. Опять не удивляюсь.

Пользователь и пароль postgres

В лучших традициях жанра, все запущено с дефолтной учеткой postgres/postgres. Фраза fixme игнорируется.

Решил на всякий случай проверить прод. Захожу, а там все то же самое, но вируса пока нет. Не стал разбираться, чтобы ненароком не словить бан от Hetzner. Первую виртуалку просто удалили. На второй сразу поменяли пароль.

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

Тут, конечно, есть недоработка докера. Он зачем-то по дефолту мапит контейнеры к 0.0.0.0, а не к локалхосту. Понятно, что так проще разработчикам, но результат налицо. Разработчики чаще всего не парятся над этим и даже не обращают внимание. Я постоянно вижу на dev серверах контейнеры с backend, смотрящие напрямую в инет. Так что надо обязательно вручную заблокировать доступ к контейнерам Docker из интернета.

В данном случае, достаточно было заблокировать доступ к postgres с помощью iptables:

/sbin/iptables -I DOCKER-USER -i eth0 -p tcp --dport 5432 -j DROP
Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Расскажите, встречались с похожими, простыми и очевидными факапами?

Онлайн-курс по устройству компьютерных сетей.

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Подписывайся на telegram канал автора

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

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

34 комментария

  1. Давно читаю ваш сайт. Вот было бы очень интересно почитать в вашем изложении статью про разворачивание сайта на хостинге. От аренды машины до рабочего сайта. со всеми нюансами настройки фаервола и иже с ним.

    • В современном IT создавать такие материалы не имеет большого смысла. Трудозатрат надо очень много, а через пол года часть материала уже будет неактуальной. Всё это нужно регулярно обновлять и поддерживать, что занимает много времени и сил. В рамках обычного сайта это нереально создать. Многие продавцы курсов, которые на этом зарабатывают, не могут себе позволить держать актуальными свои материалы.

  2. mail_crack@rocketmail.com -Помогу-Пишите!

    Мне тут помогли, спасибо.

  3. Собака Задолбака

    Мне не понятно, почему перед запуском чего угодно, особенно с выходом на 0.0.0.0 нельзя сменить данные учётной записи на корректные, для балбесов же написали "фих ме"!! Как так-то?? Сейчас всем знакомым фанатам докера эту статью покажу!!! Оленизм какой-то!

  4. А полика iptables по-умолчанию DROP для INPUT , FORWARD не спасает? Пусть слушает все интерфейсы, а попадут только если разрешить?

    • Если не ошибаюсь, docker сам управляет iptables. Я не помню, какие он правила делает по умолчанию, но взаимодействовать с iptables нужно по его правилам, если нужна нормальная работа.

  5. » встречались с похожими, простыми и очевидными факапами?
    О. Нынче заходишь иногда на сервер, пишешь ifconfig или iptables-save и глубоко вдыхая констатируешь docker.

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

      • Николай

        -A DOCKER-USER -p tcp -m conntrack --ctorigdstport 80 --ctdir ORIGINAL -j RETURN
        -A DOCKER-USER -p tcp -m conntrack --ctorigdstport 443 --ctdir ORIGINAL -j RETURN
        -A DOCKER-USER -m state --state RELATED,ESTABLISHED -j RETURN
        -A DOCKER-USER -m set --match-set whitelist src -j RETURN
        -A DOCKER-USER -p tcp -m conntrack --ctdir ORIGINAL -j DROP

      • Николай

        Вы можете защищать вашу сеть так как вы привыкли, и при этом запускать контейнеры не в изолированной сети а с использованием хостовой сети ( --net "host" )

  6. Констянтин

    Ну хорошо хоть не "мяукнули" прод какой-нибудь.

  7. Дмитрий

    1. Я всегда думал что 0.0.0.0 в выводе netstat означает - слушать порт на всех интерфейсах сервера . Причем здесь "смотрит напрямую в инет" ?

    2. По поводу - " зачем-то по дефолту мапит контейнеры к 0.0.0.0, а не к локалхосту". Ведь в приведенном compose файле явно написано 0.0.0.0:5432
    И если "потребитель" Postgres на другой виртуалке или запущен в другом стеке compose, то как иначе ?

    • ну если дефолт пароль и юзера разрабам поменять религия не позволяет, то прописать правило в айпитейблах с разрешением подключаться только определенному айпи к тому порту что мешает?

    • 1. В данном случае виртуальная машина с внешним ip, так что слушая 0.0.0.0 приложение принимает запросы в том числе и из интернета.
      2. Потому что в докере так принято по-умолчанию, вот все и оставляют, кто не придет этому значение. Тут все было запущено на одной виртуалке и на одном стеке.

    • да очень просто:
      - network:
      external: true

  8. Ещё кстати помогает команда
    lsof -p имя процесса
    Показывает какие библиотеки, сокеты и логи использует процесс. Можно понять что конкретно делает вирус.

  9. эм, а создать свой network между бд и веб сервером???

    • Зачем? Есть же дефолтный docker-compose, запустил и поехали кодить :) За отдельный network между бд и веб сервером никто лишних денег разработчику не заплатит. И админа не наймет, чтобы он подсказал.

      • есть такое. Хотя пару строчек всего и проблема решена.

      • 127.0.0.1 вместо нулей прокатило бы

      • Николай

        вот тут как раз docker не виноват:
        ```Тут, конечно, есть недоработка докера. Он зачем-то по дефолту мапит контейнеры к 0.0.0.0, а не к локалхосту.```
        как указано выше - нужно было писать 127.0.0.1 вместо нулей - как ему сказали мапить, так он и мапит, тут недоработка со стороны мейнтейнера

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

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

            • Кому должно и где должно? Так можно сказать, что учетная запись admin без пароля это нормально, а то что сервис смотрит в интернет - нет. Я считаю, что было бы лучше мапить по дефолту к локалхосту. А если надо смотреть в мир, то отдельно это настраивается настройкой внешнего ip адреса.

              • А не задумывались что такой мапинг был по какой-то конкретной причине принят разработчикам, и никак иначе?
                А то что если бы и сделали по умолчанию локалхост, то у разрабов было бы первым правилось менять его на 0.0.0.0 не задумываясь, поверьте, везде в интернете в "манах для чайников" было бы примером мапить на 0.0.0.0 и мало кто задумывался бы об этом.
                Есть best practices. Не просто так же придумали что все к чему есть доступ с мира выносить в DMZ за файрвол.

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

                  Не будут разработчики настраивать DMZ, если они не способны 0.0.0.0 поменять на 127.0.0.1 или что-то другое самостоятельно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar