PjSalty/pvpgn-pro-hardened

GitHub: PjSalty/pvpgn-pro-hardened

PvPGN-PRO Battle.net 模拟器的安全强化 fork,通过现代编译器缓解措施、模糊测试和供应链签名,为暴露在公网上的经典游戏服务器提供可直接替换的内存安全防护。

Stars: 0 | Forks: 0

# pvpgn-pro-hardened [PvPGN-PRO](https://github.com/pvpgn/pvpgn-server) 的安全强化构建版本,这是一个开源的 Battle.net 模拟器,用于运行私有的魔兽争霸 III(以及其他经典的 Blizzard/Westwood 游戏)服务器。 它是原版 PvPGN-PRO 构建版本的直接替代品:相同的 `bnetd`,相同的配置,相同的 `6112/tcp` (bnet) 和 `6200/tcp` (w3route) 端口,相同的行为。只有构建、测试和发布流水线发生了改变。你可以直接将其替换使用,在无需更改配置的情况下获得实质性的安全提升。 ## 为什么会有这个项目 每个自建经典 WC3 服务器的人都在运行同一个 C++ daemon。它直接在互联网上解析不受信任的网络输入,即 bnet 和 w3route 线路协议,而且该代码库从未进行过现代的安全审计。PvPGN-PRO 的最后一个标签发布版本是在 2018 年。 这个 fork 并不重写该 daemon。而是对其进行强化: - 将代码树更新为与上游 `master` (2021) 保持一致,比上一个标签发布版本领先了 102 次提交, - 使用全套现代缓解措施对其进行编译,并证明这些缓解措施确实存在于二进制文件中, - 在 sanitizers 下对 packet parser 进行模糊测试,并修复由此发现的内存安全 bug, - 提供了一个可重现、已签名的容器镜像,并附带 SBOM 和构建出处证明。 目标很简单:packet parser 中的内存安全 bug 应该导致干净的崩溃并重启,而不是成为远程代码执行的原语。 ## 强化带来的好处 该构建版本是按照 [OpenSSF Compiler Options Hardening Guide](https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html) 进行编译的。 `test/checksec.sh` 会对每次构建进行门控检查,如果缺少任何缓解措施,镜像将拒绝构建。 | 缓解措施 | 原版 PvPGN-PRO | pvpgn-pro-hardened | |---|---|---| | RELRO | Partial | Full (GOT read-only) | | Stack canary | 无 | `-fstack-protector-strong` | | FORTIFY_SOURCE | 无 | `=3` (28 个强化调用) | | Stack-clash protection | 无 | 有 | | CET (IBT + SHSTK) | 无 | 有 (9255 个 endbr64 填充 + property note) | | PIE | 有 | 有 | | NX / non-exec stack | 有 | 有 | | libstdc++ assertions | 无 | `_GLIBCXX_ASSERTIONS` | | auto-var-init | 无 | `-ftrivial-auto-var-init=zero` | FORTIFY_SOURCE=3 以及 libstdc++ assertions 为 daemon 中数百个遗留的 `sprintf`/`strcpy`/`strcat` 调用点加装了边界检查,因此溢出会终止运行,而不是破坏内存。`-Werror=format-security` 会将格式化字符串 bug 变为构建失败。 有关完整的 flag 集及其验证方法,请参阅 [HARDENING.md](HARDENING.md)。 ## 通过模糊测试发现并修复的 Bug libFuzzer harnesses (`fuzz/`) 在 ASan + UBSan 下驱动字节级别的 packet parser。每一个被发现的问题都已修复,确保输入能被安全拒绝,并且每一个修复都已证明不会改变有效流量的行为(参见下文的测试部分)。 - `packet_get_str_const`:当最大长度的 packet 不包含字符串终止符时,会导致在 packet 缓冲区之后超出一个字节的越界读取。 - `packet_get_data_const`:一个 `offset + len` 无符号整数溢出,使得一个越界窗口能够绕过长度检查。 - `tag_str_to_uint` / `tag_case_str_to_uint`:在 4 字符客户端/架构 tag 解码器中存在短输入过度读取和未初始化暂存区读取问题。 详情见 [docs/THREAT-MODEL.md](docs/THREAT-MODEL.md)。 ## 运行 容器(推荐): ``` docker run -d --name pvpgn \ -p 6112:6112/tcp -p 6200:6200/tcp \ -v pvpgn-data:/usr/local/pvpgn/var/pvpgn \ ghcr.io/pjsalty/pvpgn-pro-hardened:latest ``` 如需完整的运行时沙箱(只读根文件系统、降权 capabilities、`no-new-privileges`、seccomp、资源限制),请使用 [`deploy/docker-compose.hardened.yml`](deploy/docker-compose.hardened.yml)。 从源码构建: ``` cmake -S . -B build -D CMAKE_BUILD_TYPE=Release -D WITH_LUA=true cmake --build build -j"$(nproc)" bash test/checksec.sh build/src/bnetd/bnetd # confirm the mitigations landed ``` 强化默认是开启的。可以通过 `-D PVPGN_HARDENING=OFF` 来禁用。 ## 验证镜像 ``` # provenance + SBOM attestations gh attestation verify oci://ghcr.io/pjsalty/pvpgn-pro-hardened:latest -R pjsalty/pvpgn-pro-hardened # cosign keyless signature cosign verify \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --certificate-identity-regexp 'https://github.com/PjSalty/pvpgn-pro-hardened/.github/workflows/.*' \ ghcr.io/pjsalty/pvpgn-pro-hardened:latest ``` ## 测试 已证明这些更改不会破坏 daemon: - `test/run-difftest.sh`:一个差异性验证预言机会将约 11 万个有效输入通过修补后的 parser 进行测试,并与原始的上游代码进行比对,断言输出完全一致。 - `test/build-and-verify.sh`:在强化后的二进制文件上执行完整构建、checksec 门控检查以及上游单元测试(SRP3、bignum)。 - `fuzz/run-regression.sh`:修复后的崩溃重现测试运行正常,并进行了一轮简短的模糊测试活动。 所有这些都会在每次推送和 pull request 时的 CI 中运行。 ## 与上游的关系 这是一个强化 fork,而不是一个竞争项目。它跟踪 `pvpgn/pvpgn-server`,并将分歧保持在较小范围内,记录在 [DIVERGENCE.md](DIVERGENCE.md) 中;parser 的修复也已回馈给上游。有关更新的工作流,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。 支持的客户端、配置和协议与上游保持一致;请参考 [PvPGN-PRO 文档](https://github.com/pvpgn/pvpgn-server)。 ## 许可证 GPL-2.0-or-later,与上游 PvPGN 和 PvPGN-PRO 相同。请参阅 [COPYING](COPYING)。 最初的 PvPGN 是 PvPGN 和 PvPGN-PRO 作者的心血结晶;这个 fork 在他们工作的基础上增加了构建强化、模糊测试、测试和发布工具。
标签:Bash脚本, C++, DevSecOps, GitHub Advanced Security, 上游代理, 内核驱动, 安全加固, 数据擦除, 游戏服务器, 漏洞缓解, 网络协议, 请求拦截