Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ctl_ctloutput-leak — CVE-2017-13868: XNU 中未初始化内核堆数据的信息泄露。 | Kitploit
工具/GitHubGitHub/bazad/ctl_ctloutput-leak
内存取证漏洞分析漏洞利用信息收集二进制利用
GitHubbazad/ctl_ctloutput-leak

ctl_ctloutput-leak

CVE-2017-13868: XNU 中未初始化内核堆数据的信息泄露。

查看仓库
27528年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

ctl_ctloutput-leak

macOS High Sierra 10.13 中的 ctl_ctloutput 函数忽略了 sooptcopyin 调用的返回值,这打开了一个竞态窗口,可将未初始化的内核堆数据泄漏到用户空间。ctl_ctloutput-leak 是一个概念验证漏洞利用,试图触发此信息泄漏。利用需要 root 权限。

已确认该漏洞利用在 macOS High Sierra 10.13.1 Beta 17B25c 和 iOS 10.1.1 14B100(通过 mach_portal)上有效。

漏洞:CVE-2017-13868

以下是 macOS High Sierra 10.13 上 ctl_ctloutput 的相关部分:

root@kitploit:~
if (sopt->sopt_valsize && sopt->sopt_val) {
	MALLOC(data, void *, sopt->sopt_valsize, M_TEMP,	// (a) data 被分配
		M_WAITOK);					//     未使用 M_ZERO。
	if (data == NULL)
		return (ENOMEM);
	/*
	 * 4108337 - 复制用户数据,以备
	 * 内核控制需要
	 */
	error = sooptcopyin(sopt, data,				// (b) 调用 sooptcopyin()
		sopt->sopt_valsize, sopt->sopt_valsize);	//     填充缓冲区;
}								//     返回值被忽略。
len = sopt->sopt_valsize;					//
socket_unlock(so, 0);
error = (*kctl->getopt)(kctl->kctlref, kcb->unit,		// (c) 调用 getsockopt()
		kcb->userdata, sopt->sopt_name,			//     的实现来处理
			data, &len);				//     缓冲区。
if (data != NULL && len > sopt->sopt_valsize)			//
	panic_plain("ctl_ctloutput: ctl %s returned "
		"len (%lu) > sopt_valsize (%lu)\n",
			kcb->kctl->name, len,
			sopt->sopt_valsize);
socket_lock(so, 0);
if (error == 0) {
	if (data != NULL)
		error = sooptcopyout(sopt, data, len);		// (d) 如果 (c) 成功,
	else							//     则将数据缓冲区
		sopt->sopt_valsize = len;			//     复制回用户空间。
}								//

这段代码执行以下操作:

  1. 为 getsockopt 的 data 参数分配一个内核堆缓冲区,但未指定 M_ZERO 标志来清零所分配的字节。
  2. 使用 sooptcopyin 从用户空间复制 getsockopt 数据,填充刚分配的 data 缓冲区。此 copyin 本应完全覆盖已分配的数据,因此不需要 M_ZERO 标志。然而,sooptcopyin 的返回值未被检查,这意味着 copyin 可能失败,导致缓冲区中留下未初始化的数据。例如,如果程序向 getsockopt 传递了一个未映射的地址,copyin 可能失败。
  3. 然后代码调用此内核控制套接字的实际 getsockopt 实现。该实现应处理输入缓冲区,可能修改并缩短它,并返回结果代码。然而,该实现可以假定提供的缓冲区已被初始化(因为理论上它来自用户空间),因此一些实现根本不修改缓冲区。例如,NECP 函数 necp_ctl_getopt 仅返回 0,完全不处理数据缓冲区。
  4. 最后,如果实际 getsockopt 实现未返回错误,ctl_ctloutput 调用 将数据缓冲区复制回用户空间。

因此,通过向 getsockopt 指定一个未映射的数据地址,我们可以分配一个受控大小的堆缓冲区,防止该缓冲区的内容被初始化,然后触发对 sooptcopyout 的调用,该调用试图将缓冲区写回未映射的地址。我们只需在 sooptcopyin 和 sooptcopyout 调用之间重新映射该地址,即可使 copyout 成功。如果能够做到,我们就能将未初始化的内核堆数据泄漏到用户空间。

事实证明,这是一个相当容易获胜的竞态。在我的 2015 款 Macbook Pro 上测试时,赢得竞态的平均尝试次数从未超过 600 次,中位数从未超过 5 次。在 iPhone 7 上的 iOS 10.1.1 中,竞态更容易获胜,通常不超过 2 次尝试。(此测试在关闭 DEBUG 的情况下进行,因为 printf 会显著拖慢漏洞利用速度。)

使用方法

要构建,请运行 make。查看 Makefile 顶部了解各种构建选项。

通过在命令行中指定目标泄漏大小来运行漏洞利用:

root@kitploit:~
$ sudo ./ctl_ctloutput-leak 128
000000:  ef be ad de ef be ad de  00 00 00 00 00 00 00 00
000010:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000020:  00 00 00 00 00 00 00 00  01 00 00 00 40 80 00 00
000030:  de 28 45 00 04 00 00 00  a0 ff 4a 26 80 ff ff ff
000040:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000050:  08 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000060:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000070:  00 00 00 00 00 00 00 00  ef be ad de ef be ad de

时间线

我于 2017 年 10 月 7 日向 Apple 报告了此问题。它被分配了 CVE-2017-13868。Apple 在 macOS 10.13.2 和 iOS 11.2 中修复了这些问题。

许可证

ctl_ctloutput-leak 代码已发布到公共领域。作为礼节,如果您引用或使用任何这些代码,我希望您注明出处。

下载工具
sooptcopyout