Skip to content

Commit

Permalink
Yeet.
Browse files Browse the repository at this point in the history
  • Loading branch information
jordiedw committed Dec 30, 2020
0 parents commit 353d227
Show file tree
Hide file tree
Showing 5 changed files with 548 additions and 0 deletions.
89 changes: 89 additions & 0 deletions inv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash

#testing

'''
_________ ______
___/ \ V \
/ ^ |\ |\ \
/_O_/\ / / | ‾‾‾\ |
// \ |‾‾‾\_ | ‾‾
// _\| _\|
zot zot, thots.
'''

if [[ $EUID -ne 0 ]]; then
printf 'Must be run as root, exiting!\n'
exit 1
fi

log () { printf "\033[01;30m$(date +"%T")\033[0m: $1\n"; }

declare -a checkfiles=(~/.ssh/authorized_keys /root/.ssh/authorized_keys)

log "SYSTEM INFORMATION"
uname -a
lsb_release -a
cat /proc/version

## Fancy /etc/passwd
minid=$(grep "^UID_MIN" /etc/login.defs)
maxid=$(grep "^UID_MAX" /etc/login.defs)
printf "========================================================\n| Users List | Key: \033[01;34mUID = 0\033[0m, \033[01;32mUser\033[0m, \033[01;33mCan Login\033[0m, \033[01;31mNo Login\033[0m |\n========================================================\n"
awk -F':' -v minuid="${minid#UID_MIN}" -v maxuid="${maxid#UID_MAX}" '{
if ($7=="/bin/false" || $7=="/sbin/nologin") printf "\033[1;31m%s\033[0m\n", $1;
else if ($3=="0") printf "\033[01;34m%s\033[0m\n", $1;
else if ($3 >= minuid && $3 <= maxuid) printf "\033[01;32m%s\033[0m\n", $1;
else printf "\033[01;33m%s\033[0m\n", $1;
}' /etc/passwd | column

## /etc/group
printf "[ \033[01;35mUser\033[0m, \033[01;36mGroup\033[0m ]\n" && grep "sudo\|adm\|bin\|sys\|uucp\|wheel\|nopasswdlogin\|root" /etc/group | awk -F: '{printf "\033[01;35m" $4 "\033[0m : \033[01;36m" $1 "\033[0m\n"}' | column
printf "To delete users/groups, use \033[01;30msudo userdel -r $user\033[0m and \033[01;30msudo groupdel $user\033[0m\n"

## /etc/sudoers
log "Sudoers"
sudo awk '!/#(.*)|^$/' /etc/sudoers

## Less Fancy /etc/shadow
log "Passwordless accounts: "
awk -F: '($2 == "") {print}' /etc/shadow # Prints accounts without passwords
echo;

log "IP Addresses:" # Okay I stole this one from Morgan, I'll make it prettier later
ip addr | awk '/^[0-9]+:/ { sub(/:/,"",$2); iface=$2 } /^[[:space:]]*inet / { split($2, a, "/"); print iface" : "a[1]; }'
printf "\n"

for i in ${checkfiles[@]}; do [ -s $i ] && log "\033[01;31mWARNING: $i HAS ACCESSIBLE INFORMATION\033[0m\n"; done

## Find world-writeable files
#log "List all world-writeable files?"
#read -n 1 -r; echo; if [[ $REPLY =~ ^[Yy]$ ]]; then find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print; fi

## Find no-owner files
log "List all no-owner files? (This will take a while!) Y/n"
read -n 1 -r; echo; if [[ $REPLY =~ ^[Yy]$ ]]; then find / -xdev \( -nouser -o -nogroup \) -print; fi

log "List all user files? Y/n"
read -n 1 -r; echo; if [[ $REPLY =~ ^[Yy]$ ]]; then grep -R /home; fi

log "Ports"
sudo ss -ln
printf "To close ports: \033[01;30msudo lsof -i :$port\033[0m, remember to kill the process with \033[01;30mkillall -9 $program\033[0m and remove.\n"

log "Cronjobs:"
sudo grep -R . /var/spool/cron/crontabs/
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done

