本文作者:Gality
本文字数:7928字
阅读时长:20分钟
本文属于【狼组安全社区】原创奖励计划,未经许可禁止转载
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,狼组安全团队以及文章作者不为此承担任何责任。
狼组安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经狼组安全团队允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
最近在研究进程注入相关的东西,主要是参考process-inject项目,想自己实现上面的所有进程注入手法,并弄清楚其中的原理。在进程注入中,首先就需要先将当前进程提权,才能取得对其他进程内存的写权限,完成进程注入,故这篇文章主要以进程注入来说提权的相关的知识。
常规提权手法
首先是常规的进程提权方式,完全可以不理解下面的代码的含义,只需要在进程需要获取SeDebugPrivilege权限时复制该段代码并在最开始调用即可获得权限
BOOL EnableDebugPrivilege() {
HANDLE TokenHandle = NULL;
TOKEN_PRIVILEGES TokenPrivilege;
LUID uID;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) {
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &uID)) {
TokenPrivilege.PrivilegeCount = 1;
TokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
TokenPrivilege.Privileges[0].Luid = uID;
if (AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivilege, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
CloseHandle(TokenHandle);
TokenHandle = INVALID_HANDLE_VALUE;
return TRUE;
}
else
goto Fail;
}
else
goto Fail;
}
else
goto Fail;
Fail:
CloseHandle(TokenHandle);
TokenHandle = INVALID_HANDLE_VALUE;
return FALSE;
}
解释
在进程注入时,要对一个任意进程(包括系统安全进程和服务进程)进行指定了**写相关**的访问权的OpenProcess操作,只要当前进程具有SeDeDebug权限就可以了。要是一个用户是Administrator或是被给予了相应的权限,就可以具有该权限。可是,就算我们用Administrator帐号对一个系统安全进程执行OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID)还是会遇到“访问拒绝”的错误。
这是因为在默认的情况下进程的一些访问权限是没有被使能(Enabled)的,所以我们要做的首先是使能这些权限。与此相关的一些API函数有OpenProcessToken、LookupPrivilegevalue、AdjustTokenPrivileges。如果我们要修改一个进程的访问令牌
windows的每个用户登录系统后,系统会产生一个访问令牌(access token),其中关联了当前用户的权限信息,用户登录后创建的每一个进程都含有用户access token的拷贝,当进程试图执行某些需要特殊权限的操作或是访问受保护的内核对象时,系统会检查其acess token中的权限信息以决定是否授权操作。
Administrator组成员的access token中会含有一些可以执行系统级操作的特权(privileges),如终止任意进程、关闭/重启系统、加载设备驱动和更改系统时间等,不过这些特权默认是被禁用的,当Administrator组成员创建的进程中包含一些需要特权的操作时,进程必须首先打开这些禁用的特权以提升自己的权限,否则系统将拒绝进程的操作。注意,非Administrator组成员创建的进程无法提升自身的权限
首先要获得进程访问令牌的句柄,这可以通过OpenProcessToken得到,函数的原型如下:
BOOL OpenProcessToken