T1204.005
User Execution: Malicious Library
Description from ATT&CK
Adversaries may rely on a user installing a malicious library to facilitate execution. Threat actors may Upload Malware to package managers such as NPM and PyPi, as well as to public code repositories such as GitHub. User may install libraries without realizing they are malicious, thus bypassing techniques that specifically achieve Initial Access. This can lead to the execution of malicious code, such as code that establishes persistence, steals data, or mines cryptocurrency.(Citation: Datadog Security Labs Malicious PyPi Packages 2024)(Citation: Fortinet Malicious NPM Packages 2023)
In some cases, threat actors may compromise and backdoor existing popular libraries (i.e., Compromise Software Dependencies and Development Tools). Alternatively, they may create entirely new packages and leverage behaviors such as typosquatting to encourage users to install them.
Atomic Tests
Atomic Test #1: Execute a synthetic npm package postinstall script
Simulates user execution of a malicious library by installing a local, synthetic npm package whose
postinstall lifecycle script executes JavaScript and creates a harmless marker file. This behavior
represents the package-install execution pattern associated with malicious npm packages and campaigns
such as the DPRK-linked Contagious Interview activity.
The test does not contact an npm registry, download code, collect credentials, establish persistence,
or execute an operator-supplied payload. Expected output includes npm reporting execution of the
package's postinstall script, creation of the T1204.005 marker file, and a success message containing
the marker contents.
References:
- https://attack.mitre.org/techniques/T1204/005/
- https://cloud.google.com/blog/topics/threat-intelligence/mitigation-guidance-for-supply-chain-compromise
Supported Platforms: Windows
auto_generated_guid: 57e78bad-45f6-42f4-ad5b-705576394ca2
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| npm_path | npm command or full path to npm.cmd | path | npm.cmd |
| package_path | Path to the local synthetic npm package included with this atomic | path | PathToAtomicsFolder\T1204.005\src\atomic-npm-package |
| working_directory | Disposable directory used for the local npm installation and cache | path | $env:TEMP\T1204.005-Atomic-Npm |
| marker_path | Marker file created by the synthetic package postinstall script | path | $env:TEMP\T1204.005-Atomic-Npm\T1204.005-npm-postinstall.txt |
Attack Commands: Run with powershell!
$ErrorActionPreference = 'Stop'
$npmPath = [Environment]::ExpandEnvironmentVariables("#{npm_path}")
$packagePath = [Environment]::ExpandEnvironmentVariables("#{package_path}")
$workingDirectory = [Environment]::ExpandEnvironmentVariables("#{working_directory}")
$markerPath = [Environment]::ExpandEnvironmentVariables("#{marker_path}")
if (Test-Path -LiteralPath $workingDirectory) {
throw "Refusing to use pre-existing working directory: $workingDirectory"
}
New-Item -ItemType Directory -Path $workingDirectory -Force | Out-Null
$env:ART_T1204_005_MARKER = $markerPath
try {
$npmArguments = @(
'install'
$packagePath
'--prefix', $workingDirectory
'--cache', (Join-Path $workingDirectory '.npm-cache')
'--no-audit'
'--no-fund'
'--ignore-scripts=false'
'--foreground-scripts'
)
& $npmPath @npmArguments
$npmExitCode = $LASTEXITCODE
if ($npmExitCode -ne 0) {
throw "npm install failed with exit code $npmExitCode"
}
if (-not (Test-Path -LiteralPath $markerPath -PathType Leaf)) {
throw "npm completed without creating the expected marker: $markerPath"
}
$markerContent = Get-Content -LiteralPath $markerPath -Raw
if ($markerContent -notmatch 'Atomic Red Team T1204\.005') {
throw 'The marker file did not contain the expected Atomic Red Team identifier.'
}
Write-Host 'T1204.005 synthetic npm postinstall execution succeeded.'
Write-Output $markerContent.Trim()
}
finally {
Remove-Item Env:\ART_T1204_005_MARKER -ErrorAction SilentlyContinue
}Cleanup Commands
$workingDirectory = [Environment]::ExpandEnvironmentVariables("#{working_directory}")
$markerPath = [Environment]::ExpandEnvironmentVariables("#{marker_path}")
Remove-Item Env:\ART_T1204_005_MARKER -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $markerPath -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $workingDirectory -Recurse -Force -ErrorAction SilentlyContinueDependencies: Run with powershell!
Description: Node.js and npm must be installed and the configured npm command must be available.
Check Prereq Commands
$npmPath = [Environment]::ExpandEnvironmentVariables("#{npm_path}")
if (Get-Command $npmPath -ErrorAction SilentlyContinue) { exit 0 }
exit 1Get Prereq Commands
Write-Host 'Install a supported Node.js release from https://nodejs.org/ and ensure npm.cmd is available in PATH.'Description: The synthetic npm package source files must exist in the configured package directory.
Check Prereq Commands
$packagePath = [Environment]::ExpandEnvironmentVariables("#{package_path}")
$packageJson = Join-Path $packagePath 'package.json'
$postinstallScript = Join-Path $packagePath 'postinstall.js'
if ((Test-Path -LiteralPath $packageJson -PathType Leaf) -and (Test-Path -LiteralPath $postinstallScript -PathType Leaf)) { exit 0 }
exit 1Get Prereq Commands
Write-Host 'Restore package.json and postinstall.js under T1204.005\src\atomic-npm-package.'Atomic test(s) for this technique last updated: 2026-11-06 00:42:53 UTC