56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
# or more contributor license agreements. Licensed under the Elastic License
|
|
# 2.0; you may not use this file except in compliance with the Elastic License
|
|
# 2.0.
|
|
|
|
# Name: Brute Force Login Attempts
|
|
# RTA: brute_force_login.py
|
|
# ATT&CK: T1110
|
|
# Description: Simulates brute force or password spraying tactics.
|
|
# Remote audit failures must be enabled to trigger: `auditpol /set /subcategory:"Logon" /failure:enable`
|
|
|
|
import random
|
|
import string
|
|
import sys
|
|
import time
|
|
|
|
from . import common
|
|
|
|
|
|
@common.requires_os(common.WINDOWS)
|
|
def main(username="rta-tester", remote_host=None):
|
|
if not remote_host:
|
|
common.log('A remote host is required to detonate this RTA', '!')
|
|
return common.MISSING_REMOTE_HOST
|
|
|
|
common.enable_logon_auditing(remote_host)
|
|
|
|
common.log('Brute forcing login with invalid password against {}'.format(remote_host))
|
|
ps_command = '''
|
|
$PW = ConvertTo-SecureString "such-secure-passW0RD!" -AsPlainText -Force
|
|
$CREDS = New-Object System.Management.Automation.PsCredential {username}, $PW
|
|
Invoke-WmiMethod -ComputerName {host} -Class Win32_process -Name create -ArgumentList ipconfig -Credential $CREDS
|
|
'''
|
|
command = ['powershell', '-c', ps_command.format(username=username, host=remote_host)]
|
|
|
|
# fail 4 times - the first 3 concurrently and wait for the final to complete
|
|
for i in range(4):
|
|
common.execute(command, wait=i == 3)
|
|
|
|
time.sleep(1)
|
|
|
|
common.log('Password spraying against {}'.format(remote_host))
|
|
|
|
# fail 5 times - the first 4 concurrently and wait for the final to complete
|
|
for i in range(5):
|
|
random_user = ''.join(random.sample(string.ascii_letters, 10))
|
|
command = ['powershell', '-c', ps_command.format(username=random_user, host=remote_host)]
|
|
common.execute(command, wait=i == 4)
|
|
|
|
# allow time for audit event to process
|
|
time.sleep(2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit(main(*sys.argv[1:]))
|