who->who-rs;v8.0.0Rust重构已发布"

admin 2026-10-16 11:08:18 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

who -> who-rs ; v8.0.0 Rust重构已发布

永恒之锋实验室
永恒之锋实验室

Eonian Sharp

2026年9月22日 11:07
上海

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

从 4867 行 Bash 到一颗静态二进制:司稽 Whoamifuck 的 Rust 重构之路

「司稽,察留连不时去者。」——《周礼·司稽》

2021 年写第一版 Whoamifuck 的时候,我没想过这个脚本最后会长到 4867 行。

那时候的想法很直接。

应急的时候经常要看进程、端口、登录记录、计划任务、WebShell、系统版本,来来回回敲的命令其实就那些。既然每天都要敲,不如把它们收进一个脚本里。

于是有了 who.sh。

后来功能一点点往里面加。

基线检查加进去,漏洞检查加进去,HTML 报告加进去,内核漏洞版本表也塞进去。版本一路从最开始跑到了 v7。

直到有一天再打开那个文件,已经很难一眼看明白某一段代码到底会影响哪里。

4867 行。

这个数字差不多就是这次重构真正开始的原因。

现在,司稽 Whoamifuck v8.0.0 发布了。

这一版最明显的变化只有一个:

整个项目从 Bash 搬到了 Rust。


一个脚本什么时候开始变得不好维护

Shell 本身没有什么问题。

甚至直到现在,我依然觉得应急响应工具用 Shell 起步非常合适。

ps、ss、last、find、systemctl 都在那里,脚本直接调就行。写完之后扔到机器上,也不用想太多。

Whoamifuck 最早能快速做起来,很大一部分原因就是 Bash 足够方便。

问题是,这种方便是有边界的。

当文件越来越大,很多当初无所谓的问题会慢慢变得麻烦。

比如变量。

Shell 里:

$FILE
\"$FILE\"
${FILE}

看起来差不了多少,实际行为却可能完全不同。

原来的代码里甚至还能翻到这样的历史痕迹:

rm -f /tmp/valid.$$.log/tmp/$$.log

两段路径粘在了一起。

这种东西在一个几百行的小脚本里,很容易发现。

放到将近 5000 行的脚本里,就不一定了。

另一个问题是,函数越来越多以后,很多数据是靠大家心照不宣地传下去的。

这个变量是谁定义的?

哪个函数会改它?

改完之后还有谁依赖它?

Shell 不会告诉你。

你只能搜。

再往后,就是不同机器上的兼容性问题。

正常的 Debian、Ubuntu、CentOS 通常没什么问题,但应急现场从来不会只遇到这些。

有些机器 Bash 版本很老。

有些发行版裁掉了一部分命令。

有些国产系统的行为和你预想的不一样。

脚本写得越大,这种环境差异越容易冒出来。

所以这次决定做一件拖了很久的事情:

把它拆开。


为什么最后选了 Rust

其实这几年也想过别的方案。

Python 写起来更快,生态也成熟。

Go 做单文件分发也很好。

最后还是选了 Rust。

原因和“性能”关系没有很多。

Whoamifuck 又不是在做高并发服务,很多时候真正耗时间的是系统命令本身。

我更在意的是另外几件事。

首先是类型。

很多 Shell 里的问题,本质上不是逻辑复杂,而是变量状态太自由。

Rust 会逼着你在编译阶段把很多问题解决掉。

其次是项目结构。

以前所有东西都挤在 who.sh 里。

现在一个功能对应一个模块:

src/
├── main.rs
├── color.rs
├── ui.rs
├── env.rs
├── sys.rs
├── util.rs
├── version.rs
└── modules/
    ├── baseinfo.rs
    ├── userlogin.rs
    ├── vulncheck.rs
    ├── baseline.rs
    ├── webshell.rs
    ├── report_html.rs
    ├── kernel_cve_data.rs
    └── ...

现在如果要改登录日志,就去 userlogin.rs。

改漏洞检测,就去 vulncheck.rs。

至少不用先在一个 4867 行的文件里翻半天。

还有一点很实际:

静态编译。

这一点对于这种需要扔到各种陌生 Linux 环境里的工具来说,挺重要。

编译好一个 musl 版本,上传到目标机器:

scp who root@target:/tmp/
sudo /tmp/who -r

能跑就行。

不需要先确认 Python 在不在,也不用再猜目标机器上的 Bash 到底是哪一版。


我们没有把系统命令重新造一遍

这次重构有一个原则一直没变:

原来该调系统命令的地方,继续调。

有时候看到“某某工具用 Rust 重写”,很容易理解成什么东西都要自己实现。

其实没这个必要。

比如:

ps
ss
last
find
systemctl

这些工具已经在 Linux 上跑了很多年。

为了追求“纯 Rust”,重新实现一套进程枚举、Socket 获取、systemd 查询,意义不大。

甚至还有可能让结果和原版出现差异。

所以现在 Rust 主要负责这些事情:

参数处理、执行流程、数据组织、版本比较、漏洞表匹配、输出和报告生成。

真正采集系统信息的地方,还是尽量沿用 Linux 本身的命令。

这样做还有一个好处。

v8 和旧版的结果更容易对得上。

对于应急工具来说,我觉得这个比“纯不纯”重要。


有些东西则很适合搬进 Rust

另外一类代码就不一样了。

比如版本比较。

原来 Bash 里是这样的:

version_lt() {
    [ \"$1\" = \"$(printf '%s\
' \"$1\" \"$2\" | sort -V | head -n1)\" ] && [ \"$1\" != \"$2\" ]
}

它能用。

而且用了很多年。

但第一次看到这段的人,大概率得停一下。

现在对应的代码变成了:

/// a < b
pub fn version_lt(a: &str, b: &str) -> bool {
    a == min_version(a, b) && a != b
}

版本比较的语义没有改,还是按原来的 sort -V 行为处理。

只是终于变成了一个可以单独测试的函数。

漏洞版本表也是类似的情况。

Whoamifuck 里面一直保留着一份 Dirty Cow 的受影响内核版本表。

1217 条。

以前这些数据直接塞在 Shell 里。

现在它们单独放进:

kernel_cve_data.rs

需要改数据的时候,不会再碰到其他检测逻辑。

目前 v8 里的漏洞自查包括:

• CVE-2016-5195 Dirty Cow

• CVE-2022-0847 Dirty Pipe

• CVE-2026-31431 Copy Fail

• OpenSSH CVE-2018-15473、CVE-2024-6387

• Sudo CVE-2019-18634、CVE-2021-3156、CVE-2023-22809

• XZ Utils CVE-2024-3094

这些判断逻辑以后继续扩展,也比原来轻松很多。


老用户应该基本感觉不到变化

重构的时候有一个比较麻烦的问题:

如果新版本更“先进”,但老用户要重新学一遍怎么用,那这次升级其实挺失败的。

所以命令行接口基本没有动。

以前怎么跑,现在还是怎么跑。

比如:

sudo ./who -n
sudo ./who -a
sudo ./who -r
sudo ./who -m report.html

LOGO 也没动。

配色也尽量保留。

甚至一些看起来没那么“现代”的输出方式,我都没有急着改。

因为司稽用了这么多年以后,它已经有自己的使用习惯了。

v8 更像是把发动机和底盘换掉。

驾驶方式先别动。


下载和使用

如果只是想用,可以直接去 Releases 下载。

常规 x86\_64 Linux 可以用:

whoamifuck-v8.0.0-x86_64-unknown-linux-gnu.tar.gz

如果不想管目标机器是什么发行版,我更建议:

whoamifuck-v8.0.0-x86_64-unknown-linux-musl.tar.gz

ARM64 则用:

whoamifuck-v8.0.0-aarch64-unknown-linux-musl.tar.gz

解压之后:

tar xzf whoamifuck-v8.0.0-x86_64-unknown-linux-musl.tar.gz
cd whoamifuck-v8.0.0-x86_64-unknown-linux-musl

sudo ./who -h
sudo ./who -n
sudo ./who -r
sudo ./who -m report.html

因为涉及不少系统级信息,建议直接使用 root 权限运行。

如果想自己编:

git clone https://github.com/enomothem/Whoamifuck.git
cd Whoamifuck
cargo build --release

产物在:

target/release/who

五年以后,再看这个工具

老的 who.sh 我没有删。

它还在仓库里。

一方面方便对照结果,另一方面我也不太想删。

毕竟从 2021 年一直改到现在,里面留下了很多很明显的时代痕迹。

有些写法现在看起来挺笨。

有些代码如果今天重新写,肯定不会那么处理。

但当时它确实解决了问题。

这次迁移到 Rust 以后,司稽本身没有突然变成一个完全不同的工具。

平时应急时关心的东西还是那些:

端口对应哪个服务。

服务后面是什么进程。

进程什么时候起来的。

它连过哪里。

谁登录过机器。

什么文件在那个时间点发生了变化。

最后还是要把这些东西串起来。

我一直很喜欢原来留下的这句话:

端口 → 服务,服务 → 进程,进程 → 网络。 时间线、轨迹、日志,最后都要对得上。

工具能帮你少敲一些命令。

至于异常到底藏在哪里,很多时候还是得靠经验。

有时候甚至真的是感觉。


”虽然现在AI能快速制造一些东西,但是这个是我一步一步累积出来的经验,每一次排查,每一个想法,每一个思路,每一个发现,改了无数次代码,微调,实战验证。“

”这次重构,借助AI的能力进行快速使用Rust重构,结构化,其实自己重构的版本早就写好了,只不过代码太乱了,虽然能跑起来,不利于后面的迭代,所以才使用AI全部重构“

”AI虽然能快速搞出炫酷的东西,但我们不需要,我们仍然保留原有功能和格式,实现如果rust能替换的直接用rust,更快一点,不能的,就原生命令,还是熟悉的whoamifuck。“


项目地址:

https://github.com/enomothem/Whoamifuck

如果你以前用过 who.sh,可以直接试试 v8。

遇到 Bug 就提 Issue。

WHOK-ID 还在。

—— 永恒之锋 · Enomothem

工具仅用于授权范围内的安全测试、应急响应与技术研究。


who->who-rs;v8.0.0Rust重构已发布" 网络安全文章

who->who-rs;v8.0.0Rust重构已发布"

Whoamifuck应急响应工具从4867行Bash脚本重构为Rust并发布v8.0.0。重构核心在于利用Rust的类型安全、模块化结构和静态编译特性解决Shell脚本维护难题,同时保留系统命令调用与原有命令行接口,确保老用户无感升级。工具内置DirtyCow等漏洞自查功能,支持多架构静态分发,建议应急场景直接使用musl版本。
每天学一个Kali工具·Day22nuclei:YAML模板驱动的漏洞扫描\"精确制导武器\"" 网络安全文章

每天学一个Kali工具·Day22nuclei:YAML模板驱动的漏洞扫描\"精确制导武器\""

本文介绍Kali工具nuclei,一款基于YAML模板的漏洞扫描器,支持多种协议,社区维护数千模板,新漏洞曝光数小时内即可上线模板,官方宣称零误报。文章详解模板体系、Interactsh盲漏洞检测、与Burp等工具联动,并附参数速查与实战命令,适合CVE复现、批量资产体检和红队打点场景。
假期挖洞不卡壳,X漏洞计划焕新升级!" 网络安全文章

假期挖洞不卡壳,X漏洞计划焕新升级!"

文档介绍X漏洞奖励计划升级内容,包括公开产品收录范围查询、定价依据透明化、提交流程优化及官方漏洞收录评估Skill上线。旨在让研究方向更明确、漏洞价值更透明、研究成果更快转化为回报。建议白帽师傅提交前查询产品范围、核对收录条件并使用辅助工具整理材料。
评论:0   参与:  0