滥用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注册表项的权限。

原文地址:https://www.cnblogs.com/backlion/p/9888851.html

时间: 2024-11-06 07:15:15

滥用DNSAdmins权限进行Active Directory提权的相关文章

kali权限提升之本地提权

系统账号之间权限隔离 操作系统的安全基础 用户空间 内核空间 系统账号: 用户账号登陆时候获取权限令牌 服务账号无需用户登录已在后台启动服务 windows用户全权限划分: Users:普通用户组,Users 组是最安全的组,因为分配给该组的默认权限不允许成员修改操作系统的设置或用户资料 Administrators:管理员组,默认情况下,Administrators中的用户对计算机/域有不受限制的完全访问权.分配给该组的默认权限允许对整个系统进行完全控制 System:拥有和Administr

Linux命令sudo实现集权(提权)管理,防止超级权限泛滥

sudo小结1.别名要用大写2.使用"\"换行3.使用白名单策略,尽量不要赋予ALL权限(建议先关后开)4.禁止的权限放在最后,允许的权限放在前面,sudoers配置文件的权限匹配时从后到前的5.成员必须是存在的(用户必须存在)6."!"表示禁止权限7.命令.组员.组等,用","分隔开(英文逗号)8.组前面一定要带"%" su命令缺点1.普通用户需要知道root密码,并且切换到root用户下,才能使用root权限(超级权限)2

提权笔记本

/* 转载请注明出处 ID:珍惜少年时 */ 21------------FTP //找到其FTP目录,破解其密码搜索,提之 22------------linux终端 23------------telnet //可以爆破,然后dos连接之,连接后添加用户开启终端端口,然后宣告拿下! 1433----------mssql提权 //需要找到sa密码,一般存在于web.config文件中,uid pwd sa为关键字,找到该文件后Ctrl+f搜索关键字提之 3306----------mysql

Linux 的计划任务(运维基础|可用于提权)

Linux操作系统定时任务系统 Cron 入门 先写笔记: crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 crontab -l //列出某个用户cron服务的详细内容 crontab -r //删除没个用户的cron服务 crontab -e //编辑某个用户的cron服务 看存在的的计划启动, 可以直接编辑相应的启动项, 添加自己想要的命令 ,因为cron默认是ROOT权限 可以用这个提权 eg: rontab -l59 1 * * *

利用linux漏洞提权

提权就是让普通用户拥有超级用户的权限. 本次试验漏洞适用于RHELt或CenOS系列5~6系列所有版本.主要利用/tmp/目录和/bin/ping命令的权限漏洞进行提权.     试验环境:腾讯云CentOS6.8     内核:2.6.32-642.6.2.el6.x86_64 1.查看系统环境 2.创建普通用户进行权限测试 3.开始提权操作     写一段C语言,用于提权     提权成功 最终执行完命令之后,可以看到执行权限变成了root,提权成功.

Ubuntu无法sudo提权,报当前用户不在sudoers文件中错误

Ubuntu安装后默认root不能登陆系统,密码也是随机生成,其他用户使用root权限,可以使用sudo提权,前提是该用户在/etc/sudoers配置列表中. 但是有时用户名从/etc/sudoers被意外删除了,sudo不能用了,root又不知道root密码(之前没有改过或者忘记了),如果想修改/etc/sudoers也不可能了,进入了一个死循环. 但可以如下面的方法解决: 1.重启按shift键,进入Ubuntu高级模式,选择一个recovery mode进入,出现一个9个选项的菜单,如果

提权系列(一)----Windows Service 服务器提权初识与exp提权,mysql提权

一.初识提权 很多时候我们入侵一个网站的时候,想要的是得到这个服务器的权限,也就是admin权限,但是一般默认得到的是普通用的地权限,权限很小,所以就要通过其他手段,提升自己的权限. 提权是将服务器的普通用户提升为管理员用户的一种操作,提权常常用于辅助旁注攻击. 下面我们来了解下window的权限(来自百度百科): Windows 提供了非常细致的权限控制项,能够精确定制用户对资源的访问控制能力,大多数的权限从其名称上就可以基本了解其所能实现的内容. " 权限"(Permission)

[转帖]提权

windows提权 https://www.cnblogs.com/v01cano/p/10317458.html 之前一直不太理解 感觉作者写的很好记录一下. 0,起因,由于前几天拿了一个菠菜站的webshell,但是只有iis权限,执行无法创建用户等操作,更无法对整个服务器进行控制了,于是此时便需要提权了,对于一个刚刚入门的小白来说,此刻真正意识到了提权的重要性,于是便开始学习提取相关知识,以拿下该菠菜的站点. 提权前的准备工作 1,通常来说,不同的脚本所处的权限是不一样的.这就意味着,如果

vunlhub-DC-1-LinuxSuid提权

将靶场搭建起来 桥接看不到IP 于是用masscan 进行C段扫描 试试80 8080 访问之后发现是个drupal 掏出msf搜索一波 使用最近年限的exp尝试 exploit/unix/webapp/drupal_drupalgeddon2 攻击成功 返回meterpreter的shell 进行简单的信息收集 发现并不是root权限 ,想办法进行提权,首先执行常用的Linux提权检查工具 ./Linux_Exploit_Suggester.pl 并没有返回可用的提权建议 于是用searchs