![]() |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
Zitat:
It also does not work to add the group debug users because the privilege is not added. I tested it. I created successfully a new token with debug privilege (using NTCreateToken), but this needs the users LUID (which can be created by CreateLogonSession) - however I can find the users LUID by LsaGetLogonSessionData.
Delphi-Quellcode:
By the way: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; Did you see my post ![]() |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
I don't mean adding Joe the Administrators group rather the process you started with LsaLogonUser runs with admin permissions!
I thought that (zw)NTCreateToken was no longer possible in Vista :-( Please look at my sample again, the way I understand your question it's does precisely what you want! Make it a service so you don't have to give a user SeTcbPrivilege... |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
Zitat:
Zitat:
Zitat:
|
Re: LSALogonUser und Authentifikation (nichts komplexes!)
1. Define a special user with Debug privilege.
2. Joe is logged an and requests your service app a "debug session" 3. Service starts process with Joe's LogonSid and the Debug users SID 4. The process (and only the process) runs with debug privilege. Joe is the "owner" of this process. What do we miss? |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
Okay that works - adding a special User (not group), add Debug privs to it (gpedit.msc) and add the user to the groups parameter.
Now she has debug privs. By the way. I cannot run a graphic programm (like regedit) without changing the window station DACL. I tried your suggestion and added the LogonSID (retrieved by your second sample code GetLogonSid) to the groups. However the started application cannot paint to desktop. The window is drawn transparent. I retrieved the WinStation DACL in that newly started process - and always get an Access denied (5). Ok its no use - I have to add the new user to the winstation DACL - however I cannot retrieve the DACL without admin privs.
Delphi-Quellcode:
(* 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; |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
Can you show me your code?
Maybe the difference is that you run from a service, so if you get the Logged On User Sid you get the SID from the account that your service runs under. You need to get the Login Sid from the Interactive User. |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
ok..but can you show me how to achieve that?
|
Re: LSALogonUser und Authentifikation (nichts komplexes!)
The function GetLogonSid takes a hToken as first parameter. Why not pass it the token from some exe (say explorer.exe) that run's in the user's context?
Or maybe my alternative GetLogonSid, that should probably work in case of in interactive service (pre-vista). Or maybe it can be adapted to acquire the right hWinstation somehow...
Delphi-Quellcode:
I got some other ideas but I have to look into that (will be continued)
// Alternative way to get the Logon Sid
procedure GetLogonSid(var LogonSid: pSid); var hWinstation: HWINSTA; dwSize : Cardinal; begin // Open the WindowStation hWinstation := OpenWindowStation('winsta0', False, READ_CONTROL); if hWinstation = 0 then begin ShowMessageFmt('OpenWindowStation: %s', [SysErrorMessage(GetLastError)]); Exit; end; // GetUserObjectInformation returns required size in dwSizeNeeded if not GetUserObjectInformation(hWinStation, UOI_USER_SID, nil, 0, dwSize) then begin // GetUserObjectInformation returns required size GetMem(LogonSid, dwSize + 1); if not GetUserObjectInformation(hWinStation, UOI_USER_SID, LogonSid, dwSize, dwSize) then begin ShowMessageFmt('GetUserObjectInformation: %s', [SysErrorMessage(GetLastError)]); Exit; end; end; // Cleanup CloseWindowStation(hWinStation); end; |
Re: LSALogonUser und Authentifikation (nichts komplexes!)
I'm using that already - to add this SID to the groups of the new logon token does not work. Believe me.
|
Re: LSALogonUser und Authentifikation (nichts komplexes!)
Try this:
Delphi-Quellcode:
Use this GetLogonSid:
if WTSQueryUserToken(WtsGetActiveConsoleSessionID, hToken) then
begin GetLogonSid(hToken, LogonSid);
Delphi-Quellcode:
Continue on with LsaLogonUser
procedure GetLogonSID(hToken: THandle; var ppsid: PSID);
var dwLength: DWORD; ptg : ^TOKEN_GROUPS; i : integer; begin dwLength := 0; ptg := nil; try // Get required buffer size and allocate the TOKEN_GROUPS buffer. if not GetTokenInformation(hToken, TokenGroups, ptg, 0, dwLength) then begin if GetLastError <> ERROR_INSUFFICIENT_BUFFER then begin ShowMessage('GetTokenInformation failed'); Exit; end; ptg := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if ptg = nil then begin Exit; end; // Get the token group information from the access token. if not GetTokenInformation(hToken, TokenGroups, ptg, dwLength, dwLength) then begin Exit; end; // Loop through the groups to find the logon SID. for i := 0 to ptg.GroupCount-1 do begin if ptg.Groups[i].Attributes and SE_GROUP_LOGON_ID = SE_GROUP_LOGON_ID then begin // Found the logon SID; make a copy of it. dwLength := GetLengthSid(ptg.Groups[i].Sid); ppsid := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if ppsid = nil then begin Exit; end; if not CopySid(dwLength, ppsid, ptg.Groups[i].Sid) then begin // raise exception.Create(Format('CopySid: %s', [SysErrorMessage(GetLastError)])); HeapFree(GetProcessHeap, 0, ppsid); Exit; end; Break; end; end; end; finally // Free the buffer for the token groups. if ptg <> nil then begin HeapFree(GetProcessHeap, 0, ptg); end; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz