So awhile ago I was playing around with tokens and such, It was allot of fun but one of the things that tripped me up pretty bad was a efficient way to enable all the privileges that I had access to. Over the last week or so it was one of the things I took a look at so I'm going to explain it as best I can. I hope that it will make at least a little more sense than Microsoft's horrible examples.... Honestly Microsoft you need to have someone review all your shit once a year as some of it wont even compile, also the usability of your msdn site is simply horrendous.
Ok so making this painless as possible lets start off with getting the current process token. We pass it the Handle to the current process, which is exactly what GetCurrentProccess() returns. Then our desired access, and finally a Pointer to our Handle which is how we get our token out of the command.
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)
I wanted to simply enable all of the privs I had access to, I didn't want just one so what I did was made a Array and then looped through each. There are 5 that a normal user usually has access to, I'll add in a 6th just so you can see.
// We define our array...
const char* All_Privs[] = {
"SeShutdownPrivilege",
"SeChangeNotifyPrivilege",
"SeUndockPrivilege",
"SeIncreaseWorkingSetPrivilege",
"SeTimeZonePrivilege",
"SeImpersonatePrivilege"
};
// And then get the size..
const int Num_Privs = sizeof(All_Privs);
Before we can loop through all of them we have to set up a few variables first.
LUID luid;
TOKEN_PRIVILEGES Token_Privs;
BOOL Error_Check;
Here we start our for loop, we have to lookup each privileged to get the luid for it.We then set that luid and the Enable flag for it which is actually just 2, in the Token_Privs structure. After that we simply call AdjustTokenPrivileges with a pointer to the struct, check for errors and continue the loop.
for (int i = 0; i < Num_Privs; i++)
{
LookupPrivilegeValue(NULL, All_Privs[i], &luid);
Token_Privs.PrivilegeCount = 1;
Token_Privs.Privileges[0].Luid = luid;
Token_Privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 2 = enable
Error_Check = AdjustTokenPrivileges(
hToken, // our token
FALSE,
&Token_Privs, // pointer to our privs structure
NULL,
NULL,
NULL
);
// Now for the error checking..
if (Error_Check && GetLastError() != ERROR_SUCCESS)
{
printf("[*] %s is NOT enabled!... Error: %d\n", All_Privs[i], GetLastError()); // 1300 = not assigned
}
else
{
printf("[!] %s is now enabled!\n", All_Privs[i]);
}
}
So that's fairly simple, and totally accomplishes what you need it to do. But it just didn't look very good to me, so I did a little bit of digging and found a somewhat better approach.
What we do is get the token information from the token, this contains a list of all the privileges it has enabled and disabled alike. We loop through each one and since its a pointer we set the enable flag for each one that's disabled. Then at the very end we pass that into AdjustTokenPrivledges and thats it. We can then go shut down the computer or impersonate whoever we want... as long as your Token allows it.
void EnableAllPrivs(HANDLE hToken)
{
// Once to get the size
DWORD dwGetSize = 0;
GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwGetSize); //
DWORD dwRetLen = 0;
LPBYTE lpTokenInfo = new BYTE[dwGetSize];
DWORD dwTokeInfoLen = dwGetSize;
// Again to get the info
if (!GetTokenInformation(hToken, TokenPrivileges, lpTokenInfo, dwTokeInfoLen, &dwRetLen))
{
printf("There was a error with GetTokenInformation %d\n", GetLastError());
}
PTOKEN_PRIVILEGES ptHeldPrivs = reinterpret_cast<PTOKEN_PRIVILEGES>(lpTokenInfo);
wprintf(L"We have %d enabled!\n", ptHeldPrivs->PrivilegeCount);
// here is how we get what is actually enabled
for (int i = 0; i < ptHeldPrivs->PrivilegeCount; i++)
{
PLUID_AND_ATTRIBUTES plAtt = &ptHeldPrivs->Privileges[i];
wchar_t szName[256] = { 0 };
DWORD dwName = 256;
LookupPrivilegeNameW(NULL, &plAtt->Luid, szName, &dwName);
wprintf(L"The privledge %s has the attributes :%ld\n", szName, plAtt->Attributes);
if (plAtt->Attributes == 0) // 0 = none // 1 default // 2 enable // (3) enabledbydefault // 4 removed
{
plAtt->Attributes = SE_PRIVILEGE_ENABLED; // 2
}
}
// now we enable the privs
AdjustTokenPrivileges(hToken, FALSE, ptHeldPrivs, 0, NULL, NULL);
}
A quick note... the above function "should" be in unicode, and if there are errors with Anything please let me know.
Taking it a little bit further lets take a quick look at what the TOKEN_PRIVILEGES structure looks like. First off the PTOKEN_PRIVILEGES is simply a pointer to to the structure stored in memory. Furthermore its actually just a dword/int32 that defines the length/amount of privs followed by a array of the LUID_AND_ATTRIBUTE struct, which is actually just a LUID struct and a dword/int32 that defines the Attributes/privs that are enabled/disabled. Finally the LUID struct is just 2 dwords/int32. lol did we get all that?
Its actually super simple honestly once you see it in memory...
PrivilegeCount
LUID.lowpart ~~ LUID.highpart ~~ Attributes
As you can see in the above picture the "SeChangeNotifyPrivilege" is set to enabled and it is default enabled as defined by the 3. All of the rest are disabled at the moment.
Anyways what we can actually do if we really wanted to is write out or own bytes convert it to a pointer and then pass it to AdjustTokenPrivileges. I recently just did this so I didn't have to mess with csharps pinvoke structures and it works with no issues.
Anyways that's all for now...