freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

域渗透-横向移动(PTH)
2021-11-14 14:49:07

一. Windows本地认证

基础知识

  • Windows内部是不保存明文密码的,只保存密码的hash。
  • 本机用户的密码hash是放在本地的SAM文件 里面,域内用户的密码hash是存在域控的NTDS.DIT文件里面。
  • SAM文件位置:%SystemRoot%\system32\config\sam
  • 当我们登录系统的时候,系统会自动地读取SAM文件中的“密码”与我们输入的“密码”进行对比,如果相同,则认证成功。

密码格式

Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0:::

其中AAD3B435B51404EEAAD3B435B51404EE是LM Hash而31D6CFE0D16AE931B73C59D7E0C089C0是NTLM Hash。

1.1. LM HASH

全称是:LAN Manager Hash, windows最早用的加密算法,由IBM设计。

LM Hash计算

  1. 用户的密码转换为大写,密码转换为16进制字符串,不足14字节将会用0来再后面补全。
  2. 密码的16进制字符串被分成两个7byte部分。每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度
  1. 再分7bit为一组,每组末尾加0,再组成一组。
  2. 上步骤得到的二组,分别作为key 为 “KGS!@#$%”进行DES加密。
  1. 将加密后的两组拼接在一起,得到最终LM HASH值。

    #coding=utf-8
    import re
    import binascii
    from pyDes import *
    def DesEncrypt(str, Des_Key):
    k = des(binascii.a2b_hex(Des_Key), ECB, pad=None)
    EncryptStr = k.encrypt(str)
    return binascii.b2a_hex(EncryptStr)

    def group_just(length,text):
    # text 00110001001100100011001100110100001101010011011000000000
    text_area = re.findall(r'.{%d}' % int(length), text) # ['0011000', '1001100', '1000110', '0110011', '0100001', '1010100', '1101100', '0000000']
    text_area_padding = [i + '0' for i in text_area] #['00110000', '10011000', '10001100', '01100110', '01000010', '10101000', '11011000', '00000000']
    hex_str = ''.join(text_area_padding) # 0011000010011000100011000110011001000010101010001101100000000000
    hex_int = hex(int(hex_str, 2))[2:].rstrip("L") #30988c6642a8d800
    if hex_int == '0':
    hex_int = '0000000000000000'
    return hex_int

    def lm_hash(password):
    # 1. 用户的密码转换为大写,密码转换为16进制字符串,不足14字节将会用0来再后面补全。
    pass_hex = password.upper().encode("hex").ljust(28,'0') #3132333435360000000000000000
    print(pass_hex) 
    # 2. 密码的16进制字符串被分成两个7byte部分。每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度
    left_str = pass_hex[:14] #31323334353600
    right_str = pass_hex[14:] #00000000000000
    left_stream = bin(int(left_str, 16)).lstrip('0b').rjust(56, '0') # 00110001001100100011001100110100001101010011011000000000
    right_stream = bin(int(right_str, 16)).lstrip('0b').rjust(56, '0') # 00000000000000000000000000000000000000000000000000000000
    # 3. 再分7bit为一组,每组末尾加0,再组成一组
    left_stream = group_just(7,left_stream) # 30988c6642a8d800
    right_stream = group_just(7,right_stream) # 0000000000000000
    # 4. 上步骤得到的二组,分别作为key 为 "KGS!@#$%"进行DES加密。
    left_lm = DesEncrypt('KGS!@#$%',left_stream) #44efce164ab921ca
    right_lm = DesEncrypt('KGS!@#$%',right_stream) # aad3b435b51404ee
    # 5. 将加密后的两组拼接在一起,得到最终LM HASH值。
    return left_lm + right_lm

    if __name__ == '__main__':
    hash = lm_hash("123456")

