查看: 1340|回复: 1
收起左侧

[讨论] 极速扩散!TeamPcp组织利用高阶蠕虫大规模入侵开发者生态

[复制链接]
火绒工程师
发表于 2026-6-25 17:03:51 | 显示全部楼层 |阅读模式
本帖最后由 火绒工程师 于 2026-6-25 17:03 编辑

一、概述
近期,火绒安全工程师在监测网络安全过程中发现了异常情况。经过溯源与技术分析,确认了这是一起TeamPcp组织使用Shai-Hulud蠕虫病毒针对供应链的投毒,下方结合供应链厂商公开提供的信息进行事件还原与样本分析。
TeamPcp组织利用三个已知漏洞的链式攻击,通过GitHub平台缓存投放Mini Shai-Hulud供应链蠕虫病毒,窃取内存中的OIDC凭证。该组织利用所窃取的OIDC凭证发布新版本供其他用户下载,导致蠕虫病毒迅速扩散,在6分钟内于42个tanstack相关的npm包中发布了84个恶意版本。
该蠕虫病毒对上游供应链tanstack发起攻击,对下游所有使用该开源工具的用户构成危害。其通过窃取用户凭证(包括GitHub凭证、加密钱包、SSH密钥等)及各类基础设备信息,并感染用户自身仓库,进而实现交叉大规模扩散。
目前,火绒安全产品已经实现对该行为的拦截与查杀。

查杀图






二、流程图




三、样本分析
该蠕虫病毒在包中名称为router_init.js、大小2341681(2.23MB),经过高度混淆。通过5种C2信道通信,针对30+ CI/CD平台、100+凭证路径的系统性窃取、npm供应链+Github双重投毒实现自我传播、RSA-2048 + AES-256-GCM强加密、rm -rf的自毁机制、俄语地区的规避操作,实现感染vscode与claude的配置文件以实现持久化。
混淆的核心是javascript-obfuscator(开源工具)叠加了beautify自定义流密码形成双层保护。该工具使用了9种混淆,String Array编码、多级解码器别名、自防护、控制流扁平化,所有变量、函数、类名都不可逆混淆,注入死代码。在通过脚本去除String Array编码之后,通过ai修复大量的变量、函数、类的名称。

去混淆前后对比




2.1主函数执行链
执行初始化->凭证窃取->数据加密与发送->感染与注入



2.2执行初始化
创建文件单实例锁tmp.ts018051808.lock,避免同时多个运行。

创建单实例锁



对俄语地区进行地区规避,这也是判断github攻击账户并非真实攻击者的依据之一。

俄语地区规避



注册SIGINT与SIGTERM信号处理器,阻止被攻击者使用Ctrl+C或kill终止命令进程。

防用户终止进程



识别当前所处环境是否在CI/CD流水线中,通过字符串判断检测了31种环境。为后续访问凭证以及npm传播做准备工作。

CI/CD环境检测



Github仓库枚举,枚举用户所有关联仓库(owner,collaborator,organization_member),并且只关注2025-09-01后活跃的仓库,检测是否有push权限。具有push权限的提取OIDC凭证,如果权限足够还会在受害者账号下创建新仓库,仓库名称随机词语-随机词语-3位数的随机数,外加”Shai-Hulud Here We Go Again”的仓库描述。

连接Github Api


遍历所有子仓库



创建仓库名使用的随机词表如下,名称总共有16x16x1000=256000种组合。

仓库名称词表




创建子仓库,相关配置信息




自毁机制
解密出字符串IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner,该字符串后续写入github仓库的commit message如果token被撤销将触发rm -rf ~/命令,将删除受害者的所有文件。其检测Token是否存在的脚本是通过11种payload解密得到。

标记字符串




标记字符串写入github commit message




删库命令



检测token的脚本,与eval调用rm -rf命令。并且即使token未被撤销,24小时后也会执行删除${HOME}/.config/gh-token-monitor/started_at的指令,用作清理痕迹。

Token检测脚本




2.3凭证窃取
凭证窃取内容较多,本篇文章只介绍一种,其余均以表格形式给出。凭证获取范围:服务商、加密钱包、[过滤]、通讯工具、各类开发者凭证、SSH相关密钥、其他本地基础信息。
AWS凭证窃取使用5种方法:环境变量直接获取;Web Identity Token文件获取;ECS容器元数据;EC2实例元数据;本地配置文件。在窃取成功后会通过凭证窃取AWS Secrets Manager中存储的所有机密。并且在所有扫描中都会同时使用正则匹配github与npm的token。
正则匹配token github:gh[op]_[A-Za-z0-9]{36}
正则匹配token npm:npm_[A-Za-z0-9]{36,}

