Skip to content

Instantly share code, notes, and snippets.

@incogbyte
Last active September 17, 2025 15:58
Show Gist options
  • Select an option

  • Save incogbyte/b88e8655fc4f435e490e08e1654db46d to your computer and use it in GitHub Desktop.

Select an option

Save incogbyte/b88e8655fc4f435e490e08e1654db46d to your computer and use it in GitHub Desktop.
shai hulud npm supply chain attack Bambda burp filter,
// Author: @incogbyte
// Blog Post: https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack
// Usage: Proxy > HTTP history > Filter > "Script mode" > paste > Apply.
if (!requestResponse.hasResponse()) {
return false;
}
var req = requestResponse.request();
var resp = requestResponse.response();
String url = req.url();
url = (url == null ? "" : url.toLowerCase());
String ct = resp.headerValue("Content-Type");
ct = (ct == null ? "" : ct.toLowerCase());
String body = resp.bodyToString();
if (body == null) body = "";
boolean looksJs = url.endsWith(".js") || url.endsWith(".mjs") || url.endsWith(".cjs")
|| ct.contains("javascript") || ct.contains("ecmascript");
boolean isPackageJsonFile =
url.matches("(?i).*/package\\.json(?:\\?.*)?$")
|| url.matches("(?i).*/package-lock\\.json(?:\\?.*)?$")
|| url.matches("(?i).*/npm-shrinkwrap\\.json(?:\\?.*)?$");
boolean looksLikeDepsJson = ct.contains("json")
&& (body.contains("\"dependencies\"") || body.contains("\"packages\"") || body.contains("\"node_modules/"));
boolean looksSourceMap = url.endsWith(".map") && body.contains("\"sources\"") && body.contains(".js");
boolean looksPkgJson = isPackageJsonFile || looksLikeDepsJson;
if (!(looksJs || looksPkgJson || looksSourceMap)) {
return false;
}
if (body.isEmpty()) {
return false;
}
String[] MALICIOUS_PACKAGES = new String[] {
"@ctrl/deluge","@ctrl/golang-template","@ctrl/magnet-link","@ctrl/ngx-codemirror",
"@ctrl/ngx-csv","@ctrl/ngx-emoji-mart","@ctrl/ngx-rightclick","@ctrl/qbittorrent",
"@ctrl/react-adsense","@ctrl/shared-torrent","@ctrl/tinycolor","@ctrl/torrent-file",
"@ctrl/transmission","@ctrl/ts-base32",
"@nativescript-community/gesturehandler","@nativescript-community/sentry",
"@nativescript-community/text","@nativescript-community/ui-collectionview",
"@nativescript-community/ui-drawer","@nativescript-community/ui-image",
"@nativescript-community/ui-material-bottomsheet","@nativescript-community/ui-material-core",
"@nativescript-community/ui-material-core-tabs",
"@teselagen/bio-parsers","@teselagen/bounce-loader","@teselagen/file-utils",
"@teselagen/liquibase-tools","@teselagen/ove","@teselagen/range-utils",
"@teselagen/react-list","@teselagen/react-table","@teselagen/sequence-utils","@teselagen/ui",
"angulartics2","encounter-playground","eslint-config-teselagen","graphql-sequelize-teselagen",
"json-rules-engine-simplified","koa2-swagger-ui","ng2-file-upload","ngx-bootstrap",
"ngx-color","ngx-toastr","ngx-trend","oradm-to-gql","oradm-to-sqlz","ove-auto-annotate",
"react-complaint-image","react-jsonschema-form-conditionals","react-jsonschema-form-extras",
"react-jsonschema-rxnt-extras","rxnt-authentication","rxnt-healthchecks-nestjs","rxnt-kue",
"swc-plugin-component-annotate","tg-client-query-builder","tg-redbird","tg-seq-gen",
"ts-gaussian","ve-bamreader","ve-editor",
"@ahmedhfarag/ngx-perfect-scrollbar","@ahmedhfarag/ngx-virtual-scroller",
"@art-ws/common","@art-ws/config-eslint","@art-ws/config-ts","@art-ws/db-context",
"@art-ws/di-node","@art-ws/di","@art-ws/eslint","@art-ws/fastify-http-server",
"@art-ws/http-server","@art-ws/openapi","@art-ws/package-base","@art-ws/prettier",
"@art-ws/slf","@art-ws/ssl-info","@art-ws/web-app",
"@crowdstrike/commitlint","@crowdstrike/falcon-shoelace","@crowdstrike/foundry-js",
"@crowdstrike/glide-core","@crowdstrike/logscale-dashboard","@crowdstrike/logscale-file-editor",
"@crowdstrike/logscale-parser-edit","@crowdstrike/logscale-search"
};
List<Pattern> patterns = new ArrayList<>();
for (String p : MALICIOUS_PACKAGES) {
String q = Pattern.quote(p);
patterns.add(Pattern.compile("(?s)\\bimport\\b[^;]*\\bfrom\\s*['\\\"]" + q + "(?:/[\\w@\\-./]+)?['\\\"]"));
patterns.add(Pattern.compile("(?s)\\brequire\\s*\\(\\s*['\\\"]" + q + "(?:/[\\w@\\-./]+)?['\\\"]\\s*\\)"));
patterns.add(Pattern.compile("(?s)\\bimport\\s*\\(\\s*['\\\"]" + q + "(?:/[\\w@\\-./]+)?['\\\"]\\s*\\)"));
patterns.add(Pattern.compile("(?s)\\\"" + q + "\\\"\\s*:\\s*\\\"[^\\\"]+\\\""));
patterns.add(Pattern.compile("(?s)['\\\"]" + q + "(?:/[\\w@\\-./]+)?['\\\"]"));
}
Pattern[] iocs = new Pattern[] {
Pattern.compile("webhook\\[\\.]site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7", Pattern.CASE_INSENSITIVE),
Pattern.compile("/tmp/(processor|migrate-repos)\\.sh"),
Pattern.compile("shai-?hulud", Pattern.CASE_INSENSITIVE)
};
for (Pattern pat : patterns) {
if (pat.matcher(body).find()) {
return true;
}
}
for (Pattern i : iocs) {
if (i.matcher(body).find()) {
return true;
}
}
return false;
@incogbyte
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment