internal static byte[] GetSessionKey(SecHandle context) { using (var buffer = new SafeStructureInOutBuffer <SecPkgContext_SessionKey>()) { var result = SecurityNativeMethods.QueryContextAttributesEx(context, SECPKG_ATTR.SESSION_KEY, buffer, buffer.Length); if (result == SecStatusCode.Success) { byte[] ret = new byte[buffer.Result.SessionKeyLength]; Marshal.Copy(buffer.Result.SessionKey, ret, 0, ret.Length); return(ret); } } return(new byte[0]); }
/// <summary> /// Get security descriptor for the printer. /// </summary> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The printer's security descriptor.</returns> public NtResult <SecurityDescriptor> GetSecurityDescriptor(bool throw_on_error) { PrintingNativeMethods.GetPrinter(_handle, 3, SafeHGlobalBuffer.Null, 0, out int length); using (var buffer = new SafeStructureInOutBuffer <PRINTER_INFO_3>(length, false)) { var error = PrintingNativeMethods.GetPrinter(_handle, 3, buffer, length, out length).GetLastWin32Error(); if (error != Win32Error.SUCCESS) { return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error)); } return(SecurityDescriptor.Parse(buffer.Result.pSecurityDescriptor, _type, throw_on_error)); } }
public RPC_IF_ID[] GetIfIds() { if (IsClosed) { throw new ObjectDisposedException("vector"); } var vector_buffer = new SafeStructureInOutBuffer <RPC_IF_ID_VECTOR>(handle, int.MaxValue, false); var vector = vector_buffer.Result; IntPtr[] ptrs = new IntPtr[vector.Count]; vector_buffer.Data.ReadArray(0, ptrs, 0, vector.Count); return(ptrs.Select(p => (RPC_IF_ID)Marshal.PtrToStructure(p, typeof(RPC_IF_ID))).ToArray()); }
private static X509Certificate2 GetCertificate(SecHandle context, SECPKG_ATTR attr) { using (var buffer = new SafeStructureInOutBuffer <IntPtr>()) { SecurityNativeMethods.QueryContextAttributesEx(context, attr, buffer, buffer.Length).CheckResult(); try { return(new X509Certificate2(buffer.Result)); } finally { SecurityNativeMethods.CertFreeCertificateContext(buffer.Result); } } }
private SafeStructureInOutBuffer <SYMBOL_INFO> GetSymbolFromIndex(int type_index, long module_base) { SYMBOL_INFO symbol_info = new SYMBOL_INFO(SYMBOL_INFO.MAX_SYM_NAME); symbol_info.Index = type_index; int total_size = (symbol_info.MaxNameLen * 2) + symbol_info.SizeOfStruct - 2; using (var ret = new SafeStructureInOutBuffer <SYMBOL_INFO>(symbol_info, total_size, false)) { if (_sym_from_index(Handle, module_base, type_index, ret)) { return(ret.Detach()); } } return(null); }
private RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer, LRPC_FAULT_MESSAGE message) : this(message.RpcStatus) { if (message.Flags.HasFlag(LRPC_FAULT_MESSAGE_FLAGS.ExtendedErrorInfo)) { try { byte[] data = buffer.GetStructAtOffset <LRPC_FAULT_MESSAGE_EXTENDED>(0).Data.ToArray(); ExtendedErrorInfo = RpcExtendedErrorInfo.ReadErrorInfo(data); } catch { } } }
private RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer, LRPC_FAULT_MESSAGE message) : this(message.RpcStatus) { ExtendedErrorInfo = new RpcExtendedErrorInfo[0]; if (message.Flags.HasFlag(LRPC_FAULT_MESSAGE_FLAGS.ExtendedErrorInfo)) { try { byte[] data = buffer.Data.ReadBytes(16, buffer.Data.Length - 16); ExtendedErrorInfo = RpcExtendedErrorInfo.ReadErrorInfo(data); } catch { } } }
/// <summary> /// Logon user using S4U /// </summary> /// <param name="user">The username.</param> /// <param name="realm">The user's realm.</param> /// <param name="type">The type of logon token.</param> /// <returns>The logged on token.</returns> public static NtToken LogonS4U(string user, string realm, SecurityLogonType type) { LsaString pkgName = new LsaString("Negotiate"); Win32NativeMethods.LsaConnectUntrusted(out SafeLsaHandle hlsa).ToNtException(); using (hlsa) { uint authnPkg; Win32NativeMethods.LsaLookupAuthenticationPackage(hlsa, pkgName, out authnPkg).ToNtException(); byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON { MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon }; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; Marshal.StructureToPtr(logon_struct, buffer.DangerousGetHandle(), false); TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NtLmSsp"); Win32NativeMethods.AllocateLocallyUniqueId(out tokenSource.SourceIdentifier); LsaString originName = new LsaString("S4U"); QUOTA_LIMITS quota_limits = new QUOTA_LIMITS(); Win32NativeMethods.LsaLogonUser(hlsa, originName, type, authnPkg, buffer, buffer.Length, IntPtr.Zero, tokenSource, out IntPtr profile, out int cbProfile, out Luid logon_id, out SafeKernelObjectHandle token_handle, quota_limits, out NtStatus subStatus).ToNtException(); Win32NativeMethods.LsaFreeReturnBuffer(profile); return(NtToken.FromHandle(token_handle)); } } }
/// <summary> /// Get the list of registered trace providers. /// </summary> /// <returns>The list of trace providers.</returns> public static IEnumerable <EventTraceProvider> GetProviders() { int retry_count = 10; int buffer_length = 1024; Dictionary <Guid, EventTraceProvider> providers = new Dictionary <Guid, EventTraceProvider>(); while (retry_count-- > 0) { using (var buffer = new SafeStructureInOutBuffer <PROVIDER_ENUMERATION_INFO>(buffer_length, false)) { Win32Error error = Win32NativeMethods.TdhEnumerateProviders(buffer, ref buffer_length); if (error == Win32Error.ERROR_INSUFFICIENT_BUFFER) { continue; } if (error != Win32Error.SUCCESS) { error.ToNtException(); } var result = buffer.Result; var data = buffer.Data; TRACE_PROVIDER_INFO[] infos = new TRACE_PROVIDER_INFO[result.NumberOfProviders]; buffer.Data.ReadArray(0, infos, 0, infos.Length); foreach (var info in infos) { if (!providers.ContainsKey(info.ProviderGuid)) { providers.Add(info.ProviderGuid, new EventTraceProvider(info.ProviderGuid, buffer.ReadNulTerminatedUnicodeString(info.ProviderNameOffset), info.SchemaSource == 0)); } } break; } } foreach (var guid in GetTraceGuids()) { if (!providers.ContainsKey(guid)) { providers.Add(guid, new EventTraceProvider(guid)); } } return(providers.Values); }
private static string GetServiceDisplayName(SafeServiceHandle service) { using (var buf = new SafeStructureInOutBuffer <QUERY_SERVICE_CONFIG>(8192, false)) { if (!Win32NativeMethods.QueryServiceConfig(service, buf, buf.Length, out int required)) { return(string.Empty); } var result = buf.Result; if (result.lpDisplayName == IntPtr.Zero) { return(string.Empty); } return(Marshal.PtrToStringUni(result.lpDisplayName)); } }
internal static string GetOwnerModule <T>(GetOwnerModuleDelegate <T> func, T entry, int process_id) { using (var buffer = new SafeStructureInOutBuffer <TCPIP_OWNER_MODULE_BASIC_INFO>(64 * 1024, true)) { int size = buffer.Length; Win32Error error = func(entry, TCPIP_OWNER_MODULE_INFO_CLASS.TCPIP_OWNER_MODULE_INFO_BASIC, buffer, ref size); string ret; if (error == Win32Error.SUCCESS) { ret = Marshal.PtrToStringUni(buffer.Result.pModulePath); } else { ret = NtSystemInfo.GetProcessIdImagePath(process_id, false).GetResultOrDefault(string.Empty); } return(ret); } }
private static IEnumerable <T> EnumFilter <T, U>(FindFirst find_first, FindNext find_next, FindClose find_close, GetNextOffset <U> get_next, CreateObject <T, U> create) where U : struct { using (var buffer = new SafeStructureInOutBuffer <U>(128 * 1024, true)) { NtStatus no_more_hresult = Win32Error.ERROR_NO_MORE_ITEMS.ToHresult(); NtResult <IntPtr> handle = new NtResult <IntPtr>(no_more_hresult, IntPtr.Zero); var list = new List <T>(); try { handle = find_first(buffer); var status = handle.Status; while (status != no_more_hresult) { if (status != NtStatus.STATUS_SUCCESS) { throw new NtException(status); } var next_buffer = buffer; do { list.Add(create(next_buffer)); int offset = get_next(next_buffer); if (offset == 0) { break; } next_buffer = next_buffer.GetStructAtOffset <U>(offset); }while (true); status = find_next(handle.Result, buffer); } } finally { if (handle.IsSuccess) { find_close(handle.Result); } } return(list.AsReadOnly()); } }
/// <summary> /// Create from a package full name. /// </summary> /// <param name="package_full_name">The package full name.</param> /// <param name="full_information">Query for full information (needs to be installed for the current user).</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The package identity.</returns> public static NtResult <PackageIdentity> CreateFromFullName(string package_full_name, bool full_information, bool throw_on_error) { PackageFlags flags = full_information ? PackageFlags.Full : PackageFlags.Basic; int length = 0; var result = Win32NativeMethods.GetStagedPackagePathByFullName(package_full_name, ref length, null); if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } var builder = new StringBuilder(length); result = Win32NativeMethods.GetStagedPackagePathByFullName(package_full_name, ref length, builder); if (result != Win32Error.SUCCESS) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } result = _get_staged_package_origin(package_full_name, out PackageOrigin origin); if (result != Win32Error.SUCCESS) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } length = 0; result = Win32NativeMethods.PackageIdFromFullName(package_full_name, flags, ref length, SafeHGlobalBuffer.Null); if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <PACKAGE_ID>(length, false)) { result = Win32NativeMethods.PackageIdFromFullName(package_full_name, flags, ref length, buffer); if (result != Win32Error.SUCCESS) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } return(new PackageIdentity(package_full_name, buffer.Result, origin, builder.ToString()).CreateResult()); } }
private NtResult <SafeStructureInOutBuffer <T> > QueryBuffer <T>(AUTHZ_CONTEXT_INFORMATION_CLASS info_class, bool throw_on_error) where T : new() { if (SecurityNativeMethods.AuthzGetInformationFromContext(_handle, info_class, 0, out int required_size, SafeHGlobalBuffer.Null)) { return(NtStatus.STATUS_INVALID_PARAMETER.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error)); } var err = Win32Utils.GetLastWin32Error(); if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(err.CreateResultFromDosError <SafeStructureInOutBuffer <T> >(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <T>(required_size, false)) { return(SecurityNativeMethods.AuthzGetInformationFromContext(_handle, info_class, buffer.Length, out required_size, buffer).CreateWin32Result(throw_on_error, () => buffer.Detach())); } }
internal SocketSecurityInformation(SafeStructureInOutBuffer <SOCKET_SECURITY_QUERY_INFO> buffer) { var query_info = buffer.Result; Flags = query_info.Flags; PeerApplicationToken = CreateToken(query_info.PeerApplicationAccessTokenHandle); PeerMachineToken = CreateToken(query_info.PeerMachineAccessTokenHandle); if (buffer.Length < Marshal.SizeOf(typeof(SOCKET_SECURITY_QUERY_INFO_IPSEC2)) || query_info.SecurityProtocol != SOCKET_SECURITY_PROTOCOL.IPsec2) { return; } var query_info_2 = buffer.Read <SOCKET_SECURITY_QUERY_INFO_IPSEC2>(0); MmSaId = query_info_2.MmSaId; QmSaId = query_info_2.QmSaId; NegotiationWinerr = query_info_2.NegotiationWinerr; SaLookupContext = query_info_2.SaLookupContext; }
internal FilterDriver(SafeStructureInOutBuffer <FILTER_AGGREGATE_STANDARD_INFORMATION> buffer) { var result = buffer.Result; if (result.Flags.HasFlagSet(FILTER_AGGREGATE_STANDARD_INFORMATION_FLAGS.FLTFL_ASI_IS_LEGACYFILTER)) { Flags = result.LegacyFilter.Flags; Name = buffer.ReadUnicodeString(result.LegacyFilter.FilterNameBufferOffset, result.LegacyFilter.FilterNameLength / 2); Altitude = FilterManagerUtils.ParseAltitude(buffer.ReadUnicodeString(result.LegacyFilter.FilterAltitudeBufferOffset, result.LegacyFilter.FilterAltitudeLength / 2)); } else { MiniFilter = true; Flags = result.MiniFilter.Flags; FrameID = result.MiniFilter.FrameID; NumberOfInstances = result.MiniFilter.NumberOfInstances; Name = buffer.ReadUnicodeString(result.MiniFilter.FilterNameBufferOffset, result.MiniFilter.FilterNameLength / 2); Altitude = FilterManagerUtils.ParseAltitude(buffer.ReadUnicodeString(result.MiniFilter.FilterAltitudeBufferOffset, result.MiniFilter.FilterAltitudeLength / 2)); } }
private static ApiSetNamespace FromCurrentProcess() { if (NtObjectUtils.SupportedVersion < SupportedVersion.Windows10) { return(new ApiSetNamespace(ApiSetFlags.None, new List <ApiSetEntry>())); } IntPtr base_ptr = NtProcess.Current.GetPeb().GetApiSetMap(); var header = (API_SET_NAMESPACE_WIN10)Marshal.PtrToStructure(base_ptr, typeof(API_SET_NAMESPACE_WIN10)); if (header.Version < 5) { return(new ApiSetNamespace(ApiSetFlags.None, new List <ApiSetEntry>())); } var map = new SafeStructureInOutBuffer <API_SET_NAMESPACE_WIN10>(base_ptr, header.Size, false); var entries = map.ReadArray <API_SET_NAMESPACE_ENTRY_WIN10>(header.NamespaceOffset, header.Count).Select(e => CreateEntry(e, map)); return(new ApiSetNamespace(header.Flags, entries.ToList())); }
private static KerberosPrincipalName ParseName(IntPtr ptr) { if (ptr == IntPtr.Zero) { return(new KerberosPrincipalName()); } KerberosNameType name_type = (KerberosNameType)Marshal.ReadInt16(ptr, 0); int count = Marshal.ReadInt16(ptr, 2); if (count == 0) { return(new KerberosPrincipalName(name_type, new string[0])); } var name = new SafeStructureInOutBuffer <KERB_EXTERNAL_NAME>(ptr, Marshal.SizeOf(typeof(KERB_EXTERNAL_NAME)) + Marshal.SizeOf(typeof(UnicodeStringOut)) * count, false); UnicodeStringOut[] names = new UnicodeStringOut[count]; name.Data.ReadArray(0, names, 0, count); return(new KerberosPrincipalName(name_type, names.Select(u => u.ToString()))); }
public override int Read(byte[] buffer, int offset, int count) { if (offset == 0) { using (var len = new SafeStructureInOutBuffer <int>()) { _stm.Read(buffer, count, len.DangerousGetHandle()); return(len.Result); } } else { using (var len = new SafeStructureInOutBuffer <int>()) { byte[] temp_buffer = new byte[count]; _stm.Read(temp_buffer, count, len.DangerousGetHandle()); int read_len = len.Result; Buffer.BlockCopy(temp_buffer, 0, buffer, offset, count); return(read_len); } } }
/// <summary> /// Get certificates from a PE file. /// </summary> /// <param name="file">The PE file.</param> /// <param name="throw_on_error">True the throw on error.</param> /// <returns>The list of authenticode certificate entries.</returns> public static NtResult <IReadOnlyList <AuthenticodeCertificate> > GetCertificates(NtFile file, bool throw_on_error) { List <AuthenticodeCertificate> certs = new List <AuthenticodeCertificate>(); Win32Error error = Win32NativeMethods.ImageEnumerateCertificates(file.Handle, WinCertType.WIN_CERT_TYPE_ANY, out int count, null, 0).GetLastWin32Error(); if (error != Win32Error.SUCCESS) { return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error)); } for (int i = 0; i < count; ++i) { int size = 0; error = Win32NativeMethods.ImageGetCertificateData(file.Handle, i, SafeHGlobalBuffer.Null, ref size).GetLastWin32Error(); if (error != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <WIN_CERTIFICATE>(size, true)) { error = Win32NativeMethods.ImageGetCertificateData(file.Handle, i, buffer, ref size).GetLastWin32Error(); if (error != Win32Error.SUCCESS) { return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error)); } var result = buffer.Result; if (result.wCertificateType != WinCertType.WIN_CERT_TYPE_PKCS_SIGNED_DATA) { continue; } var cert = AuthenticodeCertificate.Parse(buffer.Data.ReadBytes(result.dwLength), throw_on_error); if (!cert.IsSuccess) { return(cert.Cast <IReadOnlyList <AuthenticodeCertificate> >()); } certs.Add(cert.Result); } } return(certs.AsReadOnly().CreateResult().Cast <IReadOnlyList <AuthenticodeCertificate> >()); }
private static NtResult <SafeLsaReturnBufferHandle> QueryCachedTicket(SafeLsaLogonHandle handle, uint auth_package, string target_name, KERB_RETRIEVE_TICKET_FLAGS flags, Luid logon_id, SecHandle sec_handle, bool throw_on_error) { int string_length = (target_name.Length) * 2; int max_string_length = string_length + 2; using (var request = new SafeStructureInOutBuffer <KERB_RETRIEVE_TKT_REQUEST>(max_string_length, true)) { request.Data.WriteUnicodeString(target_name + '\0'); var request_str = new KERB_RETRIEVE_TKT_REQUEST() { CacheOptions = flags, CredentialsHandle = sec_handle, LogonId = logon_id, MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbRetrieveEncodedTicketMessage, TargetName = new UnicodeStringOut() { Length = (ushort)string_length, MaximumLength = (ushort)max_string_length, Buffer = request.Data.DangerousGetHandle() } }; request.Result = request_str; using (var result = handle.CallPackage(auth_package, request, throw_on_error)) { if (!result.IsSuccess) { return(result.Cast <SafeLsaReturnBufferHandle>()); } if (!result.Result.Status.IsSuccess()) { return(result.Result.Status.CreateResultFromError <SafeLsaReturnBufferHandle>(throw_on_error)); } return(result.Result.Buffer.Detach().CreateResult()); } } }
internal ServiceInformation(string name, SecurityDescriptor sd, IEnumerable <ServiceTriggerInformation> triggers, ServiceSidType sid_type, ServiceLaunchProtectedType launch_protected, IEnumerable <string> required_privileges, SafeStructureInOutBuffer <QUERY_SERVICE_CONFIG> config, bool delayed_auto_start) { using (config) { Name = name; SecurityDescriptor = sd; Triggers = triggers; SidType = sid_type; LaunchProtected = launch_protected; RequiredPrivileges = required_privileges; if (config == null) { BinaryPathName = string.Empty; LoadOrderGroup = string.Empty; Dependencies = new string[0]; DisplayName = string.Empty; ServiceStartName = string.Empty; return; } var result = config.Result; ServiceType = result.dwServiceType; StartType = result.dwStartType; ErrorControl = result.dwErrorControl; BinaryPathName = result.lpBinaryPathName.GetString(); LoadOrderGroup = result.lpLoadOrderGroup.GetString(); TagId = result.dwTagId; Dependencies = result.lpLoadOrderGroup.GetMultiString(); DisplayName = result.lpDisplayName.GetString(); ServiceStartName = result.lpServiceStartName.GetString(); DelayedAutoStart = delayed_auto_start; } }
/// <summary> /// Logon user using S4U /// </summary> /// <param name="user">The username.</param> /// <param name="realm">The user's realm.</param> /// <param name="type">The type of logon token.</param> /// <param name="auth_package">The name of the auth package to user.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The logged on token.</returns> public static NtResult <NtToken> LsaLogonS4U(string user, string realm, SecurityLogonType type, string auth_package, bool throw_on_error) { if (user is null) { throw new ArgumentNullException(nameof(user)); } if (realm is null) { throw new ArgumentNullException(nameof(realm)); } byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON { MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon }; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; buffer.Result = logon_struct; return(LsaLogonUser(type, auth_package, "S4U", buffer, null, throw_on_error)); } }
public static NtToken LogonS4U(string user, string realm, SecurityLogonType type) { SafeLsaHandle hlsa = null; LsaString pkgName = new LsaString("Negotiate"); LsaConnectUntrusted(out hlsa).ToNtException(); using (hlsa) { uint authnPkg; LsaLookupAuthenticationPackage(hlsa, pkgName, out authnPkg).ToNtException(); byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer<KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON(); logon_struct.MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; Marshal.StructureToPtr(logon_struct, buffer.DangerousGetHandle(), false); TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NtLmSsp"); AllocateLocallyUniqueId(out tokenSource.SourceIdentifier); LsaString originName = new LsaString("S4U"); IntPtr profile; int cbProfile; Luid logon_id; NtStatus subStatus; QUOTA_LIMITS quota_limits; SafeKernelObjectHandle token_handle; LsaLogonUser(hlsa, originName, type, authnPkg, buffer, buffer.Length, IntPtr.Zero, tokenSource, out profile, out cbProfile, out logon_id, out token_handle, out quota_limits, out subStatus).ToNtException(); LsaFreeReturnBuffer(profile); return NtToken.FromHandle(token_handle); } } }
/// <summary> /// Enumerate all atoms. /// </summary> /// <returns>An enumeration of all atoms on the system.</returns> public static IEnumerable<NtAtom> GetAtoms() { int size = 1024; while (size < 5 * 1024 * 1024) { using (SafeStructureInOutBuffer<AtomTableInformation> buffer = new SafeStructureInOutBuffer<AtomTableInformation>(size, true)) { int return_length; NtStatus status = NtSystemCalls.NtQueryInformationAtom(0, AtomInformationClass.AtomTableInformation, buffer, buffer.Length, out return_length); if (status.IsSuccess()) { AtomTableInformation table = buffer.Result; IntPtr data = buffer.Data.DangerousGetHandle(); for (int i = 0; i < table.NumberOfAtoms; ++i) { ushort atom = (ushort)Marshal.ReadInt16(data); yield return new NtAtom(atom); data += 2; } } else if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH) { throw new NtException(status); } size *= 2; } } }
internal RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer) : this(buffer, buffer.Result) { }
private RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer, LRPC_FAULT_MESSAGE message) : base(NtObjectUtils.MapDosErrorToStatus(message.RpcStatus)) { // Maybe read extended error info. }
/// <summary> /// Convert security descriptor to a byte array /// </summary> /// <returns>The binary security descriptor</returns> public byte[] ToByteArray() { SafeStructureInOutBuffer<SecurityDescriptorStructure> sd_buffer = null; SafeHGlobalBuffer dacl_buffer = null; SafeHGlobalBuffer sacl_buffer = null; SafeSidBufferHandle owner_buffer = null; SafeSidBufferHandle group_buffer = null; try { sd_buffer = new SafeStructureInOutBuffer<SecurityDescriptorStructure>(); NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException(); SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask; NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException(); if (Dacl != null) { if (!Dacl.NullAcl) { dacl_buffer = new SafeHGlobalBuffer(Dacl.ToByteArray()); } else { dacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false); } NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, dacl_buffer.DangerousGetHandle(), Dacl.Defaulted).ToNtException(); } if (Sacl != null) { if (!Sacl.NullAcl) { sacl_buffer = new SafeHGlobalBuffer(Sacl.ToByteArray()); } else { sacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false); } NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, sacl_buffer.DangerousGetHandle(), Sacl.Defaulted).ToNtException(); } if (Owner != null) { owner_buffer = Owner.Sid.ToSafeBuffer(); NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, owner_buffer.DangerousGetHandle(), Owner.Defaulted); } if (Group != null) { group_buffer = Group.Sid.ToSafeBuffer(); NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, group_buffer.DangerousGetHandle(), Group.Defaulted); } int total_length = 0; NtStatus status = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, new SafeHGlobalBuffer(IntPtr.Zero, 0, false), ref total_length); if (status != NtStatus.STATUS_BUFFER_TOO_SMALL) { status.ToNtException(); } using (SafeHGlobalBuffer relative_sd = new SafeHGlobalBuffer(total_length)) { NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException(); return relative_sd.ToArray(); } } finally { if (sd_buffer != null) { sd_buffer.Close(); } if (dacl_buffer != null) { dacl_buffer.Close(); } if (sacl_buffer != null) { sacl_buffer.Close(); } if (owner_buffer != null) { owner_buffer.Close(); } if (group_buffer != null) { group_buffer.Close(); } } }
static void DumpTriggers(SafeServiceHandle service) { using (var buf = new SafeStructureInOutBuffer <SERVICE_TRIGGER_INFO>(8192, false)) { int required = 0; if (!QueryServiceConfig2(service, SERVICE_CONFIG_TRIGGER_INFO, buf, 8192, out required)) { return; } SERVICE_TRIGGER_INFO trigger_info = buf.Result; if (trigger_info.cTriggers == 0) { return; } SERVICE_TRIGGER[] trigger_arr; using (SafeHGlobalBuffer triggers = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false)) { trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers]; triggers.ReadArray(0, trigger_arr, 0, trigger_arr.Length); } for (int i = 0; i < trigger_arr.Length; ++i) { SERVICE_TRIGGER trigger = trigger_arr[i]; Console.WriteLine("Trigger: {0} - Type: {1} - Action: {2}", i, trigger.dwTriggerType, trigger.dwAction); switch (trigger.dwTriggerType) { case ServiceTriggerType.Custom: Console.WriteLine("Subtype: [ETW UUID] {0:B}", trigger.GetSubType()); break; case ServiceTriggerType.DeviceInterfaceArrival: Console.WriteLine("Subtype: [Interface Class GUID] {0:B}", trigger.GetSubType()); break; case ServiceTriggerType.GroupPolicy: { Guid sub_type = trigger.GetSubType(); if (sub_type == MACHINE_POLICY_PRESENT_GUID) { Console.WriteLine("Subtype: [Machine Policy Present]"); } else if (sub_type == USER_POLICY_PRESENT_GUID) { Console.WriteLine("Subtype: [User Policy Present]"); } else { Console.WriteLine("Subtype: [Unknown Group Policy] {0:B}", sub_type); } } break; case ServiceTriggerType.NetworkEndpoint: { Guid sub_type = trigger.GetSubType(); if (sub_type == RPC_INTERFACE_EVENT_GUID) { Console.WriteLine("Subtype: [RPC Interface]"); } else if (sub_type == NAMED_PIPE_EVENT_GUID) { Console.WriteLine("Subtype: [Named Pipe]"); } else { Console.WriteLine("Subtype: [Unknown Network Endpoint] {0:B}", sub_type); } } break; case ServiceTriggerType.DomainJoin: { Guid sub_type = trigger.GetSubType(); if (sub_type == DOMAIN_JOIN_GUID) { Console.WriteLine("Subtype: [Domain Join]"); } else if (sub_type == DOMAIN_LEAVE_GUID) { Console.WriteLine("Subtype: [Domain Leave]"); } else { Console.WriteLine("Subtype: [Unknown Domain Join] {0:B}", sub_type); } } break; case ServiceTriggerType.IPAddressAvailability: { Guid sub_type = trigger.GetSubType(); if (sub_type == NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID) { Console.WriteLine("Subtype: [First IP Address Available]"); } else if (sub_type == NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID) { Console.WriteLine("Subtype: [Last IP Address Available]"); } else { Console.WriteLine("Subtype: [Unknown IP Address Availability] {0:B}", sub_type); } } break; } if (trigger.pDataItems != IntPtr.Zero && trigger.cDataItems > 0) { DumpCustomData(trigger); } } } }
private static void LoadTypes() { if (_types == null) { SafeStructureInOutBuffer<ObjectAllTypesInformation> type_info = new SafeStructureInOutBuffer<ObjectAllTypesInformation>(); try { Dictionary<string, NtType> ret = new Dictionary<string, NtType>(StringComparer.OrdinalIgnoreCase); int return_length; NtStatus status = NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation, type_info.DangerousGetHandle(), type_info.Length, out return_length); if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH) status.ToNtException(); type_info.Close(); type_info = null; type_info = new SafeStructureInOutBuffer<ObjectAllTypesInformation>(return_length, false); int alignment = IntPtr.Size - 1; NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation, type_info.DangerousGetHandle(), type_info.Length, out return_length).ToNtException(); ObjectAllTypesInformation result = type_info.Result; IntPtr curr_typeinfo = type_info.DangerousGetHandle() + IntPtr.Size; for (int count = 0; count < result.NumberOfTypes; ++count) { ObjectTypeInformation info = (ObjectTypeInformation)Marshal.PtrToStructure(curr_typeinfo, typeof(ObjectTypeInformation)); NtType ti = new NtType(count + 2, info); ret[ti.Name] = ti; int offset = (info.Name.MaximumLength + alignment) & ~alignment; curr_typeinfo = info.Name.Buffer + offset; } _types = ret; } finally { if (type_info != null) { type_info.Close(); } } } }
private RpcClientResponse HandleImmediateResponse(AlpcMessageRaw message, SafeStructureInOutBuffer <LRPC_IMMEDIATE_RESPONSE_MESSAGE> response, AlpcReceiveMessageAttributes attributes, int data_length) { return(new RpcClientResponse(response.Data.ToArray(), attributes.Handles)); }
static void Main(string[] args) { try { if (args.Length < 1) { return; } EnablePrivileges(); using (var dir = OpenReparseDirectory(args[0])) { using (var buffer = new SafeStructureInOutBuffer <FileReparseTagInformation>()) { using (var io_status = new SafeIoStatusBuffer()) { while (true) { NtStatus status = NtSystemCalls.NtQueryDirectoryFile(dir.Handle, SafeKernelObjectHandle.Null, IntPtr.Zero, IntPtr.Zero, io_status, buffer, buffer.Length, FileInformationClass.FileReparsePointInformation, true, null, false); if (status == NtStatus.STATUS_NO_MORE_FILES) { break; } if (status != NtStatus.STATUS_SUCCESS) { throw new NtException(status); } var result = buffer.Result; var filedata = GetFileData(dir, result.Tag, result.FileReferenceNumber); Console.WriteLine("{0} {1}", filedata.FileName, filedata.Reparse.Tag); if (filedata.Reparse is MountPointReparseBuffer mount_point) { Console.WriteLine("Target: {0}", mount_point.SubstitutionName); Console.WriteLine("Print: {0}", mount_point.PrintName); } else if (filedata.Reparse is SymlinkReparseBuffer symlink) { Console.WriteLine("Target: {0}", symlink.SubstitutionName); Console.WriteLine("Print: {0}", symlink.PrintName); Console.WriteLine("Flags: {0}", symlink.Flags); } else if (filedata.Reparse is ExecutionAliasReparseBuffer alias) { Console.WriteLine("Target: {0}", alias.Target); Console.WriteLine("Package: {0}", alias.PackageName); Console.WriteLine("Entry Point: {0}", alias.EntryPoint); Console.WriteLine("AppType: {0}", alias.AppType); } else if (filedata.Reparse is OpaqueReparseBuffer opaque) { HexDumpBuilder builder = new HexDumpBuilder(true, true, true, false, 0); builder.Append(opaque.Data); Console.WriteLine(builder); } } } } } } catch (Exception ex) { Console.WriteLine(ex); } }
private static string GetNameFromSymbolInfo(SafeStructureInOutBuffer <SYMBOL_INFO> buffer) { return(buffer.Data.ReadNulTerminatedUnicodeString()); }
internal ServiceInformation(string machine_name, string name, SecurityDescriptor sd, IEnumerable <ServiceTriggerInformation> triggers, ServiceSidType sid_type, ServiceLaunchProtectedType launch_protected, IEnumerable <string> required_privileges, SafeStructureInOutBuffer <QUERY_SERVICE_CONFIG> config, bool delayed_auto_start) { Name = name; SecurityDescriptor = sd; Triggers = triggers; SidType = sid_type; LaunchProtected = launch_protected; RequiredPrivileges = required_privileges; if (config == null) { BinaryPathName = string.Empty; LoadOrderGroup = string.Empty; Dependencies = new string[0]; DisplayName = string.Empty; ServiceStartName = string.Empty; return; } var result = config.Result; ServiceType = result.dwServiceType; StartType = result.dwStartType; ErrorControl = result.dwErrorControl; BinaryPathName = result.lpBinaryPathName.GetString(); LoadOrderGroup = result.lpLoadOrderGroup.GetString(); TagId = result.dwTagId; Dependencies = result.lpLoadOrderGroup.GetMultiString(); DisplayName = result.lpDisplayName.GetString(); ServiceStartName = result.lpServiceStartName.GetString(); DelayedAutoStart = delayed_auto_start; MachineName = machine_name ?? string.Empty; ImagePath = string.Empty; ServiceDll = string.Empty; ServiceHostType = string.Empty; ServiceMain = string.Empty; // TODO: Maybe try and query using remote registry service? if (!string.IsNullOrEmpty(MachineName)) { return; } ImagePath = Win32Utils.GetImagePathFromCommandLine(BinaryPathName); using (RegistryKey key = OpenKeySafe(Registry.LocalMachine, $@"SYSTEM\CurrentControlSet\Services\{Name}")) { if (key != null) { UserName = ReadStringFromKey(key, null, "ObjectName"); ServiceDll = ReadStringFromKey(key, "Parameters", "ServiceDll"); if (string.IsNullOrEmpty(ServiceDll)) { ServiceDll = ReadStringFromKey(key, null, "ServiceDll"); } if (!string.IsNullOrEmpty(ServiceDll)) { string[] args = Win32Utils.ParseCommandLine(BinaryPathName); for (int i = 0; i < args.Length - 1; ++i) { if (args[i] == "-k") { ServiceHostType = args[i + 1]; break; } } ServiceMain = ReadStringFromKey(key, "Parameters", "ServiceMain"); if (string.IsNullOrEmpty(ServiceMain)) { ServiceMain = "ServiceMain"; } } } } }