加密算法漏洞

  1. 首先,密码长度最大只能为14个字符
  2. 密码不区分大小写。在生成哈希值之前,所有密码都将转换为大写
  1. 查看我们的加密过程,就可以看到使用的是分组的DES,如果密码强度是小于7位,那么第二个分组加密后的结果肯定是aad3b435b51404ee,如果我们看到lm hash的结尾是aad3b435b51404ee,就可以很轻易的发现密码强度少于7位
  2. 一个14个字符的密码分成7 + 7个字符,并且分别为这两个半部分计算哈希值。这种计算哈希值的方式使破解难度成倍增加,因为攻击者需要将7个字符(而不是14个字符)强制暴力破解。这使得14个字符的密码的有效强度等于,或者是7个字符的密码的两倍,该密码的复杂度明显低于14个字符的密码的理论强度。
  1. Des密码强度不高

1.2. NTLM HASH

为了解决LM加密和身份验证方案中固有的安全弱点,Microsoft 于1993年在Windows NT 3.1中引入了NTLM协议。

系统版本对LM和NTLM的支持

2000

XP

2003

Vista

Win7

2008

Win8

2012

LM

X

X

X



NTLM

X

X

X

X

X

X

X

X

注:X:当密码超过14位时使用的加密方式 X:系统默认使用的加密方式

从Windows Vista 和 Windows Server 2008开始,默认情况下只存储NTLM Hash,LM Hash将不再存在。

如果空密码或者不储蓄LM Hash的话,一般抓到的LM Hash是AAD3B435B51404EEAAD3B435B51404EE(win7)这里的LM Hash并没有价值。

Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
laosec:1000:aad3b435b51404eeaad3b435b51404ee:4ed9fa78b52edf56286dc7fac36d5742:::

抓取Win7 NTLM HASH

mimikatz
privilege::debug
sekurlsa::logonpasswords

NTML HASH计算

  1. 先将用户密码转换为十六进制格式。
  2. 将十六进制格式的密码进行Unicode编码。
  1. 使用MD4摘要算法对Unicode编码数据进行Hash计算。
admin -> hex(16进制编码) = 61646d696e
61646d696e -> Unicode = 610064006d0069006e00
610064006d0069006e00 -> MD4 = 209c6174da490caeb422f3fa5a7ae634

1.3. 本地认证流程

Windows Logon Process

即 winlogon.exe,是Windows NT 用户登陆程序,用于管理用户登录和退出。

LSASS

本地安全认证子系统服务,用于微软Windows系统的安全机制。负责用户在本地验证或远程登陆时验证用户身份,管理用户密码变更,并产生访问日志。

整体流程

  • 开机
  • winlogon.exe显示输入用户名密码的图形化页面
  • 用户输入用户名密码,winlogon.exe进程将输入信息交付给lsass.exe进程
  • lsass.exe将密码加密为NTLM Hash,并与本地SAM数据库中的NTLM Hash进行比较
  • 如果相同,则认证通过

二、Windows网络认证

2.1. 实验1:MSF进行PTH攻击

步骤一. 在已经获取的Meterpreter shell下抓取NTML HASH

步骤二. 调用psexec模块,设置好选项进行登录。

实验结果:

实验问题

1:靶机Win7

1)共享服务不允许远程访问

将注册表中LocalAccountTokenFilterPolicy的值更改为1,如果没有该文件,直接新建一个(DWORD32位)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

2:靶机Winxp

1)连接拒绝

开启Windows XP 的445端口和Server服务

2)登陆失败

检测SMBPass的值是否正确.依次打开本地计算机策略 - >计算机配置 - > Windows设置 - >安全设置 - >本地策略 - >安全选项修改网络访问:本地帐户的共享和安全模式经典 - 本地用户身份验证

疑问解决

SMB协议是Windows网络中用来存取远程文件的通讯协议.

2.2. 实验2:Mimikatz进行PTH攻击

2.3. Pass The Hash攻击原理

验证的整个过程中缺少了一样重要的东西,也就是在故事背景中埋下过的一个小伏笔:windows本身不存储明文密码

PTH原理

