Session是Windows系统的一个安全特性,该特性引入了针对用户体验提高的安全机制,即拆分Session 0和用户会话,这种拆分Session 0Session 1的机制对于提高安全性非常有用,这是因为将桌面服务进程,驱动程序以及其他系统级服务取消了与用户会话的关联,从而限制了攻击者可用的攻击面。

由于DLL注入在Session 0中的注入机制不同于在用户会话中的注入机制,因此需要特别的考虑和处理。如果需要执行DLL注入,必须使用过度级别安全机制解决Session 0上下文问题,并且在设计安全方案时,必须考虑Session 0Session 1之间的区别。

在之前的远程线程注入章节中,我们通过使用CreateRemoteThread()这个函数来完成线程注入,此方式可以注入普通的进程,但却无法注入到系统进程中,因为系统进程是处在SESSION0高权限级别的会话层,由于CreateRemoteThread()底层会调用ZwCreateThreadEx()这个未公开的内核函数,所以当我们调用该函数的底层函数时则可实现突破Session0的注入机制。

由于该内核函数并未被导出,所以我们必须找到该函数的原型定义,并通过GetProcAddress获取到ntdll.dll模块下的ZwCreateThreadEx的函数地址,并通过ZwCreateThreadEx函数指针直接调用模块;

#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);
#endif

当拿到ZwCreateThreadEx函数指针时,则接下来就可以调用了,ZwCreateThreadEx 可以用于创建一个远程线程,即在目标进程中创建一个线程,并在这个线程中运行指定的代码。与CreateRemoteThread不同,ZwCreateThreadEx可以用于创建一个在指定进程的上下文之外的线程,即可以创建一个与指定进程无关的线程。

它的函数原型定义如下:

NTSYSAPI NTSTATUS NTAPI ZwCreateThreadEx(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PVOID StartRoutine,
PVOID Argument,
ULONG CreateFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
PPS_ATTRIBUTE_LIST AttributeList);

其参数说明如下:

  • ThreadHandle 用于返回创建的线程句柄的指针。
  • DesiredAccess 用于指定线程句柄的访问权限。
  • ObjectAttributes 一个指向 OBJECT_ATTRIBUTES 结构的指针,指定线程对象的对象名和安全性属性。
  • ProcessHandle 目标进程的句柄,即在哪个进程中创建新线程。
  • StartRoutine 一个指向新线程的入口点的指针。
  • Argument 第二个参数传递给新线程的指针。
  • CreateFlags 指定创建线程的属性,如堆栈大小、创建标志、线程属性等。
  • ZeroBits 保留参数,应该传递0。
  • StackSize 线程堆栈大小。
  • MaximumStackSize 线程堆栈的最大大小。
  • AttributeList 指向结构 PS_ATTRIBUTE_LIST,该结构可以用于在线程创建时指定各种属性。

具备了上述基本条件那么注入代码的事项将变得非常容易,如下代码是这个注入程序的完整实现流程,读者可自行测试注入效果;

