通过学习windows启动流程,我们可以了解该过程中系统启动了什么服务,加载了什么驱动,运行了什么程序,这对学习rootkit有参考意义。

下图是windows从引导开始,到windows子系统启动完成的整个流程:

我将跟随书本的顺序,将一些我认为可以藏rootkit的位置加粗表示出来。

固件启动

书上介绍了两种固件启动方式,分别是BIOS和EFI。

BIOS固件启动

机器启动时进行加电自检(Power-on Self-test, POST),POST的工作有确定板载内存大小,对内存进行循环检测,枚举主板上存储设备并确定状态等。

接下来BIOS搜索可引导设备列表以查找引导扇区。硬盘的第一个扇区是主引导记录(MBR),是由windows安装程序写进去的,MBR包含引导代码和分区表,分区表由4个分区表项构成,每个分区表项指向一个主分区。MBR在分区表中找到活动分区(也叫可引导分区,也叫系统卷),然后加载活动分区的引导扇区到内存。引导扇区也叫卷引导记录(Volume Boot Record, VBR),它是分区的第一个扇区,包含一小段引导代码。

VBR中的引导代码负责读取分区文件系统,执行 %SystemDrive%\bootmgr ,这是一个16位启动器管理程序,在实模式下运行,负责建立必须的数据结构,把机器切换到保护模式,把启动管理器的保护模式版本加载到内存。

EFI固件启动

这种方式更简单些,加电自检(POST)后,执行 %SystemDrive%\EFI\Microsoft\Boot\Bootmgfw.efi程序,将机器切换到保护模式。

启动管理器

BIOS和EFI机器最终都将启动管理器 bootmgr / Bootmgfw.efi 加载到内存中执行。

启动管理器通过注册表储巢文件中的配置数据启动系统,这个文件叫做 BCD(启动配置数据),它存储在下面两个位置之一:

  • %SystemDrive%\Boot\ 对于BIOS机器
  • %SystemDrive%\EFI\Microsoft\Boot\ 对于EFI机器

一般使用 bcdedit 工具对这个文件进行操作,比如之前配置WIN7双机调试环境时,就使用了这个工具。

bcdedit /enum

上面这个命令可以枚举BCD对象,如果配置了双机调试,应该至少能看到3条记录,我这没配置:

启动加载器

  • BIOS: winload.exe
  • EFI: winload.efi

启动加载器首先加载 SYSTEM 注册表储巢(位于%SystemRoot%\System32\config),并将它装载到注册表 HKLM\SYSTEM 键下。

然后加载数字签名目录文件 nt5.cat 验证自身完整性,如果签名不匹配,加载过程终止。

然后加载内核ntoskrnl.exe 和硬件抽象层 hal.dll 到内存,如果处于调试模式,还会加载符合调试器通信模式要求的内核驱动程序,如 kdcom.dll, kd1394.dll, kdusb.dll 。

然后验证 ntoskrnl.exe 与 hal.dll 的完整性。

然后依次加载下面的DLL:

  • pshed.dll
  • bootvid.dll
  • clfs.sys
  • ci.dll

然后扫描注册表 HKLM\SYSTEM\CurrentControlSet\Service\,这里指定了服务和设备驱动,启动加载器会启动 Start 值为 SERVICE_BOOT_START(0) 的服务/驱动,这个宏在 Winnt.h 定义。

这里是第一个藏rootkit的位置,例如上图标出的 ACPI (高级配置与电源接口)驱动就是在引导时由启动加载器启动的。

我们可以通过 bcdedit 打开启动日志:

bcdedit.exe /set BOOTLOG TRUE

执行该命令,下次启动系统后,可以在 %SystemRoot% 下找到一个名为 Ntbtlog.txt 的日志文件,我们可以通过它查看启动过程中加载的模块,显然,这是一种反rootkit的手段,我们在编写rootkit时,不要忘记抹除这个文件里的信息。

初始化执行体

当启动加载器调用 ntoskrnl.exe 的导出函数 KiSystemStartup 后,控制权就交给内核了,现在需要初始化执行体子系统,创建需要的数据结构,例如内存管理器创建页表及其他支持双环模型所需的内部数据结构。HAL配置中断控制器,填充IVT/IDT,启用中断。然后创建SSDT,加载ntdll等。

这里的内容很多,我们主要关注和rootkit相关的。

刚才提到了启动加载器从 HKLM\SYSTEM\CurrentControlSet\Service\ 中启动 Start 为0的服务/驱动,Start 指明了驱动/服务的启动时机,此外,Type 指明了这是驱动还是服务。

