【问题标题】:add a call gate descriptor in Local Descriptor Table (LDT) for privilege escalation在本地描述符表 (LDT) 中添加调用门描述符以进行权限提升
【发布时间】:2015-09-23 07:37:46
【问题描述】:
我可以使用系统调用modify_ldt 在 LDT 中添加一个新条目(调用门描述符)吗?
- 如果是,是否意味着我可以使用描述符设置此描述符
权限级别(DPL) 3 和代码段等于KERNEL_CS
(这是 CPL0 的内核代码描述符)指向
进程的地址空间低于TASK_SIZE,从而允许用户模式
任务直接在 CPL0 调用它自己的代码。
- 如果没有,为什么不呢?
我是这个领域的初学者。非常感谢您的耐心和努力。
【问题讨论】:
标签:
kernel
privileges
descriptor
【解决方案1】:
我可以使用系统调用modify_ldt 在 LDT 中添加一个新条目(调用门描述符)吗?
不,您不能使用此系统调用添加调用门,因为它是系统描述符。看what information can be provided到系统调用...
struct user_desc {
unsigned int entry_number;
unsigned long base_addr;
unsigned int limit;
unsigned int seg_32bit:1;
unsigned int contents:2; // HERE
unsigned int read_exec_only:1;
unsigned int limit_in_pages:1;
unsigned int seg_not_present:1;
unsigned int useable:1;
};
...我们看到我们只能在contents 字段中提供两个位来描述我们想要的描述符类型。通过 Linux 内核中的系统调用函数跟踪这些数据并不是那么简单,但我很确定这些数据最终会到达 fill_ldt,其中包含以下几行:
// ...
desc->type = (info->read_exec_only ^ 1) << 1;
desc->type |= info->contents << 2;
desc->s = 1;
// ...
member fieldstype 和 s 以及描述符特权级别 (DPL) 和当前标志形式 byte 5 of the descriptor 的字段。成员s 结束于第 4 位(嗯,“S”位),它定义描述符是系统描述符 (S=0) 还是(代码/数据)段 (S=1)。由于上面的代码硬编码了值1,所以你总是得到一个(代码/数据)段,而不是系统描述符。所以没有呼叫门。
[..] 用于提权
因此,这里的答案是否定的。否则,这将是 Linux 内核设计中的一个巨大安全漏洞。处理器实际上允许 LDT 中的调用门,这让操作系统承担检测(或完全禁止)滥用该功能的负担,这让我有点惊讶。