#include <windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <tchar.h> // 传入进程名称返回该进程PID
DWORD FindProcessID(LPCTSTR szProcessName)
{
DWORD dwPID = 0xFFFFFFFF;
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
Process32First(hSnapShot, &pe);
do
{
if (!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile))
{
dwPID = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return dwPID;
} // 强力注入
BOOL ZwCreateThreadExInjectDll(DWORD dwProcessId, char* pDllName)
{
HANDLE hProcess = NULL;
SIZE_T dwSize = 0;
LPVOID pDllAddr = NULL;
FARPROC pFuncProcAddr = NULL;
HANDLE hRemoteThread = NULL;
DWORD dwStatus = 0; // 打开注入进程
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (NULL == hProcess)
{
return FALSE;
} // 在注入进程中申请内存
dwSize = sizeof(char) + lstrlen(pDllName);
pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (NULL == pDllAddr)
{
return FALSE;
} // 向申请的内存中写入数据
if (FALSE == WriteProcessMemory(hProcess, pDllAddr, pDllName, dwSize, NULL))
{
return FALSE;
} // 加载ntdll.dll模块
HMODULE hNtdllDll = LoadLibrary("ntdll.dll");
if (NULL == hNtdllDll)
{
return FALSE;
} // 获取LoadLibraryA函数地址
pFuncProcAddr = GetProcAddress(::GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
if (NULL == pFuncProcAddr)
{
return FALSE;
} // 获取ZwCreateThread函数地址
#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);
#endif typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdllDll, "ZwCreateThreadEx");
if (NULL == ZwCreateThreadEx)
{
return FALSE;
}
// 调用函数执行强力注入
dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hProcess,
(LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
if (NULL == hRemoteThread)
{
return FALSE;
} // 关闭句柄
CloseHandle(hProcess);
FreeLibrary(hNtdllDll);
return TRUE;
} int main(int argc, char *argv[])
{
DWORD pid = FindProcessID("lyshark.exe");
std::cout << "进程PID: " << pid << std::endl; bool flag = ZwCreateThreadExInjectDll(pid, (char *)"d://hook.dll");
std::cout << "注入状态: " << flag << std::endl; return 0;
}

3.3 DLL注入:突破会话0强力注入的更多相关文章

  1. 远程线程注入突破SESSION 0

    远程线程注入突破SESSION 0 SESSION 0 隔离 在Windows XP.Windows Server 2003,以及更老版本的Windows操作系统中,服务和应用程序使用相同的会话(Se ...

  2. 远程线程注入DLL突破session 0 隔离

    远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...

  3. 远程线程注入dll,突破session 0

    前言 之前已经提到过,远线程注入和内存写入隐藏模块,今天介绍突破session 0的dll注入 其实今天写这个的主要原因就是看到倾旋大佬有篇文章提到:有些反病毒引擎限制从lsass中dump出缓存,可 ...

  4. 恶意软件开发——突破SESSION 0 隔离的远线程注入

    一.前言 在Windows XP,Windows Server 2003以及更早的版本中,第一个登录的用户以及Windows的所有服务都运行在Session 0上,这样的做法导致用户使用的应用程序可能 ...

  5. 关于突破 SESSION 0 隔离场景发现的一些问题

    0x00 Tricks 0x01 用ZwCreateThreadEx 在 Windows 10 下直接通过管理员权限+SeDebugPrivilege启用. 0x02 用CreateRemoteThr ...

  6. 微软黑科技强力注入,.NET C#全面支持人工智能

    微软黑科技强力注入,.NET C#全面支持人工智能,AI编程领域开始C#.Py--百花齐放 就像武侠小说中,一个普通人突然得到绝世高手的几十年内力注入,招式还没学,一身内力有点方 Introducin ...

  7. Spring依赖注入servlet会话监听器

    Spring提供了一个 “ContextLoaderListener” 监听器,以使 Spring 依赖注入到会话监听器. 在本教程中,通过添加一个 Spring 依赖注入一个bean 到会话监听器修 ...

  8. Dll注入技术之远程线程注入

    DLL注入技术之远线程注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EX ...

  9. DLL注入技术之依赖可信进程注入

    DLL注入技术之依赖可信进程注入 依赖可信进程注入原理是利用Windows 系统中Services.exe这个权限较高的进程,首先将a.dll远线程注入到Services.exe中,再利用a.dll将 ...

  10. DLL注入之修改PE静态注入

    DLL注入之修改PE静态注入 0x00 前言 我们要注入的的力量功能是下载baidu首页数据.代码如下: #include "stdio.h" #include"stdi ...

随机推荐

  1. 23年校招Java开发同花顺、滴滴等面经

    前言 已经工作近半年时间了,最近突然翻到这份面经,于是想整理一下一些面试的经验,大中小公司都有 青书一面 50min 数据库.java基础. Cas机制. Tcp/udp区别 堆排序介绍,答错了,弄成 ...

  2. SAP发布HTTP接口

    1.创建类 引用标准接口 改写集成的接口方法 此处仅实现POST方法,将传入的JSON报文转为函数传入参数,调用获取物料接口,并将返回的物料信息,转换为JSON报文返回 METHOD if_http_ ...

  3. MM01 物料主数据批导

    1业务场景 期初批量导入物料主数据时,有以下要求: 维护相应的物料视图 将物料维护到多个工厂 可能需要对物料进行分割评估 对某些字段,需要在BAPI中做增强处理进行维护 2代码实现 2.1物料基本数据 ...

  4. JSP开发模式(四种模式)

    原作者为 RioTian@cnblogs, 本作品采用 CC 4.0 BY 进行许可,转载请注明出处. 学习编程开发少不了学习开发模式, JSP在创立至今有 \(4\) 种流行的开发模式: 包括 JS ...

  5. SCA技术进阶系列(一):SBOM应用实践初探

    现代软件都是组装的而非纯自研.随着开源组件在数字化应用中的使用比例越来越高,混源开发已成为当前业内主流开发方式.开源组件的引入虽然加快了软件开发效率,但同时将开源安全问题引入了整个软件供应链.软件组成 ...

  6. 清洁低碳环保新能源,3D 光伏与光热发电站可视化

    前言 碳达峰.碳中和成为今年两会"热词",在国家政府工作报告中指出,扎实做好碳达峰.碳中和各项工作,制定 2030 年前碳排放达峰行动方案,优化产业结构和能源结构,实现低碳环保节能 ...

  7. SpringCloud学习 系列十、服务熔断与降级(1-简介)

    系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...

  8. 【内核】深入分析内核panic(一)--内核问题的原因

    1 概述 linux内核包括进程管理.内存管理.中断管理.设备驱动.同步机制等各种模块,它们共同运行在一个共享的地址空间中,因此在运行中一旦出现问题,彼此之间可能具有千丝万缕的联系. 而且与用户态不同 ...

  9. Vue-pdf实现在线预览PDF文件

    前言 在大多数项目中都会遇到在线预览PDF文件,项目使用的是element ui,使用vue-pdf实现. 安装依赖 npm install --save vue-pdf 相关参数 参数介绍: url ...

  10. lucene.net全文检索(二)lucene.net 的封装

    查询 public class LuceneQuery : ILuceneQuery { #region Identity private Logger logger = new Logger(typ ...