AWS - EFS Enum

Tip

学习并练习 AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

EFS

基本信息

Amazon Elastic File System (EFS) 被 AWS 视为一个 完全托管、可扩展和弹性的网络文件系统。该服务便于创建和配置 文件系统,这些文件系统可以被多个 EC2 实例和其他 AWS 服务同时访问。EFS 的主要特点包括能够在无需人工干预的情况下自动扩展,提供低延迟访问,支持高吞吐量工作负载,保证数据持久性,并与各种 AWS 安全机制无缝集成。

默认情况下,EFS 挂载的文件夹将是 /,但它可能有 不同的名称

网络访问

EFS 是在 VPC 中创建的,默认情况下在所有 VPC 子网中可访问。然而,EFS 将具有一个安全组。为了 允许 EC2(或任何其他 AWS 服务)挂载 EFS,需要在 EFS 安全组中 允许来自 EC2 安全组的入站 NFS(2049 端口) 规则

没有这个,您 将无法联系 NFS 服务

有关如何执行此操作的更多信息,请查看:https://stackoverflow.com/questions/38632222/aws-efs-connection-timeout-at-mount

枚举

# Get filesystems and access policies (if any)
aws efs describe-file-systems
aws efs describe-file-system-policy --file-system-id <id>

# Get subnetworks and IP addresses where you can find the file system
aws efs describe-mount-targets --file-system-id <id>
aws efs describe-mount-target-security-groups --mount-target-id <id>
aws ec2 describe-security-groups --group-ids <sg_id>

# Get other access points
aws efs describe-access-points

# Get replication configurations
aws efs describe-replication-configurations

# Search for NFS in EC2 networks
sudo nmap -T4 -Pn -p 2049 --open 10.10.10.0/20 # or /16 to be sure

Caution

EFS挂载点可能在同一个VPC内,但在不同的子网中。如果你想确保找到所有EFS点,最好扫描/16子网掩码

Mount EFS

sudo mkdir /efs

## Mount found
sudo apt install nfs-common
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport <IP>:/ /efs

## Mount with efs type
## You need to have installed the package amazon-efs-utils
sudo yum install amazon-efs-utils # If centos
sudo apt-get install amazon-efs-utils # If ubuntu
sudo mount -t efs <file-system-id/EFS DNS name>:/ /efs/

IAM 访问

默认情况下,任何具有对 EFS 的网络访问的人都能够挂载、读取和写入它,即使是根用户。然而,文件系统策略可能会限制仅允许具有特定权限的主体访问它。
例如,如果您没有 IAM 权限,这个文件系统策略将不允许挂载文件系统:

{
"Version": "2012-10-17",
"Id": "efs-policy-wizard-2ca2ba76-5d83-40be-8557-8f6c19eaa797",
"Statement": [
{
"Sid": "efs-statement-e7f4b04c-ad75-4a7f-a316-4e5d12f0dbf5",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "",
"Resource": "arn:aws:elasticfilesystem:us-east-1:318142138553:file-system/fs-0ab66ad201b58a018",
"Condition": {
"Bool": {
"elasticfilesystem:AccessedViaMountTarget": "true"
}
}
}
]
}

或者这将防止匿名访问

请注意,要挂载受 IAM 保护的文件系统,您必须在挂载命令中使用类型 “efs”:

sudo mkdir /efs
sudo mount -t efs -o tls,iam  <file-system-id/EFS DNS name>:/ /efs/
# To use a different pforile from ~/.aws/credentials
# You can use: -o tls,iam,awsprofile=namedprofile

Access Points

访问点特定于应用程序的入口点进入EFS文件系统,使管理应用程序对共享数据集的访问变得更容易。

当您创建访问点时,您可以指定通过访问点创建的文件和目录的所有者和POSIX权限。您还可以为访问点定义自定义根目录,可以通过指定现有目录或创建一个具有所需权限的新目录来实现。这使您能够按应用程序或用户控制对EFS文件系统的访问,从而更容易管理和保护您的共享文件数据。

您可以通过访问点挂载文件系统,例如:

# Use IAM if you need to use iam permissions
sudo mount -t efs -o tls,[iam],accesspoint=<access-point-id> \
<file-system-id/EFS DNS> /efs/

Warning

请注意,即使尝试挂载访问点,您仍然需要能够通过网络联系NFS服务,如果EFS有文件系统策略,您需要足够的IAM权限来挂载它。

