mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-05 19:32:24 -08:00
Translated ['src/pentesting-cloud/azure-security/az-services/az-app-serv
This commit is contained in:
@@ -408,7 +408,7 @@
|
||||
- [Az - ARM Templates / Deployments](pentesting-cloud/azure-security/az-services/az-arm-templates.md)
|
||||
- [Az - Automation Account](pentesting-cloud/azure-security/az-services/az-automation-account/README.md)
|
||||
- [Az - State Configuration RCE](pentesting-cloud/azure-security/az-services/az-automation-account/az-state-configuration-rce.md)
|
||||
- [Az - Azure App Service & Function Apps](pentesting-cloud/azure-security/az-services/az-app-service.md)
|
||||
- [Az - Azure App Services](pentesting-cloud/azure-security/az-services/az-app-services.md)
|
||||
- [Az - Intune](pentesting-cloud/azure-security/az-services/intune.md)
|
||||
- [Az - File Shares](pentesting-cloud/azure-security/az-services/az-file-shares.md)
|
||||
- [Az - Function Apps](pentesting-cloud/azure-security/az-services/az-function-apps.md)
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
# Az - App Services
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## App Service Basic Information
|
||||
|
||||
Azure App Services 使开发人员能够 **无缝构建、部署和扩展 Web 应用程序、移动应用后端和 API**。它支持多种编程语言,并与各种 Azure 工具和服务集成,以增强功能和管理。
|
||||
|
||||
每个应用程序都在沙箱内运行,但隔离取决于 App Service 计划:
|
||||
|
||||
- 免费和共享层的应用程序运行在 **共享虚拟机** 上
|
||||
- 标准和高级层的应用程序运行在 **仅由同一 App Service 计划中的应用程序共享的专用虚拟机** 上。
|
||||
- 隔离层运行在 **专用虚拟机上,位于专用虚拟网络中**,提高了应用程序的隔离性。
|
||||
|
||||
> [!WARNING]
|
||||
> 请注意,**没有**这些隔离 **防止** 其他常见的 **Web 漏洞**(例如文件上传或注入)。如果使用 **管理身份**,则可能能够 **提升权限**。
|
||||
|
||||
应用程序有一些有趣的配置:
|
||||
|
||||
- **始终开启**:确保应用程序始终运行。如果未启用,应用程序将在 20 分钟不活动后停止运行,并在收到请求时重新启动。
|
||||
- 如果您有需要持续运行的 Web 作业,这是必需的,因为如果应用程序停止,Web 作业也会停止。
|
||||
- **SSH**:如果启用,具有足够权限的用户可以使用 SSH 连接到应用程序。
|
||||
- **调试**:如果启用,具有足够权限的用户可以调试应用程序。但是,这会在每 48 小时自动禁用。
|
||||
- **Web 应用 + 数据库**:Web 控制台允许创建带有数据库的应用程序。在这种情况下,可以选择要使用的数据库(SQLAzure、PostgreSQL、MySQL、MongoDB),并且还允许您创建 Azure Cache for Redis。
|
||||
- 包含数据库和 Redis 凭据的 URL 将存储在 **appsettings** 中。
|
||||
- **容器**:可以通过指示容器的 URL 和访问凭据将容器部署到 App Service。
|
||||
- **挂载**:可以从存储帐户创建 5 个挂载,这些存储帐户可以是 Azure Blob(只读)或 Azure Files。配置将存储存储帐户的访问密钥。
|
||||
|
||||
## Basic Authentication
|
||||
|
||||
在创建 Web 应用程序(通常是 Azure 函数)时,可以指示是否要 **启用基本身份验证**(默认情况下禁用)。这基本上 **启用 SCM(源代码管理器)和 FTP(文件传输协议)**,因此可以使用这些技术部署应用程序。
|
||||
|
||||
要访问 SCM 和 FTP 服务器,需要 **用户名和密码**。因此,Azure 提供了一些 **API 来获取这些平台的 URL** 和凭据。
|
||||
|
||||
**FTP 服务器没有任何特殊的魔法**,只需有效的 URL、用户名和密码即可连接并获得对应用环境的读写权限。
|
||||
|
||||
SCM
|
||||
可以使用 Web 浏览器连接到 SCM,地址为 `https://<SMC-URL>/BasicAuth`,并检查其中的所有文件和部署。
|
||||
|
||||
### Kudu
|
||||
|
||||
Kudu 是 **管理 SCM 和 Web 及 API 接口** 的平台,用于管理 App Service,并提供基于 Git 的部署、远程调试和文件管理功能。可以通过在 Web 应用中定义的 SCM URL 访问。
|
||||
|
||||
请注意,App Services 和 Function Apps 使用的 Kudu 版本不同,Function Apps 的版本要有限得多。
|
||||
|
||||
您可以在 Kudu 中找到的一些有趣的端点包括:
|
||||
- `/BasicAuth`:您需要访问此路径以 **登录 Kudu**。
|
||||
- `/DebugConsole`:一个控制台,允许您在 Kudu 运行的环境中执行命令。
|
||||
- 请注意,此环境 **无法访问** 元数据服务以获取令牌。
|
||||
- `/webssh/host`:一个基于 Web 的 SSH 客户端,允许您连接到应用程序运行的容器内。
|
||||
- 此环境 **可以访问** 元数据服务,以便从分配的托管身份中获取令牌。
|
||||
- `/Env`:获取有关系统、应用设置、环境变量、连接字符串和 HTTP 头的信息。
|
||||
- `/wwwroot/`:Web 应用的根目录。您可以从这里下载所有文件。
|
||||
|
||||
此外,Kudu 曾经是开源的,地址为 [https://github.com/projectkudu/kudu](https://github.com/projectkudu/kudu),但该项目已被弃用,比较当前 Azure 中的 Kudu 与旧版 Kudu 的行为,可以看到 **许多事情已经改变**。
|
||||
|
||||
## Sources
|
||||
|
||||
App Services 默认允许将代码作为 zip 文件上传,但也允许连接到第三方服务并从那里获取代码。
|
||||
|
||||
- 当前支持的第三方源是 **Github** 和 **Bitbucket**。
|
||||
- 您可以通过运行 `az rest --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"` 获取身份验证令牌。
|
||||
- Azure 默认会设置一个 **Github Action**,每次代码更新时将代码部署到 App Service。
|
||||
- 还可以指示一个 **远程 git 仓库**(带用户名和密码)以从那里获取代码。
|
||||
- 您可以通过运行 `az webapp deployment source show --name <app-name> --resource-group <res-group>` 或 `az rest --method POST --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/metadata/list?api-version=2022-03-01" --resource "https://management.azure.com"` 获取远程仓库的凭据。
|
||||
- 还可以使用 **Azure Repository**。
|
||||
- 还可以配置 **本地 git 仓库**。
|
||||
- 您可以通过 `az webapp deployment source show --name <app-name> --resource-group <res-group>` 获取 git 仓库的 URL,这将是应用的 SCM URL。
|
||||
- 要克隆它,您将需要 SCM 凭据,可以通过 `az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>` 获取。
|
||||
|
||||
## Webjobs
|
||||
|
||||
Azure WebJobs 是 **在 Azure App Service 环境中运行的后台任务**。它们允许开发人员在其 Web 应用程序旁边执行脚本或程序,使处理异步或耗时操作(例如文件处理、数据处理或计划任务)变得更加容易。
|
||||
Web 作业有 2 种类型:
|
||||
- **持续**:无限期循环运行,并在创建后立即触发。它非常适合需要持续处理的任务。但是,如果应用程序因未启用始终开启而停止运行,并且在过去 20 分钟内未收到请求,则 Web 作业也会停止。
|
||||
- **触发**:按需或基于计划运行。最适合定期任务,例如批量数据更新或维护例程。
|
||||
|
||||
从攻击者的角度来看,Web 作业非常有趣,因为它们可以用来 **在环境中执行代码** 并 **提升权限** 到附加的托管身份。
|
||||
|
||||
此外,检查 Web 作业生成的 **日志** 总是很有趣,因为它们可能包含 **敏感信息**。
|
||||
|
||||
## Slots
|
||||
|
||||
Azure App Service Slots 用于 **将应用程序的不同版本部署到同一 App Service**。这使开发人员能够在将新功能或更改部署到生产环境之前,在单独的环境中进行测试。
|
||||
|
||||
此外,可以将 **一定比例的流量** 路由到特定的插槽,这对于 A/B 测试和 **后门目的** 很有用。
|
||||
|
||||
## Azure Function Apps
|
||||
|
||||
基本上 **Azure Function apps 是 Azure App Service 的一个子集**,如果您访问 Web 控制台并列出所有应用服务或在 az cli 中执行 `az webapp list`,您将能够 **看到 Function apps 也列在其中**。
|
||||
|
||||
因此,这两项服务实际上在 az cli 中具有大多数 **相同的配置、功能和选项**,尽管它们可能以稍微不同的方式配置(例如 appsettings 的默认值或在 Function apps 中使用存储帐户)。
|
||||
|
||||
## Enumeration
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="az" }}
|
||||
```bash
|
||||
# List webapps
|
||||
az webapp list
|
||||
## Less information
|
||||
az webapp list --query "[].{hostName: defaultHostName, state: state, name: name, resourcegroup: resourceGroup}" -o table
|
||||
## Get SCM URL of each webapp
|
||||
az webapp list | grep '"name"' | grep "\.scm\." | awk '{print $2}' | sed 's/"//g'
|
||||
|
||||
# Get info about 1 app
|
||||
az webapp show --name <name> --resource-group <res-group>
|
||||
|
||||
# Get instances of a webapp
|
||||
az webapp list-instances --name <name> --resource-group <res-group>
|
||||
## If you have enough perm you can go to the "consoleUrl" and access a shell inside the instance form the web
|
||||
|
||||
# Get access restrictions of an app
|
||||
az webapp config access-restriction show --name <name> --resource-group <res-group>
|
||||
|
||||
# Remove access restrictions
|
||||
az webapp config access-restriction remove --resource-group <res-group> -n <name> --rule-name <rule-name>
|
||||
|
||||
# Get connection strings of a webapp
|
||||
az webapp config connection-string list --name <name> --resource-group <res-group>
|
||||
|
||||
# Get appsettings of an app
|
||||
az webapp config appsettings list --name <name> --resource-group <res-group>
|
||||
|
||||
# Get SCM and FTP credentials
|
||||
az webapp deployment list-publishing-profiles --name <name> --resource-group <res-group>
|
||||
|
||||
# Get configured Auth information
|
||||
az webapp auth show --name <app-name> --resource-group <res-group>
|
||||
|
||||
# Get backups of a webapp
|
||||
az webapp config backup list --webapp-name <name> --resource-group <res-group>
|
||||
|
||||
# Get backups scheduled for a webapp
|
||||
az webapp config backup show --webapp-name <name> --resource-group <res-group>
|
||||
|
||||
# Get snapshots
|
||||
az webapp config snapshot list --resource-group <res-group> -n <name>
|
||||
|
||||
# Restore snapshot
|
||||
az webapp config snapshot restore -g <res-group> -n <name> --time 2018-12-11T23:34:16.8388367
|
||||
|
||||
# Get slots
|
||||
az webapp deployment slot list --name <AppName> --resource-group <ResourceGroupName> --output table
|
||||
az webapp show --slot <SlotName> --name <AppName> --resource-group <ResourceGroupName>
|
||||
|
||||
# Get traffic-routing
|
||||
az webapp traffic-routing show --name <AppName> --resource-group <ResourceGroupName>
|
||||
|
||||
# Get used container by the app
|
||||
az webapp config container show --name <name> --resource-group <res-group>
|
||||
|
||||
# Get storage account configurations of a webapp (contains access key)
|
||||
az webapp config storage-account list --name <name> --resource-group <res-group>
|
||||
|
||||
# Get configured container (if any) in the webapp, it could contain credentials
|
||||
az webapp config container show --name <name> --resource-group <res-group>
|
||||
|
||||
# Get Webjobs
|
||||
az webapp webjob continuous list --resource-group <res-group> --name <app-name>
|
||||
az webapp webjob triggered list --resource-group <res-group> --name <app-name>
|
||||
|
||||
# Read webjobs logs with Azure permissions
|
||||
az rest --method GET --url "<SCM-URL>/vfs/data/jobs/<continuous | triggered>/rev5/job_log.txt" --resource "https://management.azure.com/"
|
||||
az rest --method GET --url "https://lol-b5fyaeceh4e9dce0.scm.canadacentral-01.azurewebsites.net/vfs/data/jobs/continuous/rev5/job_log.txt" --resource "https://management.azure.com/"
|
||||
|
||||
# Read webjobs logs with SCM credentials
|
||||
curl "https://windowsapptesting-ckbrg3f0hyc8fkgp.scm.canadacentral-01.azurewebsites.net/vfs/data/jobs/continuous/lala/job_log.txt" \
|
||||
--user '<username>:<password>' -v
|
||||
|
||||
# Get connections of a webapp
|
||||
az webapp conection list --name <name> --resource-group <res-group>
|
||||
|
||||
# Get hybrid-connections of a webapp
|
||||
az webapp hybrid-connections list --name <name> --resource-group <res-group>
|
||||
```
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="Az Powershell" }}
|
||||
```powershell
|
||||
# Get App Services and Function Apps
|
||||
Get-AzWebApp
|
||||
# Get only App Services
|
||||
Get-AzWebApp | ?{$_.Kind -notmatch "functionapp"}
|
||||
```
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="az get all" }}
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Get all App Service and Function Apps
|
||||
|
||||
# Define Azure subscription ID
|
||||
azure_subscription="your_subscription_id"
|
||||
|
||||
# Log in to Azure
|
||||
az login
|
||||
|
||||
# Select Azure subscription
|
||||
az account set --subscription $azure_subscription
|
||||
|
||||
# Get all App Services in the specified subscription
|
||||
list_app_services=$(az appservice list --query "[].{appServiceName: name, group: resourceGroup}" -o tsv)
|
||||
|
||||
# Iterate over each App Service
|
||||
echo "$list_app_services" | while IFS=$'\t' read -r appServiceName group; do
|
||||
# Get the type of the App Service
|
||||
service_type=$(az appservice show --name $appServiceName --resource-group $group --query "kind" -o tsv)
|
||||
|
||||
# Check if it is a Function App and print its name
|
||||
if [ "$service_type" == "functionapp" ]; then
|
||||
echo "Function App Name: $appServiceName"
|
||||
fi
|
||||
done
|
||||
```
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
#### 获取凭据并访问 webapp 代码
|
||||
```bash
|
||||
# Get connection strings that could contain credentials (with DBs for example)
|
||||
az webapp config connection-string list --name <name> --resource-group <res-group>
|
||||
## Check how to use the DBs connection strings in the SQL page
|
||||
|
||||
# Get credentials to access the code and DB credentials if configured.
|
||||
az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>
|
||||
|
||||
|
||||
# Get git URL to access the code
|
||||
az webapp deployment source config-local-git --resource-group <res-group> -n <name>
|
||||
|
||||
# Access/Modify the code via git
|
||||
git clone 'https://<username>:<password>@name.scm.azurewebsites.net/repo-name.git'
|
||||
## In my case the username was: $nameofthewebapp and the password some random chars
|
||||
## If you change the code and do a push, the app is automatically redeployed
|
||||
```
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-app-services-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## 生成 Web 应用的示例
|
||||
|
||||
### 从本地的 Python
|
||||
|
||||
本教程基于 [https://learn.microsoft.com/en-us/azure/app-service/quickstart-python](https://learn.microsoft.com/en-us/azure/app-service/quickstart-python?tabs=flask%2Cwindows%2Cazure-cli%2Cazure-cli-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli) 的内容。
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart
|
||||
cd msdocs-python-flask-webapp-quickstart
|
||||
|
||||
# Create webapp from this code
|
||||
az webapp up --runtime PYTHON:3.9 --sku B1 --logs
|
||||
```
|
||||
登录到 SCM 门户或通过 FTP 登录,可以在 `/wwwroot` 中看到压缩文件 `output.tar.gz`,该文件包含 webapp 的代码。
|
||||
|
||||
> [!TIP]
|
||||
> 仅通过 FTP 连接并修改文件 `output.tar.gz` 并不足以更改 webapp 执行的代码。
|
||||
|
||||
**攻击者可以下载此文件,修改它,然后重新上传以在 webapp 中执行任意代码。**
|
||||
|
||||
### 来自 Github 的 Python
|
||||
|
||||
本教程基于之前的教程,但使用 Github 存储库。
|
||||
|
||||
1. 在您的 Github 账户中分叉存储库 msdocs-python-flask-webapp-quickstart。
|
||||
2. 在 Azure 中创建一个新的 Python Web 应用。
|
||||
3. 在 `Deployment Center` 中更改源,使用 Github 登录,选择分叉的存储库并点击 `Save`。
|
||||
|
||||
与之前的情况一样,登录到 SCM 门户或通过 FTP 登录,可以在 `/wwwroot` 中看到压缩文件 `output.tar.gz`,该文件包含 webapp 的代码。
|
||||
|
||||
> [!TIP]
|
||||
> 仅通过 FTP 连接并修改文件 `output.tar.gz` 并重新触发部署并不足以更改 webapp 执行的代码。
|
||||
|
||||
## 权限提升
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-app-services-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考
|
||||
|
||||
- [https://learn.microsoft.com/en-in/azure/app-service/overview](https://learn.microsoft.com/en-in/azure/app-service/overview)
|
||||
- [https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans](https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user