BLOG
Frankly Malicious: Inside a 38-Package NPM Supply Chain Campaign Targeting Tech Giants
Zaynah
Smith-DaSilva
Introduction
In late April 2026, Panther Threat Research identified a coordinated supply chain attack campaign comprising 38 malicious NPM packages published across four threat actor accounts between 2026-04-24 and 2026-04-30 . The campaign was attributed to an Indonesian actor operating under the alias "frank" (primary NPM identity: frengki0707 ) and three rotating accounts ( raya4321 , cketol , frengki4321 ). The actor employed dependency confusion as its primary delivery vector, weaponizing *-internal-* package naming conventions to cause CI/CD pipelines to resolve malicious public packages ahead of legitimate private ones. The packages were organized into five specialized collection clusters, each impersonating the internal developer tooling of a major technology organization: Apple, Google/GCP, Alibaba/Aliyun, a generic multi-target group, and the actor's own cross-platform exfiltration toolkit ( frank-* ). This report documents the campaign's structure, actor attribution, technical exfiltration methodology, and targeted credential categories across all 38 artifacts.
Targeted Parties
The campaign's primary targets were developers and CI/CD infrastructure at four major technology organizations: Apple, Google/GCP, Alibaba/Aliyun, and a broader, generic multi-target group spanning unnamed enterprises. Rather than attacking end users directly, the threat actor frengki0707 and their rotating accounts ( raya4321 , cketol , frengki4321 ) focused on internal engineering ecosystems. Specifically the adversary focused on automated build pipelines and dependency resolution mechanisms used by software developers at these firms. By weaponizing the *-internal-* package naming convention, the actor crafted malicious NPM packages that mimicked the private tooling each organization would plausibly maintain, exploiting the dependency confusion vulnerability to cause build systems to pull attacker-controlled public packages over legitimate private ones. This means the immediate victims were not end customers but rather software engineers and DevOps/build infrastructure operating within or contracting for Apple, Google, and Alibaba environments, with credential categories and exfiltration payloads tailored to the secrets and access tokens those environments are most likely to hold. The inclusion of a generic multi-target cluster ( frank-* ) further suggests the actor intended to cast a wide net beyond these named organizations, opportunistically targeting any enterprise whose CI/CD pipelines resolved packages matching the naming pattern.
Campaign Overview
These 38 packages form a coordinated supply chain attack campaign targeting developers at or working with Apple, Google, and Alibaba/Aliyun infrastructure. The campaign uses a combination of dependency confusion, typosquatting, and internal tooling impersonation to trick developers into installing malicious packages. A recurring actor handle "frank" appears across multiple packages, suggesting a single threat actor or tightly coordinated group operating under that alias. The presence of terms like bypass , escape , leak , stealth , and poc (proof-of-concept) strongly suggests active exploitation intent rather than research.

