|
| 1 | +#/usr/bin/env python |
| 2 | +#-*-coding=utf-8-*- |
| 3 | + |
| 4 | +# __author__ = 'Zline' |
| 5 | + |
| 6 | +import requests |
| 7 | +import re |
| 8 | +from threading import Thread,Lock |
| 9 | +import time |
| 10 | +import sys |
| 11 | +import chardet |
| 12 | +import netaddr |
| 13 | +import struct |
| 14 | +import socket |
| 15 | + |
| 16 | +lock = Lock() |
| 17 | + |
| 18 | +def ip2int(addr): |
| 19 | + return struct.unpack("!I", socket.inet_aton(addr))[0] |
| 20 | +def int2ip(addr): |
| 21 | + return socket.inet_ntoa(struct.pack("!I", addr)) |
| 22 | +def int_dec(pagehtml): |
| 23 | + |
| 24 | + charset = None |
| 25 | + if pagehtml != '': |
| 26 | + # print 'use charset dect' |
| 27 | + enc = chardet.detect(pagehtml) |
| 28 | + # print 'enc= ', enc |
| 29 | + if enc['encoding'] and enc['confidence'] > 0.9: |
| 30 | + charset = enc['encoding'] |
| 31 | + |
| 32 | + if charset == None: |
| 33 | + charset_re = re.compile("((^|;)\s*charset\s*=)([^\"']*)", re.M) |
| 34 | + charset=charset_re.search(pagehtml[:1000]) |
| 35 | + charset=charset and charset.group(3) or None |
| 36 | + |
| 37 | + # test charset |
| 38 | + try: |
| 39 | + if charset: |
| 40 | + unicode('test',charset,errors='replace') |
| 41 | + except Exception,e: |
| 42 | + print 'Exception',e |
| 43 | + charset = None |
| 44 | + # print 'charset=', charset |
| 45 | + return charset |
| 46 | + |
| 47 | + |
| 48 | +def http_banner(url): |
| 49 | + ip=url |
| 50 | + try: |
| 51 | + url=requests.get(url,timeout=2) |
| 52 | + |
| 53 | + body = url.content |
| 54 | + |
| 55 | + charset = None |
| 56 | + if body != '': |
| 57 | + charset = int_dec(body) |
| 58 | + |
| 59 | + if charset == None or charset == 'ascii': |
| 60 | + charset = 'ISO-8859-1' |
| 61 | + |
| 62 | + if charset and charset != 'ascii' and charset != 'unicode': |
| 63 | + try: |
| 64 | + body = unicode(body,charset,errors='replace') |
| 65 | + except Exception, e: |
| 66 | + body = '' |
| 67 | + Struts=url.status_code |
| 68 | + Server=url.headers['server'][0:13] |
| 69 | + if Struts==200 or Struts==403 or Struts==401: |
| 70 | + title=re.findall(r"<title>(.*)<\/title>",body) |
| 71 | + if len(title): |
| 72 | + title = title[0].strip() |
| 73 | + else: |
| 74 | + title = '' |
| 75 | + lock.acquire() |
| 76 | + print ('%s\t%d\t%-10s\t%s'%(ip.lstrip('http://'),Struts,Server,title)) |
| 77 | + lock.release() |
| 78 | + except (requests.HTTPError,requests.RequestException,AttributeError,KeyError),e: |
| 79 | + pass |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | +if __name__ == '__main__': |
| 84 | + if len(sys.argv) >= 2: |
| 85 | + ips = sys.argv[1] |
| 86 | + else: |
| 87 | + print 'usage: python http_banner.py 192.168.1./24 ' |
| 88 | + print 'usage: python http_banner.py 192.168.1.1-192.168.1.254 ' |
| 89 | + print 'usage: python http_banner.py 192.168.1./24 8080' |
| 90 | + print 'usage: python http_banner.py 192.168.1.1-192.168.1.254 8080' |
| 91 | + sys.exit() |
| 92 | + port = '80' |
| 93 | + if len(sys.argv) == 3: |
| 94 | + port = sys.argv[2] |
| 95 | + |
| 96 | + if '-' in ips: |
| 97 | + start, end = ips.split('-') |
| 98 | + startlong = ip2int(start) |
| 99 | + endlong = ip2int(end) |
| 100 | + ips = netaddr.IPRange(start,end) |
| 101 | + for ip in list(ips): |
| 102 | + url='http://%s:%s'%(ip,port) |
| 103 | + t = Thread(target=http_banner,args=(url,)) |
| 104 | + t.daemon=False |
| 105 | + t.start() |
| 106 | + elif '/' in ips: |
| 107 | + ips = netaddr.IPNetwork(ips) |
| 108 | + for ip in list(ips): |
| 109 | + url='http://%s:%s'%(ip,port) |
| 110 | + t = Thread(target=http_banner,args=(url,)) |
| 111 | + t.daemon=False |
| 112 | + t.start() |
0 commit comments