static ProcessManager() { // In order to query information (OpenProcess) on some protected processes // like csrss, we need SeDebugPrivilege privilege. // After removing the depenecy on Performance Counter, we don't have a chance // to run the code in CLR performance counter to ask for this privilege. // So we will try to get the privilege here. // We could fail if the user account doesn't have right to do this, but that's fair. Interop.LUID luid = new Interop.LUID(); if (!Interop.mincore.LookupPrivilegeValue(null, "SeDebugPrivilege", out luid)) { return; } SafeTokenHandle tokenHandle = null; try { if (!Interop.mincore.OpenProcessToken( Interop.mincore.GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, out tokenHandle)) { return; } Interop.TokenPrivileges tp = new Interop.TokenPrivileges(); tp.Luid = luid; tp.Attributes = Interop.SE_PRIVILEGE_ENABLED; // AdjustTokenPrivileges can return true even if it didn't succeed (when ERROR_NOT_ALL_ASSIGNED is returned). Interop.mincore.AdjustTokenPrivileges(tokenHandle, false, tp, 0, IntPtr.Zero, IntPtr.Zero); } finally { if (tokenHandle != null) { tokenHandle.Dispose(); } } }
public void Execute(Dictionary <string, string> arguments) { string user = ""; string domain = ""; string password = ""; string hash = ""; string dc = ""; bool ptt = false; Interop.LUID luid = new Interop.LUID(); Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial; if (arguments.ContainsKey("/user")) { string[] parts = arguments["/user"].Split('\\'); if (parts.Length == 2) { domain = parts[0]; user = parts[1]; } else { user = arguments["/user"]; } } if (arguments.ContainsKey("/domain")) { domain = arguments["/domain"]; } if (arguments.ContainsKey("/dc")) { dc = arguments["/dc"]; } if (arguments.ContainsKey("/password")) { password = arguments["/password"]; string salt = String.Format("{0}{1}", domain.ToUpper(), user.ToLower()); encType = Interop.KERB_ETYPE.rc4_hmac; //default is non /enctype is specified if (arguments.ContainsKey("/enctype")) { string encTypeString = arguments["/enctype"].ToUpper(); if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM")) { encType = Interop.KERB_ETYPE.rc4_hmac; } else if (encTypeString.Equals("AES128")) { encType = Interop.KERB_ETYPE.aes128_cts_hmac_sha1; } else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES")) { encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } else if (encTypeString.Equals("DES")) { encType = Interop.KERB_ETYPE.des_cbc_md5; } } hash = Crypto.KerberosPasswordHash(encType, password, salt); } else if (arguments.ContainsKey("/des")) { hash = arguments["/des"]; encType = Interop.KERB_ETYPE.des_cbc_md5; } else if (arguments.ContainsKey("/rc4")) { hash = arguments["/rc4"]; encType = Interop.KERB_ETYPE.rc4_hmac; } else if (arguments.ContainsKey("/ntlm")) { hash = arguments["/ntlm"]; encType = Interop.KERB_ETYPE.rc4_hmac; } else if (arguments.ContainsKey("/aes128")) { hash = arguments["/aes128"]; encType = Interop.KERB_ETYPE.aes128_cts_hmac_sha1; } else if (arguments.ContainsKey("/aes256")) { hash = arguments["/aes256"]; encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1; } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/luid")) { try { luid = new Interop.LUID(arguments["/luid"]); } catch { Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/luid"]); return; } } if (arguments.ContainsKey("/createnetonly")) { // if we're starting a hidden process to apply the ticket to if (!Helpers.IsHighIntegrity()) { Console.WriteLine("[X] You need to be in high integrity to apply a ticket to created logon session"); return; } if (arguments.ContainsKey("/show")) { luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], true); } else { luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], false); } Console.WriteLine(); } if (String.IsNullOrEmpty(user)) { Console.WriteLine("\r\n[X] You must supply a user name!\r\n"); return; } if (String.IsNullOrEmpty(domain)) { domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName; } if (String.IsNullOrEmpty(hash)) { Console.WriteLine("\r\n[X] You must supply a /password , or a [/des|/rc4|/aes128|/aes256] hash!\r\n"); return; } if (!((encType == Interop.KERB_ETYPE.des_cbc_md5) || (encType == Interop.KERB_ETYPE.rc4_hmac) || (encType == Interop.KERB_ETYPE.aes128_cts_hmac_sha1) || (encType == Interop.KERB_ETYPE.aes256_cts_hmac_sha1))) { Console.WriteLine("\r\n[X] Only /des, /rc4, /aes128, and /aes256 are supported at this time.\r\n"); return; } else { Ask.TGT(user, domain, hash, encType, ptt, dc, luid, true); return; } }
private static void SetPrivilege(string privilegeName, int attrib) { SafeTokenHandle hToken = null; Interop.LUID debugValue = new Interop.LUID(); // this is only a "pseudo handle" to the current process - no need to close it later SafeProcessHandle processHandle = Interop.mincore.GetCurrentProcess(); // get the process token so we can adjust the privilege on it. We DO need to // close the token when we're done with it. if (!Interop.mincore.OpenProcessToken(processHandle, Interop.TOKEN_ADJUST_PRIVILEGES, out hToken)) { throw new Win32Exception(); } try { if (!Interop.mincore.LookupPrivilegeValue(null, privilegeName, out debugValue)) { throw new Win32Exception(); } Interop.TokenPrivileges tkp = new Interop.TokenPrivileges(); tkp.Luid = debugValue; tkp.Attributes = attrib; Interop.mincore.AdjustTokenPrivileges(hToken, false, tkp, 0, IntPtr.Zero, IntPtr.Zero); // AdjustTokenPrivileges can return true even if it failed to // set the privilege, so we need to use GetLastError if (Marshal.GetLastWin32Error() != Interop.ERROR_SUCCESS) { throw new Win32Exception(); } } finally { #if FEATURE_TRACESWITCH Debug.WriteLineIf(_processTracing.TraceVerbose, "Process - CloseHandle(processToken)"); #endif if (hToken != null) { hToken.Dispose(); } } }
public void Execute(Dictionary <string, string> arguments) { string altservice = ""; Interop.LUID luid = new Interop.LUID(); bool ptt = false; if (arguments.ContainsKey("/luid")) { try { luid = new Interop.LUID(arguments["/luid"]); } catch { Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/luid"]); return; } } if (arguments.ContainsKey("/ptt")) { ptt = true; } if (arguments.ContainsKey("/altservice")) { altservice = arguments["/altservice"]; } else { Console.WriteLine("\r\n[X] An /altservice:SNAME or /altservice:SNAME/host needs to be supplied!\r\n"); return; } if (arguments.ContainsKey("/ticket")) { string kirbi64 = arguments["/ticket"]; if (Helpers.IsBase64String(kirbi64)) { byte[] kirbiBytes = Convert.FromBase64String(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.SubstituteTGSSname(kirbi, altservice, ptt, luid); } else if (File.Exists(kirbi64)) { byte[] kirbiBytes = File.ReadAllBytes(kirbi64); KRB_CRED kirbi = new KRB_CRED(kirbiBytes); LSA.SubstituteTGSSname(kirbi, altservice, ptt, luid); } else { Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n"); } return; } else { Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n"); return; } }
internal unsafe AuthZSet( byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "AuthZSet: SID={0}, authority={1}, storeCtx={2}", Utils.ByteArrayToString(userSid), flatUserAuthority, userStoreCtx.GetType()); _userType = userStoreCtx.OwningContext.ContextType; _userStoreCtx = userStoreCtx; _credentials = credentials; _contextOptions = contextOptions; // flatUserAuthority is flat domain name if userType == Domain, // flat host name if userType == LocalMachine _flatUserAuthority = flatUserAuthority; // Preload the PrincipalContext cache with the user's PrincipalContext _contexts[flatUserAuthority] = userStoreCtx.OwningContext; // // Get the SIDs of the groups to which the user belongs // IntPtr pClientContext = IntPtr.Zero; IntPtr pResManager = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; try { Interop.LUID luid = default; _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid()); _psUserSid = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid)); bool f; int lastError = 0; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager"); // Create a resource manager f = Interop.Authz.AuthzInitializeResourceManager( Interop.Authz.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out pResManager ); if (f) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID"); // Construct a context for the user based on the user's SID f = Interop.Authz.AuthzInitializeContextFromSid( 0, // default flags _psUserSid.DangerousGetHandle(), pResManager, IntPtr.Zero, luid, IntPtr.Zero, out pClientContext ); if (f) { int bufferSize = 0; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx"); // Extract the group SIDs from the user's context. Determine the size of the buffer we need. f = Interop.Authz.AuthzGetInformationFromContext( pClientContext, 2, // AuthzContextInfoGroupsSids 0, out bufferSize, IntPtr.Zero ); if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize); Debug.Assert(bufferSize > 0); // Set up the needed buffer pBuffer = Marshal.AllocHGlobal(bufferSize); // Extract the group SIDs from the user's context, into our buffer.0 f = Interop.Authz.AuthzGetInformationFromContext( pClientContext, 2, // AuthzContextInfoGroupsSids bufferSize, out bufferSize, pBuffer ); if (f) { // Marshall the native buffer into managed SID_AND_ATTR structures. // The native buffer holds a TOKEN_GROUPS structure: // // struct TOKEN_GROUPS { // DWORD GroupCount; // SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; // }; // // Extract TOKEN_GROUPS.GroupCount Interop.TOKEN_GROUPS tokenGroups = (Interop.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(Interop.TOKEN_GROUPS)); uint groupCount = tokenGroups.GroupCount; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount); // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR. Interop.SID_AND_ATTRIBUTES[] groups = new Interop.SID_AND_ATTRIBUTES[groupCount]; IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(Interop.TOKEN_GROUPS)) - sizeof(Interop.SID_AND_ATTRIBUTES)); for (int i = 0; i < groupCount; i++) { groups[i] = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure(currentItem, typeof(Interop.SID_AND_ATTRIBUTES)); currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(Interop.SID_AND_ATTRIBUTES))); } _groupSidList = new SidList(groups); } else { lastError = Marshal.GetLastWin32Error(); } } else { lastError = Marshal.GetLastWin32Error(); Debug.Fail("With a zero-length buffer, this should have never succeeded"); } } else { lastError = Marshal.GetLastWin32Error(); } } else { lastError = Marshal.GetLastWin32Error(); } if (!f) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError); throw new PrincipalOperationException( SR.Format( SR.AuthZFailedToRetrieveGroupList, lastError)); } // Save off the buffer since it still holds the native SIDs referenced by SidList _psBuffer = new SafeMemoryPtr(pBuffer); pBuffer = IntPtr.Zero; } catch (Exception e) { GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message); _psBuffer?.Dispose(); _psUserSid?.Dispose(); _psMachineSid?.Dispose(); // We're on a platform that doesn't have the AuthZ library if (e is DllNotFoundException) { throw new NotSupportedException(SR.AuthZNotSupported, e); } if (e is EntryPointNotFoundException) { throw new NotSupportedException(SR.AuthZNotSupported, e); } throw; } finally { if (pClientContext != IntPtr.Zero) { Interop.Authz.AuthzFreeContext(pClientContext); } if (pResManager != IntPtr.Zero) { Interop.Authz.AuthzFreeResourceManager(pResManager); } if (pBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pBuffer); } } }