log "Services:"
which service && service --status-all
which initctl && initctl list
which systemctl && systemctl list-unit-files --type service
which rc-status && rc-status --servicelist # Alpine
#ls /etc/init.d/
ls /etc/init/*.conf

systemctl list-unit-files --type service | grep enabled > servicesList.txt

watch -d systemctl list-timers
270 changes: 270 additions & 0 deletions inventory.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
#!/bin/bash

########################################################
# https://github.com/UCI-CCDC/CCDC2020
# script raw is at https://git.io/uciccdc20
# to install: wget https://git.io/uciccdc20 -O inv.sh && chmod +x inv.sh
#UCI CCDC linux script for inventory & common operations

#Written by UCI CCDC linux subteam
#UCI CCDC, 2020
########################################################


if [[ $EUID -ne 0 ]]; then
printf 'Must be run as root, exiting!\n'
exit 1
fi

#functions to make shit prettier
banner () { printf "========================================================\n"; }

#actual functions for actual things
updateOS() {

## Install & update utilities
if [ $(command -v apt-get) ]; then # Debian based
apt-get update -y -q
elif [ $(command -v yum) ]; then
yum update
elif [ $(command -v pacman) ]; then
pacman -Syy
pacman -Su
elif [ $(command -v apk) ]; then # Alpine
apk update
apk upgrade
fi

}


#FINISH ME PLS
installPackages() {
packages="sudo nmap tmux tshark vim hostname htop clamav"
printf "this function will be used to install important/essential packages on barebones systems"
if [ $(command -v apt-get) ]; then # Debian based
apt-get install $packages -y -q

elif [ $(command -v yum) ]; then
yum -y install $packages
elif [ $(command -v pacman) ]; then
yes | pacman -S $packages
elif [ $(command -v apk) ]; then # Alpine
apk update
apk upgrade
apk add bash vim man-pages mdocml-apropos bash-doc bash-completion util-linux pciutils usbutils coreutils binutils findutils attr dialog dialog-doc grep grep-doc util-linux-doc pciutils usbutils binutils findutils readline lsof lsof-doc less less-doc nano nano-doc curl-doc

apk add $packages
fi
}


harden() {
printf "We are now doing system hardening\n"

read -r -p "Are you sure? The harden script is currently non-functional, as of March 02 [Y/n] " response
case "$response" in
[yY][eE][sS]|[yY])
wget https://raw.githubusercontent.com/UCI-CCDC/CCDC2020/master/harden.sh -O harden.sh && bash harden.sh

;;
*)
exit 1;;
esac
# I know this is shit but I really don't care anymore
#I'm lazy af, this calls the hardening script and runs it. Hope it works
}


#below should both be false
ShouldUpdate=false
ShouldInstall=false

# this fucker is the flag statement
while getopts :huixnsr:m: option
do
case "${option}" in
h)
printf "\n UCI CCDC 2020 Linux Inventory Script\n"
printf "Note: all flags other than the update functions will result in the main script not being run.\n"

printf " ==============Options==============\n"
printf " -h Prints this help menu\n"
printf " -n Runs Jacob's custom NMAP command\n"
printf " -m Runs custom NMAP command, but IP subnet must be passed as an argument (ex: -m 192.168.1.0)\n"
printf " -x Runs hardening script\n"
printf " -u Installs updates based on system version\n"
printf " -i Installs updates AND useful packages\n"
printf " -s Backups MYSQL databases and config files\n"
printf " -r Restore MYSQL database from backup tar archive (passed as argument)\n"

printf "\n\n\n"
exit 1;;
u)
ShouldUpdate=true
;;
i)
ShouldUpdate=true
ShouldInstall=true
;;

x)
harden #calls hardening function above
exit 1;;

n)
printf "Running NMAP command, text and visual xml output created in current directory"
nmap -p- -Anvv -T4 -oN nmapOut.txt -oX nmapOutVisual.xml $(hostname -I | awk '{print $1}')/24
exit 1;;

m)
printf "Running NMAP command with user specificed subnet, text and visual xml output created in current directory"
nmap -p- -Anvv -T4 -oN nmapOut.txt -oX nmapOutVisual.xml $OPTARG/24
exit 1;;

s)
printf "Backing up MYSQL databases and config files\n"

mkdir -p $HOME/sql-backup

read -s -p "Enter root password for mysql database " pass
for db in $(mysql -u root -p$pass -e 'show databases' --skip-column-names); do
mysqldump -u root -p$pass "$db" > "$HOME/sql-backup/$db.sql"
done
cp -r /etc/mysql /$HOME/sql-backup/
tar -czf $HOME/$HOSTNAME-sqlbackup.tgz $HOME/sql-backup

exit 1;;

r)
printf "Restoring MYSQL database from $OPTARG \n"
#sql database recovery, not yet verified to work

read -s -p "Enter root pass: " pass
printf "\n"
mkdir restore-sql

tar -xzf "$OPTARG" -C restore-sql/
for db in $(find restore-sql/ -name *.sql); do
bdb=$(basename $db)
mysql -u root -p$pass -e "create database ${bdb%.sql};"
mysql -u root -p$pass ${bdb%.sql} < "$db"
done

exit 1;;


#both of these are error handling. The top one handles incorrect flags, the bottom one handles when no argument is passed for a flag that requires one
\?) echo "incorrect syntax, use -h for help"
exit 1;;

:) echo "invalid option: -$OPTARG requires an argument"
exit 1;;
esac
done



echo '
_________ ______
___/ \ V \
/ ^ |\ |\ \
/_O_/\ / / | ‾‾\ |
// \ |‾‾‾\_ | ‾‾
// _\| _\|
zot zot, thots.'


#generate inv directory, audit.txt, and set up variables for redirection
printf "\n*** generating inv direcory and audit.txt in your root home directory\n"
mkdir $HOME/inv/ >&/dev/null; #creates directory; stderr is redirected in the case that directory already exists
outFile="$HOME/inv/audit-$(hostname).txt"
touch outFile
adtfile="tee -a $HOME/inv/audit-$(hostname).txt"



echo -e "\n\e[92m"
echo "Hostname: $(hostname)" | $adtfile
echo -e "\e[0m"

echo "Date: $(date)" >> $outFile

osOut=$(cat /etc/os-release | grep -w "PRETTY_NAME" | cut -d "=" -f 2)

printf "This machine's OS is "
echo -e "\e[31m"

echo $osOut | $adtfile
echo -e "\e[0m"

echo -e "\e[95m***IP ADDRESSES***\e[0m"
echo "Most recent IP: $(hostname -I | awk '{print $1}')"
echo "All IP Addresses: $(hostname -I)" | $adtfile

## /etc/sudoers
if [ -f /etc/sudoers ] ; then
printf "\nSudoers File:\n"
sudo awk '!/#(.*)|^$/' /etc/sudoers
echo ""
fi


# I stole this from jordan
minid=$(grep "^UID_MIN" /etc/login.defs || echo 1000)n
maxid=$(grep "^UID_MAX" /etc/login.defs || echo 60000)
printf "========================================================\n| Users List | Key: \033[01;34mUID = 0\033[0m, \033[01;32mUser\033[0m, \033[01;33mCan Login\033[0m, \033[01;31mNo Login\033[0m |\n========================================================\n"
awk -F':' -v minuid="${minid#UID_MIN}" -v maxuid="${maxid#UID_MAX}" '{
if ($7=="/bin/false" || $7=="/sbin/nologin") printf "\033[1;31m%s\033[0m\n", $1;
else if ($3=="0") printf "\033[01;34m%s\033[0m\n", $1;
else if ($3 >= minuid && $3 <= maxuid) printf "\033[01;32m%s\033[0m\n", $1;
else printf "\033[01;33m%s\033[0m\n", $1;
}' /etc/passwd | column

printf "\n[ \033[01;35mUser\033[0m, \033[01;36mGroup\033[0m ]\n" && grep "sudo\|adm\|bin\|sys\|uucp\|wheel\|nopasswdlogin\|root" /etc/group | awk -F: '{printf "\033[01;35m" $4 "\033[0m : \033[01;36m" $1 "\033[0m\n"}' | column

# ## Less Fancy /etc/shadow
echo -e "\n\e[93m***Passwordless accounts***\e[0m\n"
awk -F: '($2 == "") {print}' /etc/shadow # Prints accounts without passwords

echo -e "\n\e[93m***USERS IN SUDO GROUP***\e[0m\n"
echo "Users in sudo group:" >> $outFile
grep -Po '^sudo.+:\K.*$' /etc/group | $adtfile

printf "\n\e[93m***USERS IN ADMIN GROUP***\e[0m\n"
echo "Users in Admin Group:" >> $outFile
grep -Po '^admin.+:\K.*$' /etc/group | $adtfile

printf "\n\e[93m***USERS IN WHEEL GROUP***\e[0m\n"
echo "Users in Wheel Group:" >> $outFile
grep -Po '^wheel.+:\K.*$' /etc/group | $adtfile

printf "\n\e[35mCrontabs\e[0m\n"
sudo grep -R . /var/spool/cron/crontabs/
for user in $(cut -f1 -d: /etc/passwd); do crontab -u "$user" -l 2> >(grep -v 'no crontab for'); done

#saves services to variable, prints them out to terminal in blue
printf '\n***services you should cry about***\n'
services=$(ps aux | grep -i 'docker\|samba\|postfix\|dovecot\|smtp\|psql\|ssh\|clamav\|mysql\|bind9\|apache\|smbfs\|samba\|openvpn\|splunk' | grep -v "grep")
echo -e "\e[34m"
echo "Services on this machine:" >> $outFile
echo $services | $adtfile
echo -e "\e[0m" #formatting so audit file is less fucked with the color markers

banner >> $outFile
printf "\n\n" >> $outFile


#these if statements make sure that updates are executed at the end of the script running, instead of the beginning
if [ "$ShouldUpdate" = "true" ]; then
updateOS
fi

if [ "$ShouldInstall" = "true" ]; then
installPackages
fi



# this string prints the current system time and date "\033[01;30m$(date)\033[0m: %s\n"
Loading

0 comments on commit 353d227

Please sign in to comment.