现在的位置: 首页 > 综合 > 正文

模拟Windows登录用户进行特殊操作

2017年09月01日 ⁄ 综合 ⁄ 共 5591字 ⁄ 字号 评论关闭

SYSTEM权限(服务启动程序)下如何读写当前登录用户相关的数据(桌面、开始菜单、注册表等等)?管理员权限如何提升到SYSTEM权限进行一些特殊的操作(一些关键的注册表位置、创建一个SYSTEM权限的进程等等)?一个非常关键的API就是ImpersonateLoggedOnUser,可以让当前线程模拟登陆用户进行操作(当然还可以从管理员模拟SYSTEM权限),用完之后记得调用RevertToSelf。

没有进行什么总结了,懒得写了⊙﹏⊙,贴几个地址吧:
服务应用程序如何访问当前登录用户的信息
模拟用户登录
创建高权限进程
从管理员身份获得 SYSTEM 权限的四种方法
如何读取指定用户的 HKEY_CURRENT_USER 注册表键
DLL注入到system进程后(在SYSTEM权限下弹MessageBox?)

照着从管理员权限到SYSTEM权限写了段代码:

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <TlHelp32.h>
#include <AclAPI.h>
 
#pragma comment(lib, "advapi32.lib")
 
#define CHECK_NULL_RET(bCondition) if (!bCondition) goto Exit0
#define INVALID_PROCESS_ID -2
 
BOOL EnableProcessPrivilege(LPCTSTR lpszPrivName, BOOL bEnable = TRUE)
{
    HANDLE hToken; 
    TOKEN_PRIVILEGES tkp;
    BOOL bRet = FALSE;
 
    bRet = OpenProcessToken(GetCurrentProcess(), 
                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    CHECK_NULL_RET(bRet);
 
    bRet = LookupPrivilegeValue(NULL, lpszPrivName, &tkp.Privileges[0].Luid);
    CHECK_NULL_RET(bRet);
    tkp.PrivilegeCount = 1;  
    tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED; 
 
    bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
    CHECK_NULL_RET(bRet);
    bRet = TRUE;
 
Exit0:
    CloseHandle(hToken);
    return bRet;
}
 
DWORD GetProcessPidByName(LPCTSTR lpszProcName)
{
    DWORD dwPid = INVALID_PROCESS_ID;
    HANDLE hSnapshot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe32 = {0};
    pe32.dwSize = sizeof(PROCESSENTRY32);
 
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        Process32First(hSnapshot, &pe32);
        do 
        {
            if (!lstrcmpi(lpszProcName, pe32.szExeFile))
            {
                dwPid = pe32.th32ProcessID;
                break;
            }
            pe32.dwSize = sizeof(PROCESSENTRY32);
        } while (Process32Next(hSnapshot, &pe32));
        CloseHandle(hSnapshot);
    }
 
    return dwPid;
}
 
BOOL AdjustPrivilege(HANDLE hToken, DWORD dwAccess)
{
    BOOL bRet = FALSE;
    PSECURITY_DESCRIPTOR pOldSd = NULL, pNewSd = NULL;
    DWORD dwLen = 0;
    DWORD dwReturn = 0;
    DWORD dwRet = 0;
    BOOL bAcl = FALSE, bDefAcl = FALSE;
    PACL pOldAcl = NULL;
    PACL pNewAcl = NULL;
    PACL pSacl = NULL;
    static TCHAR szUserName[1024] = {0};
    EXPLICIT_ACCESS ea = {0};
    DWORD dwDaclSize = 0;
    DWORD dwSaclSize = 0;
    DWORD dwOwnerSize = 0;
    DWORD dwPrimaryGroupSize = 0;
    PSID pSidOwner = NULL;
    PSID pPrimaryGroup = NULL;
 
    GetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, 
        pOldSd, NULL, &dwLen);
    pOldSd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
        HEAP_ZERO_MEMORY, dwLen);
    CHECK_NULL_RET(pOldSd);
    bRet = GetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION,
        pOldSd, dwLen, &dwReturn);
    CHECK_NULL_RET(bRet);
    bRet = GetSecurityDescriptorDacl(pOldSd, &bAcl, &pOldAcl, &bDefAcl);
    CHECK_NULL_RET(bRet);
 
    dwReturn = sizeof(szUserName) / sizeof(szUserName[0]);
    GetUserName(szUserName, &dwReturn);
    BuildExplicitAccessWithName(&ea, szUserName,
        dwAccess, GRANT_ACCESS, NULL);
    dwRet = SetEntriesInAcl(1, &ea, pOldAcl, &pNewAcl);
    CHECK_NULL_RET((dwRet == ERROR_SUCCESS));
 
    MakeAbsoluteSD( pOldSd,
                    pNewSd,
                    &dwLen,
                    pOldAcl,
                    &dwDaclSize,
                    pSacl,
                    &dwSaclSize,
                    pSidOwner,
                    &dwOwnerSize,
                    pPrimaryGroup,
                    &dwPrimaryGroupSize);
    pOldAcl = (PACL)HeapAlloc(
                        GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        dwDaclSize);
    CHECK_NULL_RET(pOldAcl);
    pSacl = (PACL)HeapAlloc(
                        GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        dwSaclSize);
    CHECK_NULL_RET(pSacl);
    pSidOwner = (PSID)HeapAlloc(
                        GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        dwOwnerSize);
    CHECK_NULL_RET(pSidOwner);
    pPrimaryGroup = (PSID)HeapAlloc(
                        GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        dwPrimaryGroupSize);
    CHECK_NULL_RET(pPrimaryGroup);
    pNewSd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                        GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        dwLen);
    CHECK_NULL_RET(pNewSd);
 
    bRet = MakeAbsoluteSD(  pOldSd,
                            pNewSd,
                            &dwLen,
                            pOldAcl,
                            &dwDaclSize,
                            pSacl,
                            &dwSaclSize,
                            pSidOwner,
                            &dwOwnerSize,
                            pPrimaryGroup,
                            &dwPrimaryGroupSize);
    CHECK_NULL_RET(bRet);
 
    bRet = SetSecurityDescriptorDacl(
                pNewSd, bAcl, pNewAcl, bDefAcl);
    CHECK_NULL_RET(bRet);
    bRet = SetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, pNewSd);
    CHECK_NULL_RET(bRet);
    bRet = TRUE;
 
