windows下,提权代码.

#include <windows.h>

bool AdjustPrivileges() {
	HANDLE hToken = NULL;
	TOKEN_PRIVILEGES tp;
	TOKEN_PRIVILEGES oldtp;
	DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
	LUID luid;

	OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);


	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
		CloseHandle(hToken);
		OutputDebugString(TEXT("提升权限失败,LookupPrivilegeValue"));
		return false;
	}
	ZeroMemory(&tp, sizeof(tp));
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	/* Adjust Token Privileges */
	if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
		CloseHandle(hToken);
		OutputDebugString(TEXT("提升权限失败 AdjustTokenPrivileges"));
		return false;
	}
	// close handles
	CloseHandle(hToken);
	return true;
}

调用伪代码:
int main()
{
  AdjustPrivileges();
  此时OpenProcess的时候 使用PROCESS_ALL_ACCESS权限则可以成功了
}

降权代码:

#include <WtsApi32.h>
#pragma comment(lib, "Wtsapi32.lib")

BOOL IsSystem()
{
	BOOL bRet = FALSE;
	WCHAR userName[MAX_PATH] = { 0 };
	DWORD dwNum = MAX_PATH;
	WCHAR systemName[] = L"system";
	do {
		if (!GetUserNameW(userName, &dwNum)) {
			break;
		}
		if (0 == _wcsicmp(userName, systemName)) {
			bRet = TRUE;
		}
	} while (FALSE);
	return bRet;
}

BOOL JmpToUser()
{
	BOOL bRet = FALSE;
	HANDLE hUser = NULL;
	PROCESS_INFORMATION* pi = new PROCESS_INFORMATION;
	STARTUPINFOW* si = new STARTUPINFOW;
	WCHAR* path = new WCHAR[MAX_PATH];
	ZeroMemory(si, sizeof(STARTUPINFO));
	ZeroMemory(pi, sizeof(PROCESS_INFORMATION));
	do {
		hUser = GetUserHandle();
		if (0 == GetModuleFileNameW(NULL, path, MAX_PATH)) {
			break;
		}
		if (hUser == NULL) {
			break;
		}
		bRet = CreateProcessAsUser(hUser, NULL,
			path,
			NULL,
			NULL,
			TRUE,
			CREATE_UNICODE_ENVIRONMENT | CREATE_BREAKAWAY_FROM_JOB,
			NULL,
			NULL,
			si,
			pi);
		if (bRet) {
			CloseHandle(pi->hProcess);
			CloseHandle(pi->hThread);
		}
	} while (FALSE);
	delete pi;
	delete si;
	delete[] path;
	return bRet;
}

HANDLE GetUserHandle()
{

	BOOL bRet = FALSE;
	HANDLE hUser = NULL;
	HANDLE hToken = NULL;
	DWORD sessionId = 0;
	
	do {
		sessionId =  WTSGetActiveConsoleSessionId();
		if (sessionId == NULL) {
			break;
		}
		if (!WTSQueryUserToken(sessionId, &hToken)) {
			break;
		}
		if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, 0, SecurityDelegation, TokenPrimary, &hUser)) {
			break;
		}
	} while (FALSE);
	if(hToken != NULL){
		CloseHandle(hToken);
	}
	return hUser;
}

网络上其它比较优秀的提权+启动提权的代码.

#include<windows.h>
#include<stdio.h>
#include<tlhelp32.h>
int main() {
    //提权到Debug以获取进程句柄
    //https://blog.csdn.net/zuishikonghuan/article/details/47746451
    HANDLE hToken;
    LUID Luid;
    TOKEN_PRIVILEGES tp;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = Luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), NULL, NULL);
    CloseHandle(hToken);
 
    //枚举进程获取lsass.exe的ID和winlogon.exe的ID,它们是少有的可以直接打开句柄的系统进程
    DWORD idL, idW;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (Process32First(hSnapshot, &pe)) {
        do {
            if (0 == _stricmp(pe.szExeFile, "lsass.exe")) {
                idL = pe.th32ProcessID;
            }
            else if (0 == _stricmp(pe.szExeFile, "winlogon.exe")) {
                idW = pe.th32ProcessID;
            }
        } while (Process32Next(hSnapshot, &pe));
    }
    CloseHandle(hSnapshot);
 
    //获取句柄,先试lsass再试winlogon
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, idL);
    if (!hProcess)hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, idW);
    HANDLE hTokenx;
    //获取令牌
    OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hTokenx);
    //复制令牌
    DuplicateTokenEx(hTokenx, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken);
    CloseHandle(hProcess);
    CloseHandle(hTokenx);
    //启动信息
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(STARTUPINFOW));
    si.cb = sizeof(STARTUPINFOW);
    si.lpDesktop = L"winsta0\\default";//显示窗口
    //启动进程,不能用CreateProcessAsUser否则报错1314无特权
    CreateProcessWithTokenW(hToken, LOGON_NETCREDENTIALS_ONLY, NULL, L"cmd", NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
    CloseHandle(hToken);
}

另一种方式.不想提权后再启动对应权限进程.我直接就是这个权限.也就是说我拷贝了system权限.但是不能以随心所欲的利用system权限干事情.
现在是我可以使用api 进入这个权限上下文. 然后也可以正常退出.

ImpersonateLoggedOnUser(token);
RevertToSelf();

使用上述两个api即可. 在两个api之间运行的代码.都是 token权限的上下文. 如果你复制的token是system权限.那么就是system权限的上下文.

posted @ 2019-04-22 11:49  iBinary  阅读(1331)  评论(2)    收藏  举报