环境变量窃取法




Web Identity Token文件




ECS容器元数据




EC2实例元数据




本地文件配置



在获取凭证后,检查secretsmanager:ListSecrets和secretsmanager:GetSecretValue权限,直接窃取AWS Secrets Manager中存储的所有机密。

检测权限获取AWS机密文件



该脚本通过11种payload其中之一解密得到Runner.Worker内存dump获取凭证,直接在内存种匹配对应规则获取凭证。

Runner.Worker内存dump




扫描凭证过程中的正则匹配token




凭证与敏感文件的扫描表格
路径
目标
~/.aws/config, ~/.aws/credentials
AWS(服务商)
~/.azure/accessTokens.json, ~/.azure/msal_token_cache.*
Microsoft Azure(服务商)
~/.config/gcloud/access_tokens.db, credentials.db, application_default_credentials.json
Google Cloud(服务商)
~/.terraform.d/credentials.tfrc.json
HashiCorp Terraform Cloud(服务商)
~/.bitcoin/wallet.dat
Bitcoin Core(加密货币)
~/.dogecoin/wallet.dat
Dogecoin Core(加密货币)
~/.litecoin/wallet.dat
Litecoin Core(加密货币)
~/.ethereum/keystore/*
Ethereum(加密货币)
~/.zcash/wallet.dat
Zcash(加密货币)
~/.monero/*
Monero(加密货币)
~/.dash/wallet.dat
Dash(加密货币)
~/.electrum/wallets/*
Electrum (BTC)(加密货币)
~/.electrum-ltc/wallets/*
Electrum-LTC(加密货币)
~/.config/Exodus/exodus.wallet/*
Exodus 多币种钱包(加密货币)
~/.config/Ledger Live/*
Ledger Live 硬件钱包(加密货币)
~/.ssh/id_rsa
SSH RSA 私钥 (SSH)
~/.ssh/id_ecdsa
SSH ECDSA 私钥(SSH)
~/.ssh/id_ed25519
SSH Ed25519 私钥(SSH)
~/.ssh/id_dsa
SSH DSA 私钥(SSH)
~/.ssh/id_*
所有 SSH 私钥(SSH)
~/.ssh/authorized_keys
SSH 授权密钥(SSH)
~/.ssh/config
SSH 配置(SSH)
~/.ssh/known_hosts
SSH 已知主机(SSH)
/etc/ssh/ssh_host_*_key
系统 SSH 主机密钥(SSH)
~/.remmina/*
Remmina 远程桌面配置(SSH)
~/.config/remmina/*
Remmina 配置(SSH)
.git/config, ~/.gitconfig, .git-credentials, ~/.git-credentials
Git 凭证(开发者凭证)
.npmrc, ~/.npmrc
npm 注册表认证 token(开发者凭证)
~/.docker/config.json, /root/.docker/config.json
Docker Registry 凭证(开发者凭证)
~/.pypirc
PyPI 认证(开发者凭证)
~/.kube/config
Kubernetes kubectl 配置(开发者凭证)
~/.config/helm/*
Helm 仓库凭证(开发者凭证)
/etc/rancher/k3s/k3s.yaml
Rancher K3s 集群配置(开发者凭证)
/var/run/secrets/kubernetes.io/serviceaccount/token
K8s Service Account Token(开发者凭证)
~/.config/Slack/Cookies
Slack Cookies(通讯工具)
~/.config/discord/Local Storage/leveldb/*
Discord 本地存储(通讯工具)
~/.config/Element/Local Storage/*
Element (Matrix) 本地存储(通讯工具)
~/.config/Signal/*
Signal 桌面端(通讯工具)
~/.local/share/TelegramDesktop/tdata/*
Telegram Desktop(通讯工具)
~/.config/telegram-desktop/*
Telegram Desktop (Linux)(通讯工具)
~/.cert/nm-open[过滤]/*
NetworkManager Open[过滤] 证书([过滤])
%APPDATA%\Nord[过滤]\Nord[过滤].exe.Config
Nord[过滤] Windows([过滤])
%APPDATA%\Open[过滤] Connect\profiles\*
Open[过滤] Connect([过滤])
%PROGRAMDATA%\Open[过滤]\config\*
Open[过滤] 系统级配置([过滤])
%APPDATA%\Proton[过滤]\user.config
Proton[过滤]([过滤])
%APPDATA%\CyberGhost\CG6\CyberGhost.dat
CyberGhost [过滤]([过滤])
%APPDATA%\Private Internet Access\*.conf
PIA [过滤]([过滤])
%APPDATA%\Windscribe\Windscribe\*
Windscribe [过滤]([过滤])
C:\Program Files\Open[过滤]\config\*.o[过滤]
Open[过滤] Windows([过滤])
%APPDATA%\Earth[过滤]\Open[过滤]\config\*.o[过滤]
Earth[过滤]([过滤])
/etc/open[过滤]/*
Open[过滤] (Linux)([过滤])
~/.bash_history, ~/.zsh_history, ~/.history
Shell 历史命令(本地信息)
~/.mysql_history, ~/.psql_history
数据库历史(本地信息)
~/.python_history, ~/.node_repl_history
解释器历史(本地信息)
~/.lesshst
less 命令历史(本地信息)
~/.viminfo
Vim 信息文件(本地信息)
**/.env, .env, **/.env.local, **/.env.production
环境变量文件(本地信息)
**/config/database.yml
Rails 数据库配置(本地信息)
**/wp-config.php
WordPress 配置(本地信息)
~/.config/filezilla/recentservers.xml, sitemanager.xml
FileZilla FTP 凭证(本地信息)
~/.claude.json, ~/.claude/mcp.json
Claude AI 配置(本地信息)
~/.kiro/settings/mcp.json
Kiro MCP 设置(本地信息)
~/.config/atomic/Local Storage/leveldb/*
Atomic 钱包(本地信息)
~/.netrc
网络自动登录凭证(本地信息)
~/.purple/accounts.xml
Pidgin/finch 聊天账户(本地信息)
~/.config/weechat/irc.conf
WeeChat IRC 配置(本地信息)
~/.kde4/share/apps/kwallet/*.kwl, ~/.kde/share/apps/kwallet/*.kwl, ~/.config/kwalletd/*.kwl
KDE 钱包(本地信息)
~/.local/share/keyrings/*.keyring, ~/.local/share/keyrings/login.keyring
GNOME 密钥环(本地信息)
~/.pki/nssdb/*
NSS 证书数据库(本地信息)
**/settings.p
ROS 设置文件(本地信息)
~/.local/share/recently-used.xbel
最近使用文件列表(本地信息)



