首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Pinvoke调用UpdateProcThreadAttribute以增强AppContainer安全功能时失败

使用Pinvoke调用UpdateProcThreadAttribute以增强AppContainer安全功能时失败
EN

Stack Overflow用户
提问于 2020-08-28 03:38:26
回答 2查看 217关注 0票数 0

我试图使用C#和pinvoke启动应用程序容器,并通过UpdateProcThreadAttribute()将安全功能设置为属性列表。

GetLastError()返回

87 -无效参数

本文中类似的c++代码(https://scorpiosoftware.net/2019/01/15/fun-with-appcontainers/底部的github链接)运行良好。

代码:(下面是pinvoke structs/enum/externs)

代码语言:javascript
运行
复制
        public bool testAppContainer()
        {
            const uint SE_GROUP_ENABLED = 0x00000004;
            const int ProcThreadAttributeSecurityCapabilities = 0x00020009;
            STARTUPINFOEX startupInfoEx = new STARTUPINFOEX();
            PROCESSINFO pInfo = new PROCESSINFO();
            SECURITY_CAPABILITIES sc = new SECURITY_CAPABILITIES();
            IntPtr pSidInternetClientServer = IntPtr.Zero;

            startupInfoEx.StartupInfo.cb = Marshal.SizeOf(startupInfoEx);

            string appContainerName = "Test.AppContainer";

            try
            {

                //get the size, then the sid
                IntPtr clientServerSid = IntPtr.Zero;  uint cbSid = 0;
                SecurityNative.CreateWellKnownSid(SecurityNative.WELL_KNOWN_SID_TYPE.WinCapabilityInternetClientServerSid, clientServerSid, pSidInternetClientServer, ref cbSid);
                pSidInternetClientServer = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
                if (!CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinCapabilityInternetClientServerSid, clientServerSid, pSidInternetClientServer, ref cbSid))
                {
                    throw new ApplicationException($"Unable to create well known Client Server capability sid!");
                }

                //create an array of one capability
                SID_AND_ATTRIBUTES[] sidAndAttributes = new SID_AND_ATTRIBUTES[1];
                sidAndAttributes[0].Sid = pSidInternetClientServer;
                sidAndAttributes[0].Attributes = SE_GROUP_ENABLED;
                sc.Capabilities = sidAndAttributes;
                sc.CapabilityCount = 1;

                IntPtr appConSid = IntPtr.Zero;

                int hResult = AppContainerNative.DeriveAppContainerSidFromAppContainerName(appContainerName, out appConSid);
                if (hResult < 0)
                {
                    throw new ApplicationException($"Application container {appContainerName} was not found on the machine (err code {hResult})");
                }

                //security capabilities for existing app container
                sc.AppContainerSid = appConSid;

                const int reserved = 0; var size = IntPtr.Zero; int attributeCount = 1;

                bool alreadyInit = ProcessNative.InitializeProcThreadAttributeList(IntPtr.Zero, attributeCount, reserved, ref size);
                if (alreadyInit || size == IntPtr.Zero)
                {
                    throw new Exception(string.Format("Couldn't get the size of the attribute list for {0} attributes", attributeCount));
                }

                startupInfoEx.lpAttributeList = Marshal.AllocHGlobal(size);
                if (startupInfoEx.lpAttributeList == IntPtr.Zero)
                {
                    throw new Exception("Couldn't reserve space for a new attribute list");
                }

                bool initAttributeList = ProcessNative.InitializeProcThreadAttributeList(startupInfoEx.lpAttributeList, attributeCount, reserved, ref size);
                if (!initAttributeList )
                {
                    throw new Exception("Couldn't create new attribute list");
                }
            //also tried this (pass in unmanagedAddr instead of ref sc)
            //    IntPtr unmanagedAddr = Marshal.AllocHGlobal(Marshal.SizeOf(sc));
             //   Marshal.StructureToPtr(sc, unmanagedAddr, true);

                bool success = UpdateProcThreadAttribute(startupInfoEx.lpAttributeList, reserved, (IntPtr)ProcThreadAttributeSecurityCapabilities,
                    ref sc, (IntPtr)Marshal.SizeOf(sc), IntPtr.Zero, IntPtr.Zero);

             //   Marshal.FreeHGlobal(unmanagedAddr);
             //   unmanagedAddr = IntPtr.Zero;

                if (!success)
                {
                    throw new Exception($"Error adding security capabilities to process launch. Error Code: {Marshal.GetLastWin32Error()}");
                }

                var pSec = new SECURITY_ATTRIBUTES(); pSec.nLength = Marshal.SizeOf(pSec);
                var tSec = new SECURITY_ATTRIBUTES(); tSec.nLength = Marshal.SizeOf(tSec);

                success = CreateProcess(null, @"c:\windows\notepad.exe", ref pSec, ref tSec, false, 
                    (uint)ProcessNative.CreateProcessFlags.EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, null, ref startupInfoEx, out pInfo);

                if (success)
                {
                    System.Diagnostics.Debug.WriteLine($"Created new app container process {pInfo.dwProcessId}!");
                    return true;
                }
            }
            finally
            {
                // Free the attribute list
                if (startupInfoEx.lpAttributeList != IntPtr.Zero)
                {
                    ProcessNative.DeleteProcThreadAttributeList(startupInfoEx.lpAttributeList);
                    Marshal.FreeHGlobal(startupInfoEx.lpAttributeList);
                }

                // Close process and thread handles
                if (pInfo.hProcess != IntPtr.Zero)
                {
                    ProcessNative.CloseHandle(pInfo.hProcess);
                }
                if (pInfo.hThread != IntPtr.Zero)
                {
                    ProcessNative.CloseHandle(pInfo.hThread);
                }
                Marshal.FreeHGlobal(startupInfoEx.lpAttributeList);

                if (pSidInternetClientServer != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(pSidInternetClientServer);
            }
            return true;
        }



        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_CAPABILITIES
        {
            public IntPtr AppContainerSid;
            [MarshalAs(UnmanagedType.ByValArray)]
            public SID_AND_ATTRIBUTES[] Capabilities;
            public uint CapabilityCount;
            public uint Reserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SID_AND_ATTRIBUTES
        {
            public IntPtr Sid;
            public UInt32 Attributes;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct PROCESSINFO
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public Int32 dwProcessId;
            public Int32 dwThreadId;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
        public enum WELL_KNOWN_SID_TYPE
        {
            WinNullSid,
            WinWorldSid,
            WinLocalSid,
            WinCreatorOwnerSid,
            WinCreatorGroupSid,
            WinCreatorOwnerServerSid,
            WinCreatorGroupServerSid,
            WinNtAuthoritySid,
            WinDialupSid,
            WinNetworkSid,
            WinBatchSid,
            WinInteractiveSid,
            WinServiceSid,
            WinAnonymousSid,
            WinProxySid,
            WinEnterpriseControllersSid,
            WinSelfSid,
            WinAuthenticatedUserSid,
            WinRestrictedCodeSid,
            WinTerminalServerSid,
            WinRemoteLogonIdSid,
            WinLogonIdsSid,
            WinLocalSystemSid,
            WinLocalServiceSid,
            WinNetworkServiceSid,
            WinBuiltinDomainSid,
            WinBuiltinAdministratorsSid,
            WinBuiltinUsersSid,
            WinBuiltinGuestsSid,
            WinBuiltinPowerUsersSid,
            WinBuiltinAccountOperatorsSid,
            WinBuiltinSystemOperatorsSid,
            WinBuiltinPrintOperatorsSid,
            WinBuiltinBackupOperatorsSid,
            WinBuiltinReplicatorSid,
            WinBuiltinPreWindows2000CompatibleAccessSid,
            WinBuiltinRemoteDesktopUsersSid,
            WinBuiltinNetworkConfigurationOperatorsSid,
            WinAccountAdministratorSid,
            WinAccountGuestSid,
            WinAccountKrbtgtSid,
            WinAccountDomainAdminsSid,
            WinAccountDomainUsersSid,
            WinAccountDomainGuestsSid,
            WinAccountComputersSid,
            WinAccountControllersSid,
            WinAccountCertAdminsSid,
            WinAccountSchemaAdminsSid,
            WinAccountEnterpriseAdminsSid,
            WinAccountPolicyAdminsSid,
            WinAccountRasAndIasServersSid,
            WinNTLMAuthenticationSid,
            WinDigestAuthenticationSid,
            WinSChannelAuthenticationSid,
            WinThisOrganizationSid,
            WinOtherOrganizationSid,
            WinBuiltinIncomingForestTrustBuildersSid,
            WinBuiltinPerfMonitoringUsersSid,
            WinBuiltinPerfLoggingUsersSid,
            WinBuiltinAuthorizationAccessSid,
            WinBuiltinTerminalServerLicenseServersSid,
            WinBuiltinDCOMUsersSid,
            WinBuiltinIUsersSid,
            WinIUserSid,
            WinBuiltinCryptoOperatorsSid,
            WinUntrustedLabelSid,
            WinLowLabelSid,
            WinMediumLabelSid,
            WinHighLabelSid,
            WinSystemLabelSid,
            WinWriteRestrictedCodeSid,
            WinCreatorOwnerRightsSid,
            WinCacheablePrincipalsGroupSid,
            WinNonCacheablePrincipalsGroupSid,
            WinEnterpriseReadonlyControllersSid,
            WinAccountReadonlyControllersSid,
            WinBuiltinEventLogReadersGroup,
            WinNewEnterpriseReadonlyControllersSid,
            WinBuiltinCertSvcDComAccessGroup,
            WinMediumPlusLabelSid,
            WinLocalLogonSid,
            WinConsoleLogonSid,
            WinThisOrganizationCertificateSid,
            WinApplicationPackageAuthoritySid,
            WinBuiltinAnyPackageSid,
            WinCapabilityInternetClientSid,
            WinCapabilityInternetClientServerSid,
            WinCapabilityPrivateNetworkClientServerSid,
            WinCapabilityPicturesLibrarySid,
            WinCapabilityVideosLibrarySid,
            WinCapabilityMusicLibrarySid,
            WinCapabilityDocumentsLibrarySid,
            WinCapabilitySharedUserCertificatesSid,
            WinCapabilityEnterpriseAuthenticationSid,
            WinCapabilityRemovableStorageSid,
            WinBuiltinRDSRemoteAccessServersSid,
            WinBuiltinRDSEndpointServersSid,
            WinBuiltinRDSManagementServersSid,
            WinUserModeDriversSid,
            WinBuiltinHyperVAdminsSid,
            WinAccountCloneableControllersSid,
            WinBuiltinAccessControlAssistanceOperatorsSid,
            WinBuiltinRemoteManagementUsersSid,
            WinAuthenticationAuthorityAssertedSid,
            WinAuthenticationServiceAssertedSid,
            WinLocalAccountSid,
            WinLocalAccountAndAdministratorSid,
            WinAccountProtectedUsersSid,
            WinCapabilityAppointmentsSid,
            WinCapabilityContactsSid,
            WinAccountDefaultSystemManagedSid,
            WinBuiltinDefaultSystemManagedGroupSid,
            WinBuiltinStorageReplicaAdminsSid,
            WinAccountKeyAdminsSid,
            WinAccountEnterpriseKeyAdminsSid,
            WinAuthenticationKeyTrustSid,
            WinAuthenticationKeyPropertyMFASid,
            WinAuthenticationKeyPropertyAttestationSid,
            WinAuthenticationFreshKeyAuthSid,
            WinBuiltinDeviceOwnersSid
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct STARTUPINFOEX
        {
            public STARTUPINFO StartupInfo;
            public IntPtr lpAttributeList;
        }
        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, 
            ref SECURITY_ATTRIBUTES lpThreadAttributes, 
            bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment,  
            string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out PROCESSINFO lpProcessInformation);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, [MarshalAs(UnmanagedType.Struct), In] ref SECURITY_CAPABILITIES caps, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern void DeleteProcThreadAttributeList(IntPtr lpAttributeList);
EN

回答 2

Stack Overflow用户

发布于 2020-08-31 21:07:40

哇,首先,这是一个伟大的工作,我很好奇你是如何利用它(CICD?保安?)。作为一个挑战,我玩了一遍代码,并注意到您对SECURITY_CAPABILITIES结构的声明与微软文档不匹配。他们将Capabilities成员列为指向SID_AND_ATTRIBUTES结构的指针,而不是结构本身。所以,我把它改成了IntPtr .

代码语言:javascript
运行
复制
 [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_CAPABILITIES
    {
        public IntPtr AppContainerSid;
        public IntPtr Capabilities;
        public uint CapabilityCount;
        public uint Reserved;
    }

我不知道如何将一个结构数组封送到一个IntPtr,所以现在我的示例是您列出的单个功能。

代码语言:javascript
运行
复制
           //create one capability
            SID_AND_ATTRIBUTES sidAndAttributes = new SID_AND_ATTRIBUTES();
            sidAndAttributes.Sid = pSidInternetClientServer;
            sidAndAttributes.Attributes = SE_GROUP_ENABLED;
            IntPtr sidAndAttributesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(sidAndAttributes));
            Marshal.StructureToPtr(sidAndAttributes, sidAndAttributesPtr, false);
            sc.Capabilities = sidAndAttributesPtr;
            sc.CapabilityCount = 1;

这使notepad.exe能够以AppContainer完整性启动,并包含您指定的功能标志。

票数 1
EN

Stack Overflow用户

发布于 2020-09-01 00:21:18

谢谢你的回复!我确实让它起作用了。你的建议确实有帮助。这实际上是在一个具有两种功能的应用程序容器中启动一个notepad.exe。以下是所有想要尝试此操作的法警的代码。我的目标是包含一些我们正在使用的程序,以尽可能保护服务器。

代码语言:javascript
运行
复制
    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_CAPABILITIES
    {
        public IntPtr AppContainerSid;

        public IntPtr Capabilities;
        public int CapabilityCount;
        public int Reserved;
    }

     private void AddDefaultCapabilitiesSid(ref SECURITY_CAPABILITIES sc)
    {
        //get the size, then the sid
        IntPtr mem = IntPtr.Zero;
        IntPtr clientServerSid = IntPtr.Zero;
        IntPtr privateNetworkSid = IntPtr.Zero;
        IntPtr pSid = IntPtr.Zero;
        uint cbSid = 0;

        //get the size, then the sid
        SecurityNative.CreateWellKnownSid(SecurityNative.WELL_KNOWN_SID_TYPE.WinCapabilityInternetClientServerSid, pSid, clientServerSid, ref cbSid);
        clientServerSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
        if (!SecurityNative.CreateWellKnownSid(SecurityNative.WELL_KNOWN_SID_TYPE.WinCapabilityInternetClientServerSid, pSid, clientServerSid, ref cbSid))
        {
            throw new ApplicationException($"Unable to create well known Client Server capability sid!");
        }

    
        //get the size, then the sid
        SecurityNative.CreateWellKnownSid(SecurityNative.WELL_KNOWN_SID_TYPE.WinCapabilityPrivateNetworkClientServerSid, pSid, privateNetworkSid, ref cbSid);
        privateNetworkSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
        if (!SecurityNative.CreateWellKnownSid(SecurityNative.WELL_KNOWN_SID_TYPE.WinCapabilityPrivateNetworkClientServerSid, pSid, privateNetworkSid, ref cbSid))
        {
            throw new ApplicationException($"Unable to create well known Client Server capability sid!");
        }

        SecurityNative.SID_AND_ATTRIBUTES[] sidAndAttributes = new SecurityNative.SID_AND_ATTRIBUTES[2];
        sidAndAttributes[0].Sid = clientServerSid;
        sidAndAttributes[0].Attributes = SE_GROUP_ENABLED;
        sidAndAttributes[1].Sid = privateNetworkSid;
        sidAndAttributes[1].Attributes = SE_GROUP_ENABLED;


        int arraySize = sidAndAttributes.Length;
        int elemSize = Marshal.SizeOf(typeof(SecurityNative.SID_AND_ATTRIBUTES));
        IntPtr result = Marshal.AllocHGlobal(elemSize * arraySize);
        mem = new IntPtr(result.ToInt64());
        for (int i = 0; i < arraySize; i++)
        {
            IntPtr ptr = new IntPtr(result.ToInt64() + elemSize * i);
            Marshal.StructureToPtr(sidAndAttributes[i], ptr, false);

            MemToFree.Add(ptr); //free this mem later
        }
        sc.Capabilities = mem;
        sc.CapabilityCount = arraySize;
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63627101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档