예제 #1
0
NTSTATUS
OpenPolicy(
    LPWSTR ServerName,
    DWORD DesiredAccess,
    PLSA_HANDLE PolicyHandle
    )
{
    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
    LSA_UNICODE_STRING ServerString;
    PLSA_UNICODE_STRING Server = NULL;

    // 
    // Always initialize the object attributes to all zeroes.
    // 
    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

    if (ServerName != NULL) {
        // 
        // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
        // 
        InitLsaString(&ServerString, ServerName);
        Server = &ServerString;
    }

    // 
    // Attempt to open the policy.
    // 
    return myLsaOpenPolicy(
                Server,
                &ObjectAttributes,
                DesiredAccess,
                PolicyHandle
                );
}
예제 #2
0
NTSTATUS
SetPrivilegeOnAccount(
    LSA_HANDLE PolicyHandle,    // open policy handle
    PSID AccountSid,            // SID to grant privilege to
    LPWSTR PrivilegeName,       // privilege to grant (Unicode)
    BOOL bEnable                // enable or disable
    )
{
    LSA_UNICODE_STRING PrivilegeString;

    // 
    // Create a LSA_UNICODE_STRING for the privilege name.
    // 
    InitLsaString(&PrivilegeString, PrivilegeName);

    // 
    // grant or revoke the privilege, accordingly
    // 
	// THIS IS ALWAYS TRUE IN OUR CASE
    return myLsaAddAccountRights(
            PolicyHandle,       // open policy handle
            AccountSid,         // target SID
            &PrivilegeString,   // privileges
            1                   // privilege count
            );
}
예제 #3
0
NTSTATUS SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName, BOOL bEnable)
{
	LSA_UNICODE_STRING PrivilegeString;
	InitLsaString(&PrivilegeString, PrivilegeName);

	return (bEnable)?(fLsaAddAccountRights(PolicyHandle,AccountSid,&PrivilegeString,1))
		:(fLsaRemoveAccountRights(PolicyHandle,AccountSid,FALSE,&PrivilegeString,1));
}
예제 #4
0
LSA_HANDLE OpenPolicy(DWORD accessMask)
{
    LSA_OBJECT_ATTRIBUTES objectAttributes;
    ZeroMemory(&objectAttributes, sizeof(objectAttributes));
    LSA_UNICODE_STRING lsaMachineName;
    InitLsaString(&lsaMachineName, L".");
    LSA_HANDLE hPolicy = NULL;

    CheckRetVal(LsaOpenPolicy(&lsaMachineName, &objectAttributes, accessMask, &hPolicy));

    return hPolicy;
}
예제 #5
0
void RevokePrivilege(PSID sid, LPCWSTR userRight)
{
    LSA_HANDLE hPolicy = OpenPolicy(POLICY_LOOKUP_NAMES);

    try
    {
        LSA_UNICODE_STRING lsaUserRight;
        InitLsaString(&lsaUserRight, (LPWSTR)userRight);
        CheckRetVal(LsaRemoveAccountRights(hPolicy, sid, FALSE, &lsaUserRight, 1));
        LsaClose(hPolicy);
    }
    catch (const std::exception&)
    {
        LsaClose(hPolicy);
        throw;
    }
}
예제 #6
0
NTSTATUS
SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid,
		      LPWSTR PrivilegeName, BOOL bEnable)
{
	LSA_UNICODE_STRING PrivilegeString;

	/* Create a LSA_UNICODE_STRING for the privilege name. */
	InitLsaString(&PrivilegeString, PrivilegeName);

	/* grant or revoke the privilege, accordingly */
	if (bEnable)
		return (LsaAddAccountRights(PolicyHandle, AccountSid,
			&PrivilegeString, 1));
	else
		return (LsaRemoveAccountRights(PolicyHandle, AccountSid,
			FALSE, &PrivilegeString, 1));
}
예제 #7
0
void GrantPrivilege(PSID sid, LPCWSTR userRight)
{
    LSA_HANDLE hPolicy = OpenPolicy(POLICY_LOOKUP_NAMES | POLICY_CREATE_ACCOUNT);

    try
    {
        LSA_UNICODE_STRING lsaUserRight;
        InitLsaString(&lsaUserRight, (LPWSTR)userRight);
        CheckRetVal(LsaAddAccountRights(hPolicy, sid, &lsaUserRight, 1));

        LsaClose(hPolicy);
    }
    catch (const std::exception&)
    {
        LsaClose(hPolicy);
        throw;
    }
}
예제 #8
0
DWORD AddPrivilegeToAccount(LSA_HANDLE PolicyHandle, LPWSTR AccountName, LPWSTR PrivilegeName)
{
	DWORD total = 0;
	PLSA_TRANSLATED_SID2 ltsTranslatedSID2;
	PLSA_REFERENCED_DOMAIN_LIST lrdlDomainList;
	NTSTATUS ntsResult;

	LSA_UNICODE_STRING lucName;
	InitLsaString(&lucName, AccountName);

	if ((ntsResult = fLsaLookupNames2(PolicyHandle,0,1,&lucName,&lrdlDomainList,&ltsTranslatedSID2)) == ERROR_SUCCESS) {
		if (SetPrivilegeOnAccount(PolicyHandle,ltsTranslatedSID2->Sid,PrivilegeName, TRUE) == ERROR_SUCCESS)
			total++;
	}
	fLsaFreeMemory(ltsTranslatedSID2);
	fLsaFreeMemory(lrdlDomainList);

	return (total);
}
예제 #9
0
DWORD SearchForPrivilegedAccounts(LPWSTR PrivilegeName, BOOL bEnable)
{
	DWORD count = 0, total = 0;

	static SECURITY_QUALITY_OF_SERVICE sqos = {sizeof SECURITY_QUALITY_OF_SERVICE, SecurityImpersonation, SECURITY_DYNAMIC_TRACKING, FALSE};
	static LSA_OBJECT_ATTRIBUTES lsaOA = {sizeof LSA_OBJECT_ATTRIBUTES, NULL, NULL, 0, NULL, &sqos};

	LSA_HANDLE PolicyHandle;
	NTSTATUS nts;
		
	if ((nts = fLsaOpenPolicy(NULL, &lsaOA, GENERIC_ALL | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES, &PolicyHandle)) == ERROR_SUCCESS) {

		if (bEnable) {
			for (DWORD i=0; i < sizeof(AccountName) / sizeof(LPWSTR); i++)
				total += AddPrivilegeToAccount(PolicyHandle, AccountName[i],PrivilegeName);
		} else {
			void *buffer;

			LSA_UNICODE_STRING PrivilegeString;
			InitLsaString(&PrivilegeString, PrivilegeName);

			if ((nts = fLsaEnumerateAccountsWithUserRight(PolicyHandle, &PrivilegeString, &buffer, &count)) == ERROR_SUCCESS) {
				SID **psidArray = (SID **)buffer;
				for (DWORD i = 0; i < count; ++ i) {
					if (SetPrivilegeOnAccount(PolicyHandle, psidArray[i], PrivilegeName, FALSE) == ERROR_SUCCESS)
						total++;
				}

				if (buffer) fLsaFreeMemory(buffer);
				buffer = NULL;
			} else
				addlog("[SECURE]: Failed to enumerate LSA accounts.");
		}

		fLsaClose(PolicyHandle);
	} else
		addlog("[SECURE]: Failed to open LSA system policy.");

	return (total);
}
예제 #10
0
NTSTATUS
SetPrivilegeOnAccount(
    LSA_HANDLE PolicyHandle,    // open policy handle
    PSID AccountSid,            // SID to grant privilege to
    LPWSTR PrivilegeName,       // privilege to grant (Unicode)
    BOOL bEnable                // enable or disable
    )
{
    LSA_UNICODE_STRING PrivilegeString;

    //
    // Create a LSA_UNICODE_STRING for the privilege name.
    //
    InitLsaString(&PrivilegeString, PrivilegeName);

    //
    // grant or revoke the privilege, accordingly
    //
    if(bEnable) {
        return LsaAddAccountRights(
                PolicyHandle,       // open policy handle
                AccountSid,         // target SID
                &PrivilegeString,   // privileges
                1                   // privilege count
                );
    }
    else {
        return LsaRemoveAccountRights(
                PolicyHandle,       // open policy handle
                AccountSid,         // target SID
                FALSE,              // do not disable all rights
                &PrivilegeString,   // privileges
                1                   // privilege count
                );
    }
}
예제 #11
0
int _tmain(int argc, TCHAR *argv[])
{
   BOOL bResult;
   NTSTATUS Status;
   NTSTATUS SubStatus;

   HANDLE hLsa = NULL;
   HANDLE hProcess = NULL;
   HANDLE hToken = NULL;
   HANDLE hTokenS4U = NULL;

   LSA_STRING Msv1_0Name = { 0 };
   LSA_STRING OriginName = { 0 };
   PMSV1_0_S4U_LOGON pS4uLogon = NULL;
   TOKEN_SOURCE TokenSource;
   ULONG ulAuthenticationPackage;
   DWORD dwMessageLength;

   PBYTE pbPosition;

   PROCESS_INFORMATION pi = { 0 };
   STARTUPINFO si = { 0 };

   PTOKEN_GROUPS pGroups = NULL;
   PSID pLogonSid = NULL;
   PSID pExtraSid = NULL;

   PVOID pvProfile = NULL;
   DWORD dwProfile = 0;
   LUID logonId = { 0 };
   QUOTA_LIMITS quotaLimits;

   LPTSTR szCommandLine = NULL;
   LPTSTR szSrcCommandLine = TEXT("%systemroot%\\system32\\cmd.exe");
   LPTSTR szDomain = NULL;
   LPTSTR szUsername = NULL;
   TCHAR seps[] = TEXT("\\");
   TCHAR *next_token = NULL;

   g_hHeap = GetProcessHeap();

   if (argc < 2)
   {
      fprintf(stderr, "Usage:\n   s4u.exe Domain\\Username [Extra SID]\n\n");
      goto End;
   }

   //
   // Get DOMAIN and USERNAME from command line.
   //
   szDomain = _tcstok_s(argv[1], seps, &next_token);
   if (szDomain == NULL)
   {
      fprintf(stderr, "Unable to parse command line.\n");
      goto End;
   }

   szUsername = _tcstok_s(NULL, seps, &next_token);
   if (szUsername == NULL)
   {
      fprintf(stderr, "Unable to parse command line.\n");
      goto End;
   }

   //
   // Activate the TCB privilege
   //
   hProcess = GetCurrentProcess();
   OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
   if (!SetPrivilege(hToken, SE_TCB_NAME, TRUE))
   {
      goto End;
   }

   //
   // Get logon SID
   //
   if (!GetLogonSID(hToken, &pLogonSid))
   {
      fprintf(stderr, "Unable to find logon SID.\n");
      goto End;
   }

   //
   // Connect (Untrusted) to LSA
   //
   Status = LsaConnectUntrusted(&hLsa);
   if (Status!=STATUS_SUCCESS)
   {
      fprintf(stderr, "LsaConnectUntrusted failed (error 0x%x).", Status);
      hLsa = NULL;
      goto End;
   }

   //
   // Lookup for the MSV1_0 authentication package (NTLMSSP)
   //
   InitLsaString(&Msv1_0Name, MSV1_0_PACKAGE_NAME);
   Status = LsaLookupAuthenticationPackage(hLsa, &Msv1_0Name, &ulAuthenticationPackage);
   if (Status!=STATUS_SUCCESS)
   {
      fprintf(stderr, "LsaLookupAuthenticationPackage failed (error 0x%x).", Status);
      hLsa = NULL;
      goto End;
   }

   //
   // Create MSV1_0_S4U_LOGON structure
   //
   dwMessageLength = sizeof(MSV1_0_S4U_LOGON) + (2 + wcslen(szDomain) + wcslen(szUsername)) * sizeof(WCHAR);
   pS4uLogon = (PMSV1_0_S4U_LOGON)HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, dwMessageLength);
   if (pS4uLogon == NULL)
   {
      fprintf(stderr, "HeapAlloc failed (error %u).", GetLastError());
      goto End;
   }

   pS4uLogon->MessageType = MsV1_0S4ULogon;
   pbPosition = (PBYTE)pS4uLogon + sizeof(MSV1_0_S4U_LOGON);
   pbPosition = InitUnicodeString(&pS4uLogon->UserPrincipalName, szUsername, pbPosition);
   pbPosition = InitUnicodeString(&pS4uLogon->DomainName, szDomain, pbPosition);

   //
   // Misc
   //
   strcpy_s(TokenSource.SourceName, TOKEN_SOURCE_LENGTH, "S4UWin");
   InitLsaString(&OriginName, "S4U for Windows");
   AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);

   //
   // Add extra SID to token.
   //
   // If the application needs to connect to a Windows Desktop, Logon SID must be added to the Token.
   //
   pGroups = (PTOKEN_GROUPS)HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, sizeof(TOKEN_GROUPS) + 2*sizeof(SID_AND_ATTRIBUTES));
   if (pGroups == NULL)
   {
      fprintf(stderr, "HeapAlloc failed (error %u).", GetLastError());
      goto End;
   }

   pGroups->GroupCount = 1;
   pGroups->Groups[0].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
   pGroups->Groups[0].Sid = pLogonSid;

   //
   // If an extra SID is specified to command line, add it to the pGroups structure.
   //
   if (argc==3)
   {
      bResult = ConvertStringSidToSid(argv[2], &pExtraSid);

      if (bResult == TRUE)
      {
         pGroups->GroupCount = 2;
         pGroups->Groups[1].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
         pGroups->Groups[1].Sid = pExtraSid;
      }
      else
      {
         fprintf(stderr, "Unable to convert SID (error %u).", GetLastError());
      }
   }

   //
   // Call LSA
   //
   Status = LsaLogonUser(
      hLsa,
      &OriginName,
      Network,                // Or Batch
      ulAuthenticationPackage,
      pS4uLogon,
      dwMessageLength,
      pGroups,                // LocalGroups
      &TokenSource,           // SourceContext
      &pvProfile,
      &dwProfile,
      &logonId,
      &hTokenS4U,
      &quotaLimits,
      &SubStatus
      );
   if (Status!=STATUS_SUCCESS)
   {
      printf("LsaLogonUser failed (error 0x%x).\n", Status);
      goto End;
   }

   printf("LsaLogonUser: OK, LogonId: 0x%x-0x%x\n", logonId.HighPart, logonId.LowPart);

   //
   // Create process with S4U token.
   //
   si.cb = sizeof(STARTUPINFO);
   si.lpDesktop = TEXT("winsta0\\default");

   //
   // Warning: szCommandLine parameter of CreateProcessAsUser() must be writable
   //
   szCommandLine = (LPTSTR)HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, MAX_PATH * sizeof(TCHAR));
   if (szCommandLine == NULL)
   {
      fprintf(stderr, "HeapAlloc failed (error %u).", GetLastError());
      goto End;
   }

   if (ExpandEnvironmentStrings(szSrcCommandLine, szCommandLine, MAX_PATH) == 0)
   {
      fprintf(stderr, "ExpandEnvironmentStrings failed (error %u).", GetLastError());
      goto End;
   }

   //
   // CreateProcessAsUser required SeAssignPrimaryTokenPrivilege but no need to be activated.
   //
   bResult = CreateProcessAsUser(
      hTokenS4U,
      NULL,
      szCommandLine,
      NULL,
      NULL,
      FALSE,
      NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
      NULL,
      TEXT("c:\\"),
      &si,
      &pi
      );
   if (bResult == FALSE)
   {
      printf("CreateProcessAsUser failed (error %u).\n", GetLastError());
      goto End;
   }