Apple Impersonation (20 packages)
The Apple impersonation packages make up the largest cluster. Packages impersonate Apple's internal developer tooling, App Store server libraries, PKI utilities, CloudKit ( cktool ) APIs, and infrastructure management. The apple-infra-* sub-group is particularly aggressive with names like ultimate-bypass , final-escape , stealth-audit , and gcp-leak indicating that these are staged payloads designed to escalate from initial execution to full infrastructure compromise. The use of version suffixes ( -v3 , -v99 , -v9 ) mimics legitimate semantic versioning to appear credible in a package.json dependency tree.
"frank" Threat Actor Toolkit (8 packages)
The frank-* namespace is the actor's operational fingerprint. The newton3 sub-campaign shows a clear kill chain progression: db-poc → db-final → user-hunt → final-audit , consistent with iterative development of a credential harvesting and database exfiltration toolset. The npm scoped account @frengki0707 is likely the same actor, confirming a persistent identity across registries.
Google / GCP Impersonation (7 packages)
Targets GCP-adjacent developers by mimicking internal build helpers, logging utilities, mono-repo tools, and audit packages. gcp-internal-research-poc and frank-bot-gogle-cloning (note intentional typo) suggest this cluster was built to harvest GCP service account credentials and OAuth tokens from CI/CD pipeline environments.
Alibaba / Aliyun Impersonation (3 packages)
A smaller but focused cluster impersonating Alibaba Cloud SDK internals ( alicloud-pop-core mimics the legitimate Alibaba Cloud POP core library) and internal configuration utilities. frank-at-alibaba-internal directly ties this cluster to the frank actor.
Generic / Multi-Target (3 packages)
npm-global-util is a broad opportunistic package targeting any developer environment. agents-a365-runtime appears to target Microsoft 365 / Azure agent runtimes, broadening the campaign beyond Apple/Google/Alibaba. internal-sys-audit-check uses authoritative-sounding language to masquerade as a legitimate security tool on developer machines.
Technical Analysis
The 38 malicious NPM packages in this campaign employed a unified, staged exfiltration framework delivered primarily via dependency confusion where all packages used -internal- naming conventions to cause CI/CD pipelines to resolve them from the public NPM registry ahead of private ones.
This process required no user interaction beyond a standard npm install . Execution was triggered through postinstall hooks embedded in packages named with terms like -audit , -check , -monitor , and -config , which developers naturally expect to run on installation or access environment variables. Once executed, packages followed a consistent four-stage kill chain best exemplified by the frank-newton3-* sub-series ( db-poc → db-final → user-hunt → final-audit ). This chain progressed from system fingerprinting ( whoami , hostname , uname -a ) through targeted credential harvesting, lateral target enumeration, and finally C2 beacon transmission. Every package across all five clusters performed Stage 1 system identity recon, while subsequent stages were specialized by cluster. Apple-targeting packages ( apple-infra-* ) focused on NPM auth tokens, AWS credentials, and developer PKI material. The Google/GCP cluster harvested gcloud service account credentials and Kubernetes configs. The Alibaba cluster extracted Aliyun RAM keys. The frank-newton3-* series specifically targeted .env files, DB_* environment variables, SSH keys, and MySQL/Postgres dumps.
The frank-* namespace packages served as the shared exfiltration backbone across all clusters, acting as a common C2 beacon and credential packaging library that platform-specific packages ( apple-* , google-* , aliyun-* ) depended on at runtime. Each cluster functioned as a specialized collection arm with Apple tokens, GCP credentials, Aliyun keys, database secrets all funneling into the same frank-* exfiltration infrastructure. The strategic targeting of NPM publish tokens ( NPM_TOKEN , NODE_AUTH_TOKEN ) via packages like @frengki0707/google-cloud-clone and npm-global-util was the highest-value vector, as successful theft would have enabled the actor to inject malicious code into legitimate, trusted packages therefore effectively multiplying the campaign's reach beyond the initial 38 packages. Operational resilience was maintained through a four-account rotation structure ( frengki0707 → raya4321 / cketol → frengki4321 ), ensuring that takedown of any single NPM account removed only one collection arm while the rest of the infrastructure continued operating.
Attribution
This campaign is attributed with high confidence to a single Indonesian-speaking threat actor, operating across four npm publisher accounts between April 24–30, 2026.
Account Rotation
The clearest attribution link is the shared frengki base string between npm usernames frengki0707 and frengki4321. The earlier account was first observed on April 24 and went dark on April 26 after publishing 11 packages making it consistent with detection and account burnout. frengki4321 surfaced three days later, publishing ac-sasskit-beta and apple-appstore-full-library-utility. The sequential naming and timing indicate deliberate account rotation as a detection evasion strategy. A GitHub account under the handle FRENGKI-MIX also exists with matching naming conventions, though its two repositories are empty and its relationship to the campaign accounts is unconfirmed.
Persistent Alias
The name frank appears consistently across otherwise distinct accounts: getkontakfrank@gmail.com (Indonesian for "get frank's contact"), the frank-newton3-* package series under cketol, and packages such as frank-at-alibaba-internal, frank-apple-sync-service, and frank-bot-gogle-cloning under separate accounts. This recurring alias across accounts that otherwise have no surface-level connection is a significant operational failure that ties the campaign together.
Language and Infrastructure
Indonesian-language comments appear in the source of both ac-sasskit-beta (Payload: Ambil identitas sistem) and apple-internal-security-audit-v99, corroborating the language indicators present in getkontakfrank@gmail.com. "Frengki" is a given name common among the Batak ethnic group of North Sumatra, Indonesia, consistent with these findings. A GitHub account registered to raya4321 which is the npm username associated with npmtpoc@gmail.com was also identified, with zero public repositories, suggesting account creation for campaign use rather than general development activity.
At the infrastructure level, ac-sasskit-beta and apple-appstore-full-library-utility share an identical hardcoded webhook endpoint, serving as a direct technical link between the two packages published from the frengki4321 account.
Conclusion
This campaign represents a technically sophisticated, modular supply chain operation designed for broad credential harvesting across multiple major cloud ecosystems simultaneously. By combining dependency confusion delivery, postinstall hook execution, and a shared frank-* exfiltration backbone, the actor was able to run independent yet coordinated collection arms targeting Apple developer credentials, GCP service accounts, Aliyun RAM keys, database secrets, and CI/CD authentication tokens which all funneled into a common infrastructure layer. The highest-value vector identified was the targeting of NPM publish tokens ( NPM_TOKEN , NODE_AUTH_TOKEN ), which, if successfully exfiltrated, would have enabled the actor to inject malicious code into legitimate, widely-trusted packages and dramatically amplify the campaign's downstream reach. The four-account rotation structure ( frengki0707 → raya4321 / cketol → frengki4321 ) demonstrates deliberate operational resilience with a design intended to survive partial takedowns. Detection teams should prioritize alerting on -internal- NPM package resolution events in CI/CD pipelines, postinstall script execution accessing credential files ( ~/.npmrc , ~/.aws/credentials , ~/.kube/config ), and outbound beacon traffic from build environments as the highest-signal indicators of similar campaigns.
Detection
suspicious_exfiltration_domains
shady-links
IOCs
Malicious Packages
newtontrid@gmail.com / frengki4321 — 7 versions across 5 packages
# | Package Name | Version(s) | Published | Exfil Endpoint |
|---|---|---|---|---|
1 | ac-sasskit-beta | 1.0.0 | 2026-04-29T16:08Z | webhook.site/8dd22929-a6df-43ba-84c1-96dfa7b2caf1 |
2 | apple-appstore-full-library-utility | 1.0.0 | 2026-04-29T15:56Z | webhook.site/8dd22929-a6df-43ba-84c1-96dfa7b2caf1 |
3 | apple-internal-security-audit-v99 | 1.0.1 , 1.0.2 , 1.0.3 | 2026-04-30T08:00Z – 08:29Z | webhook.site/75d705fa-d3aa-4493-b1b5-a7bdcab0eece |
4 | apple-app-store-server-library-v3 | 1.0.0 | 2026-04-30T15:21Z | webhook.site/75d705fa-d3aa-4493-b1b5-a7bdcab0eece |
5 | apple-internal-security-library-v99 | 1.0.0 | 2026-04-30T15:23Z | webhook.site/75d705fa-d3aa-4493-b1b5-a7bdcab0eece · 3f4a9900d99117.lhr.life |
npmtpoc@gmail.com / raya4321 — 12 packages
# | Package Name | Exfil Endpoint | Notes |
|---|---|---|---|
6 | apple-security-internal-scanner-v3 | webhook.site/d9f34800-21dd-4668-8773-1f3c7ea8b1be | Full harvest (env, npmrc, git, AWS creds) |
7 | apple-infra-ultimate-bypass | webhook.site/1324ffab-98a9-4f19-8f72-4bbaad684aaf | GCP + cloud infra exfil |
8 | apple-infra-gcp-leak | webhook.site/1324ffab-98a9-4f19-8f72-4bbaad684aaf | GCP + cloud infra exfil |
9 | apple-infra-final-escape | webhook.site/1324ffab-98a9-4f19-8f72-4bbaad684aaf | GCP + cloud infra exfil |
10 | apple-infra-network-v2 | webhook.site/1324ffab-98a9-4f19-8f72-4bbaad684aaf | GCP + cloud infra exfil |
11 | apple-internal-pki-utils | webhook.site/9a376595-d347-4110-ac32-814e6e2f0754 | Cloud infra |
12 | apple-cloud-infrastructure-monitor | webhook.site/9a376595-d347-4110-ac32-814e6e2f0754 | Cloud infra |
13 | aliyun-internal-config | webhook.site/bebcbad8-da0e-43e1-af8d-9d069ca3bd42 | Alibaba-lure exfil |
14 | alicloud-pop-core | webhook.site/bebcbad8-da0e-43e1-af8d-9d069ca3bd42 | Alibaba-lure exfil |
15 | agents-a365-runtime | webhook.site/85f78e76-dc73-4cb5-a65c-27f2c10db591 · webhook.site/42fb16cd-cddc-4a22-a7aa-ea6505ede8d6 | Token hunter ( NPM_TOKEN , GITHUB_TOKEN ) · K8s/cloud control plane |
16 | frank-at-alibaba-internal | webhook.site/bebcbad8-da0e-43e1-af8d-9d069ca3bd42 · webhook.site/162f1419-988b-4611-9d44-c0df27e0d579 | Delayed exfil (5 min timer) |
17 | npm-global-util | webhook.site/85f78e76-dc73-4cb5-a65c-27f2c10db591 · webhook.site/44a48e8a-8ab6-454b-b36b-a05458f90a92 · webhook.site/4cc39194-f2e3-4c84-98dd-47a011c95bd9 | Token hunter · DB link discovery · Recon |
ipelapple@gmail.com / cketol — 10 packages
# | Package Name | Exfil Endpoint | Notes |
|---|---|---|---|
18 | apple-app-store-server-library-poc | webhook.site/d9f34800-21dd-4668-8773-1f3c7ea8b1be · webhook.site/c14a0e2c-eb0f-41ef-ae64-d2326b9fb8e7 · webhook.site/3c76946e-8291-4b6d-9d98-5f033b100113 · webhook.site/03d518f5-f368-44cc-bb1d-c1f89e19a028 · webhook.site/be176743-265c-4df7-bbfc-6916d8f247c5 · webhook.site/9134cc4f-17d8-4cbc-b8c7-050ffd78f07b · webhook.site/58272486-8502-44d9-9fa2-0bbf5215e885 | THE_ULTIMATE_DUMP (kube, S3, GCP, git); credential dump across multiple versions |
19 | apple-internal-config | webhook.site/2588012e-c9ab-4d1e-ba27-9abcfca70ed2 · webhook.site/7ea2f4ee-cd3f-4aac-9464-802af0638c66 | Credential dump |
20 | apple-infra-escape-audit | webhook.site/1324ffab-98a9-4f19-8f72-4bbaad684aaf | GCP + cloud infra exfil |
21 | apple-infra-stealth-audit | webhook.site/1324ffab-98a9-4f19-8f72-4bbaad684aaf | GCP + cloud infra exfil |
22 | gcp-internal-research-poc | webhook.site/58272486-8502-44d9-9fa2-0bbf5215e885 | THE_ULTIMATE_DUMP |
23 | frank-newton3-db-poc | webhook.site/3982c49d-5a5f-4cf7-9e9c-596863ed56c5 · webhook.site/9134cc4f-17d8-4cbc-b8c7-050ffd78f07b | Database hunting |
24 | frank-newton3-db-final | webhook.site/3982c49d-5a5f-4cf7-9e9c-596863ed56c5 | Database hunting |
25 | frank-newton3-user-hunt | webhook.site/3982c49d-5a5f-4cf7-9e9c-596863ed56c5 | Database hunting |
26 | frank-newton3-final-audit | webhook.site/3982c49d-5a5f-4cf7-9e9c-596863ed56c5 | Database hunting |
27 | internal-sys-audit-check | webhook.site/7ea2f4ee-cd3f-4aac-9464-802af0638c66 | System audit |
getkontakfrank@gmail.com / frengki0707 — 11 packages
# | Package Name | Exfil Endpoint | Notes |
|---|---|---|---|
28 | apple-internal-test-utility | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
29 | apple-cktool-internal-api-v9 | webhook.site/5eb35918-f014-45e8-a5c0-e2ac953b50df | Google/Apple lure |
30 | frank-apple-sync-service | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
31 | frank-research-poc-apple | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
32 | google-cloud-internal-core-utils | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
33 | google-logging-utils-internal | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
34 | google-cloud-mono-repo-helper | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
35 | google-cloud-internal-build-helper | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
36 | google-internal-cloud-audit-security-check | webhook.site/5eb35918-f014-45e8-a5c0-e2ac953b50df | Google/Apple lure |
37 | frank-bot-gogle-cloning | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Google-lure exfil |
38 | @frengki0707/google-cloud-clone | webhook.site/901b9cf5-8187-4012-a379-11351769881e | Scoped package, Google-lure |
Threat Actor Identities
NPM Username | Attribution | Active Period | |
|---|---|---|---|
getkontakfrank[@]gmail.com | frengki0707 | Earliest actor | 2026-04-24 – 2026-04-26 |
npmtpoc[@]gmail.com | raya4321 | Broadest campaign scope | 2026-04-27 – 2026-04-29 |
ipelapple[@]gmail.com | cketol | Apple/frank-newton3 series | 2026-04-27 – 2026-04-29 |
newtontrid[@]gmail.com | frengki4321 | Account rotation of frengki0707 | 2026-04-29 – 2026-04-30 |
TTPs
TTP | MITRE Reference | Evidence in Package Names |
|---|---|---|
Dependency Confusion | T1195.001 | Internal-sounding names ( apple-internal-* , aliyun-internal-* ) |
Typosquatting | T1195.001 | frank-bot-gogle-cloning , @frengki0707 |
Credential Access | T1552 | gcp-leak , pki-utils , internal-config |
Exfiltration | T1041 | db-final , user-hunt , final-escape |
Defense Evasion | T1036 | stealth-audit , bypass , escape |
Reconnaissance | T1595 | security-scanner , audit-check , user-hunt |
Exfiltration Domains
Domain | Type | Packages Involved | Notes |
|---|---|---|---|
webhook[.]site | Primary exfil | 34 packages | Real-time data collection platform |
ifconfig[.]me | IP reconnaissance | 6 packages | Public IP lookup — victim fingerprinting |
franki[.]requestcatcher[.]com | Secondary exfil | 4 packages | npmtpoc + getkontakfrank |
metadata[.]google[.]internal | Cloud metadata | 4 packages | GCP instance metadata endpoint |
frank-apple[.]requestcatcher[.]com | Secondary exfil | 1 package | getkontakfrank |
3f4a9900d99117[.]lhr[.]life | Dep. confusion ping | 1 package | apple-internal-security-library-v99 — DEP_CONFUSION_SUCCESS |
4f208cd04f6300[.]lhr[.]life | Dep. confusion ping | 1 package | apple-app-store-server-library-v3 — DEP_CONFUSION_POC |
bea39e3b425909[.]lhr[.]life | Dep. confusion ping | 2 packages | newtontrid packages |
Data Targeted
Priority | Target | Method | Responsible Cluster(s) | Specific Packages |
|---|---|---|---|---|
1 | System identity | whoami , hostname , uname -a , id | All clusters (via -poc packages) | frank-newton3-db-poc , gcp-internal-research-poc , apple-app-store-server-library-poc |
2 | NPM auth tokens | ~/.npmrc , NPM_TOKEN , NODE_AUTH_TOKEN | Frank Toolkit + Generic | @frengki0707/google-cloud-clone , npm-global-util , frank-newton3-db-poc |
3 | Cloud credentials — AWS | ~/.aws/credentials , AWS_ACCESS_KEY_ID | Apple (infra packages), Generic | apple-infra-ultimate-bypass , apple-infra-network-v2 , internal-sys-audit-check |
3 | Cloud credentials — GCP | gcloud auth list , service account JSON | Google/GCP cluster | gcp-internal-research-poc , google-cloud-internal-core-utils , frank-bot-gogle-cloning |
3 | Cloud credentials — Aliyun | Aliyun access key / secret | Alibaba/Aliyun cluster | aliyun-internal-config , alicloud-pop-core , frank-at-alibaba-internal |
4 | Git/CI auth | ~/.git-credentials , GITHUB_TOKEN | Google cluster + Generic | google-cloud-mono-repo-helper , google-cloud-internal-build-helper , agents-a365-runtime |
5 | Docker credentials | ~/.docker/config.json | Apple + Generic | apple-cloud-infrastructure-monitor , npm-global-util |
6 | Kubernetes config | ~/.kube/config | Google/GCP cluster | google-cloud-internal-core-utils , gcp-internal-research-poc |
7 | SSH keys | ~/.ssh/id_rsa , known_hosts | Frank Toolkit | frank-newton3-user-hunt (explicitly named) |
8 | Database credentials | .env , DB_* , MySQL/Postgres dumps | Frank Toolkit | frank-newton3-db-poc , frank-newton3-db-final (explicitly named) |
9 | GCP resources | gsutil ls , Artifact Registry | Google cluster | google-internal-cloud-audit-security-check , frank-bot-gogle-cloning |
10 | AWS resources | aws s3 ls , IMDSv1 169.254.169.254 | Apple infra packages | apple-infra-gcp-leak , apple-infra-ultimate-bypass |
Share:
RESOURCES






