ChocoPoC — a Python RAT Hidden in Fake GitHub PoC Exploits, with a Mapbox Dead-Drop C2

Trojanized "proof-of-concept" repos for hot CVEs pull in a compiled payload (skytext → gradient.so / gradient.pyd) that steals credentials and beacons via a Mapbox dataset dead-drop · targets vulnerability researchers & pentesters · YesWeHack + Sekoia, July 2026
Threat
ChocoPoC (Python RAT)
Severity
ACTIVE / LIVE C2
Type
Supply-chain RAT / infostealer
Access
Fake PoC repo → PyPI dependency
Version
v0.2 · 2026-07-07
Author
HuntPack
Confidence
High (vendor-attributed)
01

Executive Summary

ChocoPoC is a fully-functional Python RAT disclosed jointly by YesWeHack and Sekoia on 2026-07-01 that hides inside fake proof-of-concept (PoC) exploit repositories on GitHub claiming to exploit hot, freshly-disclosed CVEs. The campaign specifically targets vulnerability researchers and pentesters — the people most likely to clone and run an untrusted PoC. As of the report the malware and its servers were still live; researchers explicitly warned not to run any of the identified PoCs.

The trick is dependency-chaining: the PoC declares a dependency on a Python package named frint, which in turn drags in skytext. skytext ships a small compiled native extension — gradient.so on Linux, gradient.pyd on Windows — that executes the moment the PoC is launched. Activation is gated on the presence of a file named EXPLOIT_POC.py / exploit.py / exploit_poc.py (a filename-hash check, 0xF4835C9C), so the payload stays dormant in a sandbox that lacks the full PoC. The skytext package alone was downloaded ~2,400 times, mostly on Linux, with spikes right after major CVE disclosures.

Once live, ChocoPoC harvests browser credentials, cookies, autofill and history (Chrome, Brave, Edge, Firefox), plus local files, notes, shell history, network settings and process lists. For C2 it uses a Mapbox dataset as a dead drop — reading its orders from api.mapbox[.]com, resolving over DNS-over-HTTPS (dns.alidns[.]com, cloudflare-dns[.]com) with domain fronting so traffic looks like ordinary Mapbox API calls. Bulk exfiltration goes to a separate server at 91.132.163.78:8001. Persistence rides trojanized setuptools distutils hooks (_distutils_hack/override.py, a distutils-precedence.pth file), and the payload is heavily armored (timestomping, PEB walking, export hashing, anti-debug via CheckRemoteDebuggerPresent and hardware breakpoints, environmental gating).

Defender priority: The highest-value, lowest-FP angles are installation of the malicious packages (skytext / frint / slogsec), the compiled payload files (gradient.so / gradient.pyd), the Sekoia-published SHA-256 hashes, egress to 91.132.163.78, and git clone of the known fake-PoC repos. This is a developer-workstation threat: focus coverage on engineering, research and pentest hosts (Linux and Windows), and keep offensive-security tooling off production identities.

02

Source Review & Web Hunter Notes

TierSourceKey FindingCarry Fwd
1 · VendorSekoia — "Don't eat the ChocoPoCs! How vulnerability researchers were repeatedly targeted by trojanised exploits" (2026-07-01)Primary technical analysis: dependency chain (frint→skytext), gradient.so/.pyd payload, filename-gated activation, Mapbox dead-drop C2, DoH + domain fronting, exfil IP, distutils persistence, anti-analysis, full IOC set with SHA-256yes
1 · VendorYesWeHack — "Don't eat the ChocoPoCs! Vulnerability researchers were targeted by trojanised exploits" (2026-07-01)Joint disclosure: 7 fake PoC repos tied to high-profile CVEs, ~2,400 skytext downloads, warning that servers were liveyes
2 · PressThe Hacker News / BleepingComputer / Cyber Security News — ChocoPoC Mapbox dead-drop & Python RATCorroborate the Mapbox dead-drop, DoH resolution, credential theft, researcher targeting, prior slogsec/logcrypt.cryptography linkpartial

Every atomic IOC below (SHA-256 hashes, package names, payload filenames, exfil IP, Mapbox/DoH domains, fake-repo paths) traces to the Sekoia / YesWeHack indicator set. The package/payload names, hashes and the 91.132.163.78 exfil server are durable; api.mapbox.com and cloudflare-dns.com are legitimate services abused as carriers, so those are hunt/scoped indicators, not blanket blocks.

