/// <summary>
        /// Get the list of registered trace GUIDs.
        /// </summary>
        /// <returns>The list of trace GUIDs.</returns>
        public static IEnumerable <Guid> GetTraceGuids()
        {
            int curr_length = 1024;

            while (true)
            {
                using (var buffer = new SafeHGlobalBuffer(curr_length))
                {
                    Win32Error error = Win32NativeMethods.EnumerateTraceGuidsEx(TRACE_QUERY_INFO_CLASS.TraceGuidQueryList,
                                                                                SafeHGlobalBuffer.Null, 0, buffer, buffer.Length, out int return_length);
                    if (error == Win32Error.ERROR_INSUFFICIENT_BUFFER)
                    {
                        curr_length = return_length;
                        continue;
                    }

                    error.ToNtException();
                    int count = return_length / 16;

                    Guid[] ret = new Guid[count];
                    buffer.ReadArray(0, ret, 0, count);
                    return(ret);
                }
            }
        }
Beispiel #2
0
        static IEnumerable <ServiceTriggerInformation> GetTriggersForService(SafeServiceHandle service)
        {
            List <ServiceTriggerInformation> triggers = new List <ServiceTriggerInformation>();

            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(triggers.AsReadOnly());
                }

                SERVICE_TRIGGER_INFO trigger_info = buf.Result;
                if (trigger_info.cTriggers == 0)
                {
                    return(triggers.AsReadOnly());
                }

                SERVICE_TRIGGER[] trigger_arr;
                using (SafeHGlobalBuffer trigger_buffer = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false))
                {
                    trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers];
                    trigger_buffer.ReadArray(0, trigger_arr, 0, trigger_arr.Length);
                }

                for (int i = 0; i < trigger_arr.Length; ++i)
                {
                    triggers.Add(new ServiceTriggerInformation(trigger_arr[i]));
                }

                return(triggers.AsReadOnly());
            }
        }
Beispiel #3
0
        private void ParseDebugData()
        {
            try
            {
                _debug_data = new DllDebugData();

                IntPtr debug_data = Win32NativeMethods.ImageDirectoryEntryToData(handle, MappedAsImage,
                                                                                 IMAGE_DIRECTORY_ENTRY_DEBUG, out int size);
                if (debug_data == IntPtr.Zero)
                {
                    return;
                }

                SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(debug_data, size, false);
                int count = size / Marshal.SizeOf(typeof(ImageDebugDirectory));

                ImageDebugDirectory[] entries = new ImageDebugDirectory[count];
                buffer.ReadArray(0, entries, 0, count);
                foreach (var debug_dir in entries)
                {
                    if (debug_dir.Type == IMAGE_DEBUG_TYPE_CODEVIEW && debug_dir.AddressOfRawData != 0)
                    {
                        var codeview = new SafeHGlobalBuffer(RvaToVA(debug_dir.AddressOfRawData), debug_dir.SizeOfData, false);
                        _debug_data = new DllDebugData(codeview);
                        break;
                    }
                }
            }
            catch
            {
            }
        }
Beispiel #4
0
 static void ReadArray <T>(IntPtr ptr, int count, out T[] ret) where T : struct
 {
     ret = new T[count];
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(ptr, count * Marshal.SizeOf(typeof(T)), false)) {
         buffer.ReadArray(0, ret, 0, count);
     }
 }
