Az - App Services

Reading time: 13 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

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개의 마운트를 생성할 수 있습니다. 구성은 스토리지 계정에 대한 액세스 키를 저장합니다.
  • 네트워킹: 공개적으로 사용 가능하거나 VNet의 개인 엔드포인트만 접근할 수 있습니다.

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을 통해 접근할 수 있습니다.

App Services와 Function Apps에서 사용되는 Kudu 버전은 다르며, Function Apps의 버전은 훨씬 더 제한적입니다.

Kudu에서 찾을 수 있는 몇 가지 흥미로운 엔드포인트는 다음과 같습니다:

  • /BasicAuth: Kudu에 로그인하기 위해 이 경로에 접근해야 합니다.
  • /DebugConsole: Kudu가 실행되고 있는 환경에서 명령을 실행할 수 있는 콘솔입니다.
  • 이 환경은 메타데이터 서비스에 접근할 수 없습니다.
  • /webssh/host: 앱이 실행되고 있는 컨테이너 내에 연결할 수 있는 웹 기반 SSH 클라이언트입니다.
  • 이 환경은 할당된 관리 ID로부터 토큰을 얻기 위해 메타데이터 서비스에 접근할 수 있습니다.
  • /Env: 시스템, 앱 설정, 환경 변수, 연결 문자열 및 HTTP 헤더에 대한 정보를 가져옵니다.
  • /wwwroot/: 웹 앱의 루트 디렉토리입니다. 여기에서 모든 파일을 다운로드할 수 있습니다.

또한, Kudu는 https://github.com/projectkudu/kudu에서 오픈 소스였으나, 프로젝트가 중단되었으며 현재 Azure의 Kudu와 이전 Kudu의 동작을 비교하면 여러 가지가 이미 변경되었음을 알 수 있습니다.

Sources

App Services는 기본적으로 코드를 zip 파일로 업로드할 수 있도록 허용하지만, 타사 서비스에 연결하여 그곳에서 코드를 가져오는 것도 허용합니다.

  • 현재 지원되는 타사 소스는 GithubBitbucket입니다.
  • 인증 토큰을 얻으려면 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

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 git URL to access the code
az webapp deployment source config-local-git --resource-group <res-group> -n <name>

# 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>

# Get configured SMC users by your account
az webapp deployment user show
## If any user is created, the username should appear in the "publishingUserName" field

Az - App Services Privesc

웹 앱 생성 예제

로컬에서 Python 사용

이 튜토리얼은 https://learn.microsoft.com/en-us/azure/app-service/quickstart-python에서 제공된 내용을 기반으로 합니다.

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를 수정한 후 배포를 다시 트리거하는 것만으로는 웹앱에서 실행되는 코드를 변경할 수 없습니다.

권한 상승

Az - App Services Privesc

참조

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기