轩辕三官 发布于2022年11月8日 分享 发布于2022年11月8日 0x00 前言 BSOD,全称死亡蓝屏,即蓝屏死机。 通常是振铃0级的内核程序出错导致,在提权漏洞中经常遇到。 而在渗透测试中,某些情况下需要重启系统,例如配置密码筛选器DLL,启用Wdigest Auth,重启域控服务器等。 某些条件下,可以选择触发BSOD导致系统重新启动。 那么,是否存在一个稳定的方法触发BSOD呢?更进一步的利用思路呢?如何防御? 0x01 简介 本文将要介绍以下内容: 测试几种结束当前进程导致BSOD的方法 修改指定进程,当进程退出后,导致BSOD 如何防御 0x02 结束当前进程导致BSOD的方法 找到如下参考资料: https://blog.csdn.net/qq125096885/article/details/52911870 提供多种结束当前进程导致BSOD的方法 经测试,适用Win7系统的方法有以下三种: CallRtlSetProcessIsCritical CallNtSetInformationThread CallNtRaiseHardError 1、CallRtlSetProcessIsCritical 关键代码: RtlSetProcessIsCritical(TRUE,NULL,FALSE); 参考资料: https://www。代码项目。com/Articles/43405/Protecting-Your-Process-with-rtlsetprocessicriti 函数原型: NTSTATUS RtlSetProcessIsCritical( 布尔b新,//进程的新设置 BOOLEAN *pbOld,//接收旧设置的指针(可以为空) 布尔型bNeedScb);//需要系统关键中断 第一个参数,设置为真实的时,表示将当前进程标记为关键流程;设置为错误的时,当前进程不是关键过程 critical process: 系统进程特有,已知以下系统进程为关键流程: csrss.exe lsass.exe services.exe smss.exe svchost.exe wininit.exe 当关键过程退出时,会导致系统BSOD,所以如果我们将当前进程也设置为关键流程,那么在进程退出时同样会导致BSOD 如下图 2、NtSetInformationProcess 关键代码: ULONG A=1; NtSetInformationProcess(GetCurrentProcess(),ProcessBreakOnTermination,A,sizeof(ULONG)); 参考资料: http://undocumented.ntinternals.net/index.html?page=用户模式/文档化函数/NT对象/进程/ntsetinformationprocess。超文本标记语言 函数原型: NtSetInformationProcess( 在句柄进程句柄中, 在过程_信息_类过程信息类中, 在PVOID过程信息中, 在ULONG process information length); 第一个参数表示进程句柄 第二个参数ProcessInformationClass,我在NtQueryInformationProcess的说明中找到了参考,地址如下: https://份文件。微软。com/en-us/windows/desktop/API/winter nl/nf-winter nl-ntqueryinformationprocess ProcessBreakOnTermination:29,检索一个乌龙值,该值指示进程是否被认为是关键的。 所以ProcessInformationClass设置为29 第三个参数过程信息,设置为真实的时,表示将当前进程标记为关键流程;设置为错误的时,当前进程不是关键过程 第四个参数为长度,即sizeof(乌龙) 3、CallNtRaiseHardError 关键代码: typedef枚举_硬错误_响应_选项{ OptionAbortRetryIgnore, OptionOk, 选项取消, OptionRetryCancel, 选项是否, 选项是取消, 选项关闭系统 }硬件错误响应选项,*硬件错误响应选项 typedef枚举_硬错误_响应{ ResponseReturnToCaller, ResponseNotHandled, ResponseAbort, 回应取消, 响应忽略 回应否, 回复好吧, 反应, 回应 } HARDERROR_RESPONSE,* PHARDERROR _ RESPONSE 硬错误_响应或; 硬错误_响应_选项OP; OR=响应 OP=选项关闭系统 NtRaiseHardError(0xC0000217,0,0,0,OptionShutdownSystem,或); 参考资料: http://undocumented.ntinternals.net/index.html?page=用户模式/文档化功能/错误/ntraiseharderror。超文本标记语言 函数原型: NtRaiseHardError( 在NTSTATUS错误状态中, 在乌龙数量的参数中, 在惩罚码_字符串中unicode string参数掩码可选, 在PVOID *参数中, 在硬错误响应选项响应选项中, OUT PHARDERROR_RESPONSE响应); 此函数用于在处理异常时生成应用程序错误对话框。通常会弹出一个对话框提示用户是否终止进程。但是,如果我们将参数设置为0xC0000217、OptionShutdownSystem和ResponseYes,则会导致BSOD,提示0xC0000217。 如下图 注: ErrorStatus也可以是其他值,请参考以下地址的NTSTATUS描述: https://msdn.microsoft.com/en-us/library/cc704588.aspx 只需选择代表失败函数的值,如0xc 000000 c(status _ timer _ not _ cancelled)、0xc 0000216(status _ not _ server _ session)和0xc 0000219(status _ debug _ attach _ failed)。 0x03 结束指定进程导致BSOD的方法 上述三个函数中,只有NtSetInformationProcess支持传入进程句柄。 接下来,只要我们能获得指定进程的句柄并将其传入NtSetInformationProcess,就可以结束指定进程并导致BSOD。 想法如下: 提升到调试权限。 通过OpenProcess打开指定的进程,获取进程句柄。 调用CallNtSetInformationProcess将指定的进程设置为关键进程。 有关完整代码,请参考以下链接: https://github . com/3g student/home-of-C-Language/blob/master/setprocesscritical . CPP 代码还支持将指定的进程从关键进程设置为正常进程。 0x04 防御思路 为了避免这种情况,当我们结束一个流程时,我们需要检查它是否是一个关键流程。如果是关键流程,我们需要在结束前将其设置为正常流程。 这包括查询该流程是否是关键流程。 您需要使用内核API NtQueryInformationProcess来查询ProcessBreakOnTermination以获取进程信息。 关键代码如下: status=NtQueryInformationProcess(h process,ProcessBreakOnTermination,BreakOnTermination,sizeof(ULONG),NULL); 如果(状态0) printf('[!]NtQueryInformationProcess错误\ n '); if(breakOnTermination==1) printf('[]过程很关键'); 其他 printf('[!]过程并不关键’); 有关完整代码,请参考以下链接: https://github . com/3g student/home-of-C-Language/blob/master/checkcritical proess . CPP 代码实现查询指定的进程是否是关键进程。 实际上,它会查询当前系统的所有进程中是否存在关键进程。 在代码实现上,我们可以通过EnumProcesses的所有进程的PID做进一步的查询。 有关完整代码,请参考以下链接: https://github . com/3g student/home-of-C-Language/blob/master/findcriticalprocess . CPP 该代码可以查询当前系统的所有进程,筛选出系统进程,并标记关键进程。 0x05 小结 本文测试了三种终止通向BSOD的当前进程的方法,并进一步介绍了终止通向BSOD的指定进程的方法。结合利用的思想,分析防御方法,编写程序查询当前系统中的所有进程,标记关键进程,在关键进程结束前可以设置为正常进程,避免系统中的BOSD。 留下回复 链接帖子 意见的链接 分享到其他网站 更多分享选项…
推荐的帖子