03

Hunt Brief & Attack Chain

ChocoPoC is cross-platform (Linux and Windows). The CQL below uses the CrowdStrike-normalized process/file/network events, which apply to both the Windows sensor and Falcon for Linux; confirm Linux sensor coverage on engineering/research hosts before relying on it.

Hunt hypotheses (fidelity-ordered)

  1. H1 (high): A host installed a malicious ChocoPoC package (skytext / frint / slogsec) via pip. Delivery.
  2. H2 (high): The compiled payload gradient.so / gradient.pyd was written to disk (into a skytext package dir). Payload drop.
  3. H3 (high): A file matching a Sekoia-published ChocoPoC SHA-256 executed or was written. Atomic.
  4. H4 (high): A host connected to the exfil server 91.132.163.78 (port 8001). Covers T1041.
  5. H5 (high): A host git cloned one of the known fake-PoC repos (lincemorado97 / ogenich / bolubey). Early warning.
  6. H6 (medium): A Python interpreter resolved the Mapbox dead-drop / DoH carriers (api.mapbox.com, dns.alidns.com, cloudflare-dns.com). Covers T1071.001 / T1090.004.
  7. H7 (medium): A Python interpreter made outbound connections to a public IP shortly after running a PoC. Beacon/exfil generic.
  8. H8 (medium): Trojanized setuptools persistence appeared (_distutils_hack/override.py, distutils-precedence.pth). Covers T1546.016 / T1574.006-style startup hook.

Attack chain

StepBehaviorTelemetryHunt Angle
1 · LureResearcher clones a fake PoC repo for a hot CVE from GitHubProcessRollup2 (git)Q5
2 · DeliveryPoC depends on frint → skytext; pip pulls the malicious packagesProcessRollup2 (pip), FileCreateInfoQ1
3 · Payloadskytext ships gradient.so / gradient.pyd, executed when the PoC launchesPeFileWritten / FileCreateInfoQ2, Q3
4 · Activation gateRuns only if EXPLOIT_POC.py / exploit_poc.py present (filename-hash 0xF4835C9C) — sandbox-evasionProcessRollup2native hunts
5 · CollectionSteals browser creds/cookies/history, files, shell history, process listFile access / ProcessRollup2native hunts, Q7
6 · C2 (dead drop)Reads orders from a Mapbox dataset via api.mapbox.com over DoH + domain frontingDnsRequest, NetworkConnectIP4Q6, Q7
7 · ExfilBulk upload to 91.132.163.78:8001NetworkConnectIP4Q4
8 · PersistenceTrojanized distutils hooks (override.py, distutils-precedence.pth) re-run at Python startupFileCreateInfo / PeFileWrittenQ8
04

Consolidated IOC Table

All values published by Sekoia / YesWeHack. Package names, payload filenames, SHA-256 hashes and the 91.132.163.78 exfil server are durable indicators. api.mapbox.com, cloudflare-dns.com and dns.alidns.com are legitimate services abused as carriers — treat them as scoped hunt indicators (correlate with a Python interpreter / PoC context), not blanket blocks.

TypeValueConfActionContext
ipv491.132.163.78 (port 8001)highblockChocoPoC bulk-exfil server
urlhxxp://91.132.163.78:8001/assets/static/bundle.ext.min.de5b2bc9.jshighblockexfil endpoint (fake JS path)
sha25693739477cd379adef95126b22758c0e644282d2028dd297328ce856fa111dd06highdetectskytext v1.1.0 (PyPI)
sha25617997e9e0256d0f5d5d21a4852c37f16b338e4bb9c2bec09bdfd822b24aa76b4highdetectfrint v0.1.2 (PyPI)
sha2565abd45d6f4a1705dca55d882f017d4768888dce9ad99cea40b3da35c23de5caehighdetectslogsec (earlier campaign)
sha25640569318e89db751ff3886b2617d990d8a343f0d1d8727b7f978a28129ca36bchighdetectgradient.pyd (Windows payload)
sha256320b29844892e3c59bc6fcb07e701b2b3230a37cb4a13176174e9e294ec6d43ehighdetectgradient.so (Linux payload)
packageskytext · frint · slogsec · logcrypt.cryptographyhighhuntmalicious PyPI packages
filenamegradient.pyd / gradient.sohighhuntcompiled RAT payload
domainapi.mapbox[.]com (dead drop)medhuntlegit service abused as C2 carrier
domaindns.alidns[.]com · cloudflare-dns[.]commedhuntDoH resolvers used for covert resolution
repogithub.com/{lincemorado97,ogenich,bolubey}/CVE-…highhuntfake PoC repos (7 known)
triggerEXPLOIT_POC.py / exploit.py / exploit_poc.py (hash 0xF4835C9C)medhuntactivation gate (sandbox evasion)
persistence_distutils_hack/override.py · distutils-precedence.pthmedhunttrojanized setuptools startup hook
envZEBUWIAKGPHOQAP006 · JKHWQVEKRASDF12medhuntanti-recursion env-var markers
05

