2013년 12월 17일 화요일

[Python] 구글 해킹여부에 대한 모의침투 - GoogleSweep


- GoogleSweep 은 구글해킹이나 취약점을 스캔하는 툴들과 다른 기능을 제공하다.
- 네트워크상의 서브넷을 스캔하여 얼마나 구글상에 노출이 되어있는가를 보여준다.
- 구글해킹에 공격당할 가능성에 대한 모의침투(p.t)  결과를 보여준다.
- html 방식의 그래픽으로 일목요연하게 보여준다.
- Python 2.4.1 상에서 작동된다.

#!/usr/bin/env python
#
# GoogleSweep
# Robert Wesley McGrew
# wesleymcgrew@gmail.com
#
# Run without arguments and scroll down a bit for usage information
#
# Copyright 2005 Robert Wesley McGrew
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
version = '0.8'

import getopt
import sys
import socket
import google
import time
import SOAPpy

global queries_performed
global burst_size
global burst
global burst_start_time
global subnet
global subnet_supplied
global rdns

#########################################
#
# Usage information
#

def usage():
           print """
Usage:
googlesweep.py [-h num] [-r] [-b num] <[-d filename] | [-o report]> <-s subnet>

-s Subnet should take the form of a dotted-quad where
  an asterisk may take the place of up to three of elements
  starting at the right.  For example:

       192.168.5.*
       192.168.*.*
       192.*.*.*

  If you do not specify this correctly, there really is
  no telling what will happen, as it's too much trouble
  to check to see if you're incapable of reading
  documentation.  If you need more flexibility
  in your sweep list, either script around this program
  or modify the generate_ip_list() function

-o <report> should be the name of the file you wish to
  contain the pretty HTML report of the sweep.  Excellent
  for printing up in pentest reports!

-d Dumps a comma-delimited text version of the data
  to filename

-b Burst mode, with number of queries per burst
  Will perform num queries, and wait 24 hours until
  the next burst.

  The Google API limits you to 1000 requests
  daily, so I recommend not exceeding that.  You may
  set less if you want to save some queries for another
  program.

-r Perform a reverse DNS lookup of each IP
  and google the resulting hostname as well (if one exists).

-h Write a hash mark every num hosts swept.  Use 0 to
  turn off hash marks.  Default is 8.
  """

#######################################
#
# Modify this function if you need more
# flexibility in the list of hosts that
# are scanned
#

def generate_ip_list(subnet):
           num_stars = 0
           r = [(0,256),(0,256),(0,256),(0,256)]
           for i in range(0,len(subnet)):
                       if subnet[i] == '*':
                                   num_stars += 1
          
           current_quad_element = 0
           for i in range(current_quad_element, 4 - num_stars):
                       temp = ''
                       for j in range(0,len(subnet)):
                                   if subnet[j] != '.':
                                               temp += subnet[j]
                                   else:
                                               break
                       r[i] = (int(temp),int(temp)+1)
                       subnet = subnet[j+1:]
          
           ip_list = []
          
           for a in range(r[0][0], r[0][1]):
                       for b in range(r[1][0], r[1][1]):
                                   for c in range(r[2][0], r[2][1]):
                                               for d in range(r[3][0], r[3][1]):
                                                           ip_list.append(str(a) + "." + str(b) + "." + str(c) + "." + str(d))
          
           return ip_list

#######################################
#
# Generates a report based on the
# results.  Modify to suit your needs.
#

def generate_report(f, ip_list, results_ip, name_list, results_name, max):
           f.write('<html>\n')
           f.write('<title>' + 'GoogleSweep ' + version + ' Results for ' + subnet + '</title>\n')
           f.write('<body>\n')
           f.write('<h1>GoogleSweep ' + version + ' results for ' + subnet + '</h1>\n')
           f.write('<h2>Report generated: ' + time.ctime() + '</h2>\n')
           f.write('<hr>\n')
           f.write('<table border=1>\n')
           f.write('<tr><td>IP Address</td> <td>Hits</td>')
           if rdns:
                       f.write(' <td>Hostname</td> <td>Hits</td> <td>Total Hits</td>')
           f.write(' <td>Relative Popularity</td></tr>\n')
          
           for i in range(0,len(ip_list)):
                       f.write('<tr><td><a href="http://www.google.com/search?hl=en&lr=&sa=G&q=%22' + ip_list[i] + '%22">')
                       f.write(ip_list[i] + '</a></td> <td>' + str(results_ip[i]) + '</td>')
                       total = results_ip[i]
                       if rdns:
                                   if name_list[i] != '':
                                               f.write(' <td><a href="http://www.google.com/search?hl=en&lr=&sa=G&q=%22' + name_list[i] + '%22">')
                                               f.write(name_list[i] + '</a></td>')
                                   else:
                                               f.write(' <td><i>Unknown</i></td>')
                                   f.write(' <td>' + str(results_name[i]) + '</td> <td>' + str(results_ip[i] + results_name[i]) + '</td>')
                                   total += results_name[i]
                       f.write(' <td><table border=0><tr><td bgcolor="#FF0000" width=' + str(((total*50)/max)*10) + ' height=10></td></tr></table></td>')
                       f.write('</tr>\n')

           f.write('</table>\n')
           f.write('<hr>\n')
           f.write('</body>\n')
           f.write('</html>\n')
          