2.4数据加密与发送
2.4.1网络初始化
C2通讯总共有5种方式:主C2、备用域名、Session协议C2、Github外传push、Github外传deployment。
其中主C2与Session是在进程运行时直接触发两者并行触发,备用域名是在主C2失败时触发。Github外传是根据执行仓库push与deployment两者操作时分别触发。

主C2/备用域名/Session
Github外传push/deployment
运行环境
受害者本地/CI机器上
Github托管平台
触发条件
进程触发
Github Action事件
外传内容
凭证窃取章节内容
仓库所有
持久性
进程存活期间
仓库存在期间


主C2在主函数入口时以及初始化解密,git-tanstack.com:443/router.
主C2



备用域名在主C2域名不可达时使用。获取方式是通过字符串thebeautifulmarchoftime在github上搜索相关commit信息,并通过配置的RSA文件进行校验通过才使用(目前github上相关痕迹已被删除)。

备用域名获取



备用域名解密RSA公钥通过11种payload解密获得


攻击者SessionID:05f9e609d79eed391015e11380dee4b5c9ead0b6e2e7f0134e6e51767a87323026 在主函数执行链时初始化。脚本中初始化了3个Seed节点,seed1.getsession.org,seed2.getsession.org,seed2.getsession.org


Session的节点之一与TLS证书



该脚本还通过将恶意Github Actions Workflow注入受害者仓库利用 GitHub Actions Runner 进程独立外传 Secrets。这与主 C2 通道完全解耦,不受主进程存活与否、C2 域名是否可达的影响。
注入的脚本是通过AES-256-GCM + 自定义beautify函数双层解密。
恶意Github Workflow脚本解密



注入给Action deployment的脚本如下,非常简洁,将仓库中的文件转换为json格式发送给hxxps://api.masscan.cloud/v2/upload

