(*
function GetLogonSID(const hWinStation : HWINSTA{TWindowStation}) : TSecurityID;
{TODO: Use TWindowStation (if implemented) instead}
var
hAWinst : HWINSTA;
logonSID : PSID;
dwSize : Cardinal;
begin
haWinst := hWinStation;
if (hWinStation = 0) or (hWinStation = INVALID_HANDLE_VALUE) then
hAWinst := OpenWindowStation(
'winsta0',
FALSE,
READ_CONTROL,
//READ_CONTROL or WRITE_DAC
);
result := nil;
if not GetUserObjectInformation(hAWinst, UOI_USER_SID, nil,0, dwSize) then
begin
// GetUserObjectInformation returns required size
GetMem(LogonSid, dwSize + 1);
if not GetUserObjectInformation(hAWinst, UOI_USER_SID, LogonSid, dwSize, dwSize) then
begin
raise ESMWinCallFailedException.CreateFmtWinCall(
'Call to GetUserObjectInformation failed. ',
'GetLogonSID',
'',
'USM_KnownSID.pas',
0,
true,
'GetUserObjectInformation',[]);
end;
if logonSID <> nil then
begin
result := TSecurityID.Create(logonSID);
FreeMem(logonSID);
end;
end;
if (hWinStation <> 0) and (hWinStation <> INVALID_HANDLE_VALUE) then
CloseWindowStation(hAWinst);
end;
*)
function GetUserNameLUID(
const username : WideString) : TLuid;
var
ws : WideString;
res,
i,
lsCount : Cardinal;
lsLUIDS : PLuid;
LUIDarray :
array of TLUID
absolute lsLUIDS;
pLogonSessionData : PSECURITY_LOGON_SESSION_DATA;
begin
result.LowPart := 0;
result.HighPart := 0;
LsaEnumerateLogonSessions(@lsCount,lsLUIDS);
try
for i := 0
to lsCount-1
do
begin
res := LsaGetLogonSessionData(@LUIDarray[i], pLogonSessionData);
if (res = 0)
then
begin
if (CompareText(pLogonSessionData.UserName.Buffer, userName) = 0)
and
(CompareText(pLogonSessionData.AuthenticationPackage.Buffer, '
NTLM') = 0)
then
begin
result := pLogonSessionData.LogonId;
LsaFreeReturnBuffer(pLogonSessionData);
LsaFreeReturnBuffer(lsLUIDS);
exit;
end;
LsaFreeReturnBuffer(pLogonSessionData);
end;
end;
finally
LsaFreeReturnBuffer(lsLUIDS);
end;
end;
procedure ServiceController(CtrlCode: DWord);
stdcall;
begin
RunWithDebugService.Controller(CtrlCode);
end;
function TRunWithDebugService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure UpdateWindowStation(usertoken : TSecurityToken);
var
aDACL : TDAccessControlList;
s :
String;
lpEnv : Pointer;
hwinstaold,
hAWinst : HWINSTA;
hADesk : HDESK;
anOwner, aGroup : TSecurityID;
desktopDACL : TDAccessControlList;
aSACL : TSAccessControlList;
aPriv : TPrivilege;
begin
//http://msdn2.microsoft.com/en-us/library/aa379608.aspx
hAWinst := OpenWindowStation(
'
winsta0',
FALSE,
GENERIC_ALL
//damit auch später ShowMessage noch funkz - nach SetProcessWindowStation
//READ_CONTROL or WRITE_DAC
);
hwinstaold := GetProcessWindowStation();
// To get the correct default desktop, set the caller's
// window station to the interactive window station.
if not SetProcessWindowStation(hAWinst)
then
raise ESMWinCallFailedException.CreateFmtEx('
SetProcessWindowStation ',
'
','
','
USM_Token.pas', 0,true,[]);
hADesk := OpenDesktop(
'
default',
0,
FALSE,
READ_CONTROL
or WRITE_DAC
or
DESKTOP_WRITEOBJECTS
or DESKTOP_READOBJECTS);
if hADesk = 0
then
raise ESMWinCallFailedException.CreateFmtEx('
OpenDesktop ',
'
','
','
USM_Token.pas', 0,true,[]);
TSecureGeneralObject.GetSecurityInfo(
hAWinst,SE_WINDOW_OBJECT,[sif_DACL_SECURITY_INFORMATION],anOwner,aGroup,desktopDACL,aSACL);
desktopDACL.Add(TDiscretionaryAccessControlEntryAllow.Create(
nil,TAF_ThisFolderAndSubFoldersAndFiles,GENERIC_ALL,usertoken.GetTokenUser,false));
TSecureGeneralObject.SetSecurityInfo(
hAWinst,SE_WINDOW_OBJECT,[sif_DACL_SECURITY_INFORMATION],anOwner,aGroup,desktopDACL,aSACL);
TSecureGeneralObject.GetSecurityInfo(
hADesk,SE_WINDOW_OBJECT,[sif_DACL_SECURITY_INFORMATION],anOwner,aGroup,desktopDACL,aSACL);
desktopDACL.Add(TDiscretionaryAccessControlEntryAllow.Create(
nil,TAF_ThisFolderAndSubFoldersAndFiles,GENERIC_ALL,usertoken.GetTokenUser,false));
TSecureGeneralObject.SetSecurityInfo(
hADesk,SE_WINDOW_OBJECT,[sif_DACL_SECURITY_INFORMATION],anOwner,aGroup,desktopDACL,aSACL);
// Restore the caller's window station.
SetProcessWindowStation(hwinstaold);
end;
function DumpEnvironmentW(lpEnvironment: Pointer) : WideString;
var
Env: PWideChar;
begin
result := '
';
Env := lpEnvironment;
while (lstrlenW(Env) > 0)
do
begin
if WideString(Env)[1] <> '
='
then
result := result + #13#10 + WideString(Env);
Env := PWideChar(DWORD(Env) + DWORD(lstrlenW(Env) + 1) * DWORD(sizeof(Env^)));
end;
// Delete(result,1,2)
end;
procedure TRunWithDebugService.ServiceExecute(Sender: TService);
var tokenSYSTEM : TSecurityToken;
userLUID : TLUID;
res : Cardinal;
lsaHandle : THandle;
lsaSecurityMode : LSA_OPERATIONAL_MODE;
SecurityLSA : TSecurityLSA;
logonData : MSV1_0_INTERACTIVE_LOGON;
plogonData : PMSV1_0_INTERACTIVE_LOGON;
aLocalGroups: TSecurityIDList;
SourceContext: TTokenSource;
aProfileBuffer: PMSV1_0_INTERACTIVE_PROFILE;
//Pointer;
afProfileBufferLength: Cardinal;
aTokenLuid: TLUID;
aToken: TSecurityToken;
aQuotaLimits: QUOTA_LIMITS;
aSubStatus: NTSTATUS;
authLen : Cardinal;
si: STARTUPINFOW;
pif: PROCESS_INFORMATION;
lpEnv : Pointer;
ws : WideString;
aLogonSid : TSecurityID;
begin
// ShowMessage('Starting service');
//EnablePrivilege(SE_TCB_NAME,pst_Enable);
InitWellKnownSIDs;
SecurityLSA := TSecurityLSA.Create('
RunWithDebug');
try
logonData.MessageType := MsV1_0InteractiveLogon;
plogonData := Create_MSV1_0_INTERACTIVE_LOGON(
logonData.MessageType,
'
',
'
DelphiTester',
'
pass',authLen);
aLocalGroups := TSecurityIDList.Create(true);
aLogonSid := GetLogonSID;
ShowMessage(aLogonSid.GetText(true));
aLocalGroups.Add(aLogonSid);
aLocalGroups.Add(TSecurityID.Create('
','
DebuggerUser'));
aLocalGroups.Add(AdministratorsSID);
SourceContext.SourceName := '
NTLM';
SourceContext.SourceIdentifier := LOCALSERVICE_LUID;
aProfileBuffer :=
nil;
afProfileBufferLength := sizeof(aProfileBuffer);
SecurityLSA.LsaLogonUser(
'
NTLM',
//nOriginName: String;
jwaWindows.Interactive,
//aLogonType: SECURITY_LOGON_TYPE;
MSV1_0_PACKAGE_NAME,
//anAuthenticationPackageName : String;
plogonData,
//anAuthenticationInformation: Pointer;
authLen,
//anAuthenticationInformationLength: Cardinal;
aLocalGroups,
//aLocalGroups: TSecurityIDList;
SourceContext,
//aSourceContext: TTokenSource;
Pointer(aProfileBuffer),
//aProfileBuffer: Pointer;
afProfileBufferLength,
//out afProfileBufferLength: Cardinal;
aTokenLuid,
//out aTokenLuid: TLUID;
aToken,
//out aToken: TSecurityToken;
aQuotaLimits,
//out aQuotaLimits: QUOTA_LIMITS;
aSubStatus
//out SubStatus: NTSTATUS);
);
FillChar(si,sizeof(si),0);
si.cb := SizeOf(startupinfo);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_SHOW;
si.lpReserved :=
nil;
// UpdateWindowStation(aToken);
// hier nun das Token nehmen um ein neues token zu erstellen mit dem debugrecht
tokenSYSTEM := TSecurityToken.CreateTokenEffective(TOKEN_ALL_ACCESS);
tokenSYSTEM.RevertToSelf;
try
ShowMessage(aToken.TokenUser.GetText(true));
lpEnv :=
nil;
if not CreateEnvironmentBlock(@lpEnv,aToken.TokenHandle,true)
then
raise ESMWinCallFailedException.CreateFmtEx('
CreateEnvironmentBlock ',
'
CreateEnvironmentBlock',ClassName,'
USM_Token.pas', 0,true,[]);
//ShowMessage(DumpEnvironmentW(lpEnv));
if not createprocessasuserw(aToken.TokenHandle,('
c:\windows\system32\cmd.exe')
{'e:\whoami.exe'},
nil,
nil,
nil,true,CREATE_UNICODE_ENVIRONMENT,lpEnv,
nil,si,pif)
then
raise ESMWinCallFailedException.CreateFmtEx('
createprocessasuser ',
'
createprocessasuserw',ClassName,'
USM_Token.pas', 0,true,[]);
finally
ShowMessage('
OK');
LsaFreeReturnBuffer(aProfileBuffer);
CloseHandle(aToken.TokenHandle);
//ShowMessage(tokenSYSTEM.GetTokenStatistics.GetText);
userLUID := GetUserNameLUID('
dezipaitor');
end;
except
on E :
Exception do
ShowMessage(E.
Message);
end;
SecurityLSA.Free;
end;