Back to Intelligence

LiteLLM privcollect Supply-Chain Compromise + Lumma ClickFix finger.exe Chain: OTX Credential-Theft Detection Pack

SA
Security Arsenal Team
October 22, 2026
12 min read

Threat Summary

Five concurrent OTX pulses point to one enterprise risk pattern: legitimate developer trust channels and familiar web brands are being converted into credential-theft pipelines. The highest-severity event is the compromise of LiteLLM 1.107.0, a Python LLM proxy library with roughly 23 million weekly downloads, published to PyPI and official Docker images for about two hours on 2026-10-21. Reporting aligned to the pulses indicates attackers used stolen GitHub CLI OAuth tokens from three engineers to run a private release workflow against a malicious fork. The payload, associated with the family name privcollect, executed through Python startup files and targeted cloud credentials, private keys, browser data, and AI development tool authentication. The shared infrastructure marker litellm.dev and the URL http://www.litellm.dev/healthcheck should be treated as high-confidence malicious until scoped by internal exposure data.

In parallel, an Amazon-themed ClickFix campaign abused a sponsored Google result for amazon business, a spoofed login page hosted on Google Sites, and a fake CAPTCHA to coerce users into running a command through the obsolete Windows finger utility. That LOLBin chain delivered Doina, Lumma Stealer, and NetSupport Client, creating both immediate credential theft and hands-on remote access risk. A third cluster attributed to suspected Chinese-speaking actor Red Heron shows broad exploitation of WordPress, ZyXEL, and enterprise platforms from a persistent IP, 104.225.153.141, with government record theft and wide geographic targeting. A fourth pulse shows financially motivated actor BUGSTER using jailbroken AI workflows, Hermes Agent with DeepSeek V4, to plan and execute intrusions against education and telecommunications targets in India, including theft of more than 5,200 personal records.

Collectively, the objective is credential and session-material acquisition at scale: cloud keys, AI tool tokens, browser secrets, SSH/private keys, government records, and access that can be resold, reused, or operationalized through dark-web criminal markets even when no marketplace listing is present in the pulses. The common weakness is trust: package registries, Docker images, OAuth tokens, search ads, CAPTCHA friction, CMS plugins, and AI-generated scripting.

Threat Actor / Malware Profile

privcollect / LiteLLM compromise: distribution is supply-chain injection through PyPI and Docker after OAuth token theft against maintainer workflows. Payload behavior centers on Python startup execution, meaning malicious code runs when Python initializes rather than only when the library is explicitly imported. Collection priorities are cloud credential files, AI provider tokens, private keys, browser stores, dotenv-style secrets, and developer machine identity material. C2 or staging indicators in the pulses include litellm.dev and /healthcheck. Persistence is likely opportunistic through Python startup artifacts such as sitecustomize.py, usercustomize.py, .pth files, modified package init.py, container layers, or developer shell profiles; anti-analysis appears to rely on short publication windows, legitimate package provenance, and startup-trigger execution that bypasses casual import review.

Lumma Stealer / Doina / NetSupport ClickFix chain: distribution is malvertising and brand impersonation followed by user-assisted execution. The ClickFix lure instructs the victim to paste or run a command, converting the user into the loader. finger.exe is abused as a living-off-the-land retrieval or execution pivot, after which script interpreters, download cradles, and archive extraction are expected. Lumma Stealer typically targets browser credentials, cookies, autofill, crypto wallets, extension data, and session tokens; NetSupport Client provides remote control and post-theft hands-on access; Doina likely functions as a loader or intermediary staging component. C2 domains observed include grillmasterchef.com, grillrecipespro.com, ashevilleroofingcontractor.com, and IPv4 167.148.201.106. Persistence should be assumed through Run keys, scheduled tasks, services, browser extension residue, or renamed RAT binaries until disproven.

Red Heron: suspected UTC+8, Chinese-speaking operator using persistent infrastructure and vulnerability exploitation against WordPress and edge/network devices. The operational profile favors CVE-driven initial access, webshell or plugin abuse, bulk record extraction, and repeat scanning rather than stealthy low-and-slow intrusion. Treat WordPress plugin/theme uploads, unexpected administrator creation, modified core files, outbound POSTs from web servers, and ZyXEL management-plane exposure as priority leads.

