我们将编译 format 程序为 32 位和 64 位二进制文件(对于 Apple Silicon 机器,我们只编译成 64 位二进制文件)。我们预构建的 Ubuntu 20.04 VM 是 64 位 VM,但它仍然支持 32 位二进制文件。我们所需要做的就是在 gcc 命令中使用 -m32 选项。对于32位编译,我们还使用 -static 生成静态链接的二进制文件,它是自包含的,不依赖于任何动态库,因为 32 位动态库没有安装在我们的容器中。
编译命令已在 Makefile 中提供。要编译代码,你需要输入 make 来执行这些命令。编译完成后,我们需要将二进制文件复制到 fmt-containers 文件夹中,以便它们可以被容器使用。以下命令执行编译和安装。
在编译过程中,你将看到一个警告消息。这个警告是由 gcc 编译器针对格式化字符串漏洞实现的防范措施,我们现在可以忽略这个警告。
format.c: In function 'myprintf':
format.c:33:5: warning: format not a string literal and no format arguments
[-Wformat-security]
33 | printf(msg);
| ^~~~~~
需要指出的是,程序需要使用 "-z execstack" 选项编译,这允许栈可执行。我们的最终目标是将代码注入到服务器程序的栈中,然后触发代码。非可执行栈是对抗基于栈的代码注入攻击的对策,但是它可以使用 return-to-libc 技术被破解,这在另一个 SEED 实验中有详细介绍。在这个实验中,为了简单起见,我们禁用了这个可被破解的对策。