Простой пример атаки на docker
Многие люди по какой-то причине пускают docker у себя на локальном компьютере с очень уязвимыми параметрами, на которые никто не обращает внимание. Наверное, думают, что локальный компьютер это не страшно. Я хочу продемонстрировать как использовать эту уязвимость, чтобы ты проверил свой компьютер и устранил брешь в безопасности и помог другим ее устранить, скинув линк на статью.
Примеры двух уязвимостей
Часто ли ты встречал в доках в интернете примерно такой пример развертывания PostgreSQL:
docker run -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:10
?
Тут есть две серьезные ошибки.
Первая - дефолтный пароль, который даже брутфорсить не нужно. Используй всегда рандомный пароль, сгенерированный какой-нибудь специальной софтиной, даже если это локальный компьютер. Например, pwgen:
$ pwgen 20
bohz5aa9aetoh1Iapedo doow7AiX5amai8aemewe aideiL3ooreexaiquae8
paPheeFu4aekeiDoocaa sheiloon6xuedeWoongi hoodoh4Eey1gaibahRei
iGheesie5seetieH2quo iNgei8eethie9yethecu Thie9kae9fae5eej1quu
soCiakikahngoo1sheiM re4Ea0eiph5Roo7ohCei eyar3aegeigerango6To
shanguoPh9fieFoh4te8 Leo3aen4tir3ahzeishi eewi7Haig1leeVei1oog
Вторая серьёзная брешь в безопасности — параметр -p 5432:5432. Именно о ней мы сегодня и поговорим.
Ищем уязвимость с 0.0.0.0
Давай посмотрим, сколько потенциально уязвимых приложений запущено у тебя на компе. Запусти все свои контейнеры в docker и выполни команду:
$ docker ps | grep 0.0.0.0
b028f8e80d3f postgres:10 "docker-entrypoint.s…" 21 minutes ago Up 1 second 0.0.0.0:5432->5432/tcp angry_aryabhata
Если список пуст, то всё хорошо. Если что-то вывелось - беда.
Понимаешь ли ты, что такое IP 0.0.0.0? Это адрес специального назначения, цель которого - принимать соединения с любого сетевого интерфейса. Это значит, что ты пускаешь порт PostgreSQL на все сетевые адреса своего компьютера.
Если в твоем компе нет вайфая и эзернета, он стоит в шкафу, и ты никогда не планируешь выходить с его помощью в онлайн, то нет никаких проблем. Но скорее всего он подключен к интернету, и тогда ты либо светишь портами докера наружу (что есть самый плохой из вариантов), либо - в локальную сеть со своим (чужим??) роутером.
Если со внешкой всё понятно, то проблема локальной сети для некоторых может быть не очевидной. Про это и поговорим.
Дампим базы постгреса с локальной сети
Допустим, ты подключен к общей с Васей wifi-сети. Вася берет и сканирует весь пулл адресов вашего вайфая (например, 192.168.1.1-255) — находит твой айпи 192.168.1.3 и видит на нём открытый порт постгреса 5432. Пробует законнектится:
$ psql -U postgres -h192.168.1.3
psql (10.21 (Debian 10.21-1.pgdg90+1))
Type "help" for help.
postgres=#
Теперь делает всё тоже самое, но уже с pg_dump. И все твои базы у него в кармане.
Еще одна неочевидная и очень стрёмная проблема
Хочешь еще прикол один расскажу? Ты можешь думать, что никогда не коннектишься к чужим вайфаям, твой вайфай дома сильно защищен (кстати, не верю, такого не бывает), и ты никому не говоришь пароля — но скорее всего ты когда-нибудь да пользуешься VPN! А это значит, что ты коннектишься в общую локальную сеть своего VPN-провайдера, а 0.0.0.0 в докере раздает доступ к порту 5432, в том числе в эту сеть! А значит, и другие юзеры этого VPN могут сдампить твою базу.
Как правильно создавать контейнеры
На примере того же PostgreSQL:
$ docker run -e POSTGRES_PASSWORD=bohz5aa9aetoh1Iapedo -p 127.0.0.1:5432:5432 postgres:10
Никогда, слышишь, НИКОГДА не используй 0.0.0.0 (-p 5432:5432). Пускай все свои приложения сугубо на локалхосте, вот так: -p 127.0.0.1:5432:5432.
И переодически делай проверку на 0.0.0.0 во избежание утечек:
$ docker ps | grep 0.0.0.0