Detect shared hosting with Bing

Bing has a pretty cool IP advanced search operator. It can be used to detect shared hosting. It is quite annoying to type in each IP manually when you have to check several IPs (e.g. corporate IP network). The following script will scan an entire range of IPs. The examples below (Google IPs 74.125.39.103 to 74.125.39.106) give some pretty interesting results…

def printBingSharedHosting(ip_start, ip_end):
    import urllib2
    import re
    
    bing_url = 'http://www.bing.com/search?q=ip%3A'
    no_results_string = "No results"
    
    def bing_shared_hosting_get_matches(response):
        regex = '<h3><a\shref="(.*?)"\sonmousedown="'
        mo = re.finditer(regex, response)
        urls = []
        for i in mo:
            urls.extend(i.groups())
        return urls
    
    def bing_shared_hosting_query_bing(ip_str):
        body = urllib2.urlopen(bing_url+ip_str).read()
        if not no_results_string in body:
            for i in bing_shared_hosting_get_matches(body):
                result(ip_str+" : "+i)
        else:
            error("Bing page did not show '"+no_results_string+"' for ip: "+ip_str)

    info("Starting bing shared hosting search. I'm not printing anything until i find something")
    info("This method is only searching through the first result page of bing!")    
    for ip in getIpRangeList(ip_start, ip_end):
        bing_shared_hosting_query_bing(ip)


def getIpRangeList(ip_start, ip_end):

    result_list = []

    one, two, three, four = ip_start.split('.')
    one, two, three, four = (int(one), int(two), int(three), int(four))
    end_one, end_two, end_three, end_four = ip_end.split('.')
    end_one, end_two, end_three, end_four = (int(end_one), int(end_two), int(end_three), int(end_four))

    while one <= end_one:
        end_two_tmp = end_two
        if not one == end_one:
            end_two_tmp = 255
        while two <= end_two_tmp:
            end_three_tmp = end_three
            if not two == end_two:
                end_three_tmp = 255
            while three <= end_three_tmp:
                end_four_tmp = end_four
                if not three == end_three:
                    end_four_tmp = 255
                while four <= end_four_tmp:
                    result_list.append("%i.%i.%i.%i"%(one, two, three, four))
                    #debug(str(one)+" "+str(two)+" "+str(three)+" "+str(four))
                    four += 1
                four = 0
                three += 1
            three = 0
            two += 1
        two = 0
        one += 1
    
    return result_list

   
def error(*text):
    print "[PY-ERROR] "+str(" ".join(str(i) for i in text))
    if SLEEP_TIME_ON_ERROR > 0:
        sleep(SLEEP_TIME_ON_ERROR)

def result(*text):
    print "[PY-RESULT] "+str(" ".join(str(i) for i in text))

def info(*text):
    print "[PY-INFO] "+str(" ".join(str(i) for i in text))

def debug(*text):
    print "[PY-DEBUG] "+str(" ".join(str(i) for i in text))

printBingSharedHosting("74.125.39.103", "74.125.39.106")

I admit, the getIpRangeList function could be a little bit more elegant, but I didn’t want to use an external library, didn’t find any suitable code snippet and in the end, it does its job.