■ 사용자 계정 로그온 권한 조사하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


Program.cs

 

 

using System;

using System.Collections.Generic;

 

namespace TestProject

{

    /// <summary>

    /// 프로그램

    /// </summary>

    class Program

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 프로그램 시작하기 - Main()

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

        private static void Main()

        {

            Console.Title = "사용자 계정 로그온 권한 조사하기";

 

            string accountName = "hostname\\username"; // 적절한 계정명을 설정한다.

 

            IList<string> rightList = LocalSecurityAuthorityHelper.GetRightList(accountName);

 

            if(rightList.Contains(LocalSecurityAuthorityRight.LogonAsService))

            {

                Console.WriteLine($"{accountName} 계정은 서비스 로그온 권한을 갖고 있습니다.");

            }

            else

            {

                Console.WriteLine($"{accountName} 계정은 서비스 로그온 권한을 갖고 있지 않습니다.");

            }

        }

 

        #endregion

    }

}

 

 

LocalSecurityAuthorityController.cs

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Runtime.InteropServices;

using System.Text;

 

namespace TestProject

{

    /// <summary>

    /// 로컬 보안 권한 컨트롤러

    /// </summary>

    public class LocalSecurityAuthorityController

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region LSA 접근 정책 - LSA_AccessPolicy

 

        /// <summary>

        /// LSA 접근 정책

        /// </summary>

        [Flags]

        private enum LSA_AccessPolicy : long

        {

            /// <summary>

            /// POLICY_VIEW_LOCAL_INFORMATION

            /// </summary>

            POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,

 

            /// <summary>

            /// POLICY_VIEW_AUDIT_INFORMATION

            /// </summary>

            POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,

 

            /// <summary>

            /// POLICY_GET_PRIVATE_INFORMATION

            /// </summary>

            POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,

 

            /// <summary>

            /// POLICY_TRUST_ADMIN

            /// </summary>

            POLICY_TRUST_ADMIN = 0x00000008L,

 

            /// <summary>

            /// POLICY_CREATE_ACCOUNT

            /// </summary>

            POLICY_CREATE_ACCOUNT = 0x00000010L,

 

            /// <summary>

            /// POLICY_CREATE_SECRET

            /// </summary>

            POLICY_CREATE_SECRET = 0x00000020L,

 

            /// <summary>

            /// POLICY_CREATE_PRIVILEGE

            /// </summary>

            POLICY_CREATE_PRIVILEGE = 0x00000040L,

 

            /// <summary>

            /// POLICY_SET_DEFAULT_QUOTA_LIMITS

            /// </summary>

            POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,

 

            /// <summary>

            /// POLICY_SET_AUDIT_REQUIREMENTS

            /// </summary>

            POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,

 

            /// <summary>

            /// POLICY_AUDIT_LOG_ADMIN

            /// </summary>

            POLICY_AUDIT_LOG_ADMIN = 0x00000200L,

 

            /// <summary>

            /// POLICY_SERVER_ADMIN

            /// </summary>

            POLICY_SERVER_ADMIN = 0x00000400L,

 

            /// <summary>

            /// POLICY_LOOKUP_NAMES

            /// </summary>

            POLICY_LOOKUP_NAMES = 0x00000800L,

 

            /// <summary>

            /// POLICY_NOTIFICATION

            /// </summary>

            POLICY_NOTIFICATION = 0x00001000L

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Structure

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region LSA 유니코드 문자열 - LSA_UNICODE_STRING

 

        /// <summary>

        /// LSA 유니코드 문자열

        /// </summary>

        [StructLayout(LayoutKind.Sequential)]

        private struct LSA_UNICODE_STRING

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 길이

            /// </summary>

            public ushort Length;

 

            /// <summary>

            /// 최대 길이

            /// </summary>

            public ushort MaximumLength;

 

            /// <summary>

            /// 버퍼 핸들

            /// </summary>