Affected Surface & Telemetry Matrix

SurfaceRequired TelemetryPriorityGap Risk
Developer / research / pentest hosts (Linux)ProcessRollup2 (Falcon for Linux)CriticalMed — depends on Linux sensor coverage on eng hosts
Developer / research hosts (Windows)ProcessRollup2 / SyntheticProcessRollup2CriticalLow
File writes (packages, gradient payload, .pth hooks)PeFileWritten / FileCreateInfoHighMed — .so writes vary by Linux sensor config
Egress (exfil IP, Mapbox dead drop, DoH)NetworkConnectIP4, DnsRequestHighMed — DoH + domain fronting hide the true destination
Browser credential storesFile access to Login Data / cookies DBMedHigh — read access not always in EDR; use native hunt (§7)
06

ATT&CK Mapping

TacticTechniqueObserved BehaviorCoverage
Initial AccessT1195.001 Supply Chain: Software DependenciesFake PoC repo → frint → skytext malicious PyPI packagesQ1, Q5
ExecutionT1204.002 User Execution: Malicious FileResearcher runs the PoC; gradient.so/.pyd executesQ2, Q3
Defense EvasionT1497 Virtualization/Sandbox EvasionPayload gated on EXPLOIT_POC.py presence (hash 0xF4835C9C); anti-debug, timestomping, PEB walkingnative hunts
Credential AccessT1555.003 Credentials from Web BrowsersSteals Chrome/Brave/Edge/Firefox creds, cookies, autofill, historyQ7, native hunts
CollectionT1005 Data from Local SystemFiles, notes, shell history, network settings, process listsnative hunts
Command & ControlT1071.001 Web Protocols / T1102 Web ServiceMapbox dataset dead drop via api.mapbox.comQ6
Command & ControlT1090.004 Proxy: Domain Fronting / T1071.004 DNSDoH resolution (alidns/cloudflare-dns) + domain frontingQ6
ExfiltrationT1041 Exfiltration Over C2 ChannelBulk upload to 91.132.163.78:8001Q4, Q7
PersistenceT1546.016 Installer Packages / .pth startup hookTrojanized _distutils_hack + distutils-precedence.pth run at Python startupQ8
07

Native Audit-Log Hunts (non-CQL)

  • PyPI / pip inventory: On developer, research and CI hosts, inventory installed packages and flag any presence of skytext, frint, slogsec, or logcrypt.cryptography (pip list / SBOM / artifact-proxy logs). Check internal PyPI mirror download logs for these names.
  • Payload file sweep: Search site-packages trees for gradient.so / gradient.pyd and for a distutils-precedence.pth or modified _distutils_hack/override.py that did not come from a clean setuptools install.
  • Browser credential access: On hosts that ran a suspect PoC, hunt for a Python process opening Chrome/Edge/Brave Login Data / Network\Cookies or the Firefox logins.json/key4.db — a Python interpreter touching browser secret stores is the stealer tell.
  • Environment markers: Check for the anti-recursion env vars ZEBUWIAKGPHOQAP006 and JKHWQVEKRASDF12 in process environments on suspect hosts.
  • GitHub / proxy logs: Search web-proxy / git-server logs for clones of the fake-PoC repos (owners lincemorado97, ogenich, bolubey), and rotate any credentials that were present on a host that ran one.
08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.
Q1 · pip install of a malicious ChocoPoC package
CONF HIGHFP LOWCOST LOW

Looks for: a pip install command line referencing skytext, frint, or slogsec — direct or transitive install of the ChocoPoC delivery packages. Works on Windows and Linux.

// HUNT: pip install of a malicious ChocoPoC package
// MITRE: T1195.001
// CONF: high  FP: low  COST: low | REQUIRES: ProcessRollup2
// FALSE POSITIVES: none expected — these are known-bad package names
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| CommandLine=/\b(pip|pip3|uv|python|python3)\b/i
| CommandLine=/\binstall\b/i
| CommandLine=/\b(skytext|frint|slogsec)\b/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine], limit=200)
Q2 · gradient.so / gradient.pyd payload written to disk
CONF HIGHFP LOWCOST LOW

Looks for: the compiled ChocoPoC payload gradient.so (Linux) or gradient.pyd (Windows) being written — it lands inside the skytext package directory during install. Distinctive filename → very low FP.

// HUNT: ChocoPoC compiled payload gradient.so / gradient.pyd written
// MITRE: T1204.002
// CONF: high  FP: low  COST: low | REQUIRES: PeFileWritten / FileCreateInfo
#event_simpleName=/PeFileWritten|NewExecutableWritten|FileCreateInfo/
| TargetFileName=/gradient\.(so|pyd)$/i
| table([@timestamp, aid, ComputerName, TargetFileName, SHA256HashData], limit=200)
Q3 · Sekoia-published ChocoPoC SHA-256 hashes
CONF HIGHFP LOWCOST LOW

Looks for: execution or write of any Sekoia-listed ChocoPoC package or payload SHA-256. Atomic — promote straight to a Custom IOC block (see §10).

// HUNT: ChocoPoC package / payload known-bad SHA-256 (Sekoia)
// MITRE: T1195.001, T1204.002
// CONF: high  FP: low  COST: low | REQUIRES: ProcessRollup2 / PeFileWritten
#event_simpleName=/ProcessRollup2|PeFileWritten|NewExecutableWritten/
| in(SHA256HashData, values=["93739477cd379adef95126b22758c0e644282d2028dd297328ce856fa111dd06", "17997e9e0256d0f5d5d21a4852c37f16b338e4bb9c2bec09bdfd822b24aa76b4", "5abd45d6f4a1705dca55d882f017d4768888dce9ad99cea40b3da35c23de5cae", "40569318e89db751ff3886b2617d990d8a343f0d1d8727b7f978a28129ca36bc", "320b29844892e3c59bc6fcb07e701b2b3230a37cb4a13176174e9e294ec6d43e"])
| table([@timestamp, aid, ComputerName, UserName, FileName, FilePath, SHA256HashData], limit=max)
Q4 · Egress to the ChocoPoC exfil server (91.132.163.78)
CONF HIGHFP LOWCOST LOW

Looks for: any outbound connection to the dedicated ChocoPoC bulk-exfil server 91.132.163.78 (observed on port 8001). Dedicated actor infrastructure → any hit is high-signal.

// HUNT: ChocoPoC exfil server connection
// MITRE: T1041
// CONF: high  FP: low  COST: low | REQUIRES: NetworkConnectIP4
#event_simpleName=/NetworkConnectIP4/
| RemoteAddressIP4=/^91\.132\.163\.78$/
| table([@timestamp, aid, ComputerName, ContextBaseFileName, RemoteAddressIP4, RemotePort], limit=200)
Q5 · git clone of a known fake-PoC repo
CONF HIGHFP LOWCOST LOW

Looks for: a command line referencing one of the known fake-PoC repo owners (lincemorado97, ogenich, bolubey) — the earliest signal, fired at clone time before any payload runs. Distinctive strings → very low FP.

// HUNT: Clone/reference of a known ChocoPoC fake-PoC repo
// MITRE: T1195.001, T1204.002
// CONF: high  FP: low  COST: low | REQUIRES: ProcessRollup2
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| CommandLine=/(lincemorado97|ogenich|bolubey)/i
| CommandLine=/(github|CVE-20)/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine], limit=200)
Q6 · Python interpreter resolving the Mapbox / DoH carriers
CONF MEDFP MEDCOST MED

Looks for: a Python process resolving the Mapbox dead-drop (api.mapbox.com) or a DoH resolver (dns.alidns.com, cloudflare-dns.com) — the C2 carrier channel. FP: legitimate Python apps use Mapbox/Cloudflare too, so scope by the interpreter context and correlate with Q1/Q2/Q5 on the same host.