// Service Types (Bit Mask)
//
#define SERVICE_KERNEL_DRIVER          0x00000001
#define SERVICE_FILE_SYSTEM_DRIVER     0x00000002
#define SERVICE_ADAPTER                0x00000004
#define SERVICE_RECOGNIZER_DRIVER      0x00000008#define SERVICE_DRIVER                 (SERVICE_KERNEL_DRIVER | \SERVICE_FILE_SYSTEM_DRIVER | \SERVICE_RECOGNIZER_DRIVER)#define SERVICE_WIN32_OWN_PROCESS      0x00000010
#define SERVICE_WIN32_SHARE_PROCESS    0x00000020
#define SERVICE_WIN32                  (SERVICE_WIN32_OWN_PROCESS | \SERVICE_WIN32_SHARE_PROCESS)#define SERVICE_USER_SERVICE           0x00000040
#define SERVICE_USERSERVICE_INSTANCE   0x00000080#define SERVICE_USER_SHARE_PROCESS     (SERVICE_USER_SERVICE | \SERVICE_WIN32_SHARE_PROCESS)
#define SERVICE_USER_OWN_PROCESS       (SERVICE_USER_SERVICE | \SERVICE_WIN32_OWN_PROCESS)#define SERVICE_INTERACTIVE_PROCESS    0x00000100
#define SERVICE_PKG_SERVICE            0x00000200#define SERVICE_TYPE_ALL               (SERVICE_WIN32  | \SERVICE_ADAPTER | \SERVICE_DRIVER  | \SERVICE_INTERACTIVE_PROCESS | \SERVICE_USER_SERVICE | \SERVICE_USERSERVICE_INSTANCE | \SERVICE_PKG_SERVICE)//
// Start Type
//#define SERVICE_BOOT_START             0x00000000
#define SERVICE_SYSTEM_START           0x00000001
#define SERVICE_AUTO_START             0x00000002
#define SERVICE_DEMAND_START           0x00000003
#define SERVICE_DISABLED               0x00000004

执行体在 services 中搜索 Start值为1的子键,即伴随系统启动的驱动和服务,在通过 ci.dll 的代码完整性检查(驱动数字签名)后加载它们。

因此,这里是第二个藏rootkit的地方,把rootkit写入services键,设置Start 为1,那么执行体会帮我们启动rootkit。

会话管理器 smss.exe

执行体最后一项工作是初始化会话管理器 smss.exe 。会话管理器做的第一项工作是执行下面注册表键下 BootExecute 值所指定的程序:

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\

默认只有一个 autochk ,注意键的类型是 REG_MULTI_SZ ,意味着可以放多个字符串,用换行隔开,但是现在你还不能把类似 calc.exe 这样的程序填进去,因为现在windows子系统还没启动,如果程序只使用 Nt* 函数,应该是可以放在这里的,我没测试过。所以这里也是一个潜在的藏rootkit的位置。

此外,会话管理器 smss.exe 还需要设置系统环境变量,启动windows子系统,这意味着 smss.exe 本身是一个本机应用程序,它不使用windows API,只有当windows子系统启动后,才能使用windows API。读者可以自己查看一下 smss 的导入表,全是 ntdll 的 Nt* 函数。

下一步,SMSS从 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\KMode 获取值(通常是 \SystemRoot\System32\win32k.sys)并启动这个驱动。

然后,从HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls\中加载DLL,**显然,我们可以把我们的程序藏在这里。**这里的DLL是由SYSTEM用户加载的,拥有最高权限。

下一步,启动windows子系统,位置是HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\Required

Debug的值为空,Windows 的值是 Csrss.exe,至此,windows子系统启动完成,可以调用windows API了。

SMSS是会话管理器,因此最重要的就是启动会话了,SMSS通过windows子系统CSRSS启动了两个会话0和1,这两个会话分别创建了 wininit.exe 和 winlogon.exe 这两个进程。

  • 会话0创建宿主初始化进程 wininit.exe
  • 会话1创建宿主登录进程 winlogon.exe

接下来,SMSS循环等待监听本地过程调用(LPC)请求,以便LPC产生另外的子系统、创建新会话或关闭系统。

wininit.exe

wininit.exe 创建了3个子进程:

  • 本地安全授权子系统 lsass.exe
  • 服务控制管理器 services.exe
  • 本地会话管理器 lsm.exe

其中,LSASS负责用户授权,本地系统安全策略,向事件日志发布安全审计消息等工作。服务控制管理器 SCM 负责加载启动注册表 HKLM\SYSTEM\CurrentControlSet\Service\ **中 Start 为 SERVICE_AUTO_START 的驱动/服务,显然,这里是一个rootkit隐藏位置。**此外,SCM还负责处理用户程序的服务相关操作,例如我们可以通过SCM加载驱动。本地会话管理器LSM处理通过终端服务建立的到机器的连接。

