Einzelnen Beitrag anzeigen

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