// HUNT: ChocoPoC C2 carriers resolved by a Python interpreter
// MITRE: T1071.001, T1071.004, T1090.004, T1102
// CONF: medium  FP: medium  COST: medium | REQUIRES: DnsRequest
// FALSE POSITIVES: api.mapbox.com / cloudflare-dns.com are legitimate services
// TUNING: correlate with Q1/Q2/Q5 on the same aid; exclude sanctioned mapping/DoH apps
#event_simpleName=/DnsRequest/
| DomainName=/^(api\.mapbox\.com|dns\.alidns\.com|cloudflare-dns\.com)$/i
| ContextBaseFileName=/^(python3?|python\.exe|uv|pip3?)$/i
| table([@timestamp, aid, ComputerName, DomainName, ContextBaseFileName], limit=200)
Q7 · Python interpreter beaconing to a public IP
CONF MEDFP MEDCOST MED

Looks for: a Python interpreter making outbound connections to non-RFC1918 destinations — useful during IR on a host that ran a suspect PoC to surface the dead-drop/exfil traffic when the domain is fronted. FP: Python legitimately calls out; scope to suspect hosts and pivot on the remote address.

// HUNT: Python interpreter outbound to a public IP (beacon/exfil, IR-scoped)
// MITRE: T1041, T1071.001
// CONF: medium  FP: medium  COST: medium | REQUIRES: NetworkConnectIP4
// FALSE POSITIVES: Python apps make legitimate outbound calls
// TUNING: run host-scoped on a suspect aid; exclude known-good internal/SaaS ranges
#event_simpleName=/NetworkConnectIP4/
| ContextBaseFileName=/^(python3?|python\.exe)$/i
| RemoteAddressIP4!=/^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.|169\.254\.)/
| table([@timestamp, aid, ComputerName, ContextBaseFileName, RemoteAddressIP4, RemotePort], limit=200)
Q8 · Trojanized setuptools distutils persistence write
CONF MEDFP HIGHCOST LOW

Looks for: writes to the setuptools distutils shim (distutils-precedence.pth, _distutils_hack/override.py) that ChocoPoC trojanizes for Python-startup persistence. FP: HIGH — these files ship legitimately with setuptools, so this is hunt-only: use it to locate candidates, then confirm the file was modified outside a clean pip/setuptools install (hash it against a known-good copy). Never auto-block.

// HUNT: ChocoPoC distutils startup-hook persistence (hunt-only)
// MITRE: T1546.016
// CONF: medium  FP: high  COST: low | REQUIRES: PeFileWritten / FileCreateInfo
// FALSE POSITIVES: these files ship with setuptools — writes are normal on install
// TUNING: hunt-only; confirm modification outside a pip install and hash vs known-good; do not block
#event_simpleName=/PeFileWritten|NewExecutableWritten|FileCreateInfo/
| TargetFileName=/(distutils-precedence\.pth|_distutils_hack.override\.py)$/i
| table([@timestamp, aid, ComputerName, TargetFileName, ContextBaseFileName], limit=200)
09

CrowdStrike Custom IOA Recommendations

IOA NamePatternActionExclusions
ChocoPoC — Malicious Package Installpip install skytext/frint/slogsec (Q1)Detect (high)None expected — known-bad names
ChocoPoC — gradient Payload Writtengradient.so / gradient.pyd write (Q2)Detect → Block (after baseline)None expected — distinctive filename
ChocoPoC — Exfil ServerConnection to 91.132.163.78 (Q4)Detect (high) → IOC blockNone — dedicated actor infra
ChocoPoC — Fake-PoC Repo CloneCmdLine lincemorado97/ogenich/bolubey (Q5)Detect (high)None expected

Promotion path: validate the high-CONF/low-FP queries (Q1, Q2, Q4, Q5) against 7–14 days of baseline on developer/research hosts, confirm zero benign hits, then promote to Custom IOAs in detect mode; escalate Q2 to block once clean. Q3 hashes and the 91.132.163.78 IP → Custom IOC Management (block).

10

Machine-Readable IOC Appendix

