Full Code of Warflop/CloudBunny for AI

master 5cf385ab93c9 cached
8 files
12.9 KB
3.7k tokens
11 symbols
1 requests
Download .txt
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

<p align="center">
<img src="https://i.imgur.com/CyGo02V.gif">
</p>

# How works

In this tool we used three search engines to search domain information: Shodan, Censys and Zoomeye. To use the tools you need the API Keys, you can pick up the following links:

<pre>
<b>Shodan</b> - https://account.shodan.io/
<b>Censys</b> - https://censys.io/account/api
<b>ZoomEye</b> - https://www.zoomeye.org/profile
</pre>

<b>NOTE</b>: 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 <b>api.conf</b> file.

Install the requirements:

<pre>
$ pip3 install -r requirements.txt
</pre>

# 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:

<pre>
$ python3 cloudbunny.py -u securityattack.com.br
</pre>

Check our help area:

<pre>
$ python3 cloudbunny.py -h
</pre>

Change <b>securityattack.com.br</b> for the domain of your choice.

# Example

<pre>

$ 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 :)
</pre>


================================================
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)
		
Download .txt
gitextract_powpurr8/

├── LICENSE
├── README.md
├── api.conf
├── censys_search.py
├── cloudbunny.py
├── requirements.txt
├── shodan_search.py
└── zoomeye_search.py
Download .txt
SYMBOL INDEX (11 symbols across 4 files)

FILE: censys_search.py
  function split_url (line 13) | def split_url(url):
  function censys_search (line 20) | def censys_search(title):
  function censys_search_certs (line 32) | def censys_search_certs(host):

FILE: cloudbunny.py
  function banner (line 11) | def banner():
  function banner_footer (line 52) | def banner_footer():
  function search (line 68) | def search(url):
  function main (line 95) | def main():

FILE: shodan_search.py
  function test_api_shodan (line 12) | def test_api_shodan(token):
  function shodan_search (line 19) | def shodan_search(word):
  function result_search (line 35) | def result_search(list_host):

FILE: zoomeye_search.py
  function zoomeye_search (line 10) | def zoomeye_search(word):
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (15K chars).
[
  {
    "path": "LICENSE",
    "chars": 1070,
    "preview": "MIT License\n\nCopyright (c) 2018 Eddy Oliveira\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
  },
  {
    "path": "README.md",
    "chars": 2850,
    "preview": "# CloudBunny\n\nCloudBunny is a tool to capture the origin server that uses a WAF as a proxy or protection.\n\nYou can read "
  },
  {
    "path": "api.conf",
    "chars": 76,
    "preview": "[shodan]\n\ntoken =\n\n[censys]\n\ntoken =\nuid =\n\n[zoomeye]\n\nusername =\npassword ="
  },
  {
    "path": "censys_search.py",
    "chars": 1582,
    "preview": "from __future__ import print_function\nfrom urllib.parse import urlsplit \nimport censys.certificates\nimport configparser\n"
  },
  {
    "path": "cloudbunny.py",
    "chars": 5454,
    "preview": "from __future__ import print_function\nfrom bs4 import BeautifulSoup\nfrom zoomeye_search import *\nfrom shodan_search impo"
  },
  {
    "path": "requirements.txt",
    "chars": 95,
    "preview": "beautifulsoup4\nconfigparser\nPrettyTable\ncfscrape\nargparse\nrequests\ncensys\nshodan\nurllib\nzoomeye"
  },
  {
    "path": "shodan_search.py",
    "chars": 1104,
    "preview": "from __future__ import print_function\nfrom prettytable import PrettyTable\nfrom shodan import Shodan\nimport configparser\n"
  },
  {
    "path": "zoomeye_search.py",
    "chars": 998,
    "preview": "from __future__ import print_function\nimport requests\nimport configparser\n\nconfig = configparser.ConfigParser()\nconfig.r"
  }
]

About this extraction

This page contains the full source code of the Warflop/CloudBunny GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (12.9 KB), approximately 3.7k tokens, and a symbol index with 11 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!