CVE-2019-12937 ToaruOS权限提升分析
ToaruOS是一套使用C语言编写的开源计算机操作系统,是一个由伊利诺伊大学计算机科学本科生开发的业余爱好操作系统。ToAruOS可在POSIX和x86架构上运行。ToAruOS的主要功能包括对进程和线程的支持、ELF二进制的支持、运行时加载模块、管道(Pipe)和各种类型的终端设备(TTY)的支持、虚拟文件系统的支持、EXT2文件系统的支持、信号量支持等。
从 1.10.9 到 ToaruOS 的 gsudo 中的 apps/gsudo.c 有一个缓冲区溢出,允许通过 DISPLAY 环境变量将本地权限提升到 root 用户。
漏洞分析
首先去查看关于这次漏洞的针对的更新,patch:https://github.com/klange/toaruos/commit/7fdaca463fe6ce86939ea77ac08faa886f624444?diff=split
通过对比查看看出这个洞原理很简单,作者这次修复的commit只是在原来的基础上增加了两行代码
1 | FILE * pex_connect(char * target) { |
在sprintf
前面加了一行判断if (strlen(target) > 80) return NULL;
,target
的这个字符串长度如果超过80那么就直接返回。
sprintf
是一个拼接函数将target
和前面的字符串拼接放到了前面的tmp
这个局部变量为100个字节大小中,通过判断很可能是sprintf
这个函数拼接完的长度超过了tmp
的长度造成了栈溢出的漏洞。
查看一下pex_connect
这个函数是从那里调用的
是通过yutani.c
这个文件中的yutani_init
这个函数调用的,调用时传入了server_name
这个参数,这个参数是通过前面获得环境变量中的DISPLAY
参数获得,并且此参数的获取是可控的导致漏洞的触发。
如何提权?
yutani.c
是作为一个基础的依赖文件,而权限的提升正是由于gusdo
这个应用导致,可以发现这个程序调用了yutani.c
导致栈溢出,那为什么这个程序可以提权呢?
SUID 权限
在Linux中有除了rwx权限外还有s权限,当程序中的x权限变为s时表示,这个程序拥有这个程序所有者的权限。
比如普通用户可以通过passwd修改自己的密码,但是实际修改时/etc/passwd这个文件的内容,但是这个文件只用root才有权限更改,但是我们通过passwd这个拥有suid权限的程序,临时的使用root权限达到修改密码的目的。
- SUID 权限仅对二进制可执行文件有效
- 如果执行者对于该二进制可执行文件具有 x 的权限,执行者将具有该文件的所有者的权限
- 本权限仅在执行该二进制可执行文件的过程中有效
而gsudo正是拥有suid权限的程序,类似与一些Linux中的sudo、su等用途,临时使用root权限。
poc分析
这里的poc使用的是cve详情中给出的链接
1 | /* |
tmp的长度为100,溢出的长度为100+ebp(4)+ret(4),对应到payload中为eip乘以4为104加上AAA以及一个空字符刚好为108
跳转的地址为定义的”\xb0\xb0\x01\x3f”,shellcode把它放到了env这个变量中,而这个地址是介于arg与env之前的一个地址,从中随机挑选了这个地址,但是在arg地址中不能出现\x00,所以这之间大量填充了A的Nop的指令。
shellcode
https://github.com/mehsauce/kowasuos/blob/master/shellcode/execve.asm
1 | BITS 32 |
这个shellcode主要是先通过setuid(0)设置当前进程的一个权限的函数,通过执行system(/bin/sh)返回shell,ToaruOS通过int 0x7f调用系统函数,在syscall_nums.h中有系统的调用号,setuid对应的为24,system对应7,将汇编转换为一个字节码放到poc中执行达到最终的提权。
参考链接
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12937
https://xz.aliyun.com/t/5914
https://github.com/mehsauce/kowasuos/blob/master/exploits/kowasu-gsudo.c