Beispiel #5
0
        internal IkeSecurityAssociation(IKEEXT_SA_DETAILS1 sa_details)
        {
            Id                 = sa_details.saId;
            KeyModuleType      = sa_details.keyModuleType;
            LocalAddress       = FirewallUtils.GetAddress(sa_details.ikeTraffic.ipVersion, sa_details.ikeTraffic.localAddress);
            RemoteAddress      = FirewallUtils.GetAddress(sa_details.ikeTraffic.ipVersion, sa_details.ikeTraffic.remoteAddress);
            InitiatorCookie    = sa_details.cookiePair.initiator;
            ResponderCookie    = sa_details.cookiePair.responder;
            IkePolicyKey       = sa_details.ikePolicyKey;
            VirtualIfTunnelId  = sa_details.virtualIfTunnelId;
            CorrelationKey     = sa_details.correlationKey.ToArray();
            CipherAlgorithm    = sa_details.ikeProposal.cipherAlgorithm.algoIdentifier;
            KeyLength          = sa_details.ikeProposal.cipherAlgorithm.keyLen;
            Rounds             = sa_details.ikeProposal.cipherAlgorithm.rounds;
            IntegrityAlgorithm = sa_details.ikeProposal.integrityAlgorithm.algoIdentifier;
            MaxLifetime        = sa_details.ikeProposal.maxLifetimeSeconds;
            DiffieHellmanGroup = sa_details.ikeProposal.dhGroup;
            QuickModeLimit     = sa_details.ikeProposal.quickModeLimit;

            List <IkeCredentialPair> credentials = new List <IkeCredentialPair>();

            if (sa_details.ikeCredentials.numCredentials > 0)
            {
                SafeHGlobalBuffer buf = new SafeHGlobalBuffer(sa_details.ikeCredentials.credentials, 1, false);
                buf.Initialize <IKEEXT_CREDENTIAL_PAIR1>((uint)sa_details.ikeCredentials.numCredentials);
                var arr = buf.ReadArray <IKEEXT_CREDENTIAL_PAIR1>(0, sa_details.ikeCredentials.numCredentials);
                credentials.AddRange(arr.Select(c => new IkeCredentialPair(c)));
            }
            Credentials = credentials.AsReadOnly();
        }
        private static IReadOnlyList <UserGroup> ReadSids(IntPtr ptr, int count)
        {
            if (ptr == IntPtr.Zero || count == 0)
            {
                return(new List <UserGroup>().AsReadOnly());
            }
            SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(ptr, 1, false);

            buffer.Initialize <SidAndAttributes>((uint)count);
            return(buffer.ReadArray <SidAndAttributes>(0, count).Select(s => s.ToUserGroup()).ToList().AsReadOnly());
        }
        /// <summary>
        /// Get the Win32 services for the SCM.
        /// </summary>
        /// <param name="service_state">The state of the services to return.</param>
        /// <param name="service_types">The types of services to return.</param>
        /// <param name="throw_on_error">True throw on error.</param>
        /// <returns>The list of services.</returns>
        /// <remarks>SCM must have been opened with EnumerateService access.</remarks>
        public NtResult <IEnumerable <Win32Service> > GetServices(ServiceState service_state, ServiceType service_types, bool throw_on_error)
        {
            SERVICE_STATE state;

            switch (service_state)
            {
            case ServiceState.All:
                state = SERVICE_STATE.SERVICE_STATE_ALL;
                break;

            case ServiceState.Active:
                state = SERVICE_STATE.SERVICE_ACTIVE;
                break;

            case ServiceState.InActive:
                state = SERVICE_STATE.SERVICE_INACTIVE;
                break;

            default:
                throw new ArgumentException("Invalid service state", nameof(service_state));
            }

            List <Win32Service> ret_services = new List <Win32Service>();
            const int           Length       = 32 * 1024;

            using (var buffer = new SafeHGlobalBuffer(Length))
            {
                int resume_handle = 0;
                while (true)
                {
                    bool ret = Win32NativeMethods.EnumServicesStatusEx(_handle, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO,
                                                                       service_types, state, buffer, buffer.Length, out int bytes_needed, out int services_returned,
                                                                       ref resume_handle, null);
                    Win32Error error = Win32Utils.GetLastWin32Error();
                    if (!ret && error != Win32Error.ERROR_MORE_DATA)
                    {
                        return(error.CreateResultFromDosError <IEnumerable <Win32Service> >(throw_on_error));
                    }

                    ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned];
                    buffer.ReadArray(0, services, 0, services_returned);
                    ret_services.AddRange(services.Select(s => new Win32Service(_machine_name, s)));
                    if (ret)
                    {
                        break;
                    }
                }
            }
            return(ret_services.CreateResult().Cast <IEnumerable <Win32Service> >());
        }
