Data from Information Repositories
Adversaries may leverage information repositories to mine valuable information. Information repositories are tools that allow for storage of information, typically to facilitate collaboration or information sharing between users, and can store a wide variety of data that may aid adversaries in further objectives, such as Credential Access, Lateral Movement, or Defense Evasion. Targets include SharePoint, Confluence, code repositories, CRM systems, databases, and messaging platforms such as Slack and Microsoft Teams. Adversaries may harvest credentials, network diagrams, system architecture documentation, PII, or source code from these repositories. Cloud-native services (AWS RDS, ElasticSearch, Redis) may also be improperly secured, enabling unauthenticated access to sensitive data stores.
What is T1213 Data from Information Repositories?
Data from Information Repositories (T1213) maps to the Collection tactic — the adversary is trying to gather data of interest to their goal in MITRE ATT&CK.
This page provides production-ready detection logic for Data from Information Repositories, covering the data sources and telemetry it touches: Application Log: Application Log Content, Cloud Service: Cloud Service Enumeration, Microsoft 365 Unified Audit Log, SharePoint Audit Logs, OneDrive Audit Logs. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Collection
- Technique
- T1213 Data from Information Repositories
- Canonical reference
- https://attack.mitre.org/techniques/T1213/
// Detect bulk document access / data mining from SharePoint, OneDrive, and Microsoft Teams
let BulkAccessThreshold = 50;
let SensitiveKeywords = dynamic(["password", "credential", "secret", "vpn", "firewall", "network diagram",
"architecture", "api key", "token", "private key", "ssn", "social security",
"salary", "payroll", "customer data", "pii", "database", "connection string"]);
let TimeWindow = 1h;
// Branch 1: Bulk file access / download from SharePoint or OneDrive
let BulkAccess =
OfficeActivity
| where TimeGenerated > ago(24h)
| where Workload in ("SharePoint", "OneDrive")
| where Operation in ("FileDownloaded", "FileSyncDownloadedFull", "FileAccessed", "FilePreviewed", "FileSyncUploadedFull")
| summarize
OperationCount = count(),
UniqueFiles = dcount(OfficeObjectId),
UniqueExtensions = dcount(tostring(split(OfficeObjectId, ".")[-1])),
Operations = make_set(Operation, 10),
SourceIPs = make_set(ClientIP, 10),
SiteUrls = make_set(Site_Url, 10),
EarliestAccess = min(TimeGenerated),
LatestAccess = max(TimeGenerated)
by UserId, bin(TimeGenerated, TimeWindow)
| where OperationCount >= BulkAccessThreshold
| extend AccessDurationMinutes = datetime_diff('minute', LatestAccess, EarliestAccess)
| extend FilesPerMinute = iff(AccessDurationMinutes > 0, toreal(UniqueFiles) / toreal(AccessDurationMinutes), toreal(UniqueFiles))
| extend DetectionType = "BulkFileAccess"
| project TimeGenerated, UserId, DetectionType, OperationCount, UniqueFiles, FilesPerMinute, Operations, SourceIPs, SiteUrls;
// Branch 2: Sensitive keyword searches in SharePoint
let SensitiveSearch =
OfficeActivity
| where TimeGenerated > ago(24h)
| where Workload == "SharePoint"
| where Operation == "SearchQueryPerformed"
| where tolower(tostring(SearchQuery)) has_any (SensitiveKeywords)
| summarize
SearchCount = count(),
UniqueQueries = dcount(SearchQuery),
QuerySamples = make_set(SearchQuery, 5),
SourceIPs = make_set(ClientIP, 5)
by UserId, bin(TimeGenerated, TimeWindow)
| extend DetectionType = "SensitiveKeywordSearch"
| extend OperationCount = SearchCount
| project TimeGenerated, UserId, DetectionType, OperationCount, UniqueQueries, QuerySamples, SourceIPs;
// Branch 3: External sharing of documents from SharePoint/OneDrive
let ExternalSharing =
OfficeActivity
| where TimeGenerated > ago(24h)
| where Workload in ("SharePoint", "OneDrive")
| where Operation in ("SharingInvitationCreated", "AnonymousLinkCreated", "SecureLinkCreated", "AddedToSecureLink")
| extend IsExternalShare = ExternalAccess == true or Operation == "AnonymousLinkCreated"
| where IsExternalShare == true
| summarize
ShareCount = count(),
UniqueFiles = dcount(OfficeObjectId),
TargetAccounts = make_set(TargetUserOrGroupName, 10),
SiteUrls = make_set(Site_Url, 5)
by UserId, bin(TimeGenerated, TimeWindow)
| where ShareCount >= 5
| extend DetectionType = "BulkExternalSharing"
| extend OperationCount = ShareCount
| project TimeGenerated, UserId, DetectionType, OperationCount, UniqueFiles, TargetAccounts, SiteUrls;
// Union all branches
BulkAccess
| union SensitiveSearch
| union ExternalSharing
| sort by OperationCount desc Detects data mining from information repositories across three detection branches: (1) Bulk file access/download from SharePoint or OneDrive exceeding 50 operations per hour, indicating automated or manual mass data harvesting; (2) SharePoint searches containing sensitive keywords such as 'password', 'credential', 'vpn', 'api key', or 'pii', indicating targeted reconnaissance; (3) Bulk external sharing of documents, indicating potential exfiltration via sharing features. Uses OfficeActivity table which captures M365 audit logs including SharePoint, OneDrive, and Teams workloads.
Data Sources
Required Tables
False Positives
- Migration projects — IT teams or contractors using tools like ShareGate or AvePoint to migrate SharePoint content generate extremely high file access counts
- Backup and archival solutions — tools like Veeam, AvePoint Backup, or native SharePoint backup solutions download all files regularly
- Legitimate enterprise search indexing — search crawlers or content indexing services authorized by IT generate bulk FileAccessed events
- Legal eDiscovery — compliance officers performing court-ordered or internal investigation eDiscovery searches may access large volumes of documents and use sensitive keywords
- Data loss prevention (DLP) scanning tools — DLP platforms that scan SharePoint for sensitive content will trigger both bulk access and sensitive keyword detections
Sigma rule & cross-platform mapping
The detection logic for Data from Information Repositories (T1213) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
product: azure Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for T1213
References (10)
- https://attack.mitre.org/techniques/T1213/
- https://learn.microsoft.com/en-us/microsoft-365/compliance/search-the-audit-log-in-security-and-compliance
- https://learn.microsoft.com/en-us/microsoft-365/compliance/use-sharing-auditing?view=o365-worldwide
- https://support.office.com/en-us/article/configure-audit-settings-for-a-site-collection-a9920c97-38c0-44f2-8bcb-4cf1e2ae22d2
- https://confluence.atlassian.com/confkb/how-to-enable-user-access-logging-182943.html
- https://learn.microsoft.com/en-us/graph/teams-list-all-teams
- https://www.mitiga.io/blog/how-mitiga-found-pii-in-exposed-amazon-rds-snapshots
- https://www.trendmicro.com/en_us/research/20/d/exposed-redis-instances-abused-for-remote-code-execution-cryptocurrency-mining.html
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1213/T1213.md
- https://learn.microsoft.com/en-us/defender-cloud-apps/what-is-defender-for-cloud-apps
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Bulk SharePoint Document Download via PnP PowerShell
Expected signal: OfficeActivity events: Operation=FileDownloaded for each downloaded file, Workload=SharePoint, UserId=authenticated user UPN, ClientIP=executing machine IP. Azure AD SigninLogs: interactive authentication event for the SharePoint OAuth flow. Sysmon Event ID 1: Process Create for powershell.exe with PnP module loading.
- Test 2SharePoint Sensitive Keyword Search via REST API
Expected signal: OfficeActivity events: Operation=SearchQueryPerformed for each API search call, with SearchQuery field containing the sensitive keyword, Workload=SharePoint, UserId=authenticated user. Multiple events in quick succession for each term searched.
- Test 3Confluence REST API Page Enumeration and Export
Expected signal: Confluence access logs (atlassian-confluence.log): GET requests to /wiki/rest/api/space and /wiki/rest/api/search endpoints with user authentication. If Confluence audit logging is enabled: search events appear in Administration > Audit Log. Network proxy logs: HTTP requests to the Confluence FQDN with search query parameters visible in URL.
- Test 4Microsoft Teams Message Export via Graph API
Expected signal: OfficeActivity events: Operation=MessageRead or similar Teams audit events, Workload=MicrosoftTeams. Azure AD SigninLogs: token acquisition for Graph API with Teams scopes. AuditLogs: Microsoft Graph API calls for Team and ChannelMessage read operations. Microsoft Defender for Cloud Apps: Graph API activity anomaly if CASB is configured.
Response Playbook
Triage
- Identify the user account and determine if the access volume is anomalous for this user — check baseline activity using: OfficeActivity | where UserId == '<user>' | where TimeGenerated > ago(30d) | summarize count() by bin(TimeGenerated, 1h) | sort by count_ desc
- Determine the source IP(s) involved — is access coming from a corporate IP range, a known VPN endpoint, or an unfamiliar residential/cloud IP? Check against your IP allowlist and geo-location data
- Review the specific files accessed — are they limited to one SharePoint site/library or spanning multiple sites across the organization? Cross-site access is more suspicious than single-site bulk access
- Check for file type patterns — bulk access to Office documents (.docx, .xlsx, .pptx), PDFs, or config files (.json, .yaml, .env) is more concerning than image or media downloads
- Identify the client application — was access via browser (normal user activity), sync client (could be legitimate), SharePoint REST API calls (suspicious for end users), or PowerShell/Graph API (elevated suspicion)?
- Verify whether the user has any open service tickets, approved migration tasks, or eDiscovery cases that would explain the access volume
- For sensitive keyword searches: review the specific search queries — are they targeted (e.g., 'AWS production credentials') or generic (e.g., 'password reset procedure')?
Containment
- If confirmed malicious or strongly suspected breach: disable the user account in Azure Active Directory and revoke all active sessions using: Revoke-AzureADUserAllRefreshToken -ObjectId <user-object-id>
- If access is from a suspicious or foreign IP: block the IP at the network perimeter and add to Azure AD Conditional Access named locations exclusion
- If the account appears compromised: reset credentials, enforce MFA re-registration, and review all OAuth app consents granted by this account in Azure AD > Enterprise Applications
- Enable SharePoint audit log alerting and set Purview compliance policies to alert on future bulk downloads by this user (or globally as a preventive measure)
- If data has been externally shared: revoke any anonymous sharing links and external user invitations created during the suspicious period via SharePoint admin center > Sharing
- Review and temporarily restrict the user's SharePoint permissions to read-only while investigation proceeds
Evidence Collection
- Export the full OfficeActivity logs for the user over the 72-hour window around the incident: OfficeActivity | where UserId == '<user>' | where TimeGenerated between(ago(72h)..now()) | project-all
- Pull Azure AD sign-in logs to correlate authentication events with the data access timeline: SigninLogs | where UserPrincipalName == '<user>' | where TimeGenerated > ago(72h)
- Check for any OAuth application consent grants that could enable persistent API access: AuditLogs | where InitiatedBy.user.userPrincipalName == '<user>' | where OperationName == 'Consent to application'
- Review SharePoint admin reports: SharePoint Admin Center > Reports > Sharing > download CSV of all sharing activities for the user during the incident window
- Collect Unified Audit Log export from Microsoft Purview Compliance Center filtered to user and date range — this provides the authoritative record of all M365 activity
- If on-premises Confluence is involved: collect Confluence access logs from <confluence-home>/logs/atlassian-confluence.log, filtering for the suspect user's account ID
- For cloud database access (AWS RDS, ElasticSearch): collect CloudTrail logs for DescribeDBInstances, GetObject, ReceiveMessage API calls from the relevant IAM principal
Escalation Criteria
- ! Access to files containing 'password', 'credential', 'private key', or 'secret' in their names, or SharePoint searches explicitly targeting credential stores — escalate immediately to SOC Tier 2 / IR team
- ! Bulk access (>200 files in <30 minutes) from a non-corporate or Tor/VPN IP, especially outside business hours — strong indicator of account compromise
- ! Data accessed from a recently created account or an account that normally has no SharePoint activity
- ! External sharing links created for more than 10 documents in a single session, especially to personal email domains (gmail.com, yahoo.com, protonmail.com)
- ! Evidence of the accessed data being staged for exfiltration — look for corresponding OneDrive sync events to an unrecognized device, or email attachments sent shortly after the SharePoint access
- ! Same bulk access pattern observed across multiple user accounts simultaneously — possible automated credential stuffing or compromised shared service account being abused at scale
Investigation Guide
Forensic Artifacts
- >
Microsoft 365 Unified Audit Log: SharePoint FileDownloaded, FileAccessed, SearchQueryPerformed, SharingInvitationCreated, AnonymousLinkCreated events — authoritative source, retained 90 days by default (1 year with E5 compliance) - >
Azure AD Sign-in Logs: SigninLogs table in Log Analytics — check for sign-ins from unfamiliar IPs, devices, or locations correlated with the access timeline - >
SharePoint Usage Reports: SharePoint Admin Center > Reports > Usage — shows per-user file access counts and storage consumed, useful for baselining - >
Browser History / Browser Forensics: if device is accessible — SharePoint URLs in browser history, cached credentials in browser credential stores - >
Windows Event Log: Security Event ID 4648 (explicit logon) and 4624 (successful logon) if SharePoint was accessed via a Windows-authenticated network path - >
Network Proxy Logs: HTTP/HTTPS requests to *.sharepoint.com, *.confluence.com, github.com — large volumes of GET requests with document file extensions indicate mass download - >
On-premises Confluence: atlassian-confluence.log contains all page view and search events; Confluence's built-in audit log at Administration > Audit Log > Export - >
GitHub/GitLab audit logs: organization-level audit log showing repository clone, archive download, or API token creation events - >
AWS CloudTrail: GetObject calls against S3 buckets, DescribeDBSnapshots for RDS, GetShardIterator/GetRecords for Kinesis — patterns of bulk read operations
Tuning Guidance
Begin by establishing baselines for normal SharePoint access volume per user role and department. Analysts, executives, and IT staff will have significantly higher baselines than standard employees. The bulk access threshold of 50 files/hour should be tuned per environment — start high and lower iteratively. Key exclusions to configure: (1) Service accounts used by migration tools (ShareGate, AvePoint) should be added to an allowlist by UPN or object ID; (2) DLP scanning service principals — these are identifiable by their consistent access patterns and service principal display names in AAD; (3) SharePoint search crawler accounts (typically named 'SharePoint Search Crawl Account'); (4) Backup solution service accounts. For the keyword search detection, tune the keyword list to your environment — a healthcare company should add medical record terms while a financial firm should add terms like 'wire transfer instructions'. Consider layering detections with Azure AD Identity Protection risk signals — if an OfficeActivity alert fires on an account that Azure AD has already flagged as at-risk, auto-escalate to P1. For Confluence on-premises, configure audit logging at Administration > Audit Log and forward via syslog to your SIEM. GitHub organization audit logs are available via the GitHub REST API and should be ingested via a dedicated connector.
Hunting Queries
Hunt for users accessing documents across an unusually high number of distinct SharePoint site collections over 7 days. Legitimate users typically access a limited set of sites related to their role. Adversaries mining repositories for valuable data tend to traverse many site collections looking for sensitive documentation. A user accessing >3 distinct sites per day consistently is worth investigating.
// Hunt for users accessing documents across an unusually high number of distinct SharePoint sites (cross-site repository mining)
OfficeActivity
| where TimeGenerated > ago(7d)
| where Workload in ("SharePoint", "OneDrive")
| where Operation in ("FileDownloaded", "FileAccessed", "FilePreviewed")
| summarize
TotalOps = count(),
UniqueSites = dcount(Site_Url),
UniqueFiles = dcount(OfficeObjectId),
SiteList = make_set(Site_Url, 20),
EarliestAccess = min(TimeGenerated),
LatestAccess = max(TimeGenerated)
by UserId
| where UniqueSites >= 5
| extend DaysActive = datetime_diff('day', LatestAccess, EarliestAccess) + 1
| extend SitesPerDay = toreal(UniqueSites) / toreal(DaysActive)
| where SitesPerDay > 3
| sort by UniqueSites desc index=o365 sourcetype="o365:management:activity"
(Workload="SharePoint" OR Workload="OneDrive")
(Operation="FileDownloaded" OR Operation="FileAccessed" OR Operation="FilePreviewed")
earliest=-7d
| stats count as TotalOps, dc(SiteUrl) as UniqueSites, dc(ObjectId) as UniqueFiles, values(SiteUrl) as SiteList by UserId
| where UniqueSites >= 5
| eval SitesPerDay=UniqueSites / 7
| where SitesPerDay > 3
| sort - UniqueSites
| table UserId, TotalOps, UniqueSites, UniqueFiles, SitesPerDay, SiteList Hunt for bulk SharePoint file access occurring outside business hours (before 7am or after 7pm). While some legitimate after-hours access occurs, adversaries operating with stolen credentials frequently conduct data collection at night or on weekends to avoid detection. Users with 30+ after-hours file accesses over 14 days warrant review, especially if source IPs differ from their normal daytime IPs.
// Hunt for after-hours bulk SharePoint access — adversaries with stolen credentials often operate outside normal business hours
let BusinessHoursStart = 7;
let BusinessHoursEnd = 19;
OfficeActivity
| where TimeGenerated > ago(14d)
| where Workload in ("SharePoint", "OneDrive")
| where Operation in ("FileDownloaded", "FileSyncDownloadedFull", "FileAccessed")
| extend HourOfDay = hourofday(TimeGenerated)
| extend IsAfterHours = HourOfDay < BusinessHoursStart or HourOfDay >= BusinessHoursEnd
| where IsAfterHours == true
| summarize
AfterHoursOps = count(),
UniqueFiles = dcount(OfficeObjectId),
UniqueDays = dcount(bin(TimeGenerated, 1d)),
SourceIPs = make_set(ClientIP, 10),
HoursActive = make_set(HourOfDay, 24)
by UserId
| where AfterHoursOps >= 30
| sort by AfterHoursOps desc index=o365 sourcetype="o365:management:activity"
(Workload="SharePoint" OR Workload="OneDrive")
(Operation="FileDownloaded" OR Operation="FileSyncDownloadedFull" OR Operation="FileAccessed")
earliest=-14d
| eval HourOfDay=strftime(_time, "%H")
| eval IsAfterHours=if(HourOfDay < "07" OR HourOfDay >= "19", 1, 0)
| where IsAfterHours=1
| stats count as AfterHoursOps, dc(ObjectId) as UniqueFiles, dc(strftime(_time, "%Y-%m-%d")) as UniqueDays, values(ClientIP) as SourceIPs by UserId
| where AfterHoursOps >= 30
| sort - AfterHoursOps
| table UserId, AfterHoursOps, UniqueFiles, UniqueDays, SourceIPs Hunt for users who have registered OneDrive/SharePoint sync clients on multiple devices. Adversaries with access to a compromised account may register a sync client on an attacker-controlled machine to silently download all SharePoint document libraries. More than 2 sync-registered devices for a single user warrants verification, especially when combined with high file transfer counts or unfamiliar device names.
// Hunt for SharePoint/OneDrive sync client registrations on new devices — adversaries may register a sync client to silently download all document libraries
OfficeActivity
| where TimeGenerated > ago(30d)
| where Workload in ("SharePoint", "OneDrive")
| where Operation in ("MountPoint", "FileSyncUploadedFull", "FileSyncDownloadedFull")
| summarize
SyncEventCount = count(),
UniqueDevices = dcount(DeviceName),
DeviceList = make_set(DeviceName, 20),
FilesTransferred = dcount(OfficeObjectId),
SourceIPs = make_set(ClientIP, 10),
EarliestEvent = min(TimeGenerated)
by UserId
| where UniqueDevices > 2
| join kind=inner (
OfficeActivity
| where TimeGenerated > ago(30d)
| where Operation == "MountPoint"
| summarize NewDevices = dcount(DeviceName) by UserId
) on UserId
| where NewDevices >= 2
| sort by FilesTransferred desc index=o365 sourcetype="o365:management:activity"
(Workload="SharePoint" OR Workload="OneDrive")
(Operation="MountPoint" OR Operation="FileSyncUploadedFull" OR Operation="FileSyncDownloadedFull")
earliest=-30d
| stats count as SyncEventCount, dc(DeviceName) as UniqueDevices, dc(ObjectId) as FilesTransferred, values(DeviceName) as DeviceList, values(ClientIP) as SourceIPs by UserId
| where UniqueDevices > 2
| sort - FilesTransferred
| table UserId, SyncEventCount, UniqueDevices, FilesTransferred, DeviceList, SourceIPs Atomic Red Team Tests
Simulates an adversary using PnP PowerShell (a legitimate SharePoint management library) to enumerate and download all documents from a SharePoint document library. This technique is used by adversaries with valid credentials to harvest repository data at scale. PnP PowerShell generates OfficeActivity FileDownloaded events for each file retrieved.
Command
# Requires PnP PowerShell module and valid SharePoint credentials
# Install module if needed: Install-Module PnP.PowerShell -Force
# Replace URL and credentials with test tenant values
$SiteUrl = "https://YOURTENANT.sharepoint.com/sites/TESTSITE"
$LocalPath = "$env:TEMP\sptest-harvest"
New-Item -ItemType Directory -Force -Path $LocalPath | Out-Null
Connect-PnPOnline -Url $SiteUrl -UseWebLogin
$Files = Get-PnPListItem -List "Documents" -PageSize 100
foreach ($File in $Files) {
if ($File.FileSystemObjectType -eq "File") {
Get-PnPFile -Url $File["FileRef"] -Path $LocalPath -FileName $File["FileLeafRef"] -AsFile -Force
}
}
Write-Host "Downloaded $($Files.Count) items to $LocalPath" Cleanup
Remove-Item "$env:TEMP\sptest-harvest" -Recurse -Force -ErrorAction SilentlyContinue
Disconnect-PnPOnline Expected Telemetry
OfficeActivity events: Operation=FileDownloaded for each downloaded file, Workload=SharePoint, UserId=authenticated user UPN, ClientIP=executing machine IP. Azure AD SigninLogs: interactive authentication event for the SharePoint OAuth flow. Sysmon Event ID 1: Process Create for powershell.exe with PnP module loading.
Expected Detection
Bulk access detection fires when OperationCount >= 50 within the 1-hour window. KQL BulkAccess branch: OperationCount shows file count, DetectionType=BulkFileAccess. Severity scales based on file count — 50+ files triggers medium risk, 200+ triggers high.
Simulates an adversary using the SharePoint REST Search API to perform targeted searches for sensitive content such as passwords, credentials, and network documentation. This is a low-noise technique used to locate specific high-value documents without downloading all content. Generates SearchQueryPerformed events in OfficeActivity.
Command
# Requires valid SharePoint credentials and access token
# Replace YOURTENANT with your test tenant
$TenantUrl = "https://YOURTENANT.sharepoint.com"
$Headers = @{ "Accept" = "application/json;odata=verbose" }
# Authenticate — in a real attack this would use a stolen token
Connect-PnPOnline -Url $TenantUrl -UseWebLogin
$Token = Get-PnPAccessToken
$Headers["Authorization"] = "Bearer $Token"
# Perform sensitive searches
$SearchTerms = @("password", "credentials", "vpn configuration", "network diagram", "api key", "private key")
foreach ($Term in $SearchTerms) {
$SearchUrl = "$TenantUrl/_api/search/query?querytext='$Term'&rowlimit=10"
$Result = Invoke-RestMethod -Uri $SearchUrl -Headers $Headers -Method GET
$Hits = $Result.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results.Count
Write-Host "Search '$Term': $Hits results"
Start-Sleep -Seconds 2
} Cleanup
Disconnect-PnPOnline Expected Telemetry
OfficeActivity events: Operation=SearchQueryPerformed for each API search call, with SearchQuery field containing the sensitive keyword, Workload=SharePoint, UserId=authenticated user. Multiple events in quick succession for each term searched.
Expected Detection
Sensitive keyword search detection fires on SearchQuery matching SensitiveKeywords list. KQL SensitiveSearch branch: DetectionType=SensitiveKeywordSearch, QuerySamples shows actual search terms. SPL Branch 2: SearchCount per user will reach threshold after 3+ sensitive searches.
Simulates an adversary using the Confluence REST API to enumerate all spaces and export page content. Confluence stores architecture diagrams, runbooks, credentials, and other sensitive documentation. This technique uses the documented Confluence REST API with valid credentials and generates entries in the Confluence access log.
Command
#!/bin/bash
# Replace with your Confluence test instance URL and credentials
CONFLUENCE_URL="https://your-confluence.atlassian.net"
USERNAME="[email protected]"
API_TOKEN="YOUR_API_TOKEN" # Use Atlassian API token
OUTPUT_DIR="/tmp/confluence-harvest"
mkdir -p "$OUTPUT_DIR"
# Step 1: Enumerate all spaces
echo "[*] Enumerating spaces..."
curl -s -u "$USERNAME:$API_TOKEN" \
-H "Accept: application/json" \
"$CONFLUENCE_URL/wiki/rest/api/space?limit=50" \
| python3 -c "import json,sys; spaces=json.load(sys.stdin)['results']; [print(s['key'], s['name']) for s in spaces]" \
> "$OUTPUT_DIR/spaces.txt"
# Step 2: Search for sensitive pages
for TERM in "password" "credential" "vpn" "firewall" "aws" "api key"; do
echo "[*] Searching for: $TERM"
curl -s -u "$USERNAME:$API_TOKEN" \
-H "Accept: application/json" \
"$CONFLUENCE_URL/wiki/rest/api/search?cql=type=page+AND+text~\"$TERM\"&limit=10" \
| python3 -c "import json,sys; r=json.load(sys.stdin); [print(i['title'], i['_links']['webui']) for i in r.get('results',[])]" \
>> "$OUTPUT_DIR/sensitive-pages.txt"
sleep 1
done
echo "[+] Results saved to $OUTPUT_DIR/" Cleanup
rm -rf /tmp/confluence-harvest Expected Telemetry
Confluence access logs (atlassian-confluence.log): GET requests to /wiki/rest/api/space and /wiki/rest/api/search endpoints with user authentication. If Confluence audit logging is enabled: search events appear in Administration > Audit Log. Network proxy logs: HTTP requests to the Confluence FQDN with search query parameters visible in URL.
Expected Detection
Network proxy logs should show rapid sequential GET requests to /wiki/rest/api/search with sensitive keyword terms in query parameters. Web application firewall (WAF) rules can detect bulk API enumeration patterns. CASB solutions monitoring Confluence cloud activity will surface the mass search pattern as anomalous.
Simulates an adversary using the Microsoft Graph API to enumerate Teams channels and export chat messages. Messaging platforms contain sensitive discussions, shared credentials, code snippets, and internal information. This technique requires a valid access token and appropriate permissions (Team.ReadBasic.All, ChannelMessage.Read.All).
Command
# Requires Microsoft Graph PowerShell SDK and valid credentials
# Install: Install-Module Microsoft.Graph -Scope CurrentUser
# This test requires a delegated token with Teams read permissions
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Team.ReadBasic.All", "ChannelMessage.Read.All"
$OutputFile = "$env:TEMP\teams-harvest.txt"
# Step 1: Enumerate joined teams
$Teams = Get-MgUserJoinedTeam -UserId "me" -All
Write-Host "[*] Found $($Teams.Count) teams"
$Teams | Select-Object DisplayName, Id | Out-File $OutputFile
# Step 2: For first 3 teams, list channels and retrieve recent messages
foreach ($Team in ($Teams | Select-Object -First 3)) {
Write-Host "[*] Enumerating team: $($Team.DisplayName)"
$Channels = Get-MgTeamChannel -TeamId $Team.Id
foreach ($Channel in ($Channels | Select-Object -First 5)) {
Write-Host " [+] Channel: $($Channel.DisplayName)"
# Retrieve last 50 messages
Get-MgTeamChannelMessage -TeamId $Team.Id -ChannelId $Channel.Id -Top 50 |
Select-Object CreatedDateTime, @{N='Author';E={$_.From.User.DisplayName}}, @{N='Body';E={$_.Body.Content}} |
Out-File -Append $OutputFile
}
}
Write-Host "[+] Output written to $OutputFile" Cleanup
Remove-Item "$env:TEMP\teams-harvest.txt" -ErrorAction SilentlyContinue
Disconnect-MgGraph Expected Telemetry
OfficeActivity events: Operation=MessageRead or similar Teams audit events, Workload=MicrosoftTeams. Azure AD SigninLogs: token acquisition for Graph API with Teams scopes. AuditLogs: Microsoft Graph API calls for Team and ChannelMessage read operations. Microsoft Defender for Cloud Apps: Graph API activity anomaly if CASB is configured.
Expected Detection
Microsoft Defender for Cloud Apps (MDCA) should detect anomalous Graph API usage pattern. Azure AD sign-in logs show the scope requested. OfficeActivity Teams events show bulk message reads. Conditional Access policies enforcing Graph API scope restrictions may generate alerts if unexpected scopes are requested.