            public IntPtr Buffer;

 

            #endregion

        }

 

        #endregion

        #region LSA 객체 어트리뷰트 - LSA_OBJECT_ATTRIBUTES

 

        /// <summary>

        /// LSA 객체 어트리뷰트

        /// </summary>

        [StructLayout(LayoutKind.Sequential)]

        private struct LSA_OBJECT_ATTRIBUTES

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Field

 

            #region Field

 

            /// <summary>

            /// 길이

            /// </summary>

            public int Length;

 

            /// <summary>

            /// 루트 디렉토리

            /// </summary>

            public IntPtr RootDirectory;

 

            /// <summary>

            /// 객체명

            /// </summary>

            public LSA_UNICODE_STRING ObjectName;

 

            /// <summary>

            /// 어트리뷰트

            /// </summary>

            public uint Attributes;

 

            /// <summary>

            /// 보안 설명자

            /// </summary>

            public IntPtr SecurityDescriptor;

 

            /// <summary>

            /// 서비스 보안 품질

            /// </summary>

            public IntPtr SecurityQualityOfService;

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region LSA 정책 열기 - LsaOpenPolicy(systemName, objectAttributes, desiredAccess, policyHandle)

 

        /// <summary>

        /// LSA 정책 열기

        /// </summary>

        /// <param name="systemName">시스템명</param>

        /// <param name="objectAttributes">객체 어트리뷰트</param>

        /// <param name="desiredAccess">희망 액세스</param>

        /// <param name="policyHandle">정책 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("advapi32.dll", PreserveSig = true)]

        private static extern uint LsaOpenPolicy(ref LSA_UNICODE_STRING systemName, ref LSA_OBJECT_ATTRIBUTES objectAttributes,

            Int32 desiredAccess, out IntPtr policyHandle);

 

        #endregion

        #region LSA 계정 권리 추가하기 - LsaAddAccountRights(policyHandle, accountSID, userRightArray, rightCount)

 

        /// <summary>

        /// LSA 계정 권리 추가하기

        /// </summary>

        /// <param name="policyHandle">정책 핸들</param>

        /// <param name="accountSID">계정 SID</param>

        /// <param name="userRightArray">사용자 권리 배열</param>

        /// <param name="rightCount">권리 수</param>

        /// <returns>처리 결과</returns>

        [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]

        private static extern uint LsaAddAccountRights(IntPtr policyHandle, IntPtr accountSID, LSA_UNICODE_STRING[] userRightArray,

            int rightCount);

 

        #endregion

        #region SID 해제하기 - FreeSid(sidHandle)

 

        /// <summary>

        /// SID 해제하기

        /// </summary>

        /// <param name="sidHandle">SID 핸들</param>

        [DllImport("advapi32")]

        private static extern void FreeSid(IntPtr sidHandle);

 

        #endregion

        #region 계정명 찾기 - LookupAccountName(systemName, accountName, sidHandle, sidSize, domainName, domainLength, use)

 

        /// <summary>

        /// 계정명 찾기

        /// </summary>

        /// <param name="systemName">시스템명</param>

        /// <param name="accountName">계정명</param>

        /// <param name="sidHandle">SID 핸들</param>

        /// <param name="sidSize">SID 크기</param>

        /// <param name="domainName">도메인명</param>

        /// <param name="domainLength">도메인 길이</param>

        /// <param name="use">사용</param>

        /// <returns>처리 결과</returns>

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, PreserveSig = true)]

        private static extern bool LookupAccountName(string systemName, string accountName, IntPtr sidHandle, ref int sidSize,

            StringBuilder domainName, ref int domainLength, ref int use);

 

        #endregion

        #region SID 무결성 여부 구하기 - IsValidSid(sidHandle)

 

        /// <summary>

        /// SID 무결성 여부 구하기

        /// </summary>

        /// <param name="sidHandle">SID 핸들</param>

        /// <returns>SID 무결성 여부</returns>

        [DllImport("advapi32.dll")]

        private static extern bool IsValidSid(IntPtr sidHandle);

 

        #endregion

        #region LSA 닫기 - LsaClose(objectHandle)

 

        /// <summary>

        /// LSA 닫기

        /// </summary>

        /// <param name="objectHandle">객체 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("advapi32.dll")]

        private static extern int LsaClose(IntPtr objectHandle);

 

        #endregion

        #region 마지막 에러 구하기 - GetLastError()

 

        /// <summary>

        /// 마지막 에러 구하기

        /// </summary>

        /// <returns>에러 코드</returns>

        [DllImport("kernel32.dll")]

        private static extern int GetLastError();

 

        #endregion

        #region LSA NT 상태에서 윈도우즈 에러 코드 구하기 - LsaNtStatusToWinError(status)

 

        /// <summary>

        /// LSA NT 상태에서 윈도우즈 에러 코드 구하기

        /// </summary>

        /// <param name="status">상태</param>

        /// <returns>윈도우즈 에러 코드</returns>

        [DllImport("advapi32.dll")]

        private static extern int LsaNtStatusToWinError(uint status);

 

        #endregion

        #region LSA 계정 권리 열거하기 - LsaEnumerateAccountRights(policyHandle, accountSID, userRightHandle, rightCount)

 

        /// <summary>

        /// LSA 계정 권리 열거하기

        /// </summary>

        /// <param name="policyHandle">정책 핸들</param>

        /// <param name="accountSID">계정 SID</param>

        /// <param name="userRightHandle">사용자 권리 핸들</param>

        /// <param name="rightCount">권리 수</param>

        /// <returns>처리 결과</returns>

        [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]

        private static extern uint LsaEnumerateAccountRights(IntPtr policyHandle, IntPtr accountSID, out IntPtr userRightHandle,

            out int rightCount);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 액세스

        /// </summary>

        private const int Access = (int)

        (

            LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN          |

            LSA_AccessPolicy.POLICY_CREATE_ACCOUNT           |

            LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE         |

            LSA_AccessPolicy.POLICY_CREATE_SECRET            |

            LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION  |

            LSA_AccessPolicy.POLICY_LOOKUP_NAMES             |

            LSA_AccessPolicy.POLICY_NOTIFICATION             |

            LSA_AccessPolicy.POLICY_SERVER_ADMIN             |

            LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS   |

            LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |

            LSA_AccessPolicy.POLICY_TRUST_ADMIN              |

            LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION   |

            LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION

        );

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 권리 리스트 구하기 - GetRightList(accountName)

 

        /// <summary>

        /// 권리 리스트 구하기

        /// </summary>

        /// <param name="accountName">계정명</param>

        /// <returns>권리 리스트</returns>

        public IList<string> GetRightList(string accountName)

        {

            IList<string> rightList = new List<string>();

 

            long   errorCode    = 0;

            string errorMessage = string.Empty;

 

            IntPtr sidHandle     = IntPtr.Zero;

            int    sidHandleSize = 0;

 

            StringBuilder domainNameStringBuilder = new StringBuilder();

 

            int domainNameSize = 0;

            int accountType    = 0;

 

            LookupAccountName(string.Empty, accountName, sidHandle, ref sidHandleSize, domainNameStringBuilder, ref domainNameSize,

                ref accountType);

 

            domainNameStringBuilder = new StringBuilder(domainNameSize);

 

            sidHandle = Marshal.AllocHGlobal(sidHandleSize);

 

            if(!LookupAccountName(string.Empty, accountName, sidHandle, ref sidHandleSize, domainNameStringBuilder, ref domainNameSize,

                ref accountType))

            {

                errorCode = GetLastError();

 

                errorMessage = ("LookupAccountName failed : " + errorCode);

 

                throw new Win32Exception((int)errorCode, errorMessage);

            }

            else

            {

                LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();

 

                IntPtr policyHandle    = IntPtr.Zero;

                IntPtr userRightHandle = IntPtr.Zero;

 

                int rightCount = 0;

 

                LSA_OBJECT_ATTRIBUTES objectAttributes = CreateLSAObject();

 

                uint policyStatus = LsaOpenPolicy(ref systemName, ref objectAttributes, Access, out policyHandle);

 

                errorCode = LsaNtStatusToWinError(policyStatus);

 

                if(errorCode != 0)

                {

                    errorMessage = string.Format("OpenPolicy failed : {0}.", errorCode);

 

                    throw new Win32Exception((int)errorCode, errorMessage);

                }

                else

                {

                    try

                    {

                        uint result = LsaEnumerateAccountRights(policyHandle, sidHandle, out userRightHandle, out rightCount);

 

                        errorCode = LsaNtStatusToWinError(result);

 

                        if(errorCode != 0)

                        {

                            if(errorCode == 2)

                            {

                                return new List<string>();

                            }

 

                            errorMessage = string.Format("LsaEnumerateAccountRights failed : {0}", errorCode);

 

                            throw new Win32Exception((int)errorCode, errorMessage);

                        }

 

                        long userRightHandleValue = userRightHandle.ToInt64();

 

                        LSA_UNICODE_STRING userRight;

 

                        for(int i = 0; i < rightCount; i++)

                        {

                            userRight = (LSA_UNICODE_STRING)Marshal.PtrToStructure(new IntPtr(userRightHandleValue),

                                typeof(LSA_UNICODE_STRING));

 

                            string userRightString = Marshal.PtrToStringAuto(userRight.Buffer);

 

                            rightList.Add(userRightString);

 

                            userRightHandleValue += Marshal.SizeOf(userRight);

                        }

                    }

                    finally

                    {

                        LsaClose(policyHandle);

                    }

                }

 

                FreeSid(sidHandle);

            }

 

            return rightList;

        }

 

        #endregion

        #region 권리 설정하기 - SetRight(accountName, privilegeName)

 

        /// <summary>

        /// 권리 설정하기

        /// </summary>

        /// <param name="accountName">계정명</param>

        /// <param name="privilegeName">특권명</param>

        public void SetRight(string accountName, string privilegeName)

        {

            long   errorCode    = 0;

            string errorMessage = string.Empty;

 

            IntPtr sidHandle     = IntPtr.Zero;

            int    sidHandleSize = 0;

 

            StringBuilder domainNameStringBuilder = new StringBuilder();

 

            int domainNameSize = 0;

            int accountType    = 0;

 

            LookupAccountName(String.Empty, accountName, sidHandle, ref sidHandleSize, domainNameStringBuilder, ref domainNameSize,

                ref accountType);

 

            domainNameStringBuilder = new StringBuilder(domainNameSize);

 

            sidHandle = Marshal.AllocHGlobal(sidHandleSize);

 

            if(!LookupAccountName(string.Empty, accountName, sidHandle, ref sidHandleSize, domainNameStringBuilder, ref domainNameSize,

                ref accountType))

            {

                errorCode = GetLastError();

 

                errorMessage = string.Format("LookupAccountName failed : {0}", errorCode);

 

                throw new Win32Exception((int)errorCode, errorMessage);

            }

            else

            {

                LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();

 

                IntPtr policyHandle = IntPtr.Zero;

 

                LSA_OBJECT_ATTRIBUTES objectAttributes = CreateLSAObject();

 

                uint resultPolicy = LsaOpenPolicy(ref systemName, ref objectAttributes, Access, out policyHandle);

 

                errorCode = LsaNtStatusToWinError(resultPolicy);

 

                if(errorCode != 0)

                {

                    errorMessage = string.Format("OpenPolicy failed : {0} ", errorCode);

 

                    throw new Win32Exception((int)errorCode, errorMessage);

                }

                else

                {

                    try

                    {

                        LSA_UNICODE_STRING[] userRightArray = new LSA_UNICODE_STRING[1];

 

                        userRightArray[0] = new LSA_UNICODE_STRING();

 

                        userRightArray[0].Buffer        = Marshal.StringToHGlobalUni(privilegeName);

                        userRightArray[0].Length        = (ushort)(privilegeName.Length * UnicodeEncoding.CharSize);

                        userRightArray[0].MaximumLength = (ushort)((privilegeName.Length + 1) * UnicodeEncoding.CharSize);

 

                        uint result = LsaAddAccountRights(policyHandle, sidHandle, userRightArray, 1);

 

                        errorCode = LsaNtStatusToWinError(result);

 

                        if(errorCode != 0)

                        {

                            errorMessage = string.Format("LsaAddAccountRights failed : {0}", errorCode);

 

                            throw new Win32Exception((int)errorCode, errorMessage);

                        }

                    }

                    finally

                    {

                        LsaClose(policyHandle);

                    }

                }

 

                FreeSid(sidHandle);

            }

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region LSA 객체 생성하기 - CreateLSAObject()

 

        /// <summary>

        /// LSA 객체 생성하기

        /// </summary>

        /// <returns>LSA 객체 어트리뷰트</returns>

        private static LSA_OBJECT_ATTRIBUTES CreateLSAObject()

        {

            LSA_OBJECT_ATTRIBUTES newInstance = new LSA_OBJECT_ATTRIBUTES();

 

            newInstance.Length                   = 0;

            newInstance.RootDirectory            = IntPtr.Zero;

            newInstance.Attributes               = 0;

            newInstance.SecurityDescriptor       = IntPtr.Zero;

            newInstance.SecurityQualityOfService = IntPtr.Zero;

 

            return newInstance;

        }

 

        #endregion

    }

}

 

 

LocalSecurityAuthorityRight.cs

 

 

namespace TestProject

{

    /// <summary>

    /// 로컬 보안 권한 권리

    /// </summary>

    public class LocalSecurityAuthorityRight

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region Field

 

        /// <summary>

        /// 서비스 로그온

        /// </summary>

        public const string LogonAsService = "SeServiceLogonRight";

 

        /// <summary>

        /// 배치 작업 로그온

        /// </summary>

        public const string LogonAsBatchJob = "SeBatchLogonRight";

 

        /// <summary>

        /// 대화형 로그온

        /// </summary>

        public const string InteractiveLogon = "SeInteractiveLogonRight";

 

        /// <summary>

        /// 네트워크 로그온

        /// </summary>

        public const string NetworkLogon = "SeNetworkLogonRight";

 

        /// <summary>

        /// 보안 감사 생성

        /// </summary>

        public const string GenerateSecurityAudits = "SeAuditPrivilege";

 

        #endregion

    }

}

 

 

LocalSecurityAuthorityHelper.cs

 

 

using System.Collections.Generic;

 

namespace TestProject

{

    /// <summary>

    /// 로컬 보안 권한 헬퍼

    /// </summary>

    public static class LocalSecurityAuthorityHelper

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 권리 리스트 구하기 - GetRightList(accountName)

 

        /// <summary>

        /// 권리 리스트 구하기

        /// </summary>

        /// <param name="accountName">계정명</param>

        /// <returns>권리 리스트</returns>

        public static IList<string> GetRightList(string accountName)

        {

            return new LocalSecurityAuthorityController().GetRightList(accountName);

        }

 

        #endregion

        #region 권리 설정하기 - SetRight(accountName, privilegeName)

 

        /// <summary>

        /// 권리 설정하기

        /// </summary>

        /// <param name="accountName">계정명</param>

        /// <param name="privilegeName">특권명</param>

        public static void SetRight(string accountName, string privilegeName)

        {

            new LocalSecurityAuthorityController().SetRight(accountName, privilegeName);

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

※ 관리자 권한으로 실행한다.

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요