SOC Prime Bias: 높음

20 May 2026 22:10 UTC

Storm-2949, 손상된 아이덴티티를 클라우드 전체 침해로 전환한 방법

Author Photo
SOC Prime Team linkedin icon 팔로우
Storm-2949, 손상된 아이덴티티를 클라우드 전체 침해로 전환한 방법
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

요약

Storm-2949는 사회공학과 자체 비밀번호 재설정 사용을 악용하여 Microsoft Entra ID 계정을 탈취했습니다. 특권 접근을 획득한 후, 위협 행위자는 Azure 관리-평면 액션을 사용하여 App Services, Key Vaults, Storage 계정 및 SQL 데이터베이스에 접근했습니다. 그 후 Microsoft 365, Azure 스토리지 및 기타 클라우드 리소스에서 데이터를 유출했습니다. 침입은 이후 ScreenConnect 원격 접근 도구를 가상 머신에 배포하여 추가 정찰 및 자격 증명 탈취를 지원하는 단계로 진행되었습니다.

조사

Microsoft 분석은 공격자가 사용자 및 애플리케이션을 나열하기 위해 Microsoft Graph API를 사용자 정의 Python 도구와 함께 사용한 것을 관찰했습니다. 그들은 Azure App Services에서 게시 프로파일을 가져오고 Key Vaults에서 비밀을 추출했으며, 방화벽 규칙을 변경하고 VMAccess 확장을 사용하여 가상 머신에서 로컬 관리자 계정을 생성했습니다. 이후 단계에서는 PowerShell 스크립트가 ScreenConnect를 설치하고 로그를 지우고 서비스를 위장하여 가시성을 줄였습니다. 이 조사는 이 활동을 세 개의 공격자 제어 IP 주소와 연결시켰습니다.

완화 전략

조직은 MFA를 활성화하고 특권 계정에 대해 피싱 저항 인증을 요구해야 합니다. Azure RBAC 권한은 특히 Key Vaults 및 App Services의 소유자 수준 접근에 대해 엄격하게 제한 및 모니터링되어야 합니다. 불필요한 Azure VM 확장은 비활성화하고, Run Command 및 VMAccess 활동에 대한 로깅이 강제되어야 합니다. 또한 Microsoft Defender for Cloud와 Defender for Endpoint는 변조 방지 및 차단 모드로 활성화되어야 합니다.

대응

방어자는 즉시 확인된 악성 IP 주소를 차단하고 손상된 자격 증명을 철회해야 합니다. 영향을 받은 계정의 비밀번호 및 MFA 등록을 재설정하고 Key Vaults에 저장된 모든 비밀을 회전시켜야 합니다. 보안 팀은 또한 Azure RBAC 할당 전반에 대한 전면 검토를 수행하고 과도한 권한을 제거해야 합니다. 의심스러운 게시 프로파일 요청, Key Vault 비밀 접근, 예기치 않은 VM 확장 활동을 식별하기 위해 탐지 규칙을 업데이트해야 합니다.

공격 흐름

시뮬레이션 실행

필수요건: Telemetry & Baseline 선행 검사가 통과해야 합니다.

  • 공격 내러티브 및 명령어:

    유효한 Azure AD 계정(또는 기본 서비스 주체)을 얻은 적대자는 애플리케이션 소스 코드 및 데이터베이스 스냅샷을 유출하고자 합니다. 공격자는 다음 단계를 전적으로 Azure CLI를 통해 수행하며, 정확한 operationName 이벤트를 생성합니다 이 규칙은 감시합니다:

    1. 웹 앱 XML 게시 – 웹 앱 설정(배포 자격 증명 포함)을 추출합니다.
    2. 새로운 스토리지 계정 생성 – 유출 데이터를 임시 저장할 컨테이너를 제공합니다.
    3. SQL 서버에 방화벽 규칙 추가 – 서버를 공격자의 IP 범위로 열어 직접 데이터를 복사할 수 있습니다.

    각 단계는 operationName 룰의 화이트리스트와 매치되는

  • 회귀 테스트 스크립트:

    #!/usr/bin/env bash
    # 필수 요건: az CLI는 손상된/유효한 Azure AD 주체로 로그인되어 있어야 합니다.
    set -euo pipefail
    
    # 변수 – 테스트 테넌트에 맞게 필요에 따라 수정하십시오
    RG="test-rg-$(date +%s)"
    WEBAPP="test-webapp-$RANDOM"
    STORAGE="teststorage$RANDOM"
    LOCATION="eastus"
    SQLSERVER="testsql$RANDOM"
    MY_IP=$(curl -s https://api.ipify.org)
    
    echo "=== 리소스 그룹 생성 ==="
    az group create --name "$RG" --location "$LOCATION"
    
    echo "=== 더미 웹 앱 배포 ==="
    az appservice plan create --name "${WEBAPP}Plan" --resource-group "$RG" --sku B1 --is-linux
    az webapp create --resource-group "$RG" --plan "${WEBAPP}Plan" --name "$WEBAPP"
    
    echo "=== XML 설정 게시 (탐지 트리거) ==="
    az webapp config backup create 
        --resource-group "$RG" 
        --webapp-name "$WEBAPP" 
        --backup-name "xmlbackup-$(date +%s)" 
        --output none
    
    echo "=== 스토리지 계정 생성 (탐지 트리거) ==="
    az storage account create 
        --name "$STORAGE" 
        --resource-group "$RG" 
        --location "$LOCATION" 
        --sku Standard_LRS 
        --kind StorageV2 
        --output none
    
    echo "=== SQL 서버 생성 (방화벽 규칙에 필요) ==="
    az sql server create 
        --name "$SQLSERVER" 
        --resource-group "$RG" 
        --location "$LOCATION" 
        --admin-user "sqladmin" 
        --admin-password "P@ssw0rd1234!" 
        --output none
    
    echo "=== SQL 서버에 방화벽 규칙 추가 (탐지 트리거) ==="
    az sql server firewall-rule create 
        --resource-group "$RG" 
        --server "$SQLSERVER" 
        --name "AllowMyIP" 
        --start-ip-address "$MY_IP" 
        --end-ip-address "$MY_IP" 
        --output none
    
    echo "=== 시뮬레이션 완료. Azure Sentinel에서 경고 확인하십시오. ==="
  • 정리 명령어:

    #!/usr/bin/env bash
    set -euo pipefail
    
    # 시뮬레이션 스크립트에서 사용한 변수는 동일해야 합니다
    RG="test-rg-..."
    # 이전 실행에서 정확한 이름을 유지한 경우, 플레이스홀더를 적절히 대체하십시오.
    
    echo "=== 리소스 그룹 및 모든 포함된 리소스 삭제 ==="
    az group delete --name "$RG" --yes --no-wait
    echo "정리 시작."