#!/bin/bash
# bing-ip2hosts - Enumerate hostnames from Bing.com for an IP address.
# Bing.com is Microsoft's search engine which has an IP: search parameter.
#
# By Andrew Horton aka urbanadventurer, MorningStar Security
# Homepage: http://www.morningstarsecurity.com/research/bing-ip2hosts
#
# Version 0.4 Released December 19th, 2013. Updated to use nslookup, new usage, fixed tmp file issue
# Version 0.3 Released September 21st, 2012. Updated because Bing mobile search changed.
# Version 0.2 Released April 2nd, 2010
# Version 0.1 Released December 2nd, 2009 at Kiwicon III in New Zealand
#
# License: GPLv3

VERSION=o.4
TMPDIR=/tmp
ANIMATION=1
OUTPUTIP=0
HTTPPREFIX=0
IP=
PREFIX=
DEBUG=0

if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
echo -en '\E[31m'
echo -e "bing-ip2hosts ($VERSION) by Andrew Horton aka urbanadventurer
Homepage: http://www.morningstarsecurity.com/research/bing-ip2hosts
"
echo -en '\033[0m'

echo -e "Useful for web intelligence and attack surface mapping of vhosts during
penetration tests. Find hostnames that share an IP address with your target 
which can be a hostname or an IP address.  This makes use of Microsoft 
Bing.com ability to seach by IP address, e.g. \"IP:210.48.71.196\".

Usage: $0 [OPTIONS] <IP|hostname>

OPTIONS are:
-n\t\tTurn off the progress indicator animation
-t <DIR>\tUse this directory instead of /tmp. The directory must exist.
-i\t\tOptional CSV output. Outputs the IP and hostname on each line, separated by a comma.
-p\t\tOptional http:// prefix output. Useful for right-clicking in the shell.
"
exit 1
fi

while getopts "nipt:" optionName; do
    case "$optionName" in
     	 n) ANIMATION=0;;
	 t) TMPDIR="$OPTARG";;
	 i) OUTPUTIP=1;;
	 p) HTTPPREFIX=1;;
	 [?]) echo "Error"; exit 1;;
    esac
done

shift $(($OPTIND -1))

if [ -z "$1" ]; then
 echo "need an IP or hostname"
 exit 1
fi

animation="/-\|"
page=0
last_page_check=
how_many=1
uniq_hosts=0
single_page=

# if the parameter looks like an IP go ahead, otherwise resolve it
if [ `echo "$1" | egrep  "(([0-9]+\.){3}[0-9]+)|\[[a-f0-9:]+\]"`  ]; then
 IP="$1"
else
# IP=`resolveip -s "$1"`
 IP=`nslookup "$1" |egrep "^Address: \w+\.\w+\.\w+\.\w+$"|tail -1|awk '{ print $2 }'`
 #  dig -t a treshna.com  +short
 if [ "$IP" == "" ]; then
 	echo "Error: cannot resolve $1 to an IP"
	exit
 fi
fi

all_hosts=`mktemp -p $TMPDIR -t bing-ip2hosts.tmp.XXXXXX`

while [ -z "$last_page_check" ] && [ -n "$how_many" ] && [ -z "$single_page" ]; do
 if [ $ANIMATION == 1 ]; then
  echo -ne "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
  echo -en "[ $IP | Scraping $how_many | Found $uniq_hosts | ${animation: $(( $page % 4 )) :1} ]"
 fi
 url="http://www.bing.com/search?q=ip%3A$IP&go=&qs=n&first=${page}0&FORM=PERE"

 out=`mktemp -p "$TMPDIR" -t bing-ip2hosts.tmp.XXXXXX`
 wget -q -O "$out" "$url"

 last_page_check=`egrep -o '<span class="sb_count" id="count">[0-9]+-([0-9]+) of (\1)' $out`
 if [ "$DEBUG" -eq 1 ]; then
  echo "Last Page Check: $last_page_check"
 fi

 # if no results are found, how_many is empty and the loop will exit
 how_many=`egrep -o '<span class="sb_count" id="count">[^<]+' $out|cut -d '>' -f 2|cut -d ' ' -f 1-3`

 # check for a single page of results
 single_page=`egrep -o '<span class="sb_count" id="count">[0-9] results' $out`
 if [ $DEBUG -eq 1 ];then
  echo "Single Page: $single_page"
 fi

 # no captcha support or detection
 # pages will contain "Typing the characters in the picture above helps us ensure that a person, not a program, is performing a search"

 vhosts=`cat "$out"| egrep -o "<h3><a href=\"[^\"]+" $out |cut -d '"' -f 2`
 echo -e "$vhosts" >> "$all_hosts"

 uniq_hosts=`cat "$all_hosts" | cut -d '/' -f 3 | tr '[:upper:]' '[:lower:]' | sort | uniq | wc -l`

 if [ $DEBUG -eq 0 ]; then
  rm -f "$out"
 fi
 
 let page=$page+1 
 if [ $DEBUG -eq 1 ]; then
  echo "Page: $page"
 fi
done

if [ $ANIMATION == 1 ]; then
	echo
fi

uniq_hosts=`cat "$all_hosts" | cut -d '/' -f 3 | tr '[:upper:]' '[:lower:]' | sort | uniq`

if [ $DEBUG -eq 0 ]; then
  rm -f "$all_hosts"
fi

if [ $OUTPUTIP == 1 ]; then
	PREFIX="$IP,"
fi
if [ $HTTPPREFIX == 1 ]; then
	PREFIX="$PREFIX""http://"
fi

for h in `echo "$uniq_hosts"`
do
	echo "$PREFIX$h"
done