Action deployment恶意脚本



注入给Action push脚本,将文件转换为json格式之后上传到actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f,后续攻击者进行下载。

Action push恶意脚本




2.4.2数据加密与发送
数据外传格式,随机生成的12字节IV与32字节AES密钥,AES-GCM加密数据之后,通过RSA公钥加密AES的IV与密钥,之后分别base64加密组成密文。
  1. {
  2. "envelope": "base64(iv + AES-GCM-ciphertext + authTag)",
  3. "key": "base64(RSA-OAEP-encrypted-AES-key)"
  4. }
复制代码

该RSA通过11种payload内置的payload解密获得。

RSA公钥解密获得




数据加密封装类




2.5感染与注入
感染的流程:
1. 解压tarball: 解压npm包到临时目录_tmp_{timestamp}_{random8bytes}
2. 将自身router_init.js注入到指定目录: 在package.json中写入"preinstall": "node setup.mjs"
3. 写入恶意 payload: 将selfReplicatingPayload_h7(AES-256-GCM 加密) 解密后写入setup.mjs
4. 递增版本号: 使篡改后的包版本号 +1
5. 重新打包: 生成package-updated.tgz

感染npm流程



selfReplicatingPayload_h7脚本是11种payload其中之一解密得到的一个完整的自我复制脚本,运行流程:
1. 判断bun是否已经安装(恶意框架)
2. 如果有退出,如果没有判断系统版本win使用bun.exe其他使用bun,从hxxps://github.com/oven-sh/bun/releases/download/bun-v1.3.13/下载对应的版本。
3. 解压+给权限+执行(对应着本样本)
4. rm -rf清理临时目录

selfReplicatingPayload_h7脚本



VSCode与Claude持久化与自动任务的脚本都是通过11种payload解密得到。持久化通过VSCode的配置文件创建SessionStart钩子实现持久化,写入位置.vscode/settings.json。通过Tasks自动运行,写入位置.claude/settings.local.json

VSCode持久化


Claude自动任务



伪装的41个tanstack生态包名

伪装的tanstack包名




