当前位置: 首页 > news >正文

tryhackme——Windows Internals

文章目录

  • 一、进程
  • 二、线程
  • 三、虚拟内存
  • 四、动态链接库
  • 五、PE格式
  • 六、与windows内核交互

一、进程

进程(Process)是操作系统中资源分配的基本单元,Windows的大多数功能都可以包含在一个应用程序中,并具有相应的进程。

攻击者可以攻击进程来逃避检测,并将恶意软件隐藏为合法进程。以下是攻击者可能针对进程使用的一些潜在攻击向量:

  • 进程注入
  • 进程挖空
  • 进程伪装

从高层抽象视角,进程包括:

Process ComponentPurpose
私有虚拟地址空间每个进程拥有独立的虚拟内存空间,与其他进程隔离,由操作系统映射到物理内存或磁盘
可执行程序包含进程的代码(指令)和初始数据(如全局变量),存储在虚拟地址空间中
打开句柄(Open Handles)进程已打开的系统资源(如文件、网络连接、设备)的引用标识符。管理进程对共享资源的访问(如读写文件)
安全上下文包含访问令牌(Access Token),定义进程所属用户、安全组、权限(如管理员权限)。
进程ID(Process ID, PID)操作系统分配的唯一数字标识符,用于区分不同进程。
线程进程内的执行单元,共享进程资源(如内存),但拥有独立的栈和寄存器。

从底层内存视角,进程包括:

Process ComponentPurpose
代码段存储可执行的机器指令
全局变量存储程序中定义的全局/静态变量,生命周期与进程相同
进程堆动态分配的内存区域(如通过 malloc() 或 new 申请的内存)
进程资源包括打开的文件、加载的动态库(DLL)、图形句柄等,支持进程运行时的外部依赖。
环境块存储进程的环境变量(如 PATH)、启动参数等

在这里插入图片描述

高层组件是操作系统对进程的管理抽象(如PID、安全令牌),而底层组件是进程在内存中的实际存储结构(如代码段、堆)。

观察进程的相关工具:Process Hacker 2、 Process Explorer、Procmon。

在Windows操作系统中,进程的完整性级别(Integrity Level) 是安全上下文(Security Context) 的一部分,用于定义进程的信任级别和权限限制。它是 Windows 强制完整性控制(Mandatory Integrity Control, MIC) 机制的核心概念,用于防止低权限进程篡改高权限进程或资源。

如,Integrity:High 表示管理员权限进程的级别。
在这里插入图片描述

二、线程

线程是执行的基本单元,线程与其父进程共享相同的详细信息和资源,例如代码、全局变量等。线程还具有其独特的值和数据,如下表所示。

Process ComponentPurpose
堆栈所有与线程相关的特定数据(异常、过程调用等)
线程本地存储允许每个线程拥有独立的全局或静态变量副本,避免多线程竞争
堆栈参数存储线程启动时传递的参数,通常通过栈或寄存器传递给线程入口函数
上下文结构保存线程被挂起(如切换或中断)时的CPU状态

三、虚拟内存

虚拟内存(Virtual Memory)是Windows内核的核心组件之一,它负责管理进程的内存访问,确保不同应用程序和系统组件之间不会因直接操作物理内存而产生冲突。

虚拟内存的核心作用

  1. 提供进程隔离的虚拟地址空间

    • 每个进程都认为自己独占 4GB(32位)或 256TB(64位) 的连续内存空间(称为 虚拟地址空间,VAS)。
    • 实际物理内存由操作系统动态映射,进程无法直接访问,避免恶意程序篡改其他进程或内核数据。
  2. 内存映射与分页:虚拟内存通过分页机制管理物理内存。

    • 内存按页(Page,通常4KB) 划分。
    • 进程访问的虚拟地址由 内存管理单元(MMU) 转换为物理地址。
    • 若物理内存不足,部分页面会被换出到 磁盘(Pagefile.sys),称为 分页(Paging) 或 交换(Swapping)。
  3. 权限控制
    每块虚拟内存区域都有访问权限(如可读、可写、可执行),防止代码注入或越界访问。