BUGSTER AI-enabled activity: low-to-moderate technical sophistication amplified by jailbroken AI assistants and agent frameworks. Expect generated reconnaissance scripts, exploit proof-of-concepts adapted from public snippets, bulk collection scripts, and operational mistakes such as reused IPs, noisy enumeration, and inconsistent OPSEC. The overlap of CVE-2026-109618 and CVE-2026-109619 across unrelated pulses should be hunted as possible scanner or exploit-kit reuse, but not over-attributed without telemetry.

IOC Analysis

The pulses contain four operational indicator classes: domains, IPv4 addresses, URLs, and file hashes, plus CVE context. Domains such as litellm.dev, grillmasterchef.com, grillrecipespro.com, and ashevilleroofingcontractor.com are best enforced at DNS, secure web gateway, TLS SNI, and proxy layers; also alert on historical DNS answers and newly seen outbound connections even if the domain now resolves benignly. IPv4 indicators 167.148.201.106, 104.225.153.141, and 104.238.38.202 should be blocked at egress and correlated against NetFlow, firewall, EDR network events, cloud egress, and web server logs. The URL http://www.litellm.dev/healthcheck is especially useful because healthcheck beacons can hide in container orchestration and CI runners that normally poll status endpoints.

File hashes are strongest for build and developer-fleet triage: compare SHA256 values against package caches, Docker image layers, pip cache directories, artifact repositories, golden images, and EDR file inventories. Hashes from the LiteLLM pulses include 7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d, 0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a, 668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6, 462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7, c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054, 1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00, 12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484, 7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb, 84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d, 9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25, 03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea, 34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa, and b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465. SOC teams should push indicators into SIEM watchlists, EDR custom IOC feeds, DNS RPZ, proxy block categories, cloud firewall egress rules, CI artifact scanners, and SOAR enrichment. Tooling that decodes or validates context includes urlscan.io and VirusTotal for passive detonation context, GreyNoise for internet-scanning noise, OTX pulses for related infrastructure, Docker Scout or Trivy for image-layer hashes, pip-audit and Syft for package provenance, and YARA only after converting hash context into behavioral families rather than relying on exact-hash matching alone.

Detection Engineering

YAML
---
title: Suspicious Python Startup or Package Initialization Execution
description: Detects Python interpreter launches with startup-file paths, sitecustomize or usercustomize artifacts, package init modification, or outbound LiteLLM compromise beaconing consistent with the OTX LiteLLM supply-chain pulses.
id: 9d5a0c24-7c6c-4e6f-9d4b-litellm000001
status: experimental
author: Security Arsenal
date: 2026/10/22
references:
  - https://securitylabs.datadoghq.com/articles/litellm-compromised-pypi-docker
  - https://socket.dev/blog/litellm-compromise
logsource:
  category: process_creation
  product: windows
detection:
  selection_python:
    Image|endswith:
      - '\python.exe'
      - '\pythonw.exe'
  selection_startup:
    CommandLine|contains:
      - 'sitecustomize'
      - 'usercustomize'
      - '.pth'
      - 'litellm'
      - 'healthcheck'
      - 'AWS_SHARED_CREDENTIALS_FILE'
      - 'gcloud'
      - 'OPENAI_API_KEY'
      - 'ANTHROPIC_API_KEY'
  selection_network:
    CommandLine|contains:
      - 'litellm.dev'
      - 'www.litellm.dev'
  condition: selection_python and (selection_startup or selection_network)
falsepositives:
  - Legitimate Python virtualenv activation, CI test runners, LLM SDK debugging
level: high
tags:
  - attack.initial_access
  - attack.t1195.002
  - attack.execution
  - attack.t1059.006
  - attack.credential_access
  - attack.t1552.001
  - attack.exfiltration
  - attack.t1041