访问点可以用于以下目的:

  • 简化权限管理:通过为每个访问点定义POSIX用户和组,您可以轻松管理不同应用程序或用户的访问权限,而无需修改底层文件系统的权限。
  • 强制根目录:访问点可以限制对EFS文件系统中特定目录的访问,确保每个应用程序或用户在其指定的文件夹内操作。这有助于防止意外的数据泄露或修改。
  • 更容易的文件系统访问:访问点可以与AWS Lambda函数或AWS Fargate任务关联,简化无服务器和容器化应用程序的文件系统访问。

EFS IP地址

使用与EFS IP地址相关的信息,以下Python脚本可以帮助检索有关EFS系统的详细信息。这些信息对于构建挂载系统命令或在了解子网ID的情况下进行进一步枚举非常有用。此外,脚本显示访问点,当根目录或主要挂载路径受到限制时,这些访问点提供访问敏感信息的替代路径。

Usage: python efs_ip_enum.py <IP_ADDRESS>
import boto3
import sys

def get_efs_info(ip_address):
try:
session = boto3.Session(profile_name="profile")
ec2_client = session.client('ec2')
efs_client = session.client('efs')

print(f"[*] Enumerating EFS information for IP address: {ip_address}\n")

try:
response = ec2_client.describe_network_interfaces(Filters=[
{'Name': 'addresses.private-ip-address', 'Values': [ip_address]}
])

if not response['NetworkInterfaces']:
print(f"[!] No network interface found for IP address {ip_address}")
return

network_interface = response['NetworkInterfaces'][0]
network_interface_id = network_interface['NetworkInterfaceId']
print(f"[+] Found network interface: {network_interface_id}\n")
except Exception as e:
print(f"[!] Error retrieving network interface: {str(e)}")
return

try:
efs_response = efs_client.describe_file_systems()
file_systems = efs_response['FileSystems']
except Exception as e:
print(f"[!] Error retrieving EFS file systems: {str(e)}")
return

for fs in file_systems:
fs_id = fs['FileSystemId']

try:
mount_targets = efs_client.describe_mount_targets(FileSystemId=fs_id)['MountTargets']

for mt in mount_targets:
if mt['NetworkInterfaceId'] == network_interface_id:
try:
policy = efs_client.describe_file_system_policy(FileSystemId=fs_id).get('Policy', 'No policy attached')
except Exception as e:
policy = f"Error retrieving policy: {str(e)}"

print("[+] Found matching EFS File System:\n")
print(f"    FileSystemId: {fs_id}")
print(f"    MountTargetId: {mt['MountTargetId']}")
print(f"    DNSName: {fs_id}.efs.{session.region_name}.amazonaws.com")
print(f"    LifeCycleState: {mt['LifeCycleState']}")
print(f"    SubnetId: {mt['SubnetId']}")
print(f"    SecurityGroups: {', '.join(mt.get('SecurityGroups', [])) if mt.get('SecurityGroups') else 'None'}")
print(f"    Policy: {policy}\n")

try:
access_points = efs_client.describe_access_points(FileSystemId=fs_id)['AccessPoints']

if access_points:
print(f"[+] Access Points for FileSystemId {fs_id}:")
for ap in access_points:
print(f"    AccessPointId: {ap['AccessPointId']}")
print(f"    Name: {ap.get('Name', 'N/A')}")
print(f"    OwnerId: {ap['OwnerId']}")
posix_user = ap.get('PosixUser', {})
print(f"    PosixUser: UID={posix_user.get('Uid', 'N/A')}, GID={posix_user.get('Gid', 'N/A')}")
root_dir = ap.get('RootDirectory', {})
print(f"    RootDirectory: Path={root_dir.get('Path', 'N/A')}")
creation_info = root_dir.get('CreationInfo', {})
print(f"        CreationInfo: OwnerUID={creation_info.get('OwnerUid', 'N/A')}, OwnerGID={creation_info.get('OwnerGid', 'N/A')}, Permissions={creation_info.get('Permissions', 'N/A')}\n")
else:
print(f"[!] No Access Points found for FileSystemId {fs_id}\n")
except Exception as e:
print(f"[!] Error retrieving access points for FileSystemId {fs_id}: {str(e)}\n")
except Exception as e:
print(f"[!] Error processing file system {fs_id}: {str(e)}\n")

except Exception as e:
print(f"[!] General Error: {str(e)}\n")

if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python efs_enum.py <IP_ADDRESS>")
sys.exit(1)

ip_address = sys.argv[1]
get_efs_info(ip_address)

提权

AWS - EFS Privesc

后期利用

AWS - EFS Post Exploitation

持久性

AWS - EFS Persistence

Tip

学习并练习 AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks