mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['src/pentesting-cloud/azure-security/az-services/az-app-serv
This commit is contained in:
+1
-1
@@ -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는 개발자가 **웹 애플리케이션, 모바일 앱 백엔드 및 API를 원활하게 구축, 배포 및 확장**할 수 있도록 합니다. 여러 프로그래밍 언어를 지원하며, 향상된 기능과 관리를 위해 다양한 Azure 도구 및 서비스와 통합됩니다.
|
||||
|
||||
각 앱은 샌드박스 내에서 실행되지만, 격리는 App Service 계획에 따라 다릅니다:
|
||||
|
||||
- 무료 및 공유 계층의 앱은 **공유 VM**에서 실행됩니다.
|
||||
- 표준 및 프리미엄 계층의 앱은 **동일한 App Service 계획의 앱만 공유하는 전용 VM**에서 실행됩니다.
|
||||
- 격리 계층은 **전용 가상 네트워크의 전용 VM**에서 실행되어 앱의 격리를 개선합니다.
|
||||
|
||||
> [!WARNING]
|
||||
> 이러한 격리 중 **어떤 것도** 다른 일반적인 **웹 취약점**(예: 파일 업로드 또는 인젝션)을 **방지하지 않습니다**. 그리고 **관리 ID**가 사용되는 경우, 이를 통해 **권한 상승**이 가능할 수 있습니다.
|
||||
|
||||
앱에는 몇 가지 흥미로운 구성 옵션이 있습니다:
|
||||
|
||||
- **항상 켜짐**: 앱이 항상 실행되도록 보장합니다. 활성화되지 않은 경우, 앱은 20분 동안 비활성 상태가 되면 실행을 중지하고 요청이 수신되면 다시 시작됩니다.
|
||||
- 웹잡이 지속적으로 실행되어야 하는 경우 필수적입니다. 앱이 중지되면 웹잡도 중지됩니다.
|
||||
- **SSH**: 활성화된 경우, 충분한 권한을 가진 사용자가 SSH를 사용하여 앱에 연결할 수 있습니다.
|
||||
- **디버깅**: 활성화된 경우, 충분한 권한을 가진 사용자가 앱을 디버깅할 수 있습니다. 그러나 이는 48시간마다 자동으로 비활성화됩니다.
|
||||
- **웹 앱 + 데이터베이스**: 웹 콘솔을 통해 데이터베이스가 있는 앱을 생성할 수 있습니다. 이 경우 사용할 데이터베이스(SQLAzure, PostgreSQL, MySQL, MongoDB)를 선택할 수 있으며, Azure Cache for Redis를 생성할 수도 있습니다.
|
||||
- 데이터베이스 및 Redis에 대한 자격 증명이 포함된 URL은 **appsettings**에 저장됩니다.
|
||||
- **컨테이너**: 컨테이너의 URL과 액세스 자격 증명을 지정하여 App Service에 컨테이너를 배포할 수 있습니다.
|
||||
- **마운트**: Azure Blob(읽기 전용) 또는 Azure Files에서 스토리지 계정으로부터 5개의 마운트를 생성할 수 있습니다. 구성은 스토리지 계정의 액세스 키를 저장합니다.
|
||||
|
||||
## Basic Authentication
|
||||
|
||||
웹 앱(및 일반적으로 Azure 함수)을 생성할 때 **기본 인증을 활성화할지 여부**를 지정할 수 있습니다(기본적으로 비활성화됨). 이는 기본적으로 **SCM(소스 제어 관리자) 및 FTP(파일 전송 프로토콜)**를 애플리케이션에 대해 활성화하여 이러한 기술을 사용하여 애플리케이션을 배포할 수 있도록 합니다.
|
||||
|
||||
SCM 및 FTP 서버에 액세스하려면 **사용자 이름과 비밀번호**가 필요합니다. 따라서 Azure는 이러한 플랫폼에 대한 URL과 자격 증명을 얻기 위한 **API를 제공합니다**.
|
||||
|
||||
**FTP 서버는 특별한 마법이 없습니다**. 유효한 URL, 사용자 이름 및 비밀번호만 있으면 연결하여 앱 환경에 대한 읽기 및 쓰기 권한을 얻을 수 있습니다.
|
||||
|
||||
SCM
|
||||
웹 브라우저를 사용하여 `https://<SMC-URL>/BasicAuth`에 연결하고 그곳의 모든 파일 및 배포를 확인할 수 있습니다.
|
||||
|
||||
### Kudu
|
||||
|
||||
Kudu는 **SCM과 웹 및 API 인터페이스를 관리**하여 App Service를 관리하고 Git 기반 배포, 원격 디버깅 및 파일 관리 기능을 제공합니다. 웹 앱에 정의된 SCM URL을 통해 접근할 수 있습니다.
|
||||
|
||||
Kudu는 App Services와 Function Apps에서 사용되는 버전이 다르며, Function Apps의 버전은 훨씬 더 제한적입니다.
|
||||
|
||||
Kudu에서 찾을 수 있는 몇 가지 흥미로운 엔드포인트는 다음과 같습니다:
|
||||
- `/BasicAuth`: Kudu에 **로그인하기 위해 이 경로에 접근해야 합니다**.
|
||||
- `/DebugConsole`: Kudu가 실행되고 있는 환경에서 명령을 실행할 수 있는 콘솔입니다.
|
||||
- 이 환경은 **메타데이터 서비스에 접근할 수 없습니다**.
|
||||
- `/webssh/host`: 앱이 실행되고 있는 컨테이너 내에 연결할 수 있는 웹 기반 SSH 클라이언트입니다.
|
||||
- 이 환경은 **할당된 관리 ID로부터 토큰을 얻기 위해 메타데이터 서비스에 접근할 수 있습니다**.
|
||||
- `/Env`: 시스템, 앱 설정, 환경 변수, 연결 문자열 및 HTTP 헤더에 대한 정보를 가져옵니다.
|
||||
- `/wwwroot/`: 웹 앱의 루트 디렉토리입니다. 여기에서 모든 파일을 다운로드할 수 있습니다.
|
||||
|
||||
또한, 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는 기본적으로 코드가 업데이트될 때마다 App Service에 코드를 배포하기 위해 **Github Action**을 설정합니다.
|
||||
- 또한, 그곳에서 코드를 가져오기 위해 **원격 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이 될 것입니다.
|
||||
- 이를 클론하려면 `az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>`를 통해 얻은 SCM 자격 증명이 필요합니다.
|
||||
|
||||
## Webjobs
|
||||
|
||||
Azure WebJobs는 **Azure App Service 환경에서 실행되는 백그라운드 작업**입니다. 개발자가 웹 애플리케이션과 함께 스크립트나 프로그램을 실행할 수 있도록 하여 파일 처리, 데이터 처리 또는 예약된 작업과 같은 비동기 또는 시간 집약적인 작업을 더 쉽게 처리할 수 있게 합니다.
|
||||
웹잡에는 2가지 유형이 있습니다:
|
||||
- **지속적**: 무한 루프에서 실행되며 생성되자마자 트리거됩니다. 지속적인 처리가 필요한 작업에 이상적입니다. 그러나 Always On이 비활성화되어 있고 지난 20분 동안 요청을 받지 않으면 앱이 중지되므로 웹잡도 중지됩니다.
|
||||
- **트리거**: 필요에 따라 또는 일정에 따라 실행됩니다. 배치 데이터 업데이트 또는 유지 관리 루틴과 같은 주기적인 작업에 가장 적합합니다.
|
||||
|
||||
웹잡은 환경에서 **코드를 실행**하고 연결된 관리 ID에 대한 **권한 상승**에 사용할 수 있기 때문에 공격자의 관점에서 매우 흥미롭습니다.
|
||||
|
||||
또한, 웹잡이 생성하는 **로그**를 확인하는 것도 항상 흥미롭습니다. 로그에는 **민감한 정보**가 포함될 수 있습니다.
|
||||
|
||||
## Slots
|
||||
|
||||
Azure App Service Slots는 **동일한 App Service에 애플리케이션의 다양한 버전을 배포하는 데 사용됩니다**. 이를 통해 개발자는 프로덕션 환경에 배포하기 전에 별도의 환경에서 새로운 기능이나 변경 사항을 테스트할 수 있습니다.
|
||||
|
||||
또한, 특정 슬롯으로 **트래픽의 비율을 라우팅**할 수 있어 A/B 테스트 및 **백도어 목적**에 유용합니다.
|
||||
|
||||
## Azure Function Apps
|
||||
|
||||
기본적으로 **Azure Function 앱은 Azure App Service의 하위 집합**입니다. 웹 콘솔에 가서 모든 앱 서비스를 나열하거나 az cli에서 `az webapp list`를 실행하면 **Function 앱도 나열된 것을 볼 수 있습니다**.
|
||||
|
||||
따라서 두 서비스는 실제로 대부분 **같은 구성, 기능 및 옵션을 az cli에서 가지고 있으며**, 약간 다르게 구성할 수 있습니다(예: appsettings의 기본값 또는 Function 앱에서 스토리지 계정의 사용).
|
||||
|
||||
## 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 }}
|
||||
|
||||
#### 자격 증명 얻기 및 웹앱 코드에 접근하기
|
||||
```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}}
|
||||
|
||||
## 웹 앱 생성 예제
|
||||
|
||||
### 로컬에서 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`를 볼 수 있습니다.
|
||||
|
||||
> [!TIP]
|
||||
> FTP를 통해 연결하고 파일 `output.tar.gz`를 수정하는 것만으로는 웹앱에서 실행되는 코드를 변경할 수 없습니다.
|
||||
|
||||
**공격자는 이 파일을 다운로드하여 수정한 후 다시 업로드하여 웹앱에서 임의의 코드를 실행할 수 있습니다.**
|
||||
|
||||
### Github의 Python
|
||||
|
||||
이 튜토리얼은 이전 튜토리얼을 기반으로 하지만 Github 리포지토리를 사용합니다.
|
||||
|
||||
1. Github 계정에서 msdocs-python-flask-webapp-quickstart 리포를 포크합니다.
|
||||
2. Azure에서 새로운 Python 웹 앱을 생성합니다.
|
||||
3. `Deployment Center`에서 소스를 변경하고, Github로 로그인한 후 포크한 리포를 선택하고 `Save`를 클릭합니다.
|
||||
|
||||
이전 경우와 마찬가지로 SCM 포털에 로그인하거나 FTP를 통해 로그인하면 `/wwwroot`에서 웹앱의 코드를 포함하는 압축 파일 `output.tar.gz`를 볼 수 있습니다.
|
||||
|
||||
> [!TIP]
|
||||
> FTP를 통해 연결하고 파일 `output.tar.gz`를 수정한 후 배포를 다시 트리거하는 것만으로는 웹앱에서 실행되는 코드를 변경할 수 없습니다.
|
||||
|
||||
## 권한 상승
|
||||
|
||||
{{#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