---
title: ClickFix finger.exe LOLBin Retrieval or Execution
description: Detects user-assisted ClickFix chains that abuse Windows finger.exe after fake CAPTCHA lures and precede Lumma Stealer, Doina, or NetSupport Client staging.
id: 7f7a2af1-clickfix-finger-20261022-0002
status: experimental
author: Security Arsenal
date: 2026/10/22
references:
  - https://www.huntress.com/blog/amazon-clickfix-finger
logsource:
  category: process_creation
  product: windows
detection:
  selection_finger:
    Image|endswith: '\finger.exe'
  selection_args:
    CommandLine|contains:
      - '@'
      - 'http'
      - 'https'
      - 'powershell'
      - 'cmd /c'
      - 'mshta'
      - 'rundll32'
      - 'grillmasterchef.com'
      - 'grillrecipespro.com'
      - 'ashevilleroofingcontractor.com'
      - '167.148.201.106'
  selection_parent:
    ParentImage|endswith:
      - '\chrome.exe'
      - '\msedge.exe'
      - '\brave.exe'
      - '\firefox.exe'
      - '\explorer.exe'
      - '\powershell.exe'
      - '\cmd.exe'
  condition: selection_finger and selection_args and selection_parent
falsepositives:
  - Legacy administration use of finger is rare and should be allowlisted only by documented server and account
level: critical
tags:
  - attack.execution
  - attack.t1204
  - attack.t1059
  - attack.defense_evasion
  - attack.t1218
  - attack.command_and_control
  - attack.t1105
---
title: Secret File Access by Scripting or Developer Tool Processes
description: Detects processes associated with Python, Node, browsers, or unknown unsigned binaries accessing cloud, SSH, kube, browser, or dotenv secrets after supply-chain or stealer execution.
id: b8c5d2e6-secrets-access-20261022-0003
status: experimental
author: Security Arsenal
date: 2026/10/22
references:
  - https://socket.dev/blog/litellm-compromise
  - https://www.huntress.com/blog/amazon-clickfix-finger
logsource:
  category: file_event
  product: windows
detection:
  selection_paths:
    TargetFilename|contains:
      - '\.aws\credentials'
      - '\.config\gcloud'
      - '\.kube\config'
      - '\.ssh\id_rsa'
      - '\.ssh\id_ed25519'
      - '\.env'
      - '\Login Data'
      - '\Cookies'
      - '\Web Data'
      - '\Local State'
      - '\.npmrc'
      - '\.pypirc'
      - '\docker\config.json'
  selection_proc:
    Image|endswith:
      - '\python.exe'
      - '\pythonw.exe'
      - '\node.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\cmd.exe'
      - '\rundll32.exe'
      - '\regsvr32.exe'
      - '\chrome.exe'
      - '\msedge.exe'
  filter_signed_browser:
    Image|endswith:
      - '\chrome.exe'
      - '\msedge.exe'
    TargetFilename|contains:
      - '\Cache\'
      - '\GPUCache\'
  condition: selection_paths and selection_proc and not filter_signed_browser
falsepositives:
  - Backup agents, password managers, EDR scanners, developer IDE indexing; tune by signer, path, and parent process
level: high
tags:
  - attack.credential_access
  - attack.t1552.001
  - attack.t1555.003
  - attack.t1003
  - attack.collection
  - attack.t1074