在这里插入图片描述
notepad.exe的基地址:
在这里插入图片描述

四、动态链接库

动态链接库(Dynamic Link Library),允许多个程序共享同一份代码和数据,其有助于代码复用、模块化开发、节省内存/磁盘空间。针对DLL的攻击有:

  • DLL劫持(Hijacking):恶意 DLL 被优先加载(利用搜索路径缺陷)。
  • DLL侧载(Side-Loading):替换合法程序的签名 DLL。
  • DLL注入(Injection):强制目标进程加载恶意 DLL(如窃取数据)。

以下是Visual C++ Win32动态链接库项目中一个DLL的示例:

// stdafx.h Visual Studio项目中自动生成的预编译头文件,用于加速编译过程
#include "stdafx.h"
// 标识当前正在编译DLL,EXPORTING_DLL只是一个编译开关,而不是dll的名字
// 区分 DLL 的编译和使用阶段,控制函数导出/导入
#define EXPORTING_DLL
// 确保函数声明一致,无论是编译DLL还是使用 DLL,HelloWorld()的声明必须相同,避免链接错误
#include "sampleDLL.h"// DllMain相当于main函数
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
)
{return TRUE;
}void HelloWorld()
{MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}

EXPORTING_DLL用于识别编译dll还是使用dll,一般编译的时候,需要导出dll;而使用的时候,需要导入dll。相关代码如下:

#ifndef INDLL_H// 头文件保护宏,防止重复包含#define INDLL_H#ifdef EXPORTING_DLL// extern:这是一个声明,避免重复定义错误;// __declspec(dllexport) :告诉编译器HelloWorld() 函数需要导出extern __declspec(dllexport) void HelloWorld();#elseextern __declspec(dllimport) void HelloWorld();#endif#endif

DLL使用:通过加载时动态链接运行时动态链接加载到程序中。

加载时动态链接

使用加载时动态链接加载时,应用程序会显式调用 DLL 函数,只能通过提供头文件 (.h) 和导入库 (.lib) 文件来实现这种链接。以下是从应用程序调用导出的 DLL 函数的示例:

// 预编译头文件(用于 MSVC 优化编译)
#include "stdafx.h"
// 包含DLL的头文件,声明了HelloWorld()
#include "sampleDLL.h"
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{HelloWorld();return 0;
}

运行时动态链接

使用运行时动态链接加载时,会使用单独的函数(LoadLibraryLoadLibraryEx)在运行时加载 DLL,加载后,需要使用GetProcAddress来识别要调用的导出 DLL 函数。以下是在应用程序中加载和导入 DLL 函数的示例:

...
typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;hinstDLL = LoadLibrary("sampleDLL.dll"); // 包含HelloWorld()函数的dll文件
if (hinstDLL != NULL)
{HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld");if (HelloWorld != NULL)(HelloWorld);fFreeDLL = FreeLibrary(hinstDLL);
}
...

在恶意代码中,威胁行为者通常更多地使用运行时动态链接,而不是加载时动态链接。因为恶意程序可能需要在内存区域之间传输文件,而传输单个 DLL 比使用其他文件导入方式更易于管理。

五、PE格式

Windows 的可执行文件(.exe)、动态链接库(.dll)、驱动程序(.sys)等均采用 PE (Portable Executable) 格式。PE 定义了可执行文件的结构,使其能被 Windows 加载并运行。下面从结构组成和实际分析(以file.exe为例) 进行详细解析。
在这里插入图片描述
DOS Header表示文件类型,其中MZ代表.exe文件。
在这里插入图片描述
DOS Stub是一个默认在文件开头运行的程序,用于打印兼容性消息,一般DOS Stub会打印以下消息:This program cannot be run in DOS mode
在这里插入图片描述

PE文件头是PE文件的核心元数据区域,定义了文件的全局属性和布局,包括PE签名、机器类型等。

在这里插入图片描述

Image Optional Header尽管名为“可选”,但所有PE文件都必须包含此头,包含程序入口点、映像基址、数据目录等。

