I'm trying to create a elevated SYSTEM
token, but the code below fails:
#include <windows.h>
#include <stdio.h>
BOOL Elevate()
{
PSID pSID = NULL;
HANDLE hToken = NULL, hToken2 = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
fprintf(stderr, "OpenProcessToken(): %d\n", GetLastError());
goto done;
}
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hToken2))
{
fprintf(stderr, "DuplicateTokenEx(): %d\n", GetLastError());
goto done;
}
if (!AllocateAndInitializeSid(
&NtAuthority,
1,
SECURITY_MANDATORY_SYSTEM_RID,
0,
0, 0, 0, 0, 0, 0,
&pSID))
{
fprintf(stderr, "AllocateAndInitializeSid(): %d\n", GetLastError());
goto done;
}
if (!SetTokenInformation(hToken2, TokenIntegrityLevel, &pSID, sizeof(pSID)))
{
fprintf(stderr, "SetTokenInformation(): %d\n", GetLastError());
goto done;
}
done:
if (pSID)
{
FreeSid(pSID);
pSID = NULL;
}
CloseHandle(hToken);
CloseHandle(hToken2);
return TRUE;
}
int main(int argc, char** argv)
{
Elevate();
}
It fails on SetTokenInformation
, and the error code is 24: ERROR_BAD_LENGTH
. Does anyone know what's wrong?
EDIT
Remy Lebeau was right, and I found an example here: https://wiki.sei.cmu.edu/confluence/display/c/WIN02-C. Restrict privileges when spawning child processes
CodePudding user response:
Per the TOKEN_INFORMATION_CLASS
documentation
TokenIntegrityLevel
The buffer receives aTOKEN_MANDATORY_LABEL
structure that specifies the token's integrity level.
Where TOKEN_MANDATORY_LABEL
is defined as:
typedef struct _SID_AND_ATTRIBUTES {
#if ...
PISID Sid;
#else
PSID Sid;
#endif
DWORD Attributes;
} SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES;
typedef struct _TOKEN_MANDATORY_LABEL {
SID_AND_ATTRIBUTES Label;
} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
So, you need to give SetTokenInformation()
a pointer to a TOKEN_MANDATORY_LABEL
, not a pointer to a SID
, eg:
#include <windows.h>
#include <stdio.h>
BOOL Elevate()
{
TOKEN_MANDATORY_LABEL tml = {};
HANDLE hToken = NULL, hToken2 = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
BOOL result = FALSE;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
fprintf(stderr, "OpenProcessToken(): %ul\n", GetLastError());
goto done;
}
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hToken2))
{
fprintf(stderr, "DuplicateTokenEx(): %ul\n", GetLastError());
goto done;
}
if (!AllocateAndInitializeSid(
&NtAuthority,
1,
SECURITY_MANDATORY_SYSTEM_RID,
0,
0, 0, 0, 0, 0, 0,
&(tml.Label.SID)))
{
fprintf(stderr, "AllocateAndInitializeSid(): %ul\n", GetLastError());
goto done;
}
tml.Label.Attributes = ...;
if (!SetTokenInformation(hToken2, TokenIntegrityLevel, &tml, sizeof(tml)))
{
fprintf(stderr, "SetTokenInformation(): %ul\n", GetLastError());
goto done;
}
result = TRUE;
done:
if (tml.Label.SID) FreeSid(tml.Label.SID);
if (hToken) CloseHandle(hToken);
if (hToken2) CloseHandle(hToken2);
return result;
}
int main(int argc, char** argv)
{
Elevate();
}