Repository: Warflop/CloudBunny Branch: master Commit: 5cf385ab93c9 Files: 8 Total size: 12.9 KB Directory structure: gitextract_powpurr8/ ├── LICENSE ├── README.md ├── api.conf ├── censys_search.py ├── cloudbunny.py ├── requirements.txt ├── shodan_search.py └── zoomeye_search.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Eddy Oliveira Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # CloudBunny CloudBunny is a tool to capture the origin server that uses a WAF as a proxy or protection. You can read more about the tool here: https://tinyurl.com/y8p48wb3
Shodan - https://account.shodan.io/ Censys - https://censys.io/account/api ZoomEye - https://www.zoomeye.org/profileNOTE: In Zoomeye you need to enter the login and password, it generates a dynamic api key and I already do this work for you. Just enter your login and password. After that you need to put the credentials in the api.conf file. Install the requirements:
$ pip3 install -r requirements.txt# Usage By default the tool searches on all search engines (you can set this up by arguments), but you need to put the credentials as stated above. After you have loaded the credentials and installed the requirements, execute:
$ python3 cloudbunny.py -u securityattack.com.brCheck our help area:
$ python3 cloudbunny.py -hChange securityattack.com.br for the domain of your choice. # Example
$ python3 cloudbunny.py -u site_example.com.br
/| __
/ | ,-~ /
Y :| // /
| jj /( .^
>-"~"-v"
/ Y
jo o |
( ~T~ j
>._-' _./
/ "~" |
Y _, |
/| ;-"~ _ l
/ l/ ,-"~ \
\//\/ .- \
Y / Y*
l I !
]\ _\ /"\
(" ~----( ~ Y. )
~~~~~~~~~~~~~~~~~~~~~~~~~~
CloudBunny - Bypass WAF with Search Engines
Author: Eddy Oliveira (@Warflop)
https://github.com/Warflop
[+] Looking for target on Shodan...
[+] Looking for target on Censys...
[+] Looking for certificates on Censys...
[+] Looking for target on ZoomEye...
[-] Just more some seconds...
+---------------+------------+-----------+----------------------------+
| IP Address | ISP | Ports | Last Update |
+---------------+------------+-----------+----------------------------+
| 55.14.232.4 | Amazon.com | [80, 443] | 2018-11-02T16:02:51.074543 |
| 54.222.146.40 | Amazon.com | [80] | 2018-11-02T10:16:38.166829 |
| 18.235.52.237 | Amazon.com | [443, 80] | 2018-11-08T01:22:11.323980 |
| 54.237.93.127 | Amazon.com | [443, 80] | 2018-11-05T15:54:40.248599 |
| 53.222.94.157 | Amazon.com | [443, 80] | 2018-11-06T08:46:03.377082 |
+---------------+------------+-----------+----------------------------+
We may have some false positives :)
================================================
FILE: api.conf
================================================
[shodan]
token =
[censys]
token =
uid =
[zoomeye]
username =
password =
================================================
FILE: censys_search.py
================================================
from __future__ import print_function
from urllib.parse import urlsplit
import censys.certificates
import configparser
import censys.ipv4
import re
config = configparser.ConfigParser()
config.read("api.conf")
TOKEN = config.get('censys', 'token')
UID = config.get('censys', 'uid')
def split_url(url):
if re.match(r'http(s?)\:', url):
parsed = urlsplit(url)
return parsed.netloc
else:
return url
def censys_search(title):
try:
api = censys.ipv4.CensysIPv4(api_id=UID, api_secret=TOKEN)
query = api.search('80.http.get.title: "{0}"'.format(title))
title_result = set([host['ip'] for host in query])
if title_result:
return title_result
except:
print("[-] We got an error here, maybe with your credentials!")
exit(1)
def censys_search_certs(host):
try:
certificates = censys.certificates.CensysCertificates(api_id=UID, api_secret=TOKEN)
cert_query = certificates.search("parsed.names: {0} AND tags.raw: trusted AND NOT parsed.names: cloudflaressl.com".format(host))
result = set([cert['parsed.fingerprint_sha256'] for cert in cert_query])
hosts_query = censys.ipv4.CensysIPv4(api_id=UID, api_secret=TOKEN)
hosts = ' OR '.join(result)
if hosts:
searching = hosts_query.search(hosts)
host_result = set([ search_result['ip'] for search_result in searching ])
return host_result
except:
print("[-] We got an error here, maybe with your credentials!")
exit(1)
================================================
FILE: cloudbunny.py
================================================
from __future__ import print_function
from bs4 import BeautifulSoup
from zoomeye_search import *
from shodan_search import *
from censys_search import *
from random import choice
import cfscrape
import argparse
import re
def banner():
color = ['\033[95m' , '\033[96m', '\033[36m' , '\033[94m' , '\033[92m' , '\033[93m' , '\033[91m']
print(choice(color) + '''
_
(` ). _
( ). .:(` )`.
) _( '`. :( . )
.=(`( . ) .-- `. ( ) )
(( (..__.:'-' .+( ) ` _` ) )
`. `( ) ) ( . ) ( ) ._
) ` __.:' ) ( ( )) `-'.-(` )
) ) ( ) --' `- __.' :( ))
.-' (_.' .') `( ) ))
(_ ) ` __.:'
/| __
/ | ,-~ /
Y :| // /
| jj /( .^
>-"~"-v"
/ Y
jo o |
( ~T~ j
>._-' _./
/ "~" |
Y _, |
/| ;-"~ _ l
/ l/ ,-"~ \
\//\/ .- \
Y / Y*
l I !
]\ _\ /"\
(" ~----( ~ Y. )
~~~~~~~~~~~~~~~~~~~~~~~~~~
CloudBunny - Bypass WAF with Search Engines
Author: Eddy Oliveira (@Warflop)
https://github.com/Warflop \033[0m
''')
def banner_footer():
color = ['\033[95m' , '\033[96m', '\033[36m' , '\033[94m' , '\033[92m' , '\033[93m' , '\033[91m']
print(choice(color) + '''
/\\=//\-"""-.
/ /6 6\ \ \
=\_Y_/= (_ ;{}
/^//_/-/__/
"" "" """
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We may have some false positives :)
\033[0m
''')
def search(url):
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'}
try:
if not re.match(r'http(s?)\:', url):
url = 'http://' + url
scraper = cfscrape.create_scraper()
data = scraper.get(url,headers=headers)
else:
scraper = cfscrape.create_scraper()
data = scraper.get(url,headers=headers)
except:
print("Hey buddy, pass a real address please!")
exit(1)
if data.status_code == 200:
soup = BeautifulSoup(data.text,'html.parser')
for link in soup.title:
return link
else:
print("We had a problem with the URL!")
exit(1)
def main():
resolver = []
parser = argparse.ArgumentParser()
parser.add_argument("-u", '--url', help="Hey buddy, can you give me the URL to test?")
parser.add_argument("-s", '--shodan', action="store_true", help="Use Shodan")
parser.add_argument("-c", '--censys', action="store_true", help="Use Censys")
parser.add_argument("-z", '--zoomeye', action="store_true", help="Use ZoomEye")
args = parser.parse_args()
title = search(args.url).encode('utf-8')
host = split_url(args.url)
if args.shodan or args.censys or args.zoomeye:
if args.shodan:
banner()
print("[+] Looking for target on Shodan...")
if not shodan_search(title) is None:
for shodan_target in shodan_search(title):
if not shodan_target in resolver:
resolver.append(shodan_target)
if args.censys:
print("[+] Looking for target on Censys...")
if not censys_search(title) is None:
for censys_target in censys_search(title):
if not censys_target in resolver:
resolver.append(censys_target)
print("[+] Looking for certificates on Censys...")
if not censys_search_certs(host) is None:
for censys_target_cert in censys_search_certs(host):
if not censys_target_cert in resolver:
resolver.append(censys_target_cert)
if args.zoomeye:
print("[+] Looking for target on ZoomEye...")
if not zoomeye_search(title) is None:
for zoomeye_target in zoomeye_search(title):
if not zoomeye_target in resolver:
resolver.append(zoomeye_target)
if resolver:
print("[*] We found some data wait just one more second...")
print("\n")
result_search(resolver)
else:
print("\n")
print("[-] Looks like our rabbit has not gotten so deep. :(")
banner_footer()
else:
banner()
print("[+] Looking for target on Shodan...")
if not shodan_search(title) is None:
for shodan_target in shodan_search(title):
if not shodan_target in resolver:
resolver.append(shodan_target)
print("[+] Looking for target on Censys...")
if not censys_search(title) is None:
for censys_target in censys_search(title):
if not censys_target in resolver:
resolver.append(censys_target)
print("[+] Looking for certificates on Censys...")
if not censys_search_certs(host) is None:
for censys_target_cert in censys_search_certs(host):
if not censys_target_cert in resolver:
resolver.append(censys_target_cert)
print("[+] Looking for target on ZoomEye...")
if not zoomeye_search(title) is None:
for zoomeye_target in zoomeye_search(title):
if not zoomeye_target in resolver:
resolver.append(zoomeye_target)
if resolver:
print("[-] Just more some seconds...")
print("\n")
result_search(resolver)
else:
print("\n")
print("[-] Looks like our rabbit has not gotten so deep. :(")
banner_footer()
if __name__ == '__main__':
main()
================================================
FILE: requirements.txt
================================================
beautifulsoup4
configparser
PrettyTable
cfscrape
argparse
requests
censys
shodan
urllib
zoomeye
================================================
FILE: shodan_search.py
================================================
from __future__ import print_function
from prettytable import PrettyTable
from shodan import Shodan
import configparser
import requests
config = configparser.ConfigParser()
config.read("api.conf")
token = config.get('shodan', 'token')
api = Shodan(token)
def test_api_shodan(token):
response = requests.get("https://api.shodan.io/api-info?key={0}".format(token))
if response.status_code != 200:
print("[-] We got an error with your shodan credentials.")
exit(1)
def shodan_search(word):
test_api_shodan(token)
try:
banner = api.search_cursor('http.title:"{0}"'.format(word))
title_result = set([host['ip_str'] for host in banner])
if title_result:
return title_result
except:
print("[-] We got an error here!")
exit(1)
def result_search(list_host):
table = PrettyTable(['IP Address','ISP','Ports','Last Update'])
for check in list_host:
try:
host_result = api.host(check)
table.add_row([host_result['ip_str'], host_result['isp'], host_result['ports'], host_result['last_update']])
except:
print("[-] We got an error here!")
exit(1)
print(table)
================================================
FILE: zoomeye_search.py
================================================
from __future__ import print_function
import requests
import configparser
config = configparser.ConfigParser()
config.read("api.conf")
username = config.get('zoomeye', 'username')
password = config.get('zoomeye', 'password')
def zoomeye_search(word):
try:
data = '{ "username": "'+username+'", "password": "'+password+'" }'
response = requests.post('https://api.zoomeye.org/user/login', data=data)
token = response.json()['access_token']
except:
print("[-] We got an error with your zoomeye credentials. (Check if zoomeye is down ¯\_(ツ)_/¯)")
exit(1)
try:
headers = {
'Authorization': 'JWT {0}'.format(token),
}
params = {
('query', 'title: "{0}"'.format(word))
}
response = requests.get('https://api.zoomeye.org/host/search', headers=headers, params=params)
final = response.json()['matches']
title_result = set([host['ip'] for host in final])
if title_result:
return title_result
except:
print("[-] We got an error here!")
exit(1)