Beispiel #8
0
        internal FirewallLayer(FWPM_LAYER0 layer, FirewallEngine engine, Func <SecurityInformation, bool, NtResult <SecurityDescriptor> > get_sd)
            : base(layer.layerKey, layer.displayData, NamedGuidDictionary.LayerGuids.Value, engine, get_sd)
        {
            Flags = layer.flags;
            DefaultSubLayerKey = layer.defaultSubLayerKey;
            LayerId            = layer.layerId;
            List <FirewallField> fields = new List <FirewallField>();

            if (layer.numFields > 0 && layer.field != IntPtr.Zero)
            {
                var buffer = new SafeHGlobalBuffer(layer.field, 1, false);
                buffer.Initialize <FWPM_FIELD0>((uint)layer.numFields);
                fields.AddRange(buffer.ReadArray <FWPM_FIELD0>(0, layer.numFields).Select(f => new FirewallField(f)));
            }
            Fields = fields.AsReadOnly();
        }
Beispiel #9
0
        /// <summary>
        /// Get a list of registered services.
        /// </summary>
        /// <returns>A list of running services with process IDs.</returns>
        private static IEnumerable <RunningService> GetServices(SERVICE_STATE service_state)
        {
            using (SafeServiceHandle scm = OpenSCManager(null, null,
                                                         ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.EnumerateService))
            {
                if (scm.IsInvalid)
                {
                    throw new SafeWin32Exception();
                }

                ServiceType service_types = ServiceType.Win32OwnProcess | ServiceType.Win32ShareProcess;
                if (!NtObjectUtils.IsWindows81OrLess)
                {
                    service_types |= ServiceType.UserService;
                }

                const int Length = 32 * 1024;
                using (var buffer = new SafeHGlobalBuffer(Length))
                {
                    int resume_handle = 0;
                    while (true)
                    {
                        bool ret = EnumServicesStatusEx(scm, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, service_types, service_state, buffer,
                                                        buffer.Length, out int bytes_needed, out int services_returned, ref resume_handle, null);
                        int error = Marshal.GetLastWin32Error();
                        if (!ret && error != ERROR_MORE_DATA)
                        {
                            throw new SafeWin32Exception(error);
                        }

                        ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned];
                        buffer.ReadArray(0, services, 0, services_returned);
                        foreach (var service in services)
                        {
                            yield return(new RunningService(service));
                        }

                        if (ret)
                        {
                            break;
                        }
                    }
                }
            }
        }
        internal FirewallFilter(FWPM_FILTER0 filter, FirewallEngine engine, Func <SecurityInformation, bool, NtResult <SecurityDescriptor> > get_sd)
            : base(filter.filterKey, filter.displayData, new NamedGuidDictionary(), engine, get_sd)
        {
            ActionType = filter.action.type;
            if (ActionType.HasFlag(FirewallActionType.Callout))
            {
                CalloutKey     = filter.action.action.calloutKey;
                CalloutKeyName = NamedGuidDictionary.CalloutGuids.Value.GetName(CalloutKey);
            }
            else
            {
                FilterType = filter.action.action.filterType;
            }
            LayerKey        = filter.layerKey;
            LayerKeyName    = NamedGuidDictionary.LayerGuids.Value.GetName(LayerKey);
            SubLayerKey     = filter.subLayerKey;
            SubLayerKeyName = NamedGuidDictionary.SubLayerGuids.Value.GetName(SubLayerKey);
            Flags           = filter.flags;

            List <FirewallFilterCondition> conditions = new List <FirewallFilterCondition>();

            if (filter.numFilterConditions > 0)
            {
                var conds = new SafeHGlobalBuffer(filter.filterCondition, 1, false);
                conds.Initialize <FWPM_FILTER_CONDITION0>((uint)filter.numFilterConditions);
                conditions.AddRange(conds.ReadArray <FWPM_FILTER_CONDITION0>(0, filter.numFilterConditions).Select(c => new FirewallFilterCondition(c)));
            }
            Conditions      = conditions.AsReadOnly();
            Weight          = new FirewallValue(filter.weight, Guid.Empty);
            EffectiveWeight = new FirewallValue(filter.effectiveWeight, Guid.Empty);
            if (filter.providerKey != IntPtr.Zero)
            {
                ProviderKey = filter.providerKey.ReadGuid() ?? Guid.Empty;
            }
            ProviderData = filter.providerData.ToArray();
            FilterId     = filter.filterId;
        }