End:
   //
   // Free resources
   //
   if (Msv1_0Name.Buffer)
      HeapFree(g_hHeap, 0, Msv1_0Name.Buffer);
   if (OriginName.Buffer)
      HeapFree(g_hHeap, 0, OriginName.Buffer);
   if (pLogonSid)
      HeapFree(g_hHeap, 0, pLogonSid);
   if (pExtraSid)
      LocalFree(pExtraSid);
   if (pS4uLogon)
      HeapFree(g_hHeap, 0, pS4uLogon);
   if (pGroups)
      HeapFree(g_hHeap, 0, pGroups);
   if (pvProfile)
      LsaFreeReturnBuffer(pvProfile);
   if (hLsa)
      LsaClose(hLsa);
   if (hToken)
      CloseHandle(hToken);
   if (hTokenS4U)
      CloseHandle(hTokenS4U);
   if (pi.hProcess)
      CloseHandle(pi.hProcess);
   if (pi.hThread)
      CloseHandle(pi.hThread);

   return EXIT_SUCCESS;
}
예제 #12
0
int LsaLogon(HANDLE *hToken, char homeDir[MAX_PATH], char *user, 
                 char *pkBlob, int pkBlobSize, char *sign, int signSize, 
                     char *data, int dataSize, int dataFellow)
{
  int exitCode = 1;
  
  NTSTATUS ntStat = 0;
  
  LSA_STRING logonProcName;
  LSA_STRING originName;
  LSA_STRING authPckgName;
  
  HANDLE hLsa = NULL;
  
  LSA_OPERATIONAL_MODE securityMode;
  
  /*
   * Impersonation, "weak" token returned from network logon.
   * We can't create process as other user via this token.
   */
  
  HANDLE hWeakToken = NULL;
  
  /*
   * Login data.
   */
  
  LsaAuth *lsaAuth = NULL;

  ULONG lsaAuthSize = 0;

  ULONG authPckgId  = 0;
  
  TOKEN_SOURCE srcToken;
  
  PVOID profile = NULL;

  ULONG profileSize;
  
  LUID  logonId;
  
  QUOTA_LIMITS quotas;
  
  NTSTATUS loginStat;
  

  debug("-> LsaLogon()...");

  /*
   * We check only hToken arg, becouse other args are tested in AllocLsaAuth().
   */
  
  debug("Checking args...");
  
  FAIL(hToken == NULL);
  
  /*
   * Setup lsa strings.
   */

  debug("Setting up LSA Strings...");
  
  FAIL(InitLsaString(&logonProcName, "sshd-logon"));
  FAIL(InitLsaString(&originName, "NTLM"));
  FAIL(InitLsaString(&authPckgName, "SSH-LSA"));

  /*
   * Enable needed privilege to current running process.
   */

  EnablePrivilege("SeTcbPrivilege", 1);
  
  /*
   * Register new logon process.
   */
  
  debug("LsaRegisterLogonProcess()...");

  NTFAIL(LsaRegisterLogonProcess(&logonProcName, &hLsa, &securityMode));
  
  /*
   * Retrieve Authenticated Package ID.
   */
  
  debug("Retrieving Authentification Package ID...");
  
  NTFAIL(LsaLookupAuthenticationPackage(hLsa, &authPckgName, &authPckgId));
  
  /*
   * Allocate LsaAuth struct.
   */

  debug("Allocating LsaAuth struct...");
  
  FAIL(AllocLsaAuth(&lsaAuth, user, pkBlob, pkBlobSize,
                       sign, signSize, data, dataSize, dataFellow));
                       
  lsaAuthSize = lsaAuth -> totalSize_;                       

  /*
   * Create TOKEN_SOURCE part
   */
  
  debug("Setting up TOKEN_SOURCE...");
  
  FAIL(AllocateLocallyUniqueId(&srcToken.SourceIdentifier) == FALSE);
  
  memcpy(srcToken.SourceName, "**sshd**", 8);

  /*
   * Try to login using LsaAuth struct.
   */

  debug("Login attemp...");
  
  NTFAIL(LsaLogonUser(hLsa, &originName, Network,
                          authPckgId, lsaAuth, lsaAuthSize, NULL,
                              &srcToken, &profile, &profileSize,
                                  &logonId, &hWeakToken, &quotas, &loginStat));

  debug("login status: %x...", loginStat);
  
  
  //FAIL(WideCharToMultiByte( CP_UTF8, 0, profile, -1, homeDir, MAX_PATH, NULL, NULL)==0);
  //memcpy(homeDir, profile, MAX_PATH*sizeof(wchar_t));

  lstrcpyW(homeDir, profile);
  
  debug("homedir = [%ls]", (char *) homeDir);

  //strcpy(homeDir, profile);
  
  //PrintToken(hToken);
  
  /*
   * Duplicate 'weak' impersonation token into Primary Key token.
   * We can create process using duplicated token.
   */
  
  debug("Duplicating token...");
  
  FAIL(DuplicateTokenEx(hWeakToken, MAXIMUM_ALLOWED,
                            NULL, SecurityImpersonation,
                                TokenPrimary, hToken) == 0);
  
  exitCode = 0;
  
fail:

  if (exitCode)
  {
    switch(ntStat)
    {
      case STATUS_LOGON_FAILURE:
      {
        debug("SSH-LSA authorization failed. " 
                  "(err = %u, ntStat = %x).", GetLastError(), ntStat);

        exitCode = 0;

        break;
      }
      
      case STATUS_NO_SUCH_PACKAGE:
      {
        debug("SSH-LSA package not found. "
                  "(err = %u, ntStat = %x).", GetLastError(), ntStat);
                  
        break;          
      }
      
      default:
      {
        debug("Cannot logon using LSA package (err = %u, ntStat = %x).",
                  GetLastError(), ntStat);
      }
    }        
            
    hToken = NULL;
  }
  else
  {
    debug("LsaLogon : OK.");
  }

  /*
   * Clean up.
   */
  
  CloseHandle(hWeakToken);
  
  LsaFreeReturnBuffer(profile);
   
  EnablePrivilege("SeTcbPrivilege", 0);
  
  LsaDeregisterLogonProcess(hLsa);
  
  ClearLsaString(&logonProcName);
  ClearLsaString(&originName);
  ClearLsaString(&authPckgName);
         
  debug("<- LsaLogon()...");
  
  return exitCode;
}