12 KiB
Coruna Reporting C2 API
Lab 实现见 routes/c2.php。字段形状主要来自:
coruna-online/docs/CORUNA_COMPLETE_DATAFLOW_REPORT.md§7- HAR 解密红acted 样本
c2_decrypted_redacted.json
敏感值在证据里已打码;下文用「含义 + 类型」描述,不复述真实秘密。
1. 传输约定
1.1 JSON POST(除 /api/user/check、除 GET /api/user/query)
| 项 | 说明 |
|---|---|
Header timestamp |
13 位毫秒时间戳 |
| Body | Base64(AES-256-ECB-PKCS7(key, timestamp || JSON)) |
| key | SHA256(session_key || timestamp)(session_key 为 16 ASCII) |
响应同样用自生成 timestamp 头 + 加密 body。常见明文为:
null
或:
{"code":0,"msg":"ok","data":null}
Lab 默认回包:加密 {"code":0,"msg":"ok","data":null}(与客户端不死循环的成功 ack 对齐)。真实战役响应字段可能更丰富,但客户端通常只认成功/可解密。
1.2 GET /api/user/query
- 无加密 body
- 响应明文:
OK(text/plain)
1.3 POST /api/user/check
multipart/form-datafile:Coruna 头混淆的加密 7z;口令session_key || batchBase(首批常见"0")sig:不透明二进制,Lab 不校验
1.4 通用身份字段(多接口复用)
| 字段 | 观察含义 |
|---|---|
c |
32 hex,会话/渠道类 ID |
d / f |
16 hex,设备相关指纹(二者常相同) |
id / lhu |
UUID 形字符串(事件/本地句柄) |
pn / m / et |
产品名 / 机型 / 事件类型文本 |
pv |
系统版本(如 15.8.4) |
s / u / sbu |
其它会话/用户侧短字段 |
v |
插件或模块版本串 |
设备主键:只取 d / f(见 IngestService::extractDeviceKey)。
/api/user/check multipart 的 d/f 为编码形态
hex(ascii(nibbleSwap(byteReverse(json_d))))(例:000430C910E8E526 → 36323545384530313943303334303030);Lab 在入库前归一化为 JSON 侧 16 hex。
2. 接口一览
| 方法 | 路径 | 用途(战役观察) | Lab 行为 |
|---|---|---|---|
| GET | /api/user/query |
DGA/连通性探测,选 reporting C2 | 明文 OK |
| POST | /api/user/avatar/set |
首次设备 profile | 写 devices(+apps 若有) |
| POST | /api/user/get |
拉/登记状态;带已装 App 列表 | 登记设备;ack |
| POST | /api/user/avatar/put |
下载/注入/模块健康等遥测 | 登记设备;ack;落文件日志 |
| POST | /api/user/avatar/status |
钱包 keystore / identity JSON | wallet_keystores.raw_json ← result |
| POST | /api/user/status |
地址 → 资产/余额(ba/ad) |
wallet_addresses(balance JSON,source←a) |
| POST | /api/user/set |
明文助记词或私钥 | wallet_mnemonics(加密,source←a) |
| POST | /api/user/check |
相册命中图 7z 归档 | 修头解包 → photos |
| POST | /api/user/avatar/pic |
Notes 批次(list) |
notes.content ← payload.list |
| POST | /api/user/profile/{add,delete,remove} |
imagent 侧 profile 变更 | 仅日志 + ack |
| POST | /link/config/list |
WebClip/链接配置轮询 | ack data: [] |
| POST | /link/config/icon |
WebClip 图标 | ack data: null |
不做:/kill、助记词/私钥自动划转。
3. 分接口说明
3.1 GET /api/user/query
用途:reporting 是否存活;DGA 用成功响应选定当前 C2。
请求:无 body;可无特殊头。
响应(Lab / 战役一致观察):
OK
3.2 POST /api/user/avatar/set
用途:植入后上报设备画像(机型、系统、区域、运营商、宿主 App 等)。
请求明文(红acted 形状):
{
"c": "<32hex>",
"d": "<16hex>",
"f": "<16hex>",
"application": {
"applicationIdentifier": "<bundle>",
"bundleIdentifier": "<bundle>"
},
"deviceInfo": {
"productName": "iPhone OS",
"productType": "iPhone9,1",
"productVersion": "15.8.4",
"hardwareModel": "...",
"buildVersion": "..."
},
"deviceModel": "iPhone9,1",
"deviceName": "<name>",
"systemVersion": "15.8.4",
"machine": "...",
"kernVersion": "...",
"bootHash": "...",
"boottime": 0,
"carrierNames": [],
"language": "...",
"regionCode": "...",
"timezone": "...",
"totalGB": 0,
"jbsdk_version": "...",
"lhu": "<uuid>",
"s": "...",
"sbu": "...",
"u": "..."
}
响应:加密 ack(见 §1.1)。
3.3 POST /api/user/get
用途:初始状态/注册拉取;HAR 中携带已装应用简表 al。
请求明文要点:
{
"c": "<32hex>",
"d": "<16hex>",
"f": "<16hex>",
"al": [
{ "a": "<app name>", "b": "<bundle id>", "v": "<version>" }
],
"b": "...",
"i": "...",
"lhu": "<uuid>",
"m": "...",
"p": "...",
"s": "...",
"sbu": "...",
"u": "...",
"v": "..."
}
| 字段 | 含义 |
|---|---|
al[].a |
App 显示名 |
al[].b |
bundle id |
al[].v |
App 版本 |
响应:加密 {"code":0,"msg":"ok","data":null}(Lab)。战役侧可能带配置 data;未完全还原时以可解密成功 ack 为准。
3.4 POST /api/user/avatar/put
用途:通用遥测/事件总线。同路径多种 ctx:
| ctx 形态 | 含义 |
|---|---|
url, sha256, size, downloadTimeMs, isFirstLoad |
模块/资源下载 |
totalModules, abnormalModules, overallStatus, checkTimeMs |
模块健康检查 |
bundleId, targetPid, injectionTimeMs |
进程注入结果 |
空 ctx |
其它短事件(配合 desc / et / ex) |
公共字段示例:
{
"c": "<32hex>",
"d": "<16hex>",
"f": "<16hex>",
"id": "<uuid>",
"lhu": "<uuid>",
"pn": "iPhone OS",
"m": "iPhone9,1",
"pv": "15.8.4",
"desc": "<event description>",
"et": "<event type text>",
"ex": 0,
"exp": "",
"ctx": { /* 见上表 */ },
"s": "...",
"..."
}
WhatsApp 等插件也会复用此路径上报消息相关事件(静态/流量均有指认)。
响应:加密 ack。
3.5 POST /api/user/avatar/status
用途:上传仍加密的钱包/keystore/identity JSON(如 imToken walletsV2 解密前结构)。
请求明文要点:
{
"a": "<短标签>",
"c": "<32hex>",
"d": "<16hex>",
"d1": "<40hex>",
"d2": "<短串>",
"d3": "<40hex>",
"v": "<module version>",
"result": {
"crypto": {
"cipher": "aes-128-ctr",
"cipherparams": { "iv": "<hex>" },
"ciphertext": "<hex>",
"kdf": "pbkdf2",
"kdfparams": { "c": 0, "dklen": 0, "prf": "...", "salt": "<hex>" },
"mac": "<hex>"
},
"identity": { /* encAuthKey, encKey, ... */ },
"encOriginal": "...",
"imTokenMeta": { /* ... */ }
}
}
响应:加密 ack。
Lab:wallet_keystores 存整份 result(raw_json)。
3.6 POST /api/user/status
用途:地址 → 链上资产/余额映射。
请求明文要点:
{
"a": "<短标签>",
"c": "<32hex>",
"d": "<16hex>",
"d1": "<40hex>",
"d2": "...",
"d3": "<40hex>",
"v": "...",
"ba": {
"<walletAddress>": [
{
"balance": "<string>",
"chainId": "<string>",
"chainType": "<string>",
"decimal": "<string>",
"name": "<token name>",
"symbol": "<symbol>"
}
]
}
}
ba 的 key 为地址;value 为该地址下资产数组。
响应:加密 ack。Lab 写入 wallet_addresses:chain_type←chainType(缺省则按地址推断),balance 为 {SYMBOL: 格式化数量}(按 decimal/decimals),source←a 短标签映射钱包名。亦接受 ad(Global 标量 map / Trust 资产数组)。
3.7 POST /api/user/set
用途:上报明文助记词或私钥(HAR 已证实 12 词助记词在 result)。
请求明文要点:
{
"a": "<短标签>",
"c": "<32hex>",
"d": "<16hex>",
"d1": "<40hex>",
"d2": "...",
"d3": "<40hex>",
"v": "...",
"result": "<12/15/18/21/24 words mnemonic OR private key string>"
}
响应:加密 ack。Lab:wallet_mnemonics(mnemonic_enc Laravel crypt,source←a),后台仅打码展示。
3.8 POST /api/user/check
用途:相册 OCR/敏感命中后的图片归档上传(非 AES JSON)。
Content-Type:multipart/form-data
| Part | 观察 |
|---|---|
file |
Coruna 头混淆 7z;解压后为 JPEG 等 |
sig |
~352–472 字节不透明数据,用途未证实 |
idx |
12 hex:upload_count||process_index(各 6 位);Lab 解码入库 |
ftu |
12 hex:text_count||barcode_count;Lab 解码入库 |
x-hit |
BIP39 词数或 -1/-2/-3;Lab 存 photos.x_hit |
rid |
~36 字符请求/资源 id |
c,d,f,s,u,b,m,ts |
设备/会话侧短字段(与 JSON 接口同族) |
d,f |
长度 32:相对 JSON 的 16 hex 做了 nibble/byte 重排后再 hex(ascii);Lab 归一化后入库 |
ts |
即 batchBase:首批为 "0";后续为 LastProcessedTimestamp 十进制字符串 |
7z 口令:session_key || ts(Lab 读 multipart 字段 ts;缺省才回落 "0")。
响应:加密 ack(Lab)。战役侧亦为加密成功体,具体 JSON 未作为契约固定。
3.9 POST /api/user/avatar/pic
用途:Notes reader 批次上报。
请求明文要点(真机已见):
{
"c": "<32hex>",
"d": "<16hex>",
"f": "<16hex>",
"s": "...",
"u": "<40hex>",
"list": ["<note text>", "..."]
}
响应:加密 ack。Lab:notes.content ← payload.list(JSON 数组)。
3.10 POST /api/user/profile/add|delete|remove
用途:imagent 消息/profile 状态变更(静态接口表)。HAR 本批无样本。
请求:加密 JSON(形状未钉死)。
响应:加密 ack;Lab 仅日志。
3.11 POST /link/config/list
用途:WebClip / 链接配置轮询。
请求明文(HAR):
{
"c": "<32hex>",
"channel": "<32hex>",
"d": "",
"f": "",
"s": "",
"u": ""
}
响应:
- Lab:加密
{"code":0,"msg":"ok","data":[]} - 战役:可能返回链接列表;未完整还原时客户端以可解密为准
3.12 POST /link/config/icon
用途:拉取 WebClip 图标。
HAR:本批无独立解密样本。
请求:加密 JSON(预期含图标/链接标识)。
响应(Lab):加密 {"code":0,"msg":"ok","data":null}。
4. Lab 响应统一格式
除 query 外,控制器经 CorunaCrypto::encryptJson 返回:
HTTP
- Status:
200 - Header:
timestamp: <13-digit> - Body:Base64 AES 密文
明文(Lab)
{
"code": 0,
"msg": "ok",
"data": null
}
/link/config/list 的 data 为 []。
原始请求/响应落盘:public/log/c2/Ymd.log(create_log,不写 DB)。
dir: "in":请求明文(解密后payload)dir: "out":响应明文(有timestamp头则 AES 解密;query等明文直接记)
5. 调用顺序(HAR 观察)
典型顺序(同一 reporting 域名):
query → avatar/put(telemetry) → query → avatar/set → get
→ avatar/put* → check* → … → avatar/status → status → set
→ link/config/list …
相册命中(check)可早于或并行于钱包本地解密上报(avatar/status → status → set)。
6. 参考
| 文档/证据 | 内容 |
|---|---|
CORUNA_COMPLETE_DATAFLOW_REPORT.md §7.2 |
接口职责总表 |
CORUNA_DOMAIN_DGA_REPORT.md |
query 与 DGA 选服 |
c2_decrypted_redacted.json |
各路径请求字段形状 |
app/Services/CorunaCrypto.php |
加解密实现 |
app/Http/Controllers/C2/C2Controller.php |
Lab 处理与回包 |