Beispiel #11
0
        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);
                    }
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Parse the policy from the Local Security Authority.
        /// </summary>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of Central Access Policies.</returns>
        public static NtResult <CentralAccessPolicy[]> ParseFromLsa(bool throw_on_error)
        {
            NtStatus status = SecurityNativeMethods.LsaGetAppliedCAPIDs(null, out SafeLsaMemoryBuffer capids, out int capid_count);

            if (!status.IsSuccess())
            {
                return(status.CreateResultFromError <CentralAccessPolicy[]>(throw_on_error));
            }
            List <CentralAccessPolicy> ret = new List <CentralAccessPolicy>();

            using (capids) {
                status = SecurityNativeMethods.LsaQueryCAPs(capids.DangerousGetHandle(), capid_count, out SafeLsaMemoryBuffer caps, out uint cap_count);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <CentralAccessPolicy[]>(throw_on_error));
                }
                caps.Initialize <CENTRAL_ACCESS_POLICY>(cap_count);
                CENTRAL_ACCESS_POLICY[] policies = new CENTRAL_ACCESS_POLICY[cap_count];
                caps.ReadArray(0, policies, 0, policies.Length);
                foreach (var policy in policies)
                {
                    SafeHGlobalBuffer buffer       = new SafeHGlobalBuffer(policy.CAPEs, policy.CAPECount * IntPtr.Size, false);
                    IntPtr[]          rule_entries = new IntPtr[policy.CAPECount];
                    buffer.ReadArray(0, rule_entries, 0, policy.CAPECount);
                    List <CentralAccessRule> rules = new List <CentralAccessRule>();
                    foreach (var ptr in rule_entries)
                    {
                        var entry                     = new SafeStructureInOutBuffer <CENTRAL_ACCESS_POLICY_ENTRY>(ptr, Marshal.SizeOf(typeof(CENTRAL_ACCESS_POLICY_ENTRY)), false);
                        var r                         = entry.Result;
                        SecurityDescriptor sd         = null;
                        SecurityDescriptor staged_sd  = null;
                        string             applies_to = string.Empty;
                        if (r.LengthSD > 0)
                        {
                            var result = SecurityDescriptor.Parse(r.SD, throw_on_error);
                            if (!result.IsSuccess)
                            {
                                return(result.Cast <CentralAccessPolicy[]>());
                            }
                            sd = result.Result;
                        }
                        if (r.LengthStagedSD > 0)
                        {
                            var result = SecurityDescriptor.Parse(r.StagedSD, throw_on_error);
                            if (!result.IsSuccess)
                            {
                                return(result.Cast <CentralAccessPolicy[]>());
                            }
                            staged_sd = result.Result;
                        }
                        if (r.LengthAppliesTo > 0)
                        {
                            byte[] condition = new byte[r.LengthAppliesTo];
                            Marshal.Copy(r.AppliesTo, condition, 0, r.LengthAppliesTo);
                            var result = NtSecurity.ConditionalAceToString(condition, throw_on_error);
                            if (!result.IsSuccess)
                            {
                                return(result.Cast <CentralAccessPolicy[]>());
                            }
                            applies_to = result.Result;
                        }

                        rules.Add(new CentralAccessRule(r.Name.ToString(), r.Description.ToString(),
                                                        sd, staged_sd, applies_to, r.ChangeId.ToString(), r.Flags));
                    }
                    var capid = Sid.Parse(policy.CAPID, throw_on_error);
                    if (!capid.IsSuccess)
                    {
                        return(capid.Cast <CentralAccessPolicy[]>());
                    }
                    ret.Add(new CentralAccessPolicy(capid.Result, policy.Flags, policy.Name.ToString(),
                                                    policy.Description.ToString(), policy.ChangeId.ToString(), rules));
                }
            }
            return(ret.ToArray().CreateResult());
        }