---
title: "New Technique Used by Attackers in NPM to Avoid Detection"
date: "2022-06-08T12:57:48+00:00"
url: "https://staging.checkmarx.com/blog/new-technique-used-by-attackers-in-npm-to-avoid-detection/"
description: "Checkmarx SCS team recently detected several malicious NPM packages using a new evasion technique, enhancing dependency confusion attacks to help malicious packages avoid detection."
---

# New Technique Used by Attackers in NPM to Avoid Detection

Checkmarx SCS team recently detected several malicious NPM packages using a new evasion technique, enhancing dependency confusion attacks to help malicious packages avoid detection.

This novel technique tries to avoid being detected by security scanners or [AppSec platforms](https://checkmarx.com/), which sometimes only look at the latest version of a package. It does so by publishing a benign latest version after a burst of malicious versions with high version number.

## Intro

In the past few weeks, the [Checkmarx SCS](https://checkmarx.com/solutions/software-supply-chain-security/) team has detected 14 [malicious packages](https://checkmarx.com/product/malicious-packages/) exhibiting a new behavior. They all have a benign latest version along with multiple malicious versions trying to exfiltrate the machine’s environment variables.

At first glance, it seems that this kind of technique will defeat the purpose of the attack, as the malicious functionality won’t be installed by end-users using the “npm install” command, which automatically serves the package’s latest version. However, these end-users are not the attackers’ targets.

It seems the attackers’ intent is to target automatic updates of “patch” and “minor” versions as part of dependency confusion attacks.

## How NPM Versioning Works

To better understand this nuance, some background on NPM and semantic versioning (semver) is required. Great resource about semver is [https://semver.org/](https://semver.org/) and is highly recommended to checkout.

In a nutshell, a valid semver version is constructed from 3 parts: “major”, “minor”, and “patch”

- Major – Promoted when making significant version changes, usually known breaking changes
- Minor – Promoted when adding new features
- Patch – Promoted when fixing issues, either functionality or security

![](https://staging.checkmarx.com/wp-content/uploads/2022/06/image_1-1024x443-1.png)As previously mentioned, using the “npm install” command will install the latest version of the package even if the version number is not the highest among the versions that were released; however, most package installations are performed as a dependency of other packages. These dependencies are specified in the package.json file of the package:

```
...
"dependencies": {
  "dep": "3.3.3",
  "latest_dep": "*",
  "my_dep": "^1.0.0",
  "another_dep": "~2.2.0",
},...
```

The example above shows 4 options for consuming dependencies:

1. The “dep” package will install precisely the “3.3.3” version of the package and no other (commonly known as version pinning).
2. The “latest\_dep” will install the package’s latest version available.
3. The “my\_dep” includes the Caret sign (^) prior to the version number, in which case NPM will pull “patch” and “minor” updates to the specified version. For instance, version 1.1.0 or 1.0.1 but not 2.0.0.
4. The “another\_dep” includes the Tilda sign (~) prior to the version number, in which case NPM will only pull “patch” updates to the specified version. For instance, version 2.2.1 but not 2.3.0 or 3.0.0.

## The Technique

With this understanding of NPM versioning mechanism and the [original dependency confusion](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) technique, it is easier to understand the attackers’ intent.

The attacker releases a burst of versions for each package, almost all of them with low “major” version number and high “minor” and “patch” version numbers. The low “major” component of the version is intended to match the one used by the victim and the high “minor” and “patch” components are made to ensure automatic update in case the dependency version is not pinned to a specific one.

Finally, the attacker releases one last version with low version number to function as the latest version of the package. This version contains legitimate code that in many cases is even related to the package’s name and seems to be borrowed from a related package.

![](https://staging.checkmarx.com/wp-content/uploads/2022/06/image_2-1.png)Releasing a package in this manner, as seen in the image above for example, will result in the following outcomes:

- The dependency confusion attack will work – a package dependent on the malicious package without version pinning, such as ‘: “^3.1.0”’, will download and install the malicious version “3.758.11”
- A security scanner that scans only the latest version of a package will deem it legitimate.

## The Attack

Aside from using this novel technique, this cluster of 14 malicious packages discover in the last few weeks has several other characteristics in its package:

### 1 – The objective of these attacks is to exfiltrate all the victim machine’s environment variables to the attacker via a webhook of the legitimate service “pipedream”:

![](https://staging.checkmarx.com/wp-content/uploads/2022/06/image_3-1024x774-1.png)### 2 – Sandbox detection

Another evasion technique the attacker employed is trying to avoid running on environments suspected as sandboxes. This attempt was implemented by filtering out specific values of environment variables.

```
var filter = [
  { key: ['npm', 'config', 'registry'].join('_'), val: ['taobao', 'org'].join('.') },
  { key: ['npm', 'config', 'registry'].join('_'), val: ['registry', 'npmmirror', 'com'].join('.') },
  { key: 'USERNAME', val: ['daas', 'admin'].join('') },
  { key: '_', val: '/usr/bin/python' },
  { key: 'npm_config_metrics_registry', val: ['mirrors', 'tencent', 'com'].join('.') },
  [
    { key: 'MAIL', val: ['', 'var', 'mail', 'app'].join('/') },
    { key: 'HOME', val: ['', 'home', 'app'].join('/') },
    { key: 'USER', val: 'app' },
  ],
  [
    { key: 'EDITOR', val: 'vi' },
    { key: 'PROBE_USERNAME', val: '*' },
    { key: 'SHELL', val: '/bin/bash' },
    { key: 'SHLVL', val: '2' },
    { key: 'npm_command', val: 'run-script' },
    { key: 'NVM_CD_FLAGS', val: '' },
    { key: 'npm_config_fund', val: '' },
  ],
  [
    { key: 'HOME', val: '/home/username' },
    { key: 'USER', val: 'username' },
    { key: 'LOGNAME', val: 'username' },
  ],
  [
    { key: 'PWD', val: '/my-app' },
    { key: 'DEBIAN_FRONTEND', val: 'noninteractive' },
    { key: 'HOME', val: '/root' },
  ],
  [
    { key: 'INIT_CWD', val: '/analysis'},
    { key: 'APPDATA', val: '/analysis/bait'}
  ]
];
```

Should one of these values appears in the environment variable the code breaks from its malicious functionality and won’t exfiltrate this sensitive information.

```
var data = process.env || {};
  if (
    filter.some((entry) =>
      [].concat(entry).every((item) => (data[item.key] || '').includes(item.val) || item.val === '*')
    ) ||
    Object.keys(data).length < 10
  ) {
    return;
  }
```

During the past few weeks, we observed that the “filter” variable grows bigger to include more environment variables, identifying more scanners that the attackers want to avoid, which indicates that they are learning and improving their capabilities.

### 3 – obfuscation

Some of the packages in these attacks were also using obfuscation and double obfuscation to hinder researchers from studying the packages’ code.

## IOC’s

- bd43527e019ae8efb47eb39bb9313ac5.m.pipedream\[.\]net
- eol8qq3niztjn4p.m.pipedream\[.\]net
- eolock03iutvcf7.m.pipedream\[.\]net
- c2e7a0cfd4f45f811ede4b077ae48dfa.m.pipedream\[.\]net
- eoxb1lay4m45mms.m.pipedream\[.\]net
- eof0n35fe1w7o9j.m.pipedream\[.\]net
- eobn5xcv41edv52.m.pipedream\[.\]net
- 1268384ff816fb002f65302287b639ce.m.pipedream\[.\]net
- dbky7khu4dz2.m.pipedream\[.\]net
- eorthox7nn7e4fg.m.pipedream\[.\]net
- eovsmsusn4979sc.m.pipedream\[.\]net
- eo9jtk2svcyyaus.m.pipedream\[.\]net
- eojea1m1h2bi4nw.m.pipedream\[.\]net

## Conclusion

Dependency confusion attacks continue to flood NPM ecosystem and introduce new techniques to make it harder for defenders to detect and block them. The technique described above demonstrates the advantages of “version pinning” while writing a new package. This approach has its own shortcomings, such as a potentially longer timeframe in which your package could be exploitable by new vulnerabilities, but these should be considered against the alternative of leaving your package susceptible to these kinds of attacks.

## Packages

 Package name Exfiltration web hook NPM Username NPM User Email @goatapp/web-content-components  bd43527e019ae8efb47eb39bb9313ac5.m.pipedream.net  7gtfezcn  os1yl@candassociates.com  citrix-translate  eol8qq3niztjn4p.m.pipedream.net  hctrx  apdorpctc@candassociates.com  ctct-theme  eolock03iutvcf7.m.pipedream.net  hctct-thm  ncxrlkjc@candassociates.com  dig-tokens  c2e7a0cfd4f45f811ede4b077ae48dfa.m.pipedream.net  h8t7o12q  2wgqc@candassociates.com  epic-ue-loading  eoxb1lay4m45mms.m.pipedream.net  hepc-gms  jwrqqxlzy@candassociates.com  sn-signals  eof0n35fe1w7o9j.m.pipedream.net  hsn-signal  jjhuqtrzta@candassociates.com  teams-data  eobn5xcv41edv52.m.pipedream.net  hb0b  yexemin154@ovout.com  unserialize  1268384ff816fb002f65302287b639ce.m.pipedream.net  ug7fn1wq  8ffia@candassociates.com  @fs-design/pantry  dbky7khu4dz2.m.pipedream.net  hfund  nnrpexeohddjm@candassociates.com  @gobizweb/core  eorthox7nn7e4fg.m.pipedream.net  hg0biz  somjdlbccqwi@scpulse.com  @square-icons/react  eovsmsusn4979sc.m.pipedream.net  hsqre-con  xeskmt@candassociates.com  @vividcortex/multiplexer  eo9jtk2svcyyaus.m.pipedream.net  hvvd-cortx  cxunnjyuzint@scpulse.com  analytika-analytika-utils  eojea1m1h2bi4nw.m.pipedream.net  hcarem  hsvhslsfagfzy@candassociates.com  gfg-security-utilities  eorthox7nn7e4fg.m.pipedream.net  hgfg  tcsakmdoxqdhhx@candassociates.com
