Windows Print Spooler服务最新漏洞CVE-2021-34527详解

.text:0000000180085F3A mov rax, cs:pLocalIniSpooler

.text:0000000180085F41 xor r9d, r9d

.text:0000000180085F44 and [rsp+58h+var_30], 0

.text:0000000180085F49 xor r8d, r8d

.text:0000000180085F4C xor ecx, ecx

.text:0000000180085F4E mov [rsp+58h+var_38], rax

.text:0000000180085F53 lea edx, [r9+1]

.text:0000000180085F57 call ?ValidateObjectAccess@@YAHKKPEAXPEAKPEAU_INISPOOLER@@W4SERVER_MANAGEMENT_ACCESS_REQUEST@@@Z ; ValidateObjectAccess(ulong,ulong,void *,ulong *,_INISPOOLER *,SERVER_MANAGEMENT_ACCESS_REQUEST)

.text:0000000180085F64 loc_180085F64: ; CODE XREF: SplAddPrinterDriverEx+98↑j

.text:0000000180085F64 ; SplAddPrinterDriverEx+BE↑j

.text:0000000180085F64 and [rsp+58h+var_20], 0

.text:0000000180085F6A mov r9d, esi

.text:0000000180085F6D mov eax, [rsp+58h+arg_28]

.text:0000000180085F74 mov r8, r14

.text:0000000180085F77 mov [rsp+58h+var_28], ebx

.text:0000000180085F7B mov edx, r15d

.text:0000000180085F7E mov [rsp+58h+var_30], eax

.text:0000000180085F82 mov rcx, rdi

.text:0000000180085F85 mov [rsp+58h+var_38], rbp

.text:0000000180085F8A call InternalAddPrinterDriverEx

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

  • 27

  • 28

  • 29

其中esi为dwFileCopyFlags,是一个调用者可控的参数,bt esi,0xf将esi中偏移0xf的比特位保存到CF标志位,即CF标志位与esi的0x10比特位相同,dwFileCopyFlags=0x8014时CF=1。cmovnb ebx, [rsp+58h+arg_30]即mov if not below,cmovnb会检测CF标志位是否为0且当CF为0时进行移位操作,此时[rsp+0x90]=1,CF=1不会将ebx赋值为1。调试现场如下

图片

由于ebx=0,jz short loc_180085F64会跳转到InternalAddPrinterDriverEx处执行后续复制并加载驱动的操作,跳过了0x180085F57处ValidateObjectAccess的检测。

0x02.2 InternalAddPrinterDriverEx

===========================================================================================================


==================================================================

RpcAddPrinterDriverEx会在spoolsv!RpcAddPrinterDriverEx处解析,调用到localspl!LocalAddPrinterDriverEx处的回调,并最终由于localspl!SplAddPrinterDriverEx处的验证ValidateObjectAccess无效导致可以调用到localspl!InternalAddPrinterDriverEx加载驱动并执行。

=================================================================================================================================================================================================================================================================================

调用到localspl!SplAddPrinterDriverEx时的栈回溯如下

0:009> k

# Child-SP RetAddr Call Site

00 0000001f7f83e938 00007ffcfb225852 localspl!SplAddPrinterDriverEx

01 0000001f7f83e940 00007ff66c23ba9f localspl!LocalAddPrinterDriverEx+0xa2

02 0000001f7f83e990 00007ff66c215ffe spoolsv!AddPrinterDriverExW+0x6f

03 0000001f7f83e9d0 00007ff66c212c71 spoolsv!YAddPrinterDriverEx+0x2ce

04 0000001f7f83ea10 00007ffd027184a3 spoolsv!RpcAddPrinterDriverEx+0x181

2021-6的补丁中在spoolsv!RpcAddPrinterDriverEx中调用YAddPrinterDriverEx加载驱动前加了几处校验,如下右为补丁后的spoolsv.exe。补丁后YIsElevated、RunningAsLUA分别校验了当前用户的token和LUA权限,这两处校验在RCE中可以通过IPC被绕过;YIsElevationRequired检验了HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint\NoWarningNoElevationOnInstall的注册表项,但是笔者在2021-6全补丁的Windows server和Windows10系统上均未发现有该注册表项,所以这个缓解在目前来看也是无效的。(这两处缓解可能是针对Yunhai Zhang和ZhiPeng Huo提供的CVE-2021-1675的poc)