KQL — Microsoft Sentinel / Defender
let BadDomains = dynamic(['litellm.dev','www.litellm.dev','grillmasterchef.com','grillrecipespro.com','ashevilleroofingcontractor.com']);
let BadIPs = dynamic(['167.148.201.106','104.225.153.141','104.238.38.202']);
let BadHashes = dynamic(['7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d','0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a','668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6','462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7','c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054','1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00','12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484','7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb','84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d','9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25','03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea','34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa','b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465']);
union
(
  DeviceNetworkEvents
  | where TimeGenerated > ago(14d)
  | where RemoteUrl has_any (BadDomains) or RemoteIP in (BadIPs)
  | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemoteUrl, RemotePort, ActionType
),
(
  DeviceProcessEvents
  | where TimeGenerated > ago(14d)
  | where FileName in~ ('finger.exe','python.exe','pythonw.exe','powershell.exe','pwsh.exe','cmd.exe','rundll32.exe','regsvr32.exe')
     or ProcessCommandLine has_any ('litellm','sitecustomize','usercustomize','.pth','finger','healthcheck','grillmasterchef','grillrecipespro','ashevilleroofingcontractor')
     or SHA256 in (BadHashes)
  | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256, FolderPath
),
(
  DeviceFileEvents
  | where TimeGenerated > ago(14d)
  | where SHA256 in (BadHashes)
     or FileName in~ ('sitecustomize.py','usercustomize.py','client32.exe','client32.ini')
     or FolderPath has_any ('site-packages','pip\cache','.aws','.config\gcloud','.ssh','.kube','AppData\Local\Google\Chrome\User Data')
  | project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, FolderPath, SHA256, ActionType
)
| sort by TimeGenerated desc
PowerShell
[CmdletBinding()]
param(
  [string]$Out = 'otx-credential-theft-hunt.json',
  [switch]$IncludeHashSweep
)
$badDomains = @('litellm.dev','www.litellm.dev','grillmasterchef.com','grillrecipespro.com','ashevilleroofingcontractor.com')
$badIPs = @('167.148.201.106','104.225.153.141','104.238.38.202')
$badHashes = @(
 '7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d',
 '0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a',
 '668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6',
 '462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7',
 'c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054',
 '1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00',
 '12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484',
 '7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb',
 '84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d',
 '9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25',
 '03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea',
 '34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa',
 'b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465'
)
$result = [ordered]@{ Host=$env:COMPUTERNAME; WhenUtc=(Get-Date).ToUniversalTime(); Findings=@() }
function Add-Finding($Type,$Value,$Detail){ $script:result.Findings += [ordered]@{Type=$Type; Value=$Value; Detail=$Detail; TimeUtc=(Get-Date).ToUniversalTime()} }
try {
  Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue | Where-Object { $badIPs -contains $_.RemoteAddress } | ForEach-Object {
    $p = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
    Add-Finding 'NetworkIOC' $_.RemoteAddress ('PID=' + $_.OwningProcess + '; Process=' + $p.ProcessName + '; Local=' + $_.LocalAddress + ':' + $_.LocalPort)
  }
} catch {}
try {
  Get-DnsClientCache -ErrorAction SilentlyContinue | Where-Object { $name=$_.Entry.ToLower(); $badDomains | Where-Object { $name -like ('*' + $_ + '*') } } | ForEach-Object {
    Add-Finding 'DNSCacheIOC' $_.Entry ($_.Data)
  }
} catch {}
$runKeys = @('HKCU:\Software\Microsoft\Windows\CurrentVersion\Run','HKLM:\Software\Microsoft\Windows\CurrentVersion\Run','HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce','HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce')
foreach ($rk in $runKeys) {
  try {
    Get-ItemProperty -Path $rk -ErrorAction SilentlyContinue | ForEach-Object {
      $_.PSObject.Properties | Where-Object { $_.Name -notlike 'PS*' -and ($_.Value -match 'python|finger|netsupport|client32|litellm|powershell|mshta|rundll32') } | ForEach-Object {
        Add-Finding 'PersistenceRunKey' ($rk + '::' + $_.Name) ([string]$_.Value)
      }
    }
  } catch {}
}
try {
  Get-ScheduledTask -ErrorAction SilentlyContinue | ForEach-Object {
    $txt = ($_ | Out-String)
    if ($txt -match 'python|finger|netsupport|client32|litellm|grillmasterchef|grillrecipespro|ashevilleroofingcontractor|167\.148\.201\.106') { Add-Finding 'ScheduledTask' $_.TaskName ($txt.Substring(0,[Math]::Min(900,$txt.Length))) }
  }
} catch {}
$svc = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue | Where-Object { $_.Name -match 'client32|netsupport' -or $_.PathName -match 'client32|netsupport|AppData|Temp' }
foreach ($s in $svc) { Add-Finding 'Service' $s.Name ($s.PathName) }
$pyRoots = @()
foreach ($base in @($env:LOCALAPPDATA,$env:APPDATA,$env:ProgramFiles,${env:ProgramFiles(x86)})) {
  if ($base -and (Test-Path $base)) { $pyRoots += (Get-ChildItem -Path $base -Directory -Recurse -Depth 3 -ErrorAction SilentlyContinue | Where-Object { $_.FullName -match 'Python|site-packages|Lib\\site-packages' } | Select-Object -ExpandProperty FullName -Unique) }
}
foreach ($root in ($pyRoots | Select-Object -Unique)) {
  $candidates = Get-ChildItem -Path $root -Include 'sitecustomize.py','usercustomize.py','*.pth','__init__.py' -Recurse -ErrorAction SilentlyContinue
  foreach $f in $candidates {
    $hit = $false
    try { $raw = Get-Content -Path $f.FullName -Raw -ErrorAction SilentlyContinue; if ($raw -match 'litellm\.dev|healthcheck|boto3|google\.auth|OPENAI_API_KEY|ANTHROPIC_API_KEY|requests\.post|subprocess|base64') { $hit=$true } } catch {}
    if ($hit) {
      $h = (Get-FileHash -Path $f.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
      Add-Finding 'PythonStartupArtifact' $f.FullName ('SHA256=' + $h + '; BadHash=' + ($badHashes -contains $h))
    }
  }
}
if ($IncludeHashSweep) {
  $sweepRoots = @($env:TEMP,$env:LOCALAPPDATA,$env:USERPROFILE + '\Downloads',$env:USERPROFILE + '\.cache',$env:USERPROFILE + '\.pip')
  foreach $sr in $sweepRoots {
    if (Test-Path $sr) {
      Get-ChildItem -Path $sr -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Length -lt 60MB } | ForEach-Object {
        $h = (Get-FileHash -Path $_.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
        if ($badHashes -contains $h) { Add-Finding 'BadFileHash' $_.FullName ('SHA256=' + $h) }
      }
    }
  }
}
$result | ConvertTo-Json -Depth 6 | Out-File -Encoding UTF8 $Out
Write-Output $Out

Response Priorities

Immediate: block litellm.dev, www.litellm.dev, grillmasterchef.com, grillrecipespro.com, ashevilleroofingcontractor.com, 167.148.201.106, 104.225.153.141, and 104.238.38.202 at DNS, proxy, EDR network control, cloud egress, and email URL rewrite. Search CI logs, artifact registries, Docker digests, pip caches, and developer endpoints for LiteLLM 1.107.0 and the listed SHA256 values; quarantine images built during the exposure window. Hunt for finger.exe launched from browsers or shells, Python startup artifacts, and secret-file access by scripting interpreters. Preserve package manager logs, GitHub audit logs, workflow run IDs, OAuth grant histories, and container build provenance before retention expires.

24 hours: because credential-stealing malware and developer token theft are involved, force verification and rotation for affected identities: GitHub OAuth and CLI tokens, PyPI and Docker Hub credentials, cloud access keys, AI provider keys, SSO sessions, browser-synced passwords, SSH private keys on developer hosts, Kubernetes service accounts, and any secrets present in .env files. Prefer cryptographic revocation over password reset alone; invalidate refresh tokens, revoke sessions, rotate cloud keys, reissue machine credentials, and review newly created admins, deploy keys, workflow files, release workflows, and OAuth app authorizations. For possible Lumma infections, treat browser cookies and session tokens as compromised even if passwords were changed after infection.

1 week: harden the exploited trust paths. Pin package versions, require Sigstore or provenance attestations, isolate CI runners, block release workflows from forks, enforce least-privilege granular tokens for GitHub and package registries, and add canary credentials to developer images. Disable or constrain finger.exe via AppLocker or WDAC, alert on sponsored-search brand traffic, and restrict Google Sites or user-hosted login lookalikes through web isolation for high-risk users. For WordPress and edge devices, patch exposed CVEs, remove unused plugins, enforce WAF virtual patching, lock down ZyXEL management interfaces, and add egress deny-by-default for web servers. Add detections for AI-agent generated tooling by hunting for burst scripting, enumeration loops, and mismatched code quality versus operator tradecraft rather than attempting to block AI usage outright.

Related Resources

Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.