One-click blocks for SOC tooling. Hashes and the exfil IP are Sekoia/YesWeHack-published; swap expirations to fit your policy. The Mapbox/DoH domains are legitimate services abused as carriers — hunt/scope, do not blanket-block.

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
ipv4,91.132.163.78,block,critical,2026-12-31,ChocoPoC exfil server,tool:ChocoPoC;kind:exfil
sha256,93739477cd379adef95126b22758c0e644282d2028dd297328ce856fa111dd06,prevent,critical,2026-12-31,skytext v1.1.0,tool:ChocoPoC;pkg:skytext
sha256,17997e9e0256d0f5d5d21a4852c37f16b338e4bb9c2bec09bdfd822b24aa76b4,prevent,critical,2026-12-31,frint v0.1.2,tool:ChocoPoC;pkg:frint
sha256,5abd45d6f4a1705dca55d882f017d4768888dce9ad99cea40b3da35c23de5cae,prevent,critical,2026-12-31,slogsec,tool:ChocoPoC;pkg:slogsec
sha256,40569318e89db751ff3886b2617d990d8a343f0d1d8727b7f978a28129ca36bc,prevent,critical,2026-12-31,gradient.pyd Windows payload,tool:ChocoPoC;kind:payload
sha256,320b29844892e3c59bc6fcb07e701b2b3230a37cb4a13176174e9e294ec6d43e,prevent,critical,2026-12-31,gradient.so Linux payload,tool:ChocoPoC;kind:payload
Behavioral Signatureshunt logic
[ ChocoPoC behaviors ]
- pip install of skytext / frint / slogsec / logcrypt.cryptography
- gradient.so (Linux) or gradient.pyd (Windows) in a skytext pkg dir
- Payload activates only if EXPLOIT_POC.py / exploit_poc.py present
  (filename-hash gate 0xF4835C9C) - dormant in bare sandboxes
- Python process reading browser Login Data / cookies / logins.json
- DNS to api.mapbox.com dead drop + DoH (alidns / cloudflare-dns)
  with domain fronting
- Bulk exfil to 91.132.163.78:8001
  (/assets/static/bundle.ext.min.de5b2bc9.js)
- Persistence: _distutils_hack/override.py + distutils-precedence.pth
- Env markers ZEBUWIAKGPHOQAP006 / JKHWQVEKRASDF12
- git clone of lincemorado97 / ogenich / bolubey CVE repos
Fake-PoC Repos & Toolingattribution
Malware:  ChocoPoC (Python RAT) - Sekoia / YesWeHack
Prior:    slogsec + logcrypt.cryptography (late-2025, same operator)
Delivery: PyPI frint -> skytext -> gradient.so / gradient.pyd
C2:       api.mapbox.com dataset dead drop (DoH + domain fronting)
Exfil:    91.132.163.78:8001
Fake PoC repos (7 known):
  github.com/lincemorado97/CVE-2025-64446_CVE-2025-58034
  github.com/lincemorado97/CVE-2025-55182_CVE-2025-66478
  github.com/lincemorado97/CVE-2025-14847
  github.com/ogenich/CVE-2026-10520
  github.com/ogenich/CVE-2026-48908
  github.com/bolubey/CVE-2026-0257
  github.com/bolubey/CVE-2026-50751
Hardening / Audit Checklistprevent checklist
[ ] Run untrusted PoCs only in a disposable, network-isolated VM/container
[ ] Inventory dev/CI hosts for skytext / frint / slogsec / logcrypt.cryptography
[ ] Sweep site-packages for gradient.so / gradient.pyd + distutils-precedence.pth
[ ] Block egress to 91.132.163.78; alert Python -> api.mapbox.com / DoH resolvers
[ ] Internal PyPI proxy: allow-list / quarantine new/low-reputation packages
[ ] Separate offensive-security tooling from production identities/SSO
[ ] Rotate creds/cookies on any host that ran a suspect PoC
[ ] Disable/monitor DoH from endpoints so covert resolution is visible
11

Detection Validation Gates

  • Telemetry ready: Confirm ProcessRollup2, PeFileWritten/FileCreateInfo, DnsRequest and NetworkConnectIP4 are flowing from developer/research/pentest hosts — and that Falcon for Linux is deployed on Linux engineering hosts, since skytext was primarily downloaded on Linux.
  • Benign baseline: Run Q6 and Q7 (Python egress) over 7–14 days on engineering hosts; record sanctioned Python apps that call Mapbox/Cloudflare, and exclude those before alerting.
  • Positive test: In an isolated VM, pip install a harmless package renamed skytext and confirm Q1 fires; drop a benign file named gradient.pyd into site-packages and confirm Q2 fires; add a firewall log/route to 91.132.163.78 and confirm Q4 fires.
  • Promotion: Only promote Q1/Q2/Q4/Q5 to detect/block after zero benign hits across the baseline window. Q8 stays hunt-only (FP high).
12