根据结果逆推:如果需要正确的response(蓝色)来通过认证,因为response本质上也是Net NTLM Hash(红色)根据公式“Net NTLM Hash = NTLM Hash(Challenge)”,我们需要正确的NTLM Hash(黄色)和Challenge(绿色)。而由于Challenge是服务端发送给,只要我们拥有正确的NTLM Hash,即可通过认证,无需明文密码!简单来说:哈希传递是能够在不需要账户明文密码的情况下完成认证的一个技术。

基于上述逆推结果,诞生了Pass The Hash(即hash传递攻击)

应用场景

内网渗透中获取不到明文密码、破解不了NTLM Hash而又想扩大战果横向移动。

必要条件

  • 需要服务端的用户名
  • 需要正确的NTLM HASH

PTH工具

  • Smbmap
  • CrackMapExec
  • Smbexec
  • Metasploit

例子:使用CrackMapExec实现Hash传递

root@kali:~/cache# cme smb 192.168.3.5 -u administrator -H dab7de8feeb5ecac65faf9fdc6cac3a9 -x whoami
SMB 192.168.3.5 445 LIYINGZHEA30B
[*] Windows 7 Ultimate 7601 Service Pack 1 x64 (name:LIYINGZHEA30B)
(domain:PAYLOADS) (signing:False) (SMBv1:True)
SMB 192.168.3.5 445 LIYINGZHEA30B
[+] PAYLOADS\administrator dab7de8feeb5ecac65faf9fdc6cac3a9
(Pwn3d!)SMB 192.168.3.5 445 LIYINGZHEA30B [+] Executed command

2.4. Pass The Key攻击

PTK是在域中攻击kerberos认证的一种方式,原理是通过获取用户的aes hmac,通过kerberos认证,可在NTLM认证被禁止的情况下用来实现类似PTH的功能。

当机器打了KB2871997补丁之后,发现使用域管理员组内无法进行hash传递攻击,但是administrator账号(sid为500)例外;不管administrator账号怎么修改,或者新增的管理员账号,sid为500,即可进行hash传递攻击

实验要求:

privilege::debug #提升权限
sekurlsa::ekeys  #获取kerberos加密凭证
#使用AES-256进行Key传递攻击
sekurlsa::pth /user:administrator /domain:laosec.cn /aes256:1a39fa07e4c96606b371fe12334848efc60d8b3c4253ce6e0cb1a454c7d42083
#使用AES-128进行Key传递攻击
sekurlsa::pth /user:administrator /laosec.cn /aes128:4728551c859bbe351e9c11b5d959163e
#使用机器名来尽心测试访问
dir \\DC\c$
#使用psexec获取目标主机shell
psexec64 \\hostname cmd.exe

2.7. KB2871997补丁

KB2871997 的补丁并没有多大的用处,由于在 Windows Vista 时代,微软就通过将LocalAccountTokenFilterPolicy值默认设置为 0 来禁止非administrator账号的远程连接(包括哈希传递攻击),但是administrator用户不受影响。即使目标主机更新了KB2871997的补丁,仍然可以使用SID=500的用户进行哈希传递攻击,而 SID=500 的用户默认为administrator,所以仍然可以使用administrator用户进行哈希传递攻击。并且在打了KB2871997 补丁的机器上,通过将LocalAccountTokenFilterPolicy设置为1,也还是可以使用普通管理员账号进行哈希传递攻击。

实验

系统环境

域管理员账号

IP地址

Windows server 2008R2域环境

administrator

192.168.1.131

步骤一:未打 KB2871997 补丁前,使用 administrator 账号可以成功进行哈希传递攻击。

步骤二:打上 KB2871997 补丁后,使用 administrator 账号依然可以成功进行哈希传递攻击。

步骤三:gpedit.msc开启本地组策略编辑器修改用户名,在将 administrator 账号重命名为 admin 账号后,还是可以使用 admin 账号紧进行哈希传递攻击,因为 admin 账号的SID值为 500。

防御手段

  • 禁用默认的administrator账号防御手段防御手段
# 渗透测试 # 内网渗透
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录