Exit0:
    if (pOldSd != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pOldSd);
    if (pOldAcl != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pOldAcl);
    if (pSacl != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pSacl);
    if (pSidOwner != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pSidOwner);
    if (pPrimaryGroup != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pPrimaryGroup);
    if (pNewSd != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pNewSd);
 
    return bRet;
}
 
BOOL PrivilegeExecStart(LPCTSTR lpszProcName, LPTSTR lpszCmdLine)
{
    BOOL bRet = FALSE;
    HANDLE hProcess = INVALID_HANDLE_VALUE;
    HANDLE hToken = NULL;
    HANDLE hNewToken = NULL;
    DWORD dwPid = 0;
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};
 
    bRet = EnableProcessPrivilege(SE_DEBUG_NAME, TRUE);
    CHECK_NULL_RET(bRet);
 
    dwPid = GetProcessPidByName(lpszProcName);
    CHECK_NULL_RET((dwPid != INVALID_PROCESS_ID));
 
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
    CHECK_NULL_RET(hProcess);
 
    bRet = OpenProcessToken(hProcess, READ_CONTROL | WRITE_DAC, &hToken);
    CHECK_NULL_RET(bRet);
 
    bRet = AdjustPrivilege(hToken, TOKEN_ALL_ACCESS);
    CHECK_NULL_RET(bRet);
 
    bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
    CHECK_NULL_RET(bRet);
 
    bRet = DuplicateTokenEx(
                hToken, 
                TOKEN_ALL_ACCESS,
                NULL,
                SecurityImpersonation,
                TokenPrimary,
                &hNewToken);
    CHECK_NULL_RET(bRet);
 
    si.cb = sizeof(STARTUPINFO);
    bRet = ImpersonateLoggedOnUser(hNewToken);
    CHECK_NULL_RET(bRet);
    bRet = CreateProcessAsUser(
                hToken,
                lpszCmdLine,
                NULL,
                NULL,
                NULL,
                FALSE,
                NULL,
                NULL,
                NULL,
                &si,
                &pi);
    CHECK_NULL_RET(bRet);
    bRet = TRUE;
 
Exit0:
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(hToken);
    CloseHandle(hNewToken);
    CloseHandle(hProcess);
 
    return bRet;
}
 
BOOL PrivilegeExecStop(void)
{
    return RevertToSelf();
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR szCmdLine[MAX_PATH] = TEXT("C:\\Windows\\regedit.exe");
    if (PrivilegeExecStart(TEXT("lsass.exe"), szCmdLine))
    {
        PrivilegeExecStop();
    }
    return 0;
}
Copyed From 程序人生 
Home Page:http://www.programlife.net 
Source URL:http://www.programlife.net/impersonateloggedonuser.html 

 

效果截图:
从管理员权限获取SYSTEM权限

转自:http://www.programlife.net/impersonateloggedonuser.html

抱歉!评论已关闭.