# AWS - EFS Enum

{{#include ../../../banners/hacktricks-training.md}}

## EFS

### Osnovne informacije

Amazon Elastic File System (EFS) se predstavlja kao **potpuno upravljani, skalabilni i elastični mrežni fajl sistem** od strane AWS-a. Usluga olakšava kreiranje i konfiguraciju **fajl sistema** koji mogu istovremeno da koriste više EC2 instanci i drugih AWS usluga. Ključne karakteristike EFS-a uključuju njegovu sposobnost da se automatski skalira bez manuelne intervencije, obezbedi pristup sa niskom latencijom, podrži visoko-protokne radne opterećenja, garantuje trajnost podataka i besprekorno se integriše sa raznim AWS bezbednosnim mehanizmima.

Po **default-u**, EFS folder koji se montira biće **`/`** ali može imati **drugo ime**.

### Mrežni pristup

EFS se kreira u VPC-u i biće **po default-u dostupan u svim VPC podmrežama**. Međutim, EFS će imati Bezbednosnu Grupu. Da bi se **omogućio pristup EC2** (ili bilo kojoj drugoj AWS usluzi) za montiranje EFS-a, potrebno je **dozvoliti u EFS bezbednosnoj grupi dolaznu NFS** (port 2049) **pravilo iz EC2 Bezbednosne Grupe**.

Bez ovoga, **nećete moći da kontaktirate NFS uslugu**.

Za više informacija o tome kako to uraditi, pogledajte: [https://stackoverflow.com/questions/38632222/aws-efs-connection-timeout-at-mount](https://stackoverflow.com/questions/38632222/aws-efs-connection-timeout-at-mount)

### Enumeracija
```bash
# 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]
> Može se desiti da je EFS tačka montiranja unutar iste VPC, ali u različitom podmreži. Ako želite da budete sigurni da ste pronašli sve **EFS tačke, bilo bi bolje skenirati `/16` netmask**.

### Montiraj EFS
```bash
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 Access

Po **podrazumevanoj** postavci, svako ko ima **mrežni pristup EFS-u** moći će da montira, **čita i piše čak i kao root korisnik**. Međutim, politike datotečnog sistema mogu biti postavljene **samo za omogućavanje pristupa principima sa specifičnim dozvolama**.\
Na primer, ova politika datotečnog sistema **neće dozvoliti čak ni montiranje** datotečnog sistema ako **nemate IAM dozvolu**:
```json
{
"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"
}
}
}
]
}
```
Ili će ovo **sprečiti anonimni pristup**:

<figure><img src="../../../images/image (278).png" alt=""><figcaption></figcaption></figure>

Napomena da za montiranje datotečnih sistema zaštićenih IAM-om MORATE koristiti tip "efs" u komandi za montiranje:
```bash
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

**Access points** su **specifični ulazni punktovi** za **aplikacije** **u EFS datotečnom sistemu** koji olakšavaju upravljanje pristupom aplikacija deljenim skupovima podataka.

Kada kreirate access point, možete **odrediti vlasnika i POSIX dozvole** za datoteke i direktorijume kreirane putem access point-a. Takođe možete **definisati prilagođeni korenski direktorijum** za access point, bilo tako što ćete odrediti postojeći direktorijum ili kreirati novi sa željenim dozvolama. Ovo vam omogućava da **kontrolišete pristup vašem EFS datotečnom sistemu po aplikaciji ili po korisniku**, čineći upravljanje i obezbeđivanje vaših deljenih datoteka lakšim.

**Možete montirati datotečni sistem sa access point-a koristeći nešto poput:**
```bash
# 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]
> Imajte na umu da čak i pokušaj montiranja pristupne tačke zahteva da **kontaktirate NFS servis putem mreže**, i ako EFS ima **politiku** datotečnog sistema, potrebne su vam **dovoljne IAM dozvole** za montiranje.

Pristupne tačke mogu se koristiti u sledeće svrhe:

- **Pojednostavljenje upravljanja dozvolama**: Definisanjem POSIX korisnika i grupe za svaku pristupnu tačku, možete lako upravljati dozvolama pristupa za različite aplikacije ili korisnike bez modifikovanja dozvola osnovnog datotečnog sistema.
- **Sprovođenje korenskog direktorijuma**: Pristupne tačke mogu ograničiti pristup određenom direktorijumu unutar EFS datotečnog sistema, osiguravajući da svaka aplikacija ili korisnik radi unutar svog dodeljenog foldera. Ovo pomaže u sprečavanju slučajnog izlaganja ili modifikacije podataka.
- **Lakši pristup datotečnom sistemu**: Pristupne tačke mogu biti povezane sa AWS Lambda funkcijom ili AWS Fargate zadatkom, pojednostavljujući pristup datotečnom sistemu za serverless i kontejnerizovane aplikacije.

## EFS IP adresa

Koristeći informacije vezane za EFS IP adresu, sledeći Python skript može pomoći u dobijanju detalja o EFS sistemu. Ove informacije su korisne za izgradnju komande za montiranje sistema ili za dalje enumerisanje sa znanjem o ID-u podmreže. Pored toga, skript prikazuje pristupne tačke, što može biti dragoceno kada je korenski direktorijum ili primarni put montiranja ograničen. U takvim slučajevima, pristupne tačke pružaju alternativne puteve za pristup osetljivim informacijama.
```bash
Usage: python efs_ip_enum.py <IP_ADDRESS>
```

```python
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)

```
## Privesc

{{#ref}}
../aws-privilege-escalation/aws-efs-privesc.md
{{#endref}}

## Post Exploitation

{{#ref}}
../aws-post-exploitation/aws-efs-post-exploitation.md
{{#endref}}

## Persistence

{{#ref}}
../aws-persistence/aws-efs-persistence.md
{{#endref}}

{{#include ../../../banners/hacktricks-training.md}}