Hardening — Tiered & Deployable

Immediate (this week — low risk)
  • Block egress to 91.132.163.78 at firewall/proxy and load the ChocoPoC hashes (Q3) as Custom IOCs. (MITRE M1031 Network Intrusion Prevention.)
  • Analyst guidance + policy: untrusted PoC exploits are run only in a disposable, network-isolated VM or container — never on a workstation with production credentials or SSO cookies. (M1048 Application Isolation and Sandboxing.)
  • Inventory + quarantine the malicious packages (skytext, frint, slogsec, logcrypt.cryptography) across dev/CI hosts and your internal PyPI mirror. (M1047 Audit.)
Near term (1–4 weeks — pilot first)
  • Internal package proxy with allow-listing: route pip through a controlled proxy (e.g. Artifactory/devpi) that quarantines new or low-reputation packages and blocks direct PyPI on managed hosts. (M1016 Vulnerability Scanning / M1051 Update Software.)
  • Make DoH visible: disable or force-proxy DNS-over-HTTPS from endpoints so ChocoPoC's covert resolution (alidns/cloudflare-dns) is inspectable, and alert on non-browser processes performing DoH. (M1037 Filter Network Traffic.)
  • Least-privilege browsers for researchers: use dedicated research browser profiles with no saved production credentials, so a browser-stealer yields nothing of value. (M1027 Password Policies / M1017 User Training.)
Strategic (1–3 months — architectural)
  • Dedicated offensive-security enclave: segment pentest/research hosts into their own network/identity zone with monitored egress, so a compromised researcher box can't reach production or SSO. (M1030 Network Segmentation / M1026 Privileged Account Management.)
  • SBOM + dependency provenance in CI so transitive pulls of packages like frintskytext are flagged before they land on a host. (M1016 Vulnerability Scanning.)
  • Phishing-resistant MFA + short-lived tokens everywhere, so stolen cookies/passwords from a stealer are low-value. (M1032 Multi-factor Authentication.)
13

Deployable Playbooks

P1 · Inventory hosts for the malicious ChocoPoC packages (cross-platform)

# Linux / macOS (bash) — run on dev/research hosts or via your fleet tool
for p in skytext frint slogsec logcrypt.cryptography; do
  pip show "$p" 2>/dev/null | grep -E '^(Name|Version|Location):' && echo "FOUND: $p"
done
# Also sweep site-packages for the payload:
find / -type f \( -name 'gradient.so' -o -name 'gradient.pyd' \) 2>/dev/null

P2 · Windows — find the gradient payload and malicious packages

# PowerShell
Get-ChildItem -Path "$env:LOCALAPPDATA\Programs\Python","C:\Python*","$env:APPDATA\Python" `
  -Recurse -Include 'gradient.pyd','gradient.so' -ErrorAction SilentlyContinue |
  Select-Object FullName, Length, LastWriteTime,
    @{n='SHA256';e={(Get-FileHash $_.FullName -Algorithm SHA256).Hash}}
foreach ($p in 'skytext','frint','slogsec') { pip show $p 2>$null }

P3 · Block the exfil server (stopgap host firewall)

# Windows
New-NetFirewallRule -DisplayName 'Block ChocoPoC exfil 91.132.163.78' `
  -Direction Outbound -Action Block -RemoteAddress 91.132.163.78
# Linux (iptables)
iptables -A OUTPUT -d 91.132.163.78 -j DROP
# Prefer an enterprise egress/proxy block; host rules are a per-host stopgap.

P4 · Remove ChocoPoC packages + payload from a confirmed host

# After isolating the host and collecting evidence:
pip uninstall -y skytext frint slogsec logcrypt.cryptography 2>/dev/null
find / -type f \( -name 'gradient.so' -o -name 'gradient.pyd' \
  -o -name 'distutils-precedence.pth' \) -print 2>/dev/null
# Manually review/restore _distutils_hack/override.py from a clean setuptools;
# then rotate every credential/cookie that was present on the host.
14

Containment Runbook

