#!/bin/sh
#
# $Id: vhostid,v 0.4 2010/07/21 13:09:39 stef Exp $
#
# NB: this is still beta software and haven't been tested well.
#
# When you scan a network for web server ports (http/https) you will
# have to determine the (virtual) host names they respond to. This
# is sometimes difficult and always tedious.
#
# This tool uses a few common tricks to find host names related to an
# IP address. It doesn't give you a list but it decreases the amount
# of work you have to do to create one.
#
# The tool generates an HTML page on stdout.
#
# Copyright (c) 2010, Stefan Pettersson, http://www.bigpointyteeth.se/
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

me=$(basename $0)
rederror="<font color=\"red\">error</font>"
error() { echo "$me: $1" 1>&2; }
fatal() { echo "$me: $1" 1>&2; exit 1; }
usage() { echo "usage: $me [-h] <file>" 1>&2; }
cleanup() {
    fatal "user abort"
}

# Take IP as input and return the reverse name.
reverse() {
    local result=dunno
    rev=$(host $1)
    if [ $? -eq 0 ]; then
        rev=$(echo $rev | awk '{print $NF}')
        result="$ip -> $rev"
        fwd=$(host $rev)
        if [ $? -eq 0 ]; then
            fwd=$(echo $fwd | awk '{print $NF}')
            result="$result -> $fwd"
        else
            result="$result -> $rederror"
        fi
    else
        result="$ip -> $rederror"
    fi
    echo $result
}

# Take IP as input and return true/false whether
# Bing has any entries for the ip: operator.
bingip() {
    local result=dunno
    curl -A "" -s "http://www.bing.com/search?q=ip%3A$1&FORM=OSDSRC" |\
     grep -q "><div id=\"no_results\"><h1>"
    if [ $? -eq 0 ]; then
        result="no results"
    else
        result="yes"
    fi
    echo $result
}

# Take IP as input and return netname from whois.
netname() {
    local result=dunno
    result=$(whois $1 | grep -i netname)
    if [ $? -ne 0 ]; then
        result=$rederror
    fi
    echo $result
}

# Take IP as input, retrieve the SSL cert and return
# the subject line.
sslcert() {
    local result=dunno
    result=$(echo | openssl s_client -connect $1:443 2>&1 |\
     sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\
     openssl x509 -noout -subject 2>&1 | grep ^subject)
    if test -n "$result"; then
        :   # noop
    else
        result=$rederror
    fi
    echo $result
}

# handle sudden signals properly
#trap "fatal 'user abort'" 1 2 3 15
trap cleanup INT TERM #EXIT
# exit when something returns non-zero exit status
#set -o errexit
# exit when using an unset variable
set -o nounset

# parse options
while getopts h opt; do
    case "$opt" in
        h)     usage; exit 0 ;;
    esac
done
shift $(($OPTIND -1))

# parse positional parameters
if [ $# -ne 1 ]; then
    error "bad number of parameters"
    usage
    exit 1
else
    # handle positional parameters
    file=$1
    test -f $file || fatal "'$file' is not a file"
    ips=$(cat $file)
fi

echo "<html>
<head>
    <title>Results</title>
</head>
<body>"

echo "<h1>Results for $(wc -l $file | awk '{print $1}') addresses</h1>"
echo "<ul>"
for ip in $ips; do
    echo "<li><font size=\"+2\">$ip</font> <a href=\"http://$ip/\">http</a>|<a href=\"https://$ip/\">https</a></li>"
    echo "<ul>"
    echo "<li><b>DNS:</b> $(reverse $ip)</li>"
    echo "<li><b>BING IP:</b> $(bingip $ip)</li>"
    echo "<li><b>NETNAME:</b> $(netname $ip)</li>"
    echo "<li><b>SUBJECT:</b> $(sslcert $ip)</li>"
    echo "<li><a href=\"http://www.bing.com/search?q=ip%3A$ip&FORM=OSDSRC\">Search Bing</a></li>"
    echo "<li><a href=\"http://www.robtex.com/ip/$ip.html\">Check Robtex</a></li>"
    echo "</ul>"
    echo "<br>"
done
echo "</ul>
<hr>
Generated by $me on $(date).<br>
<i>\$Id: vhostid,v 0.4 2010/07/21 13:09:39 stef Exp $</i>
</body>
</html>"

exit 0
# eof
