XK-LAB // 真实恶意样本分析 MALWARE SAMPLES ● 只写抓到的 · 抓不到就写未留存 · 不编样本、不编哈希

这一页只写窗口内真实发生过的事,不写「典型恶意样本长什么样」。先把总账摊开:本窗口抓到的下载事件 0 条、未留存文件本体,所以「样本条数」要分两个口径数—— 文件样本 0 条:Cowrie cowrie.session.file_download 0 条,Dionaea binaries/ 0 个条目、downloads 表 0 行。没有文件就没有 SHA-256、没有大小、没有 file/strings 输出。 行为级样本 3 条:三条攻击链在 Cowrie / Suricata / Dionaea 里都留下了逐条可复核的会话记录,分析对象是协议行为与凭据结构,不是二进制。 这就是本窗口的真相:对手全在「直接连端口 + 猜口令」,一个下载器都没放进来。下面每条都按同一套字段写,字段缺就是缺。

① 168.144.28.221 · 2 小时 28 分 4,242 次 SSH 连接,没有一个文件落地文件本体未留存

source: 已核实摘要 — docs/样本分析-20261018.md(SA-20261018-01)

  • 样本来源:Cowrie(:2222)+ Suricata eve.json + Dionaea 三处交叉,唯一关联源 168.144.28.221。
  • 首次出现时间:2026-10-15T13:42:30Z,末次 16:10:51Z,跨度 2 小时 28 分。
  • URL / HTTP 方法:无。全程直接 TCP 连 2222 / 1433 / 3306,Dionaea 全量日志里 "url" 字段 0 条 —— 不存在「先访问 URL 再下载」的链路。
  • UA:无 HTTP UA。协议特征是 SSH 客户端 banner SSH-2.0-Go,4,241 次(占全部连接的 99.98%)。
  • 文件哈希 / 大小:未留存。/opt/dionaea/var/lib/dionaea/binaries entries 0、downloads 0 行、Cowrie file_download 0 条 ⇒ 没有对象可以算 hash。
  • 行为逐行解读:
    • 下载命令:无。没有 wget/curl,因为根本没进到 shell。
    • 落地路径:无。文件系统没被写过(蜜罐侧无落盘事件)。
    • 持久化尝试:无。无 authorized_keys 追加、无 crontab、无 systemd 单元。
    • 回连地址:无。会话里没有任何出向连接。
    • 实际动作:8,880 秒内 4,242 次 connect;登录「成功」4,239 次、失败 2 次;账号 Top root 704 / ubuntu 133 / user 119 / test 40 / admin 39;口令 Top 123456 471 / 123 184 / 1 99 / 111111 81 / 1qaz@WSX 80;同时 1433 与 3306 各探 1 次。
  • 为什么没得手:它拿到的「成功」是我们放行的默认口令——蜜罐 userdb 里就写着 123456,所以 4,239 次绿字只是记录链路正常,不代表打穿了任何真实主机;它真正缺的是「进去之后要干什么」,全程没有一条命令事件,说明这是刷弱口令清单的批处理,不是入侵。反过来看也很清楚:2,000+ 次尝试里没有一次跨出认证阶段,也就永远碰不到文件系统。
  • 我们的规则命中情况(1000101–1000108 目前只在仓库 detections/,未部署;下表是离线复核,不是线上已触发):
    • 1000101 SSH banner 以 Go 开头 → 会命中(4,241 条 SSH-2.0-Go)。
    • 1000103 同源 SYN 到 2222 达速率阈值 → 大概率命中(4,242 次/8,880 秒 ≈ 143 次/300 秒,远超阈值;需以实际 SYN 计数复核)。
    • 1000104 同源 60s 触及 ≥6 个蜜罐端口 → 不命中(全程只 3 个端口)。
    • 1000107 外部源直连 DB 端口(1433/3306/6379/9200/27017) → 会命中(1433、3306 各 1 次)。
    • 100400 Wazuh 同源 300s ≥20 次 cowrie.session.connect → 会命中(与 1000103 同口径)。
    • 100401 / 100402 → 不命中(端口数不足;Dionaea logins 0 条,对方未提交 DB 凭据)。
② 163.5.210.194 · 一周 6,956 个会话,每会话只发一发口令文件本体未留存

source: 已核实摘要 — content/posts/ssh-bruteforce-163.5.210.194.md

  • 样本来源:Suricata 首见 flow + Cowrie 会话日志 + Wazuh 告警三处交叉,唯一关联源 163.5.210.194。
  • 首次出现时间:Suricata 2026-10-15T18:47:50Z(flow start 18:47:38,state=closed / reason=timeout / alerted=false,来回只有 3+1 个包);蜜罐首个完整会话 19:06:56(session eb943b776b79,源端口 60664)。
  • URL / HTTP 方法:无。一周 13,904 行事件里 13,903 行 dest_port=2222,唯一例外是蜜罐主动回连的出向流(10.0.0.10:2222 → 163.5.210.194:56144)。
  • UA:无 HTTP UA。SSH 客户端 banner 是裸 OpenSSH(没有版本号),6,952 条 —— 它故意伪装成普通 OpenSSH。
  • 文件哈希 / 大小:未留存。全周 cowrie.command.input 计数为 0,连命令都没执行过,谈不上样本。
  • 行为逐行解读:
    • 下载命令:无。没有 shell、没有 wget、没有 chattr +i,会话在 session.closed 就到头。
    • 落地路径:无。
    • 持久化尝试:无。
    • 回连地址:无(那一条出向流是蜜罐自己发的,方向相反)。
    • 实际动作:全周 6,956 次会话 / 6,931 次登录成功 / 只 6 次失败(0.09%);每会话平均 0.997 次登录,口令第一发就中、从不重试;会话时长中位 2.54 秒、p90 3.79 秒;口令结构 Top:6 位纯数字 2,260/6,931(32.6%)、3 位纯数字、6 位全 1;账号 root 963 次(13.9%),其余是 dell/user/admin/test/ubuntu 这类设备默认账号。
  • 为什么没得手:它要的不是这台机器,是**「能登进去的机器清单」——0 条命令就是证据;它还能得手到什么程度,取决于我们蜜罐放行什么,而它连一条命令都没发,所以「得手」这件事从未发生。反过来说,这条链最值得学的是它把按失败次数写的规则整条废掉**:6 次失败对 6,931 次成功,任何「N 次失败报警」的规则在它身上永远不响。
  • 我们的规则命中情况:
    • 1000101 Go banner / 1000102 libssh → 不命中(本源 banner 是裸 OpenSSH,两条指纹必然 0)。
    • 1000103 同源 2222 ≥10 次/300s → 命中 544 / 614 个窗口(已离线回放统计,规则本身未部署)。
    • 100400 Wazuh 同源 300s ≥20 次会话 → 一次都不中(峰值只有 14)。
    • 已部署的 Wazuh 100110(120 秒 5 次登录失败)7 天命中 0 次 —— 按失败次数报警在这套蜜罐上是空转。
    • 100401 / 100402 → 不命中(7 天零多端口探测;无 DB 凭据提交)。
③ 179.63.84.194 · 单端口 1433 打 2,752 次,并提交了 2,750 次 sa 凭据文件本体未留存