PhaseActionsOwnerEvidence
IsolateNetwork-contain the host in Falcon; preserve memory, the cloned PoC repo, the Python env / site-packages, and shell history; do NOT reboot (lose volatile C2 state).SOCRTR capture, process tree, netconns
EradicateUninstall skytext/frint/slogsec, delete gradient.so/.pyd and the distutils-precedence.pth hook, restore _distutils_hack from clean setuptools; block the exfil IP and ChocoPoC hashes (Q3/Q4).IRRemoved-file hashes, pip diff
Credential recoveryAssume browser secrets are stolen: rotate all saved passwords, invalidate cookies/sessions, revoke tokens/SSH keys and cloud creds present on the host; force re-MFA. ChocoPoC harvests Chrome/Brave/Edge/Firefox stores wholesale.IR + IdPCredential-rotation log
Hunt-backSweep dev/research/CI fleet with Q1–Q8; pivot on the package/payload hashes and the exfil IP; check the internal PyPI mirror and git-server logs for other clones of the fake-PoC repos.Threat HuntFleet query results, mirror/git logs
15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1195.001Malicious PyPI package installQ1YesGood
T1204.002gradient.so/.pyd payload writtenQ2YesGood
Atomic hashesKnown-bad package / payload filesQ3IOCGood
T1041Exfil server connectionQ4YesGood
T1195.001 (early)Fake-PoC repo cloneQ5YesGood
T1071.001 / T1090.004Mapbox dead-drop / DoH carriersQ6Partial (scoped/FP-tuned)
T1041 (fronted)Python beacon to public IPQ7Partial (IR-scoped)
T1546.016distutils startup-hook persistenceQ8Partial (hunt-only, FP high)
T1555.003Browser credential theftGap — file-read of cred stores via native hunt (§7)
T1497Filename-gated sandbox evasionGap — in-process logic; not directly observable

Detection is strongest at the supply-chain delivery (package install, payload write, repo clone), the atomic hashes, and the dedicated exfil IP — all low-FP. The Mapbox dead-drop is deliberately hidden behind DoH + domain fronting, so C2 detection is partial and best paired with making DoH visible (§12). Browser credential theft and the in-process sandbox gate are gaps addressed via native file-access hunts (§7) and disposable-VM policy.

16

Hunt Summary Ticket

TITLE:      ChocoPoC trojanized-PoC Python RAT hunt
SEVERITY:   Critical - live C2, targets researchers/pentesters
SCOPE:      Developer / research / pentest / CI hosts (Linux + Windows);
            internal PyPI mirror; egress/DoH
HYPOTHESIS: A researcher cloned a fake PoC repo; pip pulled frint->skytext;
            gradient.so/.pyd stole browser creds and beaconed via a
            Mapbox dead-drop, exfiltrating to 91.132.163.78:8001.
QUERIES:    Q1 pkg install | Q2 gradient payload | Q3 hashes | Q4 exfil IP
            Q5 fake-PoC repo | Q6 Mapbox/DoH | Q7 python beacon | Q8 .pth persist
DO FIRST:   Q1, Q2, Q4, Q5 (lowest FP, structural) then Q3.
FINDINGS:   <record hosts / packages / payload hashes / exfil hits here>
GAPS:       Browser cred theft + sandbox gate (use §7 native hunts).
ACTIONS:    Block 91.132.163.78 + hashes; quarantine skytext/frint/slogsec;
            run PoCs only in disposable VMs; rotate creds on any host that
            ran a suspect PoC; make DoH visible; isolate + IR.
OWNER:      HuntPack
VERSION:    v0.2 · 2026-07-07
17

Changelog

v0.22026-07-24CQL correctness pass. All table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.
v0.12026-07-07Initial HuntPack from Sekoia / YesWeHack ChocoPoC analysis — 8 CQL queries, 4 Custom IOA recs, IOC appendix (5 SHA-256 hashes + exfil IP + packages/repos), tiered hardening, cross-platform playbooks, containment runbook.
18

References

TierSourceUsed ForAccess Date
1 · VendorSekoia — Don't eat the ChocoPoCs! (trojanised PoC exploits)Primary analysis, dependency chain, payload, Mapbox dead-drop C2, DoH, exfil IP, persistence, full IOC set with SHA-2562026-07-07
1 · VendorYesWeHack — Don't eat the ChocoPoCs!Joint disclosure, fake-PoC repos, download stats, live-server warning2026-07-07
2 · PressThe Hacker News — New ChocoPoC RAT Targets Vulnerability Researchers via Fake PoC Exploit ReposCorroboration of delivery, Mapbox dead-drop, credential theft, prior slogsec link2026-07-07
RefMITRE ATT&CK — T1195.001 Supply Chain: Software DependenciesTechnique mapping, mitigations2026-07-07