SetTokenInformation 失败并返回 24,但长度正确
SetTokenInformation fails with 24, but the length is correct
我正在尝试创建提升的 SYSTEM
令牌,但下面的代码失败了:
#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();
}
SetTokenInformation
失败,错误代码为 24:ERROR_BAD_LENGTH
。有人知道怎么回事吗?
编辑
Remy Lebeau 是对的,我在这里找到了一个例子:https://wiki.sei.cmu.edu/confluence/display/c/WIN02-C.+Restrict+privileges+when+spawning+child+processes
根据 TOKEN_INFORMATION_CLASS
文档
TokenIntegrityLevel
The buffer receives a TOKEN_MANDATORY_LABEL
structure that specifies the token's integrity level.
其中 TOKEN_MANDATORY_LABEL
定义为:
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;
所以,你需要给 SetTokenInformation()
一个指向 TOKEN_MANDATORY_LABEL
的指针,而不是指向 SID
的指针,例如:
#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 = ...; // desired integrity level
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();
}
我正在尝试创建提升的 SYSTEM
令牌,但下面的代码失败了:
#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();
}
SetTokenInformation
失败,错误代码为 24:ERROR_BAD_LENGTH
。有人知道怎么回事吗?
编辑
Remy Lebeau 是对的,我在这里找到了一个例子:https://wiki.sei.cmu.edu/confluence/display/c/WIN02-C.+Restrict+privileges+when+spawning+child+processes
根据 TOKEN_INFORMATION_CLASS
文档
TokenIntegrityLevel
The buffer receives aTOKEN_MANDATORY_LABEL
structure that specifies the token's integrity level.
其中 TOKEN_MANDATORY_LABEL
定义为:
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;
所以,你需要给 SetTokenInformation()
一个指向 TOKEN_MANDATORY_LABEL
的指针,而不是指向 SID
的指针,例如:
#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 = ...; // desired integrity level
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();
}