LabHub
学习 学习路径 课程

闭网现场 — 国防领域

做出引入包,并找出签名校验断掉的地方

在 LabHub 中继续学习

目标

从零开始制作要导入隔离网络的软件包并签名,再以接收方身份进行验证,并通过两种篡改亲自确认验证会在哪一层失败。

为什么重要

这个 Pod 中没有 gpg,也无法安装。实际隔离网络通常也是如此——不在许可清单中的软件,本身就必须先接受导入审核。因此,我们使用随处可用的 openssl 进行签名和验证。完整性也不是一层,而是两层:文件哈希保证“这是清单中所说的那个文件”,签名则保证“这份清单由掌握相应密钥的人制作”。只检查一层时,必然会放过其中一种情况;只有亲自构造两种情况后,才能真正体会这一点。

步骤

  1. 使用 python3/root/bundle/payload/ 下创建六个文件,其中两个是二进制文件。
  2. /root/bundle/stage/MANIFEST.sha256 中使用相对路径记录每个文件的 SHA-256。
  3. /root/bundle/keys/ 中创建 RSA 2048 密钥对,将私钥权限设为 600,并将公钥指纹保存在 release.pub.sha256 中。
  4. 使用 openssl dgst -sha256 -sign 创建 /root/bundle/stage/MANIFEST.sig
  5. 打包为 /root/bundle/out/intake-2609-01.tar.gz,并创建同名 .sha256 文件。不要包含密钥文件。
  6. 解压到 /root/bundle/recv/,按软件包哈希 → 签名 → 文件哈希的顺序验证,并将结果写入 receipt.txt
  7. /root/bundle/tamper-a//root/bundle/tamper-b/ 中进行两种篡改,并将结果写入 /root/bundle/tamper.txt。A 只修改 payload/deps/libpq.so.5.bin 的一个字节;B 在此基础上还修改清单中的对应行。
  8. /root/bundle/intake.md 中编写包含七个章节的导入审批申请。

参考

创建要导入的目录树

使用 python3/root/bundle/payload/ 下创建六个文件,其中两个是二进制文件。

使用 python3 创建六个文件。其中两个是二进制文件,无法用肉眼确认,只能通过指纹验证。不要修改生成脚本,原样使用。

创建逐文件哈希清单

/root/bundle/stage/MANIFEST.sha256 中使用相对路径记录每个文件的 SHA-256。

在 payload 目录中使用相对路径生成。find 的 -printf '%P\n' 会去掉开头的 ./。接收方会解压到另一个目录,因此绝对路径在那里没有用处。

创建签名密钥对并保留指纹

/root/bundle/keys/ 中创建 RSA 2048 密钥对,将私钥权限设为 600,并将公钥指纹保存在 release.pub.sha256 中。

使用 openssl genrsa 创建 2048 位私钥,并将权限设为 600。使用 -pubout 导出公钥,转换为 DER 后通过 sha256sum 生成指纹。

对清单签名

使用 openssl dgst -sha256 -sign 创建 /root/bundle/stage/MANIFEST.sig

签名对象不是整个 payload,而是清单这一份文件。使用 openssl dgst -sha256 -sign 时必须添加 -out——如果重定向屏幕输出,二进制数据会损坏。

打包软件包(不包含密钥)

打包为 /root/bundle/out/intake-2609-01.tar.gz,并创建同名 .sha256 文件。不要包含密钥文件。

将 payload、清单和签名打包在一起。不要包含公钥——如果公钥与软件包通过同一途径送达,控制该途径的人就能将四者全部替换。打包后使用 tar -tzf 目视确认其中包含的内容。

按顺序执行接收方流程

解压到 /root/bundle/recv/,按软件包哈希 → 签名 → 文件哈希的顺序验证,并将结果写入 receipt.txt

顺序是关键:整个软件包的哈希 → 签名 → 各文件哈希。如果先检查文件哈希,就会依据一份尚未确认真伪的清单进行比对。

通过两种情况确认验证失败位置

/root/bundle/tamper-a//root/bundle/tamper-b/ 中进行两种篡改,并将结果写入 /root/bundle/tamper.txt。A 只修改 payload/deps/libpq.so.5.bin 的一个字节;B 在此基础上还修改清单中的对应行。

创建两份副本:A 中只修改二进制文件的一个字节;B 在相同篡改基础上,将清单对应行也更新为新哈希。对两份副本都执行签名验证和文件哈希比对。

编写导入审批申请

/root/bundle/intake.md 中编写包含七个章节的导入审批申请。

需要七个章节。审核人员必须能够在看不到我们屏幕的情况下重复同样的验证,因此不要只写“已通过”,而要写明数值和命令。