winlogon.exe

负责处理用户登录,将证书发送到 LSASS.EXE ,如果登录成功,winlogon 就会启动下面注册表键下指定的程序:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\UserInit

通过下图可以看到,Shell下就是我们熟悉的桌面进程 explorer.exe:

userinit.exe 除了在组策略对象处理过程中发挥作用,我们更关心它和启动程序脚本相关的功能,它会启动下面的注册表键下的程序和脚本,和后面列出的两个目录下的程序和脚本:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run%SystemDrive%\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\
%SystemDrive%\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\

这些地方都可以藏我们的程序和脚本。

总结

还是贴出这张图。

通过windows启动流程分析rootkit的潜在位置相关推荐

  1. 解析并符号 读取dll_Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  2. Zygote进程启动流程分析

    文中的源代码版本为api23 Zygote进程启动流程分析 先说结论,zygote进程启动过程中主要做了下面这些事情: 启动DVM虚拟机 预加载部分资源,如一些通用类.通用资源.共享库等 启动syst ...

  3. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  4. SpringBoot启动流程分析(四):IoC容器的初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  5. Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析

    uboot启动流程分析如下: 第一阶段: a -- 设置cpu工作模式为SVC模式 b -- 关闭中断,mmu,cache v -- 关看门狗 d -- 初始化内存,串口 e -- 设置栈 f -- ...

  6. bootloader启动流程分析

    bootloader启动流程分析 1.Bootloader的概念和作用 Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序.在完成对系统的初始化任务之后,它会将Flash中 ...

  7. MyBatis启动流程分析

    目录 MyBatis简单介绍 启动流程分析 简单总结 附录 MyBatis内置别名转换 参考 MyBatis简单介绍 MyBatis是一个持久层框架,使用简单,学习成本较低.可以执行自己手写的SQL语 ...

  8. NameNode之启动流程分析

    NameNode启动流程分析 public staticvoid main(Stringargv[]) throws Exception { if (DFSUtil.parseHelpArgument ...

  9. springboot中获得app_Spring Boot 应用程序启动流程分析

    SpringBoot 有两个关键元素: @SpringBootApplication SpringApplication 以及 run() 方法 SpringApplication 这个类应该算是 S ...

  10. GEF入门实例_总结_04_Eclipse插件启动流程分析

    一.前言 本文承接上一节:GEF入门实例_总结_03_显示菜单和工具栏 注意到app目录下的6个类文件. 这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们 ...

最新文章

  1. behavior php,behavior.php
  2. 小球(信息学奥赛一本通-T1363)
  3. 元胞自动机交通流模型c++_MATLAB——含出入匝道的交织区快速路元胞自动机模型...
  4. HTML的基本知识(三)
  5. 嘉楠勘智 K210 RISC-V 64位双核处理器开发板(荔枝丹)
  6. 人生是什么?——感悟1:勇于承担自己的选择才是真正的勇气
  7. nginx resolver
  8. 跨境电商平台有哪些?各国电商平台及品类概览
  9. GNU C++ 智能指针4-- 解析_Sp_counted_ptr类
  10. 美团点评Cat业务实践
  11. c3p0 连接数据库报错
  12. OK6410A 开发板 (三) 4 u-boot-2021.01 boot 解析 SPL 编译链接部分
  13. 对比SQL学习power bi--(2)表关联顺序!
  14. 32位程序和64位程序
  15. 基于java与springboot结合商品推荐算法实现商品推荐网站+商品管理系统后台,mysql,vue
  16. 毕业论文浅析计算机病毒,浅析计算机病毒的有效防御论文
  17. 思维导图学习法 金融学基础课程思维导图分享
  18. 树莓派安装ROS问题:python-pip: 依赖: python-pip-whl (=18.1-5+rpt1) 但是它将不会被安装
  19. 过主动防御的有效方法
  20. pandas常用语法

热门文章

  1. 温故知新(七七)nextTick 是在本次循环执行,还是在下次,setTimeout(()=>{},0)呢
  2. arm 开发环境搭建-基于QEMU和Docker
  3. 计算机系统盘怎么扩充,扩大c盘空间,小编教你如何扩大C盘空间
  4. 计算机类sci四大水刊,官方证实:「四大水刊」之一的 ONCOTARGET 2018年起将不再被 SCI 收录,你怎么看?...
  5. Toad oracle
  6. 今日头条信息流 - 橙子建站
  7. git中rejected的解决方法
  8. 图像与视频处理中的优化方法
  9. 【8086汇编】输入一个整数,判断其奇偶性(输入范围:-32768~32767,含提示信息)
  10. 《炬丰科技-半导体工艺》激光增强湿法蚀刻制造的大规模高质量玻璃微透镜阵列