#!/bin/bash ## CTFs Made Interactive - ctfmi.sh # Script to help with playing CTFs. # Author: illustrissimus declare -r ERR_BASH=255 declare -r ERR_ENV=254 declare -r MAX_TASKS=100 ## Section 0 - check sanity of the execution environment. [ ${BASH_VERSINFO[0]} -lt 5 ] && echo "[-][0.1] Minimum supported version is 5.0 and you have $BASH_VERSION" >&2 && exit $ERR_BASH # Assumption: uname, ps, basename, readlink and grep exist. SYSTYPE=$(uname -s) case "${SYSTYPE}" in Darwin*) if ! ps -p $$ -ocommand=|grep -q "bash"; then echo "[-][0.2] Only bash is supported" >&2 && exit $ERR_BASH fi ;; Linux*) if ! basename $(readlink /proc/$$/exe)|grep -q "bash"; then echo "[-][0.2] Only bash is supported" >&2 && exit $ERR_BASH fi ;; *) echo "[-][0.2] Unrecognized environment" >&2 && exit $ERR_ENV ;; esac # Other assumptions are tested explicitly. declare -a PREREQ=("ping" "nmap" "cut" "tr" "awk" "wc" "sleep") for p in "${PREREQ[@]}"; do if ! hash "$p" 2>/dev/null; then echo "[-][0.3] $p is required but not installed. Aborting" >&2 && exit $ERR_ENV fi done ## 1.0 Perform a parallel ping sweep. # $1 ... list of hosts to ping ping_sweep() { declare -n HS="$1" declare -a TASKS=() CURRENT_TASKS=0 for h in "${HS[@]}"; do while [ $CURRENT_TASKS -ge $MAX_TASKS ]; do sleep 0.1 CURRENT_TASKS=$(jobs|wc -l) done ( if ! ping -c 2 -n -q "$h" 2>/dev/null|grep received|cut -d"," -f2|cut -d" " -f2|grep -q "0"; then echo "[+][1.0] $h responding to ping" else echo "[-][1.0] $h not responding to ping" fi ) & TASKS+=( ${!} ) CURRENT_TASKS=$(jobs|wc -l) done for t in "${TASKS[@]}"; do wait $t done unset TASKS } ## 1.1 Perform a port scan for common TCP ports in AD environments. # $1 ... list of hosts to scan tcp_port_scan() { declare -n HS="$1" declare -a TASKS=() CURRENT_TASKS=0 for h in "${HS[@]}"; do while [ $CURRENT_TASKS -ge $MAX_TASKS ]; do sleep 0.1 CURRENT_TASKS=$(jobs|wc -l) done ( IFS=$'\n' PORTS=($(nmap -n -Pn -sT -oG - -p22,53,80,88,443,445,457,591,593,981,1080,1433,3306,3389,5985,5986,7001,7002,8005,8008,8080,8443,8530,8531,8888,9006,9080,9443,30821 "$h"|grep "Ports:"|cut -d":" -f3|tr -d ' '|tr , "\n"|awk -F"/" '{print $1 "/" $3 ":" $2}')) for p in "${PORTS[@]}"; do if ! echo "$p"|grep -q "open"; then echo "[-][1.1] $h:$p" else echo "[+][1.1] $h:$p" fi done ) & TASKS+=( ${!} ) CURRENT_TASKS=$(jobs|wc -l) done for t in "${TASKS[@]}"; do wait $t done unset TASKS } ## Main entry point echo "[*] Welcome to ctfmi.sh (v2023.04.002)" printf "[r][1.0] Enter network range(s) in CIDR notation understandable to nmap, e.g. '192.168.1.0/24 10.10.110.0/24': " read -r CIDR # Expand into host list: IFS=$'\n' HOSTS=($(echo "$CIDR" |nmap -n -sL -iL -|grep "Nmap scan report for"|cut -d" " -f5)) ## Section 1 - asset discovery, port scanning. ping_sweep HOSTS tcp_port_scan HOSTS