从 NtUserXxx 引发的 BSOD 看系统调用处理差异
2023-10-16 17:00:30
正可谓“千里之堤,溃于蚁穴”,一次平常不过的系统调用也有可能成为推倒系统稳定性的那根稻草。微软于2014年发布了 MS14-058 安全更新,修补了多个 Windows 系统的漏洞。其中一个漏洞的 PoC 代码中,我们可以看到其通过调用 NtUserXxx 系统调用来引发 Windows XP 和 Windows 7 的系统蓝屏死机(BSOD)。本文将重点分析该漏洞的原理,并且在此基础上,对两个操作系统在处理该系统调用时暴露出的差异做简单分析。
漏洞原理
这个漏洞的原理十分简单,它利用了 NtUserXxx 系统调用处理过程中的一个缺陷。在 Windows XP 和 Windows 7 中,NtUserXxx 系统调用的处理过程大致可以分为以下几个步骤:
- 检查参数的有效性,包括指针是否有效、数值是否在合理范围内等。
- 如果参数有效,则将控制权移交至内核态,并执行相应的系统调用。
- 执行完毕后,内核态将控制权还给用户态,并返回执行结果。
漏洞的产生正是由于在 Windows XP 和 Windows 7 中,上述步骤的执行顺序不同所导致的。在 Windows XP 中,步骤 1 和步骤 2 的执行顺序是固定的,即先检查参数的有效性,再执行系统调用。而在 Windows 7 中,步骤 1 和步骤 2 的执行顺序是动态的,即先检查参数的有效性,如果参数有效,则执行系统调用,否则直接返回错误代码。
也就是说,在 Windows XP 中,即使参数无效,系统调用也会被执行,而如果参数无效导致执行系统调用时发生了异常,就会导致系统蓝屏死机。而在 Windows 7 中,如果参数无效,系统调用根本就不会被执行,因此不会导致系统蓝屏死机。
差异分析
从上述漏洞原理中,我们可以看出,Windows XP 和 Windows 7 在处理 NtUserXxx 系统调用时暴露出了如下差异:
- 参数检查的顺序不同: 在 Windows XP 中,参数检查的顺序是固定的,即先检查参数的有效性,再执行系统调用。而在 Windows 7 中,参数检查的顺序是动态的,即先检查参数的有效性,如果参数有效,则执行系统调用,否则直接返回错误代码。
- 对参数无效的处理方式不同: 在 Windows XP 中,如果参数无效,系统调用也会被执行,而如果参数无效导致执行系统调用时发生了异常,就会导致系统蓝屏死机。而在 Windows 7 中,如果参数无效,系统调用根本就不会被执行,因此不会导致系统蓝屏死机。
上述差异导致了 Windows XP 和 Windows 7 在处理 NtUserXxx 系统调用时暴露出了不同的安全风险。在 Windows XP 中,由于参数检查的顺序是固定的,因此攻击者可以通过构造无效的参数来导致系统蓝屏死机。而在 Windows 7 中,由于参数检查的顺序是动态的,因此攻击者无法通过构造无效的参数来导致系统蓝屏死机。
总结
本文通过一个在 Windows XP 和 Windows 7 操作系统内核中分别调用同一个 NtUserXxx 系统调用产生不同现象的问题,对其做了简单分析。该漏洞的原理十分简单,它利用了 NtUserXxx 系统调用处理过程中的一个缺陷。从该漏洞的原理中,我们可以看出,Windows XP 和 Windows 7 在处理 NtUserXxx 系统调用时暴露出了如下差异:参数检查的顺序不同和对参数无效的处理方式不同。上述差异导致了 Windows XP 和 Windows 7 在处理 NtUserXxx 系统调用时暴露出了不同的安全风险。