-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAddPrivilege.cpp
More file actions
128 lines (108 loc) · 3.69 KB
/
Copy pathAddPrivilege.cpp
File metadata and controls
128 lines (108 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <ntstatus.h>
#include <windows.h>
#include <ntsecapi.h>
#include <Sddl.h>
std::string GetErrorAsString(DWORD errorMessageID)
{
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
std::string message(messageBuffer, size);
//Free the buffer.
LocalFree(messageBuffer);
return message;
}
LSA_HANDLE GetPolicyHandle(WCHAR* SystemName)
{
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
USHORT SystemNameLength;
LSA_UNICODE_STRING lusSystemName;
NTSTATUS ntsResult;
LSA_HANDLE lsahPolicyHandle;
// Object attributes are reserved, so initialize to zeros.
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
//Initialize an LSA_UNICODE_STRING to the server name.
SystemNameLength = wcslen(SystemName);
lusSystemName.Buffer = SystemName;
lusSystemName.Length = SystemNameLength * sizeof(WCHAR);
lusSystemName.MaximumLength = (SystemNameLength + 1) * sizeof(WCHAR);
// Get a handle to the Policy object.
ntsResult = LsaOpenPolicy(
&lusSystemName, //Name of the target system.
&ObjectAttributes, //Object attributes.
POLICY_ALL_ACCESS, //Desired access permissions.
&lsahPolicyHandle //Receives the policy handle.
);
if (ntsResult != STATUS_SUCCESS)
{
// An error occurred. Display it as a win32 error code.
auto winError = LsaNtStatusToWinError(ntsResult);
wprintf(L"OpenPolicy returned %lu\n", winError);
std::cout << "Error message: " << GetErrorAsString(winError) << std::endl;
return NULL;
}
return lsahPolicyHandle;
}
bool InitLsaString(
PLSA_UNICODE_STRING pLsaString,
LPCWSTR pwszString
)
{
DWORD dwLen = 0;
if (NULL == pLsaString)
return FALSE;
if (NULL != pwszString)
{
dwLen = wcslen(pwszString);
if (dwLen > 0x7ffe) // String is too large
return FALSE;
}
// Store the string.
pLsaString->Buffer = (WCHAR*)pwszString;
pLsaString->Length = (USHORT)dwLen * sizeof(WCHAR);
pLsaString->MaximumLength = (USHORT)(dwLen + 1) * sizeof(WCHAR);
return TRUE;
}
void AddPrivileges(PSID AccountSID, LSA_HANDLE PolicyHandle)
{
LSA_UNICODE_STRING lucPrivilege;
NTSTATUS ntsResult;
// Create an LSA_UNICODE_STRING for the privilege names.
if (!InitLsaString(&lucPrivilege, L"SeLockMemoryPrivilege"))
{
wprintf(L"Failed InitLsaString\n");
return;
}
ntsResult = LsaAddAccountRights(
PolicyHandle, // An open policy handle.
AccountSID, // The target SID.
&lucPrivilege, // The privileges.
1 // Number of privileges.
);
if (ntsResult == STATUS_SUCCESS)
{
wprintf(L"Privilege added.\n");
}
else
{
wprintf(L"Privilege was not added - %lu \n",
LsaNtStatusToWinError(ntsResult));
std::cout << "Error message: " << GetErrorAsString(LsaNtStatusToWinError(ntsResult)) << std::endl;
}
}
int main()
{
/*
Get Sid from runnign powershell commands:
$objUser = New-Object System.Security.Principal.NTAccount("aybas")
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$strSID.Value
There is probably a way through Win32 API, but that seems easier
*/
LPCSTR strSid = "S-1-5-21-2554383953-2022197192-2242278139-1010";
PSID sid;
WCHAR SystemName[] = L"DESKTOP-AVV4L7N";
ConvertStringSidToSidA(strSid, &sid);
AddPrivileges(sid, GetPolicyHandle(SystemName));
}