FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。
FreeBuf+小程序把安全装进口袋
在近期的一次安全分析过程中,我们在64位Linux系统内核里的create_elf_tables()函数中发现了一个整型溢出漏洞,本地攻击者将可以通过一份SUID-root代码来利用这个漏洞,并获取到目标设备的完整root权限。
目前,受该漏洞影响的Linux发行版有RedHatLinux企业版、CentOS和Debian8。
150#defineSTACK_ROUND(sp,items)\
151(((unsignedlong)(sp-items))&~15UL)
...
165create_elf_tables(structlinux_binprm*bprm,structelfhdr*exec,
169intargc=bprm->argc;
170intenvc=bprm->envc;
171elf_addr_t__user*sp;
178intitems;
190p=arch_align_stack(p);
287items=(argc+1)+(envc+1)+1;
288bprm->p=STACK_ROUND(sp,items);
295sp=(elf_addr_t__user*)bprm->p;
“argc”表示传递给execve()系统调用的命令行参数个数,个数受fs/exec.c中MAX_ARG_STRINGS的限制;“envc”表示传递给execve()的环境变量个数,个数同样受到MAX_ARG_STRINGS的限制;但是由于MAX_ARG_STRINGS为0x7FFFFFFF,所以我们可以让整数“items”发生溢出并让程序失效。
此时,我们就可以以增加用户态的栈指针,然后将用户态栈指针指向我们的参数和环境变量字符串,最终在用户模式执行SUID-root代码时重写这些字符串。
在使用execve()运行SUID-root代码时,我们的“items”值为0x80000000,参数指针的大小约为0x80000000*sizeof(char*)=16GB,参数字符串为16GB,环境字符串也为16GB,因此我们的漏洞利用环境“只”需要2*16GB=32GB内存,而并非3*16GB=48GB或者更多,因为我们使用了一些小技巧来减少内存指纹。
下面这个图表代表了SUID-root代码开始执行后,我们的用户态栈结构:
-“A”(“alpha”)为create_elf_tables()分配的栈空间大小(代码190-287行),大约为512字节。
-“sprand”是create_elf_tables()分配的随机栈空间大小(代码190行),大小范围在0-8192字节之间。
-“protect”参数字符串是一个非常重要的命令行参数&选项,这个参数必须不能受到内存崩溃的影响。
-“padding”参数字符串大约需要占用16GB栈空间。
-“protect”环境字符串是一个重要的环境变量,必须必须不能受到内存崩溃的影响。
-“scratch”环境字符串为1MB。
-“onebyte”环境字符串为256KB,其部分数据会被fname[]缓冲区覆盖。
-“B”(“beta”)为ld.so分配的栈空间数量。
此时,ld.so会使用handle_ld_preload()中fname[]缓冲区的数据重写“onebyte”环境变量中的部分数据,并让process_envvars()中的UNSECURE_ECVVARS等过滤器失效。
我们的POC代码能够利用create_elf_tables()中的这个整型溢出漏洞,演示样例如下:
#gcc-O0-opoc-suidbinpoc-suidbin.c
#chownrootpoc-suidbin
#chmod4555poc-suidbin
$gcc-opoc-exploitpoc-exploit.c
$time./poc-exploit
ERROR:ld.so:object'LD_LIBRARY_PATH=.0LD_LIBRARY_PATH=.0LD_LIBRARY_PATH=.'fromLD_PRELOADcannotbepreloaded:
ignored.
ERROR:ld.so:object'LD_LIBRARY_PATH=.0LD_LIBRARY_PATH=.'fromLD_PRELOADcannotbepreloaded:ignored.
ERROR:ld.so:object'LD_LIBRARY_PATH=.'fromLD_PRELOADcannotbepreloaded:ignored.
argc2147090419
stack0x7ffbe115008f<0x7ffbe1150188<0x7fffe0e50128<0x7ff7e11503ea<0x7ffbe102cdea