(测试环境:win10,1909)
最近测试注入遇到一个问题:OpenProcess 失败,报错码:5,没有权限。
问题排查:
1,是否是管理员权限启动程序?
是
2,注入的目标进程有什么特殊?
目标进程是svchost.exe,是服务进程,在session0;我的程序在session1。
是因为在不同session吗?
3,上网搜索相关内容并继续试验
弄巧成拙:通过ProcessHacker把资源管理器进程重启后,发现又可以注入服务进程了。
所有和session没有什么关系,那是为什么?对比前后资源管理器进程的差别可以发现,如下图:
(都是系统管理员权限启动)左边是重启后,右边是重启前。可以发现关键差别是SeDebugPrivilege 属性被“点开”。进程的SeDebugPrivilege被“点开"后,可以注入svchost.exe。
所有目前没有和session有什么关系,privileges matters!
成功注入后,从内存中创建的线程,如下图:
//更新 2023/02/15
微软的文档解释了,为什么有跨session注入的问题。如下:
“在Windows 8之前,终端服务通过设计隔离每个终端会话。 因此,如果目标进程位于与调用进程不同的会话中, CreateRemoteThread 将失败。”---------微软文档
所以在win8之前会有跨session注入的问题,在win10及以后则没有相关问题。
在win7 x64上测试发现:OpenProcess,VirtualAlloc,WriteProcessMemory都可以成功执行,
CreateRemoteThread 执行失败,报错
The storage control blocks were destroyed.
ERROR_NOT_ENOUGH_MEMORY
8 (0x8) 。
在win7,正确的跨session 注入的方式,参考:https://article.itxueyuan.com/KA7k81。
通过更底层的api,
#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