我正在阅读有关Ubuntu-12.10安全漏洞CVE-2013-1763的文章,该漏洞描述了堆栈缓冲区溢出的漏洞,该漏洞可被利用来提升进程的权限并获得root访问。
硬编码的攻击是在链接:https://github.com/spinlockirqsave/examples/blob/master/hacker/ubuntu_信贷/主要c上进行的。
关于同样的问题,我有几个问题:
sdiag_family=0x37是怎么决定的?x()是如何在用户空间中执行的?sdiag_family=0x37和mmap_start=0x1a000值之间有什么关系吗?发布于 2015-08-04 13:21:29
如果您查看受影响代码 (来自内核3.7.0,第115至132行):
static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
int err;
struct sock_diag_req *req = nlmsg_data(nlh);
const struct sock_diag_handler *hndl;
if (nlmsg_len(nlh) < sizeof(*req))
return -EINVAL;
hndl = sock_diag_lock_handler(req->sdiag_family);
if (hndl == NULL)
err = -ENOENT;
else
err = hndl->dump(skb, nlh);
sock_diag_unlock_handler(hndl);
return err;
}sock_diag_lock_handler()函数以req->sdiag_family值作为索引进行访问。索引来自userland。调用的函数代码是:
static const inline struct sock_diag_handler *sock_diag_lock_handler(int family)
{
if (sock_diag_handlers[family] == NULL)
request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
NETLINK_SOCK_DIAG, family);
mutex_lock(&sock_diag_table_mutex);
return sock_diag_handlers[family];
}因此,我们可以看到,提供的索引直接用于访问名为sock_diag_handlers[]的数组,而无需检查数组长度。该数组包含40个元素,但利用程序中的索引为0x37,即55 -因此代码读取超过数组结束的16个条目的字节(即128个字节,因为每个条目都是一个指针,并且攻击显然是针对64位机器的)。
调用方(__sock_diag_rcv_msg())将返回的值用作指向结构的指针,该结构特别包含一个称为dump()的字段,该字段是函数指针--代码在指针后面调用该函数。
该漏洞依赖于内核内存空间中在数组的偏移量55处存在一个合适的指针(不是数组的一部分,而是恰好存在于其中的一些其他数据)。该指针指向内核空间中的良性和正常结构,这意味着完全不同;但是错误的代码将将该结构解释为struct sock_diag_handler,并读取它假定为fault字段的内容,该字段恰好包含0x1A000值。所以代码会“跳转”到那个地址。
漏洞攻击所剩下的就是确保在0x1A000地址上有可执行代码。该地址是用户空间的一部分;userland漏洞可以通过mmap()调用保留该空间,并在其中放置一些代码。在这里,使当前正在执行的进程"root“的代码。
需要理解的重要一点是“用户空间”和“内核空间”并存。当它执行一个进程时,它将内存“视为”页面的集合,其中一些页被映射到实际的RAM中。“内核空间”是这些页面的子集。映射是用MMU完成的,它强制执行访问权限:当执行的代码具有“用户权限”(与“内核权限”相反;这里我们不是在讨论根和非根)时,任何访问标记为“内核空间”的页面的尝试都会触发异常(分段错误)。当进程执行系统调用(例如,send()调用)时,它跳入内核空间并暂时获得内核权限,此时所有内核空间都可以访问。但是页面的映射并没有改变;用户土地页仍然存在,关键的是,虽然用户权限不足以访问内核页面,但是内核特权足以访问用户页面。因此,没有什么可以阻止具有内核特权的代码跳入用户空间中的代码。这就是这里发生的事。
因此,开发控制流是:
send()系统调用,这些参数导致在内核空间以内核权限执行__sock_diag_rcv_msg()。mmap()调用),但以内核权限执行。__sock_diag_rcv_msg(),他对整个过程非常满意,然后返回。最终,系统调用终止,用户土地进程以用户权限重新获得控制。0x37和0x1A000只是在特定内核版本的情况下“工作得很好”的值,该漏洞是在特定的内核版本中定制的:攻击者注意到,在内核空间中,在溢出数组之后128个字节的内核空间中,有一个指向内核空间结构的指针,该结构的伪dump字段包含一个值,该值被解释为指针,指向的地址足够低,足以到达普通用户mmap()。我们在这里讨论的数据(超限数组及其在RAM中的结构)是“常量数据”段的一部分:这些是在编译内核时填充的正常、常量的数据结构。因此,在编译新内核时,它们可能会发生变化,但受影响内核的所有实例在这方面都是相同的--这就是为什么漏洞是特定于内核版本的原因(这里是Ubuntu 12.10以64位模式提供的版本),但是将在所有使用该内核的系统上工作。
其他受影响的内核版本或具有不同选项的其他编译可能需要为sdiag_family和mmap_start提供不同的值,但适当结构上的条件并不困难,而且可能存在许多其他适当的组合。(或者至少存在,因为内核现在已经在这方面进行了修复,并且不会在数组结束后进行任何访问,从而避免了整个问题。)
https://security.stackexchange.com/questions/95850
复制相似问题