在经历了最近的sudo漏洞之后,我被问到了一个显而易见的问题:如何在近10年内不注意到这种事情?它们真的很难找到,不太可能被模糊发现还是没人尝试过?
我很好奇是否可以在合理的时间内使用著名的afl模糊器发现此错误。
首先,显然sudo是setuid二进制文件。以root用户身份随机输入运行潜在的错误二进制文件不是最安全的方法。为了避免任何潜在的意外系统损坏,我为此设置了一个新的虚拟机,为此测试选择了sudo 1.9.5.p1。 afl旨在将输出生成到fileor stdout中,但是我们要模糊命令行参数。因此,我们需要自行修补sudo,以忽略实际的argv并改为从stdin加载它。
尽管作者本人并不确定这样做是否有用,但afl来源有助于在argv-fuzz-inl.h中提供适当的功能:
AFL不支持argvfuzzing,因为TBH在实践中并不是非常有用。在experimental / argv_fuzzing /中有一个示例,显示了如果您确实想在一般情况下如何执行此操作。
argv-fuzz-inl.h提供的示例从stdin读取NUL分隔的参数。请注意,sudo在单个二进制文件中同时提供了sudo和sudoedit实用程序,因此要测试这两者,我们还需要将fuzzer argv [0]公开。 argv-fuzz-inl.h中的代码不执行此操作,因此需要对其进行修复:
--- a / src / sudo.c +++ b / src / sudo.c @@ -66,6 +66,8 @@ #include" sudo_plugin.h" #include" sudo_plugin_int.h" +#include" argv-fuzz-inl.h" + / * *局部变量* / @@ -149,6 +151,7 @@ sudo_dso_public int main(int argc,char * argv [], char * envp []); int main(int argc,char * argv [],char * envp []){+ AFL_INIT_ARGV(); int nargc,状态= 0; char ** nargv,** env_add,** user_info;
快速测试表明,从stdin传递的测试用例中,sudo / sudoedit选择不能正常工作,因为出于某种原因,它使用__progname。快速解决方法:
--- a / lib / util / progname.c +++ b / lib / util / progname.c @@ -83,7 +83,7 @@ void initprogname2(const char *名称,const char * const *允许){int i;-#ifdef HAVE ___ PROGNAME +#如果0 extern const char * __ progname;如果(__progname!= NULL&& * __ progname!=' \ 0')
最后,我们不想等待密码输入,因此只需使其无条件失败即可:
--- a / plugins / sudoers / auth / sudo_auth.c +++ b / plugins / sudoers / auth / sudo_auth.c @@ -259,7 +259,7 @@ verify_user(struct passwd * pw,char * prompt,int validated ,"-禁用身份验证配置选项。")); debug_return_int(-1); }-+返回0; / *在密码输入期间启用挂起。 * / sigemptyset(& sa.sa_mask); sa.sa_flags = SA_RESTART;
由于某种原因afl-gcc工具无法使用,因此我使用了基于LLVM的工具。我们只需要为./configure覆盖CC:
准备就绪后,我以并行模式启动了四个afl实例。半小时后,出现一个实例…
debian @ debian:〜/ fuzz $ xxd sync_dir / fuzz3 / crashes / id:000000,sig:06,src:000561,op:havoc,rep:200000000:7375 646f 6564 6974 002d 7320 2d20 8052 sudoedit.-s-.R00000010 :202d 7320 ff20 8001 0073 2073 20ff 2080 -s。 ...的.00000020:0100 7320 2d35 8080 ff20 8001 0073 202d ..s -5 ... ... s -00000030:0880 80f8 3f2d 7320 2d20 802d 7320 2d20 ....?-s-.-s-00000040:803b 202d 7320 ff20 8001 0073 202d 2080。; -s。 ... s-.00000050:8080 3b39 9573 20ef 2080 806a 8000 7f80 ..; 9.s。 ..j .... 00000060:3b20 2d73 202d 2080 8020 3995 7320 ef09; -s-.. 9.s ..00000070:8080 6a80 007f 803b 202d 7320 2d20 8080 ..j ....; -s-..00000080:3bf6 202d 732d 7320 2d20 8052 202d 7320;。 -s-s-.R -s 00000090:ff20 2d35 8080 ff20 8001 0073 202d 0880。 -5 ... ... s-.. 000000a0:80f8 3f2d 7373 202d 2080 8080 3b39 9573 ..?-ss-...; 9.s000000b0:20ef 2080 806a 8000 7f80 3b20 2d73 202d。 ..j ....; -s -000000c0:2080 8020 3995 7320 ef09 8080 6a80 007f .. 9.s .... j ... 000000d0:803b 202d 7320 2d20 8080 3bf6 202d 732d。; -s-..;。 -s-000000e0:7320 2d20 8052 202d 7320 ff20 8001 0073 s-.R -s。 ... s000000f0:202d 3580 80ff 2080 0100 7320 2d08 8080 -5 ... ... s -... 00000100:f83f 2d73 202d 2080 2d73 202d 2080 3b20。?-s-.-s-。; 00000110:8000 7f80 3b20 2d73 202d 2080 803b f620 ....; -s-..;。 00000120:2d73 202d 2080 3b20 2d73 20ff 2080 0100 -s-。 -s。 ... 00000130:7320 2d20 8064 f83f 2d73 202d 2080 803b s-.d。?-s-..; 00000140:392d 8054 8080 8080 5c20 2d74 202d 2680 9-.T ....-t-&amp ;. 00000150:0100 80 ...
当然,这是利用sudoedit -s崩溃的原因。 假设我并行运行4个实例,标题中的问题答案是:大约2小时的CPU时间。 是的 2小时的CPU时间足以在广泛使用的setuid实用程序中找到严重的安全漏洞。 在过去的十年中,没有人对sudo感到困惑吗?或者,也许sudo经过了测试但被遗忘了sudoedit?(老实说,在此之前,我不知道sudoedit存在)。 我想得出的结论是,快速使用模糊测试程序可以发现广泛使用的实用程序中仍然存在严重的错误。