#######################################
#
# Searches google and keeps track of
# when to stop and start bursts
#

def search_google(term):
           global queries_performed
           global burst
           global burst_start_time
           global burst_size

           results = google.doGoogleSearch(term)
           num_results = results.meta.estimatedTotalResultsCount
           queries_performed += 1
           if queries_performed == 1 and burst:
                       burst_start_time = time.time()
                       print ''
                       print 'Began new burst at ' + time.ctime(burst_start_time)
           if queries_performed == burst_size and burst:
                       print ''
                       print 'Burst ended at ' + time.ctime()
                       print 'Sleeping until ' + time.ctime(burst_start_time+(60*60*24)+60) # plus a minute or so fudge-factor
                       while time.time() < (burst_start_time+(60*60*24)+60):
                                   time.sleep((burst_start_time+(60*60*24)+60)-time.time())
           return num_results

#######################################
#
# Main program code
#

print 'GoogleSweep v' + version
print 'Robert Wesley McGrew - wesleymcgrew@gmail.com'

rdns = False
output_exists = False
dump = False
report = False
subnet_supplied = False
force = False
hash = True
hash_num = 8
queries_performed = 0
burst_size = 0
burst = False
burst_start_time = 0

try:
           opts, args = getopt.gnu_getopt(sys.argv[1:],"h:b:d:o:s:r")
except getopt.GetoptError:
           usage()
           sys.exit(1)

for o, a in opts:
           if o == '-h':
                       if int(a) == 0:
                                   hash = False
                       else:
                                   hash_num = int(a)
           if o == '-r':
                       rdns = True
           if o == '-b':
                       burst = True
                       burst_size = int(a)
           if o == '-d':
                       dump = True
                       dump_file = a
                       output_exists = True
           if o == '-o':
                       report = True
                       report_file = a
                       output_exists = True
           if o == '-s':
                       subnet_supplied = True
                       subnet = a

if args or not output_exists or not subnet_supplied:
           usage()
           sys.exit(1)

print 'Building scan list...'

ip_list = generate_ip_list(subnet)

print str(len(ip_list)) + ' IP addresses'

num_queries = len(ip_list)
if num_queries > 1000 and not burst:
           print 'Number of required API queries ' + num_queries + ' > allowed 1000 daily.  Use burst mode'
           sys.exit(1)

name_list = []
num_names = 0
if rdns:
           print 'Performing reverse DNS lookup of all IP addresses...'
           for ip in ip_list:
                       try:
                                   hostname, alias, ips = socket.gethostbyaddr(ip)
                                   num_names += 1
                       except:
                                   hostname = ''
                       name_list.append(hostname)
           print str(num_names) + ' hosts have names'
           num_queries += num_names

if num_queries > 1000 and not burst:
           print 'Number of required API queries ' + num_queries + ' > allowed 1000 daily.  Use burst mode'
           sys.exit(1)

print 'Performing ' + str(num_queries) + ' API queries total.'

hash_counter = 0
queries_performed = 0
max = 0
results_ip = []
results_name = []
if dump:
           try:
                       dump_handle = open(dump_file,'w')
           except:
                       print 'Could not open ' + dump_file + ' for writing.'
                       sys.exit(1)
                      
for i in range(0,len(ip_list)):
           results_ip.append(search_google(ip_list[i]))
           if rdns:
                       if name_list[i] != '':
                                   results_name.append(search_google(name_list[i]))
                       else:
                                   results_name.append(0)
           if dump:
                       if rdns:
                                   dump_handle.write(ip_list[i] + ',' +
                                                               str(results_ip[i]) + ',' +
                                                                 name_list[i] + ',' +
                                                                 str(results_name[i]) + ',' +
                                                                 str(results_ip[i]+results_name[i]) + '\n')
                       else:
                                   dump_handle.write(ip_list[i] + ',' +
                                                             str(results_ip[i]) + '\n')
                       dump_handle.flush()
          
           if rdns:
                       if results_ip[i] + results_name[i] > max:
                                   max = results_ip[i] + results_name[i]
           else:
                       if results_ip[i] > max:
                                   max = results_ip[i]
                      
           if hash:
                       if hash_counter < hash_num:
                                   hash_counter += 1
                       else:
                                   sys.stdout.write('#')
                                   sys.stdout.flush()
                                   hash_counter = 0

if dump:
           dump_handle.close()

if report:
           print ''
           print 'Generating report (' + report_file + ')'
           try:
                       report_handle = open(report_file,'w')
           except:
                       print 'Coult not open ' + report_file + ' for writing.'
                       sys.exit(1)
           generate_report(report_handle,ip_list,results_ip,name_list,results_name, max)
           report_handle.close()

print ''
print 'Completed.'

댓글 없음:

댓글 쓰기