节表紧接在PE header之后,定义了每个节的属性和位置。节存储实际内容,而节表描述如何解析它们。常见的节如下:

SectionPurpose
.text包含可执行代码和入口点
.data包含已初始化数据(字符串、变量等)
.rdata 或 .idata包含导入(Windows API)和 DLL
.reloc包含重定位信息
.rsrc包含应用程序资源(图像等)
.debug包含调试信息

六、与windows内核交互

关于进程注入技术:

1、获取目标进程句柄 (OpenProcess)

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,  // 请求所有权限(可能被安全软件拦截)FALSE,               // 句柄不可继承DWORD(atoi(argv[1])) // 目标进程 PID(通过命令行参数传入)
);

2、在目标进程中分配内存 (VirtualAllocEx)

LPVOID remoteBuffer = VirtualAllocEx(hProcess,                  // 目标进程句柄NULL,                      // 由系统自动选择分配地址sizeof(payload),           // 分配的内存大小(Payload 长度)(MEM_RESERVE | MEM_COMMIT), // 保留并提交物理内存PAGE_EXECUTE_READWRITE      // 内存权限:可执行、可读写
);

3、将Payload写入目标内存 (WriteProcessMemory)

WriteProcessMemory(hProcess,           // 目标进程句柄remoteBuffer,       // 目标内存地址(由 VirtualAllocEx 返回)payload,            // 本地 Payload 数据指针sizeof(payload),    // Payload 大小NULL                // 可选参数(返回实际写入字节数)
);

4、创建远程线程执行 Payload (CreateRemoteThread)

HANDLE remoteThread = CreateRemoteThread(hProcess,                      // 目标进程句柄NULL,                          // 默认安全属性0,                             // 默认栈大小(LPTHREAD_START_ROUTINE)remoteBuffer, // 线程起始地址(指向 Payload)NULL,                          // 无参数传递给线程0,                             // 线程立即运行NULL                           // 不返回线程 ID
);
http://www.xdnf.cn/news/736075.html

相关文章:

  • PyQt6基础_QtCharts绘制横向柱状图
  • 代码随想录算法训练营第60期第五十二天打卡
  • 六步完成软件验收:从计划到终验的全面指南(一)
  • 【瑶池数据库训练营及解决方案本周精选(探索PolarDB,参与RDS迁移、连接训练营)】
  • mobile app 工具简要对比
  • 秒出PPT正式改名秒出AI,开启AI赋能新体验!
  • 数字人革新教育:开启智慧教学新时代
  • 力扣面试150题--二叉树的层平均值
  • 探讨分贝计在医疗环境中的具体应用及其重要性
  • 基于VU37P的高性能采集板卡
  • (独家)SAP VC物料 超级BOM怎么开单?怎么计算或发布表标准成本?
  • 第10讲、Odoo 18框架设计原理全解析
  • Redis 难懂命令-- ZINTERSTORE
  • mysql怎么查询longblob类型数据的大小
  • 小程序33-列表渲染
  • 彻底解决Win11文件资源管理器预览窗格无法预览问题
  • 使用lombok使用自动生成构造方法进行依赖注入
  • KAG进化论:从知识增强到Ai AGENT超级智能体+MOE专家模型将如何引爆下一代AI?
  • 31、请求处理@MatrixVariable与UrlPathHelper
  • PCIe-PCI、PCIe中断机制概述
  • 怎么在window上打开ubuntu虚拟机?
  • 小黑大语言模型通过设计demo进行应用探索:langchain中chain的简单理解demo
  • 事件不触发、交互失效?基于 WebDebugX 的移动端事件调试实战总结
  • 帕金森常见情况解读
  • Cypress API 中文详解
  • 主机号全0,代表网络本身地址; 主机号全1,代表广播地址
  • NLP学习路线图(十二):停用词处理
  • Redis 数据恢复的月光宝盒,闪回到任意指定时间
  • 我的世界服务端搭建
  • 将图片存为二进制流到数据库并展示到前端的实现