Home » Осторожно, вирус! » Как взламывают веб сервера

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

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

Если у вас есть желание научиться работать с роутерами микротик и стать специалистом в этой области, рекомендую по программе, основанной на информации из официального курса MikroTik Certified Network Associate. Курс стоящий, все подробности читайте по ссылке. Есть бесплатные курсы.

Пересылает мне утром владелец учетной записи в 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
Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

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

Онлайн курс Основы сетевых технологий

Теоретический курс с самыми базовыми знаниями по сетям. Курс подходит и начинающим, и людям с опытом. Практикующим системным администраторам курс поможет упорядочить знания и восполнить пробелы. А те, кто только входит в профессию, получат на курсе базовые знания и навыки, без воды и избыточной теории. После обучения вы сможете ответить на вопросы:
  • На каком уровне модели OSI могут работать коммутаторы;
  • Как лучше организовать работу сети организации с множеством отделов;
  • Для чего и как использовать технологию VLAN;
  • Для чего сервера стоит выносить в DMZ;
  • Как организовать объединение филиалов и удаленный доступ сотрудников по vpn;
  • и многое другое.
Уже знаете ответы на вопросы выше? Или сомневаетесь? Попробуйте пройти тест по основам сетевых технологий. Всего 53 вопроса, в один цикл теста входит 10 вопросов в случайном порядке. Поэтому тест можно проходить несколько раз без потери интереса. Бесплатно и без регистрации. Все подробности на странице .

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

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

Автор Zerox

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

26 комментариев

  1. Аватар

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

    • Zerox

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

  2. Аватар

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

    • Zerox

      Да уж, простой жизни теперь не стало. Я вообще толком так и не понял, как корректно работать с 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" )

  3. Аватар
    Констянтин

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

  4. Аватар
    Дмитрий

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

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

    • Аватар

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

    • Zerox

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

    • Аватар

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

  5. Аватар

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

  6. Аватар

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

    • Zerox

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

      • Аватар

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

      • Аватар

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

      • Аватар
        Николай

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

        • Zerox

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

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

Ваш адрес email не будет опубликован.

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