AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi LSALogonUser und Authentifikation (nichts komplexes!)

LSALogonUser und Authentifikation (nichts komplexes!)

Ein Thema von Dezipaitor · begonnen am 10. Aug 2007 · letzter Beitrag vom 14. Aug 2007
Antwort Antwort
Seite 2 von 4     12 34   
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#11

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 14:10
Zitat von Remko:
Sure: Suppose you poweruser is called Joe.
Let your service find the LogonSid for Joe. Use LsaLogonUser to start your process (eg Delphi) (eg with the supplied credentials). Include in the PTOKEN_GROUPS both the (local) admin sid and Joe's LogonSid. The process has full access to Joe's desktop without the need to set ACL's because you "are" Joe. Because the process has also Admin's SID you also have his privilegs. If wanted replace admin by a special user with debug privileges.
It is not good to use add Joe to the administrator groups. We have to create programs without such power
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:

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;
By the way:
Did you see my post Security Library. I would appreciate it if you could make a comment (I also need reinforcement).
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#12

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 14:20
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...
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#13

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 14:38
Zitat von Remko:
I don't mean adding Joe the Administrators group rather the process you started with LsaLogonUser runs with admin permissions!
I know! The newly created process has admin permission. That is not good. Debug privs is only neccessary.

Zitat:
I thought that (zw)NTCreateToken was no longer possible in Vista
Dont know

Zitat:
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...
It does not work as I want, because I need to add the debug privilege to the users token. The only way I know is to use CreateToken. I already tested it. It works, but it is complicated and dangerous.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#14

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 14:53
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?
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#15

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 15:57
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;
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#16

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 16:35
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.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#17

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 16:42
ok..but can you show me how to achieve that?
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#18

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 17:38
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:
// 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;
I got some other ideas but I have to look into that (will be continued)
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#19

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 18:27
I'm using that already - to add this SID to the groups of the new logon token does not work. Believe me.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#20

Re: LSALogonUser und Authentifikation (nichts komplexes!)

  Alt 12. Aug 2007, 20:33
Try this:
Delphi-Quellcode:
  if WTSQueryUserToken(WtsGetActiveConsoleSessionID, hToken) then
  begin
    GetLogonSid(hToken, LogonSid);
Use this GetLogonSid:

Delphi-Quellcode:
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;
Continue on with LsaLogonUser
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz