첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.01MB

▶ SECURITY_IMPERSONATION_LEVEL.cs

namespace TestProject
{
    /// <summary>
    /// 보안 가장 레벨
    /// </summary>
    public enum SECURITY_IMPERSONATION_LEVEL
    {
        /// <summary>
        /// SecurityAnonymous
        /// </summary>
        SecurityAnonymous = 0,

        /// <summary>
        /// SecurityIdentification
        /// </summary>
        SecurityIdentification = 1,

        /// <summary>
        /// SecurityImpersonation
        /// </summary>
        SecurityImpersonation = 2,

        /// <summary>
        /// SecurityDelegation
        /// </summary>
        SecurityDelegation = 3
    }
}

 

728x90

 

▶ TOKEN_TYPE.cs

namespace TestProject
{
    /// <summary>
    /// 토큰 타입
    /// </summary>
    public enum TOKEN_TYPE
    {
        /// <summary>
        /// TokenPrimary
        /// </summary>
        TokenPrimary = 1,

        /// <summary>
        /// TokenImpersonation
        /// </summary>
        TokenImpersonation = 2
    }
}

 

300x250

 

▶ Program.cs

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading;

namespace TestProject
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 사용자 로그온하기 - LogonUser(userName, domain, password, logonType, logonProvider, userToken)

        /// <summary>
        /// 사용자 로그온하기
        /// </summary>
        /// <param name="userName">사용자명</param>
        /// <param name="domain">도메인</param>
        /// <param name="password">패스워드</param>
        /// <param name="logonType">로그온 타입</param>
        /// <param name="logonProvider">로그온 공급자</param>
        /// <param name="userToken">사용자 토큰</param>
        /// <returns>처리 결과</returns>
        [DllImport("advapi32", EntryPoint = "LogonUser", SetLastError = true)]
        private static extern bool LogonUser(string userName, string domain, string password, int logonType, int logonProvider, out IntPtr userToken);

        #endregion
        #region 토큰 복제하기 (확장) - DuplicateTokenEx(existingTokenHandle, desiredAccess, threadAttributeHandle, tokenType, impersonationLevel, duplicateTokenHandle)

        /// <summary>
        /// 토큰 복제하기 (확장)
        /// </summary>
        /// <param name="existingTokenHandle">기존 토클 핸들</param>
        /// <param name="desiredAccess">희망 액세스</param>
        /// <param name="threadAttributeHandle">스레드 어트리뷰트 핸들</param>
        /// <param name="tokenType">토큰 타입</param>
        /// <param name="impersonationLevel">가장 레벨</param>
        /// <param name="duplicateTokenHandle">복제 토큰 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("advapi32", EntryPoint = "DuplicateTokenEx")]
        private static extern bool DuplicateTokenEx
        (
            IntPtr     existingTokenHandle,
            uint       desiredAccess,
            IntPtr     threadAttributeHandle,
            int        tokenType,
            int        impersonationLevel,
            ref IntPtr duplicateTokenHandle
        );

        #endregion
        #region 스레드 토큰 설정하기 - SetThreadToken(threadHandle, tokenHandle)

        /// <summary>
        /// 스레드 토큰 설정하기
        /// </summary>
        /// <param name="threadHandle">스레드 핸들</param>
        /// <param name="tokenHandle">토큰 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("advapi32", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetThreadToken(IntPtr threadHandle, IntPtr tokenHandle);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

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

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            Console.WriteLine($"Main 함수 : {WindowsIdentity.GetCurrent().Name}");

            IntPtr userTokenHandle;

            LogonUser("user2", ".", "password2", 8, 0, out userTokenHandle);

            IntPtr copyUserTokenHandle = IntPtr.Zero;

            DuplicateTokenEx
            (
                userTokenHandle,
                0,
                IntPtr.Zero,
                (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                (int)TOKEN_TYPE.TokenImpersonation,
                ref copyUserTokenHandle
            );

            Thread thread = new Thread(new ParameterizedThreadStart(ExecuteThread));

            thread.Start(copyUserTokenHandle);
        }

        #endregion
        #region 스레드 실행하기 - ExecuteThread(parameter)

        /// <summary>
        /// 스레드 실행하기
        /// </summary>
        /// <param name="parameter">매개 변수</param>
        private static void ExecuteThread(object parameter)
        {
            IntPtr userTokenHandle = (IntPtr)parameter;

            SetThreadToken(IntPtr.Zero, userTokenHandle);

            WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();

            Console.WriteLine($"ProcessThread 함수 : {WindowsIdentity.GetCurrent().Name}");
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요