source: 已核实摘要 — detections/README.md(Dionaea 基线段落,只到聚合层)

  • 样本来源:Dionaea mssqld 蜜罐的 credentials 事件,交叉 Suricata 1433 告警;唯一关联源 179.63.84.194。
  • 首次出现时间:未留存(只到聚合层)。detections/README.md 只给基线窗口 2026-10-11 09:23Z → 10-18 12:00Z 的合计(2,752 次 1433),不给首见时刻 —— 这一格不补。
  • URL / HTTP 方法:无。原生 TDS 协议直连 1433,不经过 HTTP。
  • UA:无(非 HTTP 会话,无 User-Agent 可谈)。
  • 文件哈希 / 大小:未留存。凭据提交发生在认证阶段,credentials 事件只有账号口令,没有文件。
  • 行为逐行解读:
    • 下载命令:无。
    • 落地路径:无。
    • 持久化尝试:无。
    • 回连地址:无。
    • 实际动作:2,752 次连 1433(单端口,不扫别处);credentials 事件 2,753 条(mssqld 2,750 / mysqld 3),其中 2,750 条来自本源;原始字段逐字为 "credentials": [{"password": "sa", "username": "sa"}](Wazuh 侧实测该字段会被解码成字符串化数组)。
  • 为什么没得手:Dionaea 的 MSSQL 服务是故意放行认证的诱捕面,sa/sa 这种口令能「提交成功」正是它存在的目的;它证明的是「对方已经从探活进到猜口令」,离「拿到数据库」还有真实的权限校验没走。没有命令、没有文件,所以也就没有任何东西可以被它带走。
  • 我们的规则命中情况:
    • 100402 蜜罐 MSSQL 收到登录凭据(credentials 键存在) → 会命中(2,753 条 credentials,是本窗口唯一能吃满这条规则的证据)。
    • 1000107 外部源直连 DB 端口 → 会命中(2,752 次 1433 全在外部源)。
    • 100401 同源 60s 触及多端口 → 不会命中(2,752 次全是单端口 1433,这条规则反而不该误报它)。
    • 1000101 / 1000102 / 1000103 → 不命中(无 SSH 会话)。
④ 下载事件 0 条:下次怎么把它留住缺口 · 怎么留住

这不是第四个样本,是这一页最该被记住的一条缺口。三条链路全部「连端口、猜口令、不落文件」,于是我们能写行为、写口令结构、写协议特征,却写不出一个 SHA-256。要补的不是分析能力,是留存链路:

  1. Cowrie 允许下载并落盘:cowrie.cfg 里 [honeypot] download_limit_size 设到非 0(例如 104857600,100MB 上限),下载的二进制才会写进 /opt/cowrie/dl/ 并在 cowrie.session.file_download 事件里带 shasum、outfile、url。默认是 0 = 只记录不落盘,这就是本窗口「0 条」的直接原因。
  2. Suricata 开 file-store:suricata.yaml 的 file-store 段启用(enabled: yes、dir 指到独立分区、stream-depth 给够),HTTP/SMB 流量里的对象会按 fileinfo 落成文件,eve.json 的 http 事件随之带 fileinfo.filename / sha256 / size。这一层管的是「不经过蜜罐、直接打 Web 服务」的下载。
  3. 蜜罐目录只读挂载 + 单独可写落盘区:/opt/cowrie、/opt/dionaea 用 -v ...:ro 挂只读(防攻击者改蜜罐自身),只把 dl/、binaries/ 单独挂成可写卷并加配额 —— 否则真抓到样本时,要么落不下,要么把磁盘灌满。

留到之后怎么做:不复制、不上传、不提供下载链接,只记录 hash 与元数据(file 类型、大小、来源 URL、时间、UA),再按 docs/样本分析-TEMPLATE.md 的红线写报告。哈希算出来之前,这一页的第 ① ② ③ 条就一直标着「未留存」——这不是没写,是确实没有。

核实口径 · 这一页为什么可信可复核
每份样本的第一行都标了 source: 已核实摘要,指向仓库里可查的原始记录:docs/样本分析-20261018.md(168.144.28.221 全量报告)、content/posts/ssh-bruteforce-163.5.210.194.md(周维度复盘)、detections/README.md(基线统计与 Dionaea 凭据事件)。这一页没有任何一个哈希、大小、文件类型是推测出来的 —— 抓不到的就写「未留存」,写不出时间就写「未留存(只到聚合层)」,不补数、不补样例值。三条红线照旧:不复制样本本体、不给下载链接、蜜罐里的「登录成功」不等于真实主机失陷(蜜罐放行什么由我们自己配置,绿=记录链路正常,不是打得穿)。