티스토리 뷰
퍼블릭클라우드/AWS
[CIS AWS v1.3.0] 1.15 Ensure IAM Users Receive Permissions Only Through Groups
Turtle1000 2021. 3. 7. 22:24에드센스에서 위에 계속 같은 내용을 붙여놓으니까 통과가 안되는 것 같아 없애버렸습니다 흑..
1.14 Ensure access keys are rotated every 90 days or less <- 해당 내용은 이미 1.12에서 구현이 되어있어 그냥 건너뛰었습니다. 직접 해보시길 바랍니다.
이번 내용은 IAM 사용자에게 정책을 부여하는 것이 아닌 그룹에 부여하고 해당 그룹에 사용자를 추가해야한다는 내용입니다.(근데 솔직히 이렇게 하는게 현실적으로 쉽지 않은 부분이기도 하죠..)
아무튼, 확인은 아래 그림처럼 하실 수 있습니다.
사용자를 클릭해서 '권한'탭에 정책이 적용이 되어있으면 취약입니다. 안전은 그 반대로 그룹에 권한이 적용되고 사용자는 그룹에 속해있고 정책은 적용되어 있지 않아야겠죠?
AWS CLI 또는 API에서 해당 정책들은 유형에 따라 사용하는 명령어가 다릅니다.
# json 형태로 뽑아냄. 자동화를 위해!
aws iam list-users --query "Users[*].UserName"
# 관리형 정책
aws iam list-attached-user-policies --user-name <iam_user>
# 인라인 정책
aws iam list-user-policies --user-name <iam_user>
자 그럼 결과를 확인해보겠습니다.
위 그림과 같이 결과가 나온걸 보실 수 있습니다.
자 이걸 이제 python으로 코딩해보면,
import subprocess
import json
import time
from threading import Thread, active_count
def get_string(b_obj, idx=0):
str_tmp = b_obj.decode()
# -1이 들어올 경우 전체 값 반환
if idx == -1:
return str_tmp.splitlines()
else:
return str_tmp.splitlines()[idx]
def get_json(b_obj):
str_tmp = b_obj.decode()
return json.loads(str_tmp)
def exec_cmd(tmp_cmd):
try:
tmp_data = subprocess.check_output(tmp_cmd, shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
error_msg = get_string(e.output, 1)
if 'NoSuchEntity' in error_msg:
aws_acct = [int(tmp) for tmp in error_msg.split(' ') if tmp.isdigit()]
print(f'[-] AWS ACCOUNT{aws_acct} has no password policy.')
elif 'GenerateCredentialReport' in error_msg:
print(f'[-] {error_msg}')
else:
print(error_msg)
return b'Error'
return tmp_data
def worker(user_name):
worker_cmd = (
'aws iam list-attached-user-policies '
'--query "AttachedPolicies" '
'--user-name "{}"'
).format(user_name)
attached_policies = get_json(subprocess.check_output(worker_cmd, shell=True))
worker_cmd = (
'aws iam list-user-policies '
'--query "PolicyNames[*]" '
'--user-name "{}"'
).format(user_name)
inline_policies = get_json(subprocess.check_output(worker_cmd, shell=True))
#print(user_name, len(attached_policies), len(inline_policies))
user_policies_cnt = len(attached_policies) + len(inline_policies)
if user_policies_cnt != 0:
print(f'{user_name} is vuln.')
else:
print(f'{user_name} is safe.')
if __name__ == '__main__':
cmd = (
'aws iam list-users '
'--query "Users[*].UserName"'
)
list_users = get_json(exec_cmd(cmd))
print(list_users)
for user in list_users:
# 문자열 전달하므로 인자 뒤에 ',' 붙여줌
Thread(target=worker, args=(user,)).start()
while True:
# active_count()가 1이면 main thread만 남았다는 뜻
if active_count() == 1:
break
# 5초에 한 번씩 검사
time.sleep(5)
결과는 아래와 같습니다.
계정 하나 잘못만들어서 계속 사서 고생이네요.
아마 점점 코드를 보시면서 '왜 저렇게 코딩하지?' 라는 고민을 하실텐데요. 제가 CIS를 클라우드별로 작성이 완료되면 종합(?)을 해볼까 합니다. 그 때를 위해서 일단 계속 추가하면서 가고 있구요~
뭐 할지안할지는 사실 정확히 모르는거지만 암튼 그렇습니다.
감사합니다.
'퍼블릭클라우드 > AWS' 카테고리의 다른 글
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- platform
- 2xx
- CIS
- steampipe
- 우주와컴퓨터
- web
- stateType
- scp
- findinglatestversion
- opensource
- Cloud
- 계정정보저장
- defaulttheme
- compliance
- 4xx
- AWS #CIS
- .get()
- teplate
- REACT
- IAM
- terraform
- temlate
- cloudsecurity
- conftest policy
- security
- fleet manager
- ViaAWSService
- ControlTower
- JavaScript
- aws
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함