Skip to Content
logo
SlackReddit

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.

Source

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:

Supported Platforms: Windows

auto_generated_guid: 57e78bad-45f6-42f4-ad5b-705576394ca2

Inputs

NameDescriptionTypeDefault Value
npm_pathnpm command or full path to npm.cmdpathnpm.cmd
package_pathPath to the local synthetic npm package included with this atomicpathPathToAtomicsFolder\T1204.005\src\atomic-npm-package
working_directoryDisposable directory used for the local npm installation and cachepath$env:TEMP\T1204.005-Atomic-Npm
marker_pathMarker file created by the synthetic package postinstall scriptpath$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 SilentlyContinue

Dependencies: 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 1
Get 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 1
Get 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

On this page