图片

随后由于spoolsv!AddPrinterDriverExW调用到localspl!LocalAddPrinterDriverEx处的回调,又由于上述分析的localspl!SplAddPrinterDriverEx中验证无效进入localspl!InternalAddPrinterDriverEx的流程。

localspl!InternalAddPrinterDriverEx主要进行了如下操作,其中%spooler%=C:\Windows\System32\spool\

1.ValidateDriverInfo进行驱动签名等的检查

2.CreateInternalDriverFileArray创建spooler目录下的驱动文件,即%spooler%\drivers\x64

3.GetPrintDriverVersion、CheckFilePlatform检查驱动版本和驱动运行平台

4.SplIsCompatibleDriver进行驱动版本和驱动兼容性检查,驱动版本号只能为3

5.CreateVersionDirectory使用提供的驱动版本号,创建spooler目录下驱动版本号目录,由于驱动版本号只能为3,最终目录为%spooler%\drivers\x64\3

6.CopyFilesToFinalDirectory创建%spooler%\3目录下New、Old文件夹,创建New、Old目录下的临时目录,如%spooler%\drivers\x64\3\Old\1、%spooler%\drivers\x64\3\Old\2;并将上传的驱动移动到临时目录下

7.WaitRequiredForDriverUnload加载6中临时目录下的驱动,路径如%spooler%\drivers\x64\3\old\1\xx.dll

0x02.2.1 ValidateDriverInfo

=====================================================================================================


localspl!ValidateDriverInfo在如下代码会校验加载驱动的签名,可以使用0x8000的dwFileCopyFlags绕过,0x8000即RpcAddPrinterDriverEx 的API文档中提到的APD_INSTALL_WARNED_DRIVER,翻译过来即强制加载驱动。

图片

0x02.2.2 CreateInternalDriverFileArray

================================================================================================================


localspl!CreateInternalDriverFileArray中会使用如下代码根据RpcAddPrinterDriverEx 的dwFileCopyFlags参数生成CreateFile的参数,a5=1会使用%spooler%目录下路径做为CreateFile的参数;RCE利用时我们上传的驱动此时是在一个UNC路径下,如笔者本地为\\192.168.18.153\share\rev.dll,所以这里需要构造dwFileCopyFlags&0x10=1使spooler使用我们的UNC路径。

图片

其中a5参数从localspl!LocalAddPrinterDriverEx这里传入,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IYu2mThc-1625827565106)(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==)]

0x02.2.3 SplIsCompatibleDriver

========================================================================================================


==================================================================

localspl!SplIsCompatibleDriver会检查将要加载的驱动的版本号,版本号v117只能为3。

===========================================================================================================================

图片

其中v117会在localspl!InternalAddPrinterDriverEx这里校验两次,v117==2和v117>3都会导致驱动加载失败。

图片

localspl!SplIsCompatibleDriver检查驱动兼容性时会调用到ntprint!PSetupIsCompatibleDriver,最终会调用到如下代码,其中a6=v117为驱动版本号,当v117<=2时返回0会导致驱动加载失败。

图片

综上,当v117==2、v117>3、v117<=2时均会最终导致驱动加载失败,v117只能为3。

0x02.2.4 CopyFilesToFinalDirectory

============================================================================================================


==================================================================

localspl!CopyFilesToFinalDirectory主要是创建%spooler%\drivers\x64\3\New、%spooler%\drivers\x64\3\Old,并创建临时目录如%spooler%\drivers\x64\3\Old\1,将UNIDRV.DLL、kernelbase.dll、rev.dll依次从C:\Windows\System32\spool\drivers\x64\3\New、C:\Windows\System32\spool\drivers\x64\3里使用MoveFileExW移动到%spooler%\drivers\x64\3\Old\1里。

==============================================================================================================================================================================================================================================================================================================================================================================================================

图片

最终在localspl!CompleteDriverUpgrade里更新所加载驱动的信息并加载上述临时目录下的驱动。

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
img

dc6f4668534a.png)

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-MqUfoI0u-1710986028450)]

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值