题外话:读此文前,你要有思想准备,不是那么简单,你有可能懵圈。 git
这是一个Windows打印机后台程序的本地提权漏洞,但这个漏洞与以往介绍的本地提权漏洞彻底不一样,有必定的限制条件,但从理解windows的角度确实有意思。github
通常状况下,我研究东西的速度很快,多是学的比较杂的缘故,每一个相关的方向都懂一点。但这个漏洞的复现我花了很多时间,走了一些弯路。windows
这个漏洞微软修补时间为今年的5月份,听说和“震网”是同一个级别的漏洞(震网中也使用了打印机漏洞),固然兴趣更浓了,必定要一睹风采。安全
1、POC
服务器
源码:https://github.com/ionescu007/PrintDemon微信
我用vs2019编译成exe,将整个源码和exe打包放在:网络
连接:https://pan.baidu.com/s/17CclA4J3TwT9mY-XcfpGoA函数
提取码:hpen测试
2、漏洞影响范围:spa
Windows的许多最新版本,包括Windows Server 200八、20十二、2016和2019以及Windows 七、8.1和10,危害挺大的。
3、复现过程
一、环境:win10 x64;
声明,我当时测试时使用的是win7 x64;下面的说明先以win7为例,后面的以win10为例,我会在文中说明;
二、创建个普通权限的用户,test
三、将打包中的exe放入此win测试机中;当运行时出现这样的提示,说明test权限不够,要用管理员权限才能复制程序;
四、将两个主程序printserver.exe和printclient.exe复机到桌面,运行printserver.exe,
这时,看下打印机,多出一个PrintDemon;
看下打印机队列;
多出一个任务“本地下层文档”,隶属于用户test,“已暂停”状态;
运行printclient.exe,出现错误提示;
出现不能识别的错误提示。。。提示打开00002.shd文件,在c:\windows\system32\spool\PRINTERS目录下;
先记住这两个文件和那个目录;
找缘由,为何报错,看源代码:
再找下 这个 only support Version 4:
哎,写得清清楚楚,这个POC是用win10来作验证的,这么大说明都看不见啊,用win7固然报错了。换成win10,好了,这下面都是win10的操做了。
五、一样的步骤;
六、成功发送到打印机。
七、怎么提权?这仍是test啊,没有变成“管理员 test”啊。
八、咱们知道当使用普通权限登陆windows时,若是往windows里复制文件都是提示要管理员权限才行,还记得咱们复制的运行printserver的两个系统dll文件吗,往上看图,有个vcruntion140d.dll。说明在整个windows目录下都是要管理员权限才能动的。
九、看源码,发如今“c:\windows\tracing\”写入了demoport.txt;
说明:发如今“c:\windows\tracing\”这里是可写入的权限;并且这个位置是程序设定的,那就意味着我能够设定任何位置,如windows\system32下;
十、我来拖几个文件进去,看看是否能够写入,
确实能够,并且是在windows下。
这意味着:打印操做以SYSTEM特权运行,从而容许它覆盖OS上任何位置的任何文件。低权限的 test用户突破了没法修改系统资源的安全限制。
4、成因
一、打印机工做机制
Windows系统的打印机有两个核心组件:打印机驱动和打印机端口。
-
打印机驱动
在添加一个打印机时,须要安装打印机驱动。在MSDN文档描述中,早期系统要求只有具有SeLoadDriverPrivilege权限的用户才能安装打印驱动,但为了便于标准用户安装驱动,从Windows Vista开始,只要打印机驱动是已经存在的可当即使用的驱动,就不须要任何特权便可安装。例如,经过一条PowerShell命令便可安装“Generic / Text-Only”驱动。这里查看一下驱动;
打印机端口
在添加一个打印机时,须要设置打印机的端口。Windows支持多种类型的打印机端口:LPT1端口、USB端口、网络端口和文件等。若是设置端口为文件,则意味着打印机将数据打印到指定文件。例如,经过一条PowerShell命令便可添加一个输出到指定文件的打印端口:
准备好驱动和端口后,经过一条PowerShell命令便可建立一个打印机。就用这个图代替下,意思同样,不用懵吧。
一个完整的打印机命令结果图。
二、脱机打印的机制
在Windows系统上,若是系统配置启用了假脱机服务,则全部的打印任务都不是当即执行。相反,系统使用Print Spooler来管理脱机打印任务。具体来讲,当用户调用打印操做后,系统将打印做业存储在特定的假脱机文件夹中。
默认状况下,Windows生成的脱机打印任务文件为.SPL文件,此外Windows还会建立后缀名为.SHD的shadow文件并同SPL文件作关联。建立shadow文件的用途是:在打印程序出现问题或者打印任务被挂起后,PrintSpooler依然能够经过SHD文件恢复打印任务。
在Windows系统重启或Print Spooler服务重启以后,.SHD和.SPL文件会被从新读取以恢复打印任务。
三、打印提权的原理
脱机打印机制使得Windows系统在重启后会恢复可能存在的未执行打印任务。可是,重启后的Printer Spooler服务程序直接使用了System权限来恢复未执行的打印做业。对于打印机端口为文件的打印任务,打印文件的写入也就在System权限下被执行。所以,系统重启使得脱机打印任务具有了System权限的任意文件写入能力。
四、Windows系统提供了两种添加打印机端口的API,分别是AddPort函数和XcvData函数。其中MSDN对AddPort的描述:
“AddPort函数浏览网络以查找现有端口,并弹出对话框供用户选择。AddPort函数应该经过调用EnumPorts来验证用户输入的端口名称,以确保不存在重复的名称。AddPort函数的调用方必须具备访问端口所链接的服务器的SERVER_ACCESS_ADMINISTER权限。要添加端口而不显示对话框,可调用XcvData函数而不是AddPort”。
经过控制面板添加打印机在底层是调用了AddPort函数,该函数会触发spooler程序对端口的合法性校验。经过PowerShell命令添加打印机在底层则是直接调用XcvData函数,该函数不会触发spooler程序对用户添加的端口进行安全校验。
5、修复补丁
因为该漏洞能影响众多的Windows系统版本,并且能够在标准用户下发起漏洞攻击,建议受影响的用户及时进行系统更新或安装漏洞补丁。
此外,微软的安全更新只是对打印端口API进行了更严格的校验。可是,若是恶意文件端口在漏洞修复前已经建立,则漏洞攻击实际已经生效,此时进行系统更新仍然是不安全的。建议用户先使用PowerShell命令Get-PrinterPort来检查系统中是否存在可疑的打印机端口,在删除可疑端口后再实施系统更新。
研究这个漏洞,花了数个晚上的时间,光写此文,就整整花了我一中午的时间,约2个半小时。你细细地看完,收获会很大。
本文分享自微信公众号 - MicroPest(gh_696c36c5382b)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。