四、总结说明综上所述,供应链投毒攻击通过迂回手段、利用终端用户系统漏洞实施入侵,污染软件开发、分发、运行的上游供应链环节,使恶意代码依附于正规软件或组件,顺势侵入众多下游业务系统。
火绒安全在此提醒广大用户:及时核查tanstack相关依赖包版本;慎用破解版、不明来源安装包,引入组件前核查漏洞补丁;实时开启安全防护软件,规范凭证权限管理,严防供应链投毒风险入侵。
除了使用火绒安全软件进行查杀,用户还可手动处置,可通过扫描tanstack/*文件夹路径下的文件是否带有以下字符串来确认。
  1. "optionalDependencies": {
  2. "@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
  3. }
复制代码



五、IOC信息
Md5:833fd59ebe66a4449982c6d18db656b4
C2:git-tanstack.com/router:443
Session Seed 节点 1 :seed1.getsession.org
Session Seed 节点 2 :seed2.getsession.org
Session Seed 节点 3 :seed3.getsession.org
Session 文件存储 :filev2.getsession.org
Github Workflow Action push外联:api.masscan.cloud
SessionID:05f9e609d79eed391015e11380dee4b5c9ead0b6e2e7f0134e6e51767a87323026



六、附录
1、名词解释
GitHub :是全球最大的代码托管平台。
OIDC凭证:网络身份认证中使用的核心令牌,类似于身份证的作用。
tanstack :是一套用于构建现代Web应用的开源开发工具库集合广泛应用于 React、Vue、Solid 等前端生态。
TeamPcp:黑客组织名称
Mini Shai-Hulud:供应链蠕虫病毒Shai-Hulud的升级版,由TeamPcp组织开发并且于2026年5月在暗网BreachForums开源。
Npm:是Node.js运行时环境默认集成的软件包管理工具。
CI/CD: 一种自动化的软件开发与交付流程。该环境下权限高,可访问各类凭证,可修改npm发布流程实现供应链传播。


2、相关调研信息
域名调研
注册时间
2026-05-09 15:21:18 UTC
攻击前仅2天注册,典型"一次性域名"
注册商
Spaceship,Inc.(IANA: 3862)
Namecheap旗下低价注册商
更新时间
2026-05-12 05:33:26 UTC
攻击后约10小时被更新/冻结
域名状态
clientHold+clientTransferProhibited+clientUpdateProhibited
已被冻结,DNS不再解析
DNS服务器
ace.ns.cloudflare.com/melany.ns.cloudflare.com
Cloudflare代{过}{滤}理(隐藏源站 IP)
DNSSEC
unsigned

到期时间
2027-05-09
仅注册1年


证书调研
签发 CA
Let's Encrypt E8
Sectigo Public Server Auth CA DV E36
签发时间
2026-05-09 16:47:27 UTC
2026-05-09 17:43:17 UTC
到期时间
2026-08-07 16:47:26 UTC
2026-08-07 17:43:17 UTC
CT录入
2026-05-09 17:45:57 UTC
2026-05-09 17:47:05 UTC
SAN
*.git-tanstack.com, git-tanstack.com
同
序列号
05701026ebbc7a4811a6cdcdf8f15c971485
00a2e37f52f2e5cfebb9834378462b1b93

域名注册后约1.5小时内完成SSL证书签发,攻击流程高度自动化。
通过对router_init.js代码中解密字符串确认其属于Mini Shai-Hulud家族,被TeamPcp组织使用。
恶意仓库创建时的字符串



TeamPcp在攻击中使用的账户(github.com/zblgg与github.com/voicproducoes)(经过对该账号的所有行为分析,账号属于被TeamPcp组织盗用)


3、11种payload概括描述
名称
作用
rv
Bash模式Bun下载脚本(未直接调用)
UO
Token检测
av
Python Bun下载脚本(未直接调用)
dnsTxtRecordType_NO
RSA公钥解密备用域名的时候使用
DO
Claude持久化
pythonMemExtractScript_OO
Runner.Worker内存dump
rsaPublicKeyEncrypted_MO
RSA公钥—数据加密
encryptedConfigBlob_FO
VS Code自动任务
encryptedConfigBlob_sv
Github Action deployment
selfReplicatingPayload_h7
npm包preinstall脚本注入加感染
encryptedConfigBlob_ZO
Github Action push

解密脚本AES-256-GCM + beautify解密。该脚本密钥0c0e873033875f1bc471eda37e3b9d0f9b89bd41a4bbb4f86746caa2176c40aa

  1. import hashlib
  2. import struct
  3. import base64
  4. import gzip
  5. from cryptography.hazmat.primitives.ciphers.aead import AESGCM

  6. # ============================================================
  7. # beautifyCipher_x1 — custom substitution cipher
  8. # ============================================================

  9. BEAUTIFY_MASTER_KEY_HEX = "0c0e873033875f1bc471eda37e3b9d0f9b89bd41a4bbb4f86746caa2176c40aa"
  10. PBKDF2_SALT = "svksjrhjkcejg"
  11. PBKDF2_ITERATIONS = 0x30D40  # 200000
  12. PBKDF2_KEYLEN = 0x20         # 32 bytes
  13. PBKDF2_HASH = "sha256"


  14. class Sha256CtrPrng:
  15.     """SHA256-based CTR_DRBG-style PRNG (mirrors sha256CtrPrng_k1)"""

  16.     def __init__(self, key: bytes):
  17.         self.key = key
  18.         self.counter = 0
  19.         self.buf = b""
  20.         self.offset = 0

  21.     def refill(self) -> None:
  22.         h = hashlib.sha256()
  23.         h.update(self.key)
  24.         h.update(struct.pack(">Q", self.counter))
  25.         self.counter += 1
  26.         self.buf = h.digest()
  27.         self.offset = 0

  28.     def next_byte(self) -> int:
  29.         if self.offset >= len(self.buf):
  30.             self.refill()
  31.         b = self.buf[self.offset]
  32.         self.offset += 1
  33.         return b

  34.     def next_u32(self) -> int:
  35.         return (
  36.             (self.next_byte() << 24)
  37.             | (self.next_byte() << 16)
  38.             | (self.next_byte() << 8)
  39.             | self.next_byte()
  40.         )


  41. def fisher_yates_shuffle(prng: Sha256CtrPrng) -> bytes:
  42.     """Fisher-Yates shuffle producing a 256-byte permutation (mirrors fisherYatesShuffle_aN)"""
  43.     arr = list(range(256))
  44.     for i in range(255, 0, -1):
  45.         limit = 0xFFFFFFFF - (0xFFFFFFFF % (i + 1))
  46.         while True:
  47.             r = prng.next_u32()
  48.             if r <= limit:
  49.                 break
  50.         j = r % (i + 1)
  51.         arr[i], arr[j] = arr[j], arr[i]
  52.     return bytes(arr)


  53. def _derive_master_key() -> bytes:
  54.     """PBKDF2 key derivation (mirrors beautifyCipher_x1 constructor)"""
  55.     # NB: JS passes the hex string AS-IS (UTF-8) to pbkdf2Sync, NOT the decoded bytes
  56.     password = BEAUTIFY_MASTER_KEY_HEX.encode()
  57.     return hashlib.pbkdf2_hmac(
  58.         PBKDF2_HASH, password, PBKDF2_SALT.encode(), PBKDF2_ITERATIONS, dklen=PBKDF2_KEYLEN
  59.     )


  60. # Derived once at module load (mirrors beautifyCipherSingleton_UI)
  61. _beautify_master_key = _derive_master_key()


  62. def beautify_decode(encoded_input: str) -> str:
  63.     """
  64.     Decrypt a beautify-encoded string (mirrors beautifyCipher_x1.decode / NI / globalThis.beautify)

  65.     Format: base64(nonce[12] || ciphertext[n])
  66.     Each ciphertext byte is decoded via a position-dependent inverse permutation.
  67.     """
  68.     data = base64.b64decode(encoded_input)
  69.     nonce = data[:12]
  70.     ciphertext = data[12:]

  71.     # seed = SHA256(masterKey || nonce)
  72.     h = hashlib.sha256()
  73.     h.update(_beautify_master_key)
  74.     h.update(nonce)
  75.     seed = h.digest()

  76.     output = bytearray(len(ciphertext))
  77.     for i in range(len(ciphertext)):
  78.         # per-position key: SHA256(seed || i.toString())
  79.         h_i = hashlib.sha256()
  80.         h_i.update(seed)
  81.         h_i.update(str(i).encode())
  82.         key_i = h_i.digest()

  83.         # Build permutation from PRNG
  84.         prng = Sha256CtrPrng(key_i)
  85.         permutation = fisher_yates_shuffle(prng)

  86.         # Build inverse permutation
  87.         inverse_perm = [0] * 256
  88.         for j in range(256):
  89.             inverse_perm[permutation[j]] = j

  90.         output[i] = inverse_perm[ciphertext[i]]

  91.     return output.decode("utf-8")


  92. # ============================================================
  93. # aes256gcmDecrypt_w8 — AES-256-GCM + gzip
  94. # ============================================================


  95. def aes256gcm_decrypt(key_hex: str, payload_b64: str) -> str:
  96.     """
  97.     Decrypt an AES-256-GCM-encrypted, gzip-compressed payload.
  98.     (mirrors aes256gcmDecrypt_w8)

  99.     Format: base64(iv[12] || authTag[16] || ciphertext[n])
  100.     """
  101.     key = bytes.fromhex(key_hex)
  102.     full_data = base64.b64decode(payload_b64)

  103.     iv = full_data[0:12]          # bytes 0x0 - 0xc  (12 bytes)
  104.     auth_tag = full_data[12:28]   # bytes 0xc - 0x1c (16 bytes)
  105.     ciphertext = full_data[28:]   # bytes 0x1c onward

  106.     aesgcm = AESGCM(key)
  107.     # cryptography's AESGCM.decrypt expects (nonce, ciphertext+tag, aad)
  108.     plaintext = aesgcm.decrypt(iv, ciphertext + auth_tag, None)

  109.     decompressed = gzip.decompress(plaintext)
  110.     return decompressed.decode("utf-8")


  111. # ============================================================
  112. # Combined convenience — mirrors the usage pattern in the JS
  113. # ============================================================


  114. def decrypt_config_blob(beautify_blob: str, payload_b64: str) -> str:
  115.     """Full two-stage decryption as used throughout the script."""
  116.     key_hex = beautify_decode(beautify_blob)
  117.     return aes256gcm_decrypt(key_hex, payload_b64)
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?快速注册

x
masxj
发表于 2026-6-25 20:58:30 | 显示全部楼层
厉害!对于我们小白来说看起来像天书一样。
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2026-10-31 12:13 , Processed in 0.053585 second(s), 3 queries , Redis On.

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表