| Attribute | Details | |—|—| | Technique ID | COLLECT-METADATA-001 | | Technique Name | SharePoint Metadata Collection | | MITRE ATT&CK v18.1 | T1123 – Audio Capture | | Tactic | Collection (TA0009) | | Platforms | Microsoft 365, SharePoint Online, OneDrive for Business | | Severity | High | | Technique Status | ACTIVE | | Last Verified | 2026-01-10 | | Affected Versions | SharePoint Online (Microsoft 365), OneDrive for Business, Microsoft 365 E3/E5 tenants | | Patched In | Not applicable – relies on legitimate SharePoint/Graph APIs and user permissions | | Author | SERVTEP – Artur Pchelnikau |
| Framework | Control / ID | Description | |—|—|—| | CIS Microsoft 365 | CIS O365 3.1, 3.4 | Restrict high‑privilege accounts and monitor access to SharePoint/OneDrive data and audit logs. | | DISA STIG (O365/SharePoint) | O365-SP-000020 | Ensure auditing is enabled and access to sensitive sites is monitored and restricted. | | CISA SCuBA | M365-SPO-LOG-1 | Enable and retain SharePoint Online activity logging for security investigations. | | NIST 800-53 | AC-6, AU-6, AU-12 | Least privilege for data access; audit review and analysis; centralized logging of data access. | | GDPR | Art. 5, Art. 32 | Data minimization and integrity/confidentiality of personal data; appropriate security logging and monitoring. | | DORA | Art. 9, Art. 11 | Logging, monitoring, and ICT security controls for critical data repositories. | | NIS2 | Art. 21 | Technical and organizational measures for risk management and incident handling for critical services. | | ISO 27001 | A.8.12, A.8.16, A.12.4 | Protection of data at rest/in use; monitoring and logging of system activities. | | ISO 27005 | Data Discovery Risk Scenario | Exposure of data‑location metadata enabling targeted exfiltration of sensitive repositories. |
*.sharepoint.com, graph.microsoft.com, and login.microsoftonline.com from attacker host.Supported Versions:
# Check if PnP.PowerShell is installed
Get-Module -ListAvailable PnP.PowerShell
# Install if missing (requires admin on the management host)
Install-Module PnP.PowerShell -Scope CurrentUser -Force
# Test connectivity and consent to a target site
$SiteUrl = "https://<tenant>.sharepoint.com/sites/<target-site>"
Connect-PnPOnline -Url $SiteUrl -Interactive
# Enumerate lists and libraries to confirm access
Get-PnPList | Select Title, BaseType, Hidden, ItemCount
What to Look For:
Documents, Records, HR, Finance, Legal with significant ItemCount.Version Note:
Command (Legacy Windows PowerShell – classic module):
Install-Module SharePointPnPPowerShellOnline -Scope CurrentUser
Connect-PnPOnline -Url $SiteUrl -UseWebLogin
Get-PnPList | Select Title, BaseType, Hidden, ItemCount
Command (PowerShell 7+ with PnP.PowerShell):
Install-Module PnP.PowerShell -Scope CurrentUser -Force
Connect-PnPOnline -Url $SiteUrl -Interactive
Get-PnPList | Select Title, BaseTemplate, ItemCount
# Using Microsoft Graph CLI (mgc)
mgc login --scopes "Sites.Read.All Files.Read.All"
# List SharePoint sites the account can see
mgc sites list --search "SharePoint"
# Enumerate lists for a given site
mgc sites list --site-id <site-id>
mgc sites list list --site-id <site-id>
What to Look For:
M&A, R&D, Board, Finance).Supported Versions: SharePoint Online, OneDrive for Business, Microsoft 365 (all modern tenants).
Objective: Establish a session to SharePoint Online and discover candidate sites for metadata harvesting.
Command (interactive):
# Install/Import module
Install-Module PnP.PowerShell -Scope CurrentUser -Force
Import-Module PnP.PowerShell
# Connect to the admin center
$AdminUrl = "https://<tenant>-admin.sharepoint.com"
Connect-PnPOnline -Url $AdminUrl -Interactive
# Enumerate all site collections
$Sites = Get-PnPTenantSite | Select Url, Template, Owner, StorageUsageCurrent
$Sites | Export-Csv "C:\Temp\SPO_Sites.csv" -NoTypeInformation
Expected Output:
What This Means:
OpSec & Evasion:
Troubleshooting:
The remote server returned an error: (401) Unauthorized
References & Proofs:
Get-PnPTenantSite documentation.Objective: Export detailed metadata from document libraries (paths, size, authors, labels) without touching file content.
Command:
$SiteUrl = "https://<tenant>.sharepoint.com/sites/Finance"
$ListName = "Documents" # or specific library
$OutFile = "C:\Temp\Finance_Doc_Metadata.csv"
Connect-PnPOnline -Url $SiteUrl -Interactive
# Export selected metadata fields
$Items = Get-PnPListItem -List $ListName -PageSize 500 -Fields "FileLeafRef","FileRef","Created","Modified","Author","Editor","File_x0020_Size","SensitivityLabel"
$Results = $Items | ForEach-Object {
$fv = $_.FieldValues
[PSCustomObject]@{
FileName = $fv.FileLeafRef
FileUrl = $fv.FileRef
Created = $fv.Created
Modified = $fv.Modified
Author = $fv.Author.LookupValue
Editor = $fv.Editor.LookupValue
FileSize = $fv."File_x0020_Size"
Label = $fv.SensitivityLabel
}
}
$Results | Export-Csv -Path $OutFile -NoTypeInformation -Encoding UTF8
Expected Output:
What This Means:
OpSec & Evasion:
-PageSize and Start-Sleep) to avoid sudden spikes in SharePoint/Graph activity.Troubleshooting:
Cannot find a list with the Name Documents
Shared Documents, localized names).Get-PnPList | Select Title, RootFolder to identify actual titles.The attempted operation is prohibited because it exceeds the list view threshold
-PageSize and CAML queries to segment the dataset (e.g., by Created date) or use Graph API which does not enforce the same threshold.References & Proofs:
Get-PnPListItem and list export examples.Objective: Operationalize continuous metadata collection for change tracking and targeting.
Command (runbook pattern):
# Pseudo-code for Azure Automation / scheduled job
$TenantAdminUrl = "https://<tenant>-admin.sharepoint.com"
$OutputFolder = "C:\Exports\SPO_Metadata\" # or Azure Files / Blob
Connect-PnPOnline -Url $TenantAdminUrl -ClientId $AppId -CertificatePath "cert.pfx" -Tenant "<tenant>.onmicrosoft.com"
$Sites = Get-PnPTenantSite | Where-Object { $_.Template -eq "GROUP#0" -or $_.Template -eq "SITEPAGEPUBLISHING#0" }
foreach ($s in $Sites) {
Connect-PnPOnline -Url $s.Url -ClientId $AppId -CertificatePath "cert.pfx" -Tenant "<tenant>.onmicrosoft.com"
$lists = Get-PnPList | Where-Object { $_.BaseType -eq "DocumentLibrary" -and -not $_.Hidden }
foreach ($l in $lists) {
# Similar export logic as Step 2
# Export CSV per library and append to central dataset
}
}
Expected Output:
What This Means:
Supported Versions: SharePoint Online, OneDrive for Business; Microsoft Graph v1.0.
Objective: Use Microsoft Graph to enumerate sites and lists in a way that blends into other Graph‑based workloads.
Command (REST):
GET https://graph.microsoft.com/v1.0/sites?search={tenantName}
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists
Command (PowerShell with Graph SDK):
Connect-MgGraph -Scopes "Sites.Read.All","Files.Read.All"
Select-MgProfile -Name beta # or v1.0 where sufficient
# List sites
Get-MgSite -Search "sharepoint" | Select-Object Id, Name, WebUrl
# List all lists in a site
Get-MgSiteList -SiteId <site-id> | Select-Object Id, DisplayName, List*
Expected Output:
Objective: Retrieve listItem objects including their field sets (metadata) without fetching file content.
Command (REST):
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields
Command (PowerShell):
$siteId = "<site-id>"
$listId = "<list-id>"
$items = Invoke-MgGraphRequest -Method GET -Uri "/sites/$siteId/lists/$listId/items?`$expand=fields"
$items.value | ForEach-Object {
[PSCustomObject]@{
ItemId = $_.id
Title = $_.fields.Title
Path = $_.fields.FileRef
Author = $_.fields.Author
Editor = $_.fields.Editor
Created = $_.fields.Created
Modified = $_.fields.Modified
}
} | Export-Csv "C:\Temp\Graph_List_Metadata.csv" -NoTypeInformation
Expected Output:
OpSec & Evasion:
References & Proofs:
Objective: Correlate who accessed what (Graph Activity Log / Purview Unified Audit Log) with exported metadata to prioritize targets and hide in normal patterns.
High‑Level Steps:
FileAccessed, FileDownloaded, FileModified events for target sites.References & Proofs:
Execution Example (PowerShell atomic):
# Requires Atomic Red Team framework
Invoke-AtomicTest T1123 -TestNumbers 1
Cleanup Command:
Invoke-AtomicTest T1123 -TestNumbers 1 -Cleanup
Reference:
Note: There is no dedicated Atomic test for SharePoint Online metadata collection. For SaaS techniques, simulate collection by executing the PnP/Graph scripts in a controlled lab tenant, then verify that logging and detection components (Sentinel, Splunk, Purview) behave as expected.
Version: Current 2.x line. Minimum Version: 1.12+ for modern SharePoint Online support. Supported Platforms: Windows PowerShell 5.1, PowerShell 7.x on Windows/Linux/macOS.
Version-Specific Notes:
Installation:
Install-Module PnP.PowerShell -Scope CurrentUser -Force
Import-Module PnP.PowerShell
Usage (List Metadata Export):
Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/<site>" -Interactive
Get-PnPListItem -List "Documents" -PageSize 500 -Fields "FileLeafRef","FileRef" |
Select-Object @{n='FileName';e={$_.FieldValues.FileLeafRef}},
@{n='Url';e={$_.FieldValues.FileRef}} |
Export-Csv "C:\Temp\Doc_Metadata.csv" -NoTypeInformation
Version: 2.x. Minimum Version: 1.x. Supported Platforms: PowerShell 5.1 and 7.x on all major OSes.
Installation:
Install-Module Microsoft.Graph -Scope CurrentUser -Force
Import-Module Microsoft.Graph
Usage:
Connect-MgGraph -Scopes "Sites.Read.All","Files.Read.All"
Get-MgSite -Search "Finance" | Select-Object Id, Name, WebUrl
Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/<site>" -Interactive; `
Get-PnPListItem -List "Documents" -PageSize 500 -Fields "FileLeafRef","FileRef","Created","Author" | `
ForEach-Object { [PSCustomObject]@{ FileName=$_.FieldValues.FileLeafRef; Url=$_.FieldValues.FileRef; Created=$_.FieldValues.Created; Author=$_.FieldValues.Author.LookupValue } } | `
Export-Csv "C:\Temp\Quick_Metadata.csv" -NoTypeInformation
Rule Configuration:
o365, wineventlog (or equivalent for Microsoft 365 and endpoint logs).o365:sharepoint, WinEventLog:Security or Sysmon if forwarded.Operation, UserId, ClientIP, UserAgent, CommandLine.SPL Query (SharePoint side – heavy FileAccessed operations without downloads):
index=o365 sourcetype="o365:sharepoint"
| where Operation IN ("FileAccessed","FilePreviewed") AND isnull(ObjectId) = 0
| stats count AS AccessCount, values(ObjectId) AS Files, values(ClientIP) AS ClientIPs BY UserId
| where AccessCount > 200
| sort - AccessCount
SPL Query (Endpoint side – PowerShell automation targeting SharePoint/Graph):
index=wineventlog (sourcetype="WinEventLog:Security" OR sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational")
| search (CommandLine="*Connect-PnPOnline*" OR CommandLine="*Get-PnPListItem*" OR CommandLine="*graph.microsoft.com*sites*")
| stats count BY Account_Name, ComputerName, CommandLine
| where count > 50
What This Detects:
Manual Configuration Steps:
svc_backup*, svc_migration*).Rule Configuration:
OfficeActivity (or SharePointOnline/Graph Activity Log table in the data lake).Operation, OfficeWorkload, UserId, ClientIP, OfficeObjectId.KQL Query:
OfficeActivity
| where TimeGenerated > ago(1h)
| where OfficeWorkload == "SharePoint" and Operation in ("FileAccessed", "FilePreviewed")
| summarize AccessCount = count(), Files = make_set(OfficeObjectId, 50) by UserId, ClientIP
| where AccessCount > 200
| extend EntityType = "Account", AccountCustomEntity = UserId
What This Detects:
Manual Configuration Steps (Azure Portal):
High-Volume SharePoint Metadata Access and Severity to High.Rule Configuration:
DeviceProcessEvents (M365 Defender) or SecurityEvent/Sysmon if forwarded.ProcessCommandLine, AccountName, DeviceName.KQL (M365 Defender style):
DeviceProcessEvents
| where Timestamp > ago(1h)
| where FileName =~ "powershell.exe"
| where ProcessCommandLine has_any ("Connect-PnPOnline", "Get-PnPListItem", "graph.microsoft.com/v1.0/sites")
| summarize CmdCount = count(), examples = make_set(ProcessCommandLine, 10) by AccountName, DeviceName
| where CmdCount > 20
What This Detects:
Although SharePoint Online is a cloud service, the collection tooling often runs on Windows endpoints (admin workstations, jump servers, automation hosts). Monitoring these endpoints provides additional visibility.
Event ID: 4688 (New Process Created)
NewProcessName = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" AND CommandLine contains Connect-PnPOnline or Get-PnPListItem.Manual Configuration Steps (Group Policy):
gpmc.msc).gpupdate /force.Manual Configuration Steps (Local Policy):
secpol.msc).auditpol:
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
Minimum Sysmon Version: 13.0+ Supported Platforms: Windows 10/11, Windows Server 2016+.
<Sysmon schemaversion="4.82">
<EventFiltering>
<ProcessCreate onmatch="include">
<CommandLine condition="contains">Connect-PnPOnline</CommandLine>
<CommandLine condition="contains">Get-PnPListItem</CommandLine>
<CommandLine condition="contains">graph.microsoft.com/v1.0/sites</CommandLine>
</ProcessCreate>
</EventFiltering>
</Sysmon>
Manual Configuration Steps:
sysmon-spo-metadata.xml.sysmon64.exe -accepteula -i sysmon-spo-metadata.xml
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 20 |
Where-Object { $_.Message -like '*Connect-PnPOnline*' -or $_.Message -like '*Get-PnPListItem*' }
For SharePoint Online and OneDrive, the more relevant components are Microsoft Defender for Office 365 and Defender for Cloud Apps (formerly MCAS). However, when Defender for Cloud ingests Microsoft 365 data, it can surface alerts correlated with suspicious Graph/SharePoint activity.
Manual Configuration Steps (Enable Defender plans):
# Connect to Exchange Online / Purview
Connect-ExchangeOnline
$Start = (Get-Date).AddDays(-7)
$End = Get-Date
$Site = "https://<tenant>.sharepoint.com/sites/Finance"
Search-UnifiedAuditLog -StartDate $Start -EndDate $End `
-Operations FileAccessed,FileDownloaded,FilePreviewed `
-ResultSize 5000 `
| Where-Object { $_.AuditData -like "*${Site}*" } |
Export-Csv "C:\Temp\Finance_Audit.csv" -NoTypeInformation
FileAccessed, FileDownloaded, FilePreviewed.SharePoint / OneDrive.AuditData JSON contains site URL, file URL, user, IP, and client details.Manual Configuration Steps (Enable Unified Audit Log):
Manual Configuration Steps (Search Audit Logs):
PowerShell Alternative (Bulk Export):
Connect-ExchangeOnline
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) `
-Operations FileAccessed,FileDownloaded,FilePreviewed |
Export-Csv "C:\Temp\SPO_FileOps.csv" -NoTypeInformation
Action 1: Enforce Least‑Privilege Access to SharePoint Sites and Libraries
Manual Steps (SharePoint Admin Center – web):
Manual Steps (PowerShell – PnP):
Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/Finance" -Interactive
Get-PnPGroup -AssociatedOwnerGroup | Get-PnPGroupMember
# Remove high-risk accounts
Remove-PnPGroupMember -Identity "Finance Owners" -LoginName "user@tenant.onmicrosoft.com"
Action 2: Restrict App‑Only Permissions to Sites.Selected
Manual Steps (Azure Portal):
# Example (simplified): grant app access to a single site
Connect-PnPOnline -Url "https://<tenant>.sharepoint.com" -Interactive
Grant-PnPAzureADAppSitePermission -AppId <AppId> -DisplayName "MetadataApp" -Site "https://<tenant>.sharepoint.com/sites/Finance" -Permissions Read
Action: Monitor and Control Mass Access via Defender for Cloud Apps
Conditional Access:
Manual Steps:
CA-SharePoint-Admins-Only-From-Trusted-Locations.Office 365 SharePoint Online.RBAC/ABAC:
Validation Command (Verify Fix):
# List apps with high-privilege SharePoint Graph scopes
Connect-MgGraph -Scopes "Directory.Read.All,Application.Read.All"
Get-MgServicePrincipal -Filter "appId eq '<AppId>'" | Get-MgOauth2PermissionGrant
Expected Output (If Secure):
C:\Temp\SPO_Sites.csv, C:\Temp\Finance_Doc_Metadata.csv.graph.microsoft.com and *.sharepoint.com from atypical IPs or devices.Connect-PnPOnline, Get-PnPListItem, Search-UnifiedAuditLog commands.FileAccessed, FilePreviewed, SearchUnifieAuditLog and Graph Activity Log records for large SharePoint enumerations.# Temporarily disable network adapter on suspected admin workstation
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
# Export Security and Sysmon logs
wevtutil epl Security C:\Evidence\Security.evtx
wevtutil epl "Microsoft-Windows-Sysmon/Operational" C:\Evidence\Sysmon.evtx
# Export PowerShell operational logs
wevtutil epl "Microsoft-Windows-PowerShell/Operational" C:\Evidence\PSOperational.evtx
# Preserve exported metadata files
Copy-Item "C:\Temp\*Metadata*.csv" C:\Evidence\ -Force
Connect-ExchangeOnline
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) `
-UserIds <suspicious-user@tenant.onmicrosoft.com> `
-ResultSize 5000 |
Export-Csv "C:\Evidence\UnifiedAudit_SPO.csv" -NoTypeInformation
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | IA-PHISH-001 – Device code phishing attacks | Adversary gains user or admin access to Microsoft 365. |
| 2 | Privilege Escalation | PE-ACCTMGMT-003 – SharePoint Site Collection Admin | Compromise or abuse of SharePoint admin rights. |
| 3 | Current Step | COLLECT-METADATA-001 – SharePoint Metadata Collection | Systematic metadata crawl of SharePoint/OneDrive sites. |
| 4 | Collection & Exfiltration | CA-UNSC-006 – Private keys theft / CA-UNSC-014 – SaaS API key exposure | Use metadata to identify high‑value stores and exfiltrate content with keys/tokens. |
| 5 | Impact | REALWORLD-003 – POP/IMAP Basic Auth Abuse / REALWORLD-004 – Legacy API Brute Force | Leverage knowledge of repositories for targeted extortion, ransomware, or data‑leak campaigns. |