01_pwnbox/pwnbox-webserver.sh
#!/bin/bash

# Usage:
#   ./pyweb.sh (default port is 80)
#   ./pyweb.sh 8080 (listen on port 8080)

IFS='
'

COLOR_RST="\e[0m"
COLOR_RED_BOLD="\e[1;31m"
COLOR_GREEN_BOLD="\e[1;32m"
COLOR_YELLOW_BOLD="\e[1;33m"
COLOR_BLUE_BOLD="\e[1;34m"

function generate_url () {
    # Usage: print_url <IP> <PORT>

    # Is it a loopback IP address?
    echo $1 | grep -E '^(::1|127\.)' >/dev/null 2>&1
    if [ $? -eq 0 ]; then FLAG_LOOPBACK=1; else FLAG_LOOPBACK=0; fi
    
    # Is it a private IP address?
    echo $1 | grep -E '^(fe80::|::1|127\.|192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)' >/dev/null 2>&1
    if [ $? -eq 0 ]; then FLAG_PUB=0; else FLAG_PUB=1; fi

    # Is it an IPv6 address?
    echo $1 | grep ":" >/dev/null 2>&1
    if [ $? -eq 0 ]; then FLAG_IPV6=1; else FLAG_IPV6=0; fi

    # Should we include the port number? No, only if 80.
    echo $2 | grep -E '^80$' >/dev/null 2>&1
    if [ $? -eq 0 ]; then FLAG_DISP_PORT=0; else FLAG_DISP_PORT=1; fi

    OUTPUT="http://"
    if [ $FLAG_IPV6 -eq 1 ]; then OUTPUT="ipv6,${OUTPUT}[$1]"; else OUTPUT="ipv4,${OUTPUT}$1"; fi
    if [ $FLAG_LOOPBACK -eq 1 ]; then OUTPUT="loopback,${OUTPUT}"; else OUTPUT=",${OUTPUT}"; fi
    if [ $FLAG_PUB -eq 1 ]; then OUTPUT="public,${OUTPUT}"; else OUTPUT="private,${OUTPUT}"; fi
    if [ $FLAG_DISP_PORT -eq 1 ]; then OUTPUT="${OUTPUT}:$2"; fi
    OUTPUT="${OUTPUT}/"
    
    echo $OUTPUT
}

function generate_suggested_urls () {
    echo "${1}tools/Invoke-PrivescCheck.ps1"
    echo "${1}tools/SharpHound.ps1"
    echo "${1}tools/PowerView.ps1"
    echo "${1}tools/procdump64.exe"
    echo "${1}tools/LinEnum.sh"
} 

PORT="80"
if [ $# -gt 0 ];
then
    PORT=$1
fi

# If the server is accessed through NAT
PUB_IP=$(curl --connect-timeout 1 ifconfig.io 2>/dev/null)
if [ $? -eq 0 ];
then
    echo -e "${COLOR_BLUE_BOLD}[*]${COLOR_RST} URL using our public IP address:"
    url=$(generate_url $PUB_IP $PORT | cut -d',' -f4)
    echo -e "    > ${COLOR_RED_BOLD}${url}${COLOR_RST}"
fi

# If the server is accessed directly from the LAN
echo -e "${COLOR_BLUE_BOLD}[*]${COLOR_RST} URLs using our local IP address(es):"
for i in $(ip a | grep inet | cut -d' ' -f6 | cut -d'/' -f1);
do
    for u in $(generate_url $i $PORT)
    do
        URL=$(echo $u | cut -d',' -f4)
        echo $u | cut -d',' -f2 | grep -v "loopback" >/dev/null
        LOOPBACK=$?
        echo $u | cut -d ',' -f3 | grep "ipv6" >/dev/null
        IPV4=$?

        # Skip loopback IP addresses 
        if [ $LOOPBACK == 0 ]
        then
            # Colors: IPv4 = green else blue
            if [ $IPV4 == 1 ]; then COLOR=$COLOR_GREEN_BOLD; else COLOR=$COLOR_BLUE_BOLD; fi

            # Print base URL
            echo -e "    > ${COLOR}${URL}${COLOR_RST}"
            
            # If it's an IPv4 address, print suggested URLs
            if [ $IPV4 == 1 ]
            then
                for su in $(generate_suggested_urls $URL)
                do
                    echo "      |__ ${su}"
                done
            fi
        fi
    done
done


CMD="python3 -m http.server $PORT --bind 0.0.0.0"
if [ $PORT -lt 1024 ]
then
    echo -e "${COLOR_YELLOW_BOLD}[!]${COLOR_RST} This port requires 'root' privileges, executing with 'sudo' ..."
    CMD="sudo ${CMD}"
fi

echo -e "${COLOR_BLUE_BOLD}[*]${COLOR_RST} Starting web server..."
eval "$CMD"

