From 5c0f0b7bf47a633c3a362c9379eeae2b2a5d4a12 Mon Sep 17 00:00:00 2001 From: Anshuman Bhartiya Date: Fri, 4 Aug 2017 13:13:17 -0700 Subject: [PATCH 1/4] Added argparser --- .gitignore | 2 ++ README.md | 45 +++++++---------------------- cloudflare_enum.py | 72 ++++++++++++++++++++++++---------------------- 3 files changed, 51 insertions(+), 68 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..972062a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +env/ +.vscode/ \ No newline at end of file diff --git a/README.md b/README.md index 101cfbb..2510223 100644 --- a/README.md +++ b/README.md @@ -2,38 +2,15 @@ A simple tool to allow easy querying of Cloudflare's DNS data written in Python. -```sh -mandatory@mandatorys-box /t/cloudflare_enum> ./cloudflare_enum.py thehackerblog@yopmail.com Testing1 disney.com -[ STATUS ] Logging in to Cloudflare... -[ SUCCESS ] Login was successful! -[ STATUS ] Adding domain to Cloudflare... -[ SUCCESS ] Querying Cloudflare DNS archives... -A: disney.com -> 199.181.132.249 -A: api.disney.com -> 96.45.49.200 -A: app.disney.com -> 208.218.3.17 -A: apps.disney.com -> 199.181.132.250 -A: archive.disney.com -> 198.105.199.57 -A: archives.disney.com -> 199.181.132.250 -A: data.disney.com -> 10.190.71.248 -A: feeds.disney.com -> 198.105.197.192 -A: home.disney.com -> 199.181.132.250 -A: huey11.disney.com -> 192.195.66.12 -A: huey.disney.com -> 204.128.192.10 -A: localhost.disney.com -> 127.0.0.1 -A: louie.disney.com -> 204.128.192.30 -A: mail2.disney.com -> 204.128.192.16 -A: mail.disney.com -> 204.128.192.15 -A: m.disney.com -> 199.181.132.250 -A: mx1.disney.com -> 192.195.66.26 -A: mx1.disney.com -> 204.128.192.17 -A: mx2.disney.com -> 192.195.66.28 -A: mx2.disney.com -> 204.128.192.36 -A: services.disney.com -> 204.202.143.170 -A: services.disney.com -> 204.202.143.171 -A: webcache.disney.com -> 204.128.192.55 -A: webcast.disney.com -> 207.177.177.41 -A: www1.disney.com -> 199.181.132.250 -A: www2.disney.com -> 199.181.132.250 -CNAME: code.disney.com -> matterhorn.disney.com -...etc... ``` + +``` + +## Requirements + +* pip install requests +* pip install bs4 + +## Notes + +Make sure you don't have a `&` in the password of your Cloudflare account. diff --git a/cloudflare_enum.py b/cloudflare_enum.py index 6f52e06..28e8791 100755 --- a/cloudflare_enum.py +++ b/cloudflare_enum.py @@ -3,6 +3,7 @@ # Created using Metafidv2 by Matthew Bryant (mandatory) # Unauthorized use is stricly prohibited, please contact mandatory@gmail.com with questions/comments. import requests +import argparse import json import time import csv @@ -16,7 +17,6 @@ def __init__( self ): self.global_headers = { } self.verbose = True - self.s = requests.Session() self.s.headers.update( self.global_headers ) self.atok = '' @@ -119,44 +119,44 @@ def get_domain_dns( self, domain ): return return_data['result'] - def get_spreadsheet( self, domain ): + def get_spreadsheet( self, domain, output ): dns_data = self.get_domain_dns( domain ) if dns_data: - filename = domain.replace( ".", "_" ) + ".csv" + # filename = domain.replace( ".", "_" ) + ".csv" - with open( filename, 'wb' ) as csvfile: + with open( output, 'wb' ) as csvfile: dns_writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) dns_writer.writerow( [ "name", "type", "content" ] ) for record in dns_data: dns_writer.writerow( [ record["name"], record["type"], record["content"] ] ) - - self.statusmsg( "Spreadsheet created at " + os.getcwd() + "/" + filename ) + + self.statusmsg( "Spreadsheet created at " + output ) def print_banner( self ): if self.verbose: print """ - - `..--------..` - .-:///::------::///:.` - `-//:-.`````````````.-://:.` ` ` - .://-.```````````````````.-://-` : `- . - `-//:.........................-://. /. -: `:` `` - `://--------:::://////:::--------://-::.::`:- .:. - ``.---..` `///::::::///////////////////:::::::///::::::--:.`.-. - .://::::///::///::///////////////////////////:::///:-----::--:-` ` - `:/:-...--:://////////////////////////////////////////----------.--.` - `:/:..-:://////////////////////////////////////////////-----------.```` - .//-::////////////////////////////////////:::::////////-...--------...` - -/////////////////////////////////////////////::::----:. `.-::::::-..`` - ``.--:////////////////////////////////////////////////::-..```-///::::///:-` - `.:///::::://////////////////////////////////////:::::::::::::::-----......-:/:. - `-//:-----::::://///////////////////////////////:///////////////////:-::::---..-//:` - `:/:---://+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//+++//::--//: - `//:-/+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++oooo+//://. - :///ossssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssosssssso+//: - `//+sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss+/- - `//+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++++/. - `````````````````````````````````````````````````````````````````````````````````````` + + `..--------..` + .-:///::------::///:.` + `-//:-.`````````````.-://:.` ` ` + .://-.```````````````````.-://-` : `- . + `-//:.........................-://. /. -: `:` `` + `://--------:::://////:::--------://-::.::`:- .:. + ``.---..` `///::::::///////////////////:::::::///::::::--:.`.-. + .://::::///::///::///////////////////////////:::///:-----::--:-` ` + `:/:-...--:://////////////////////////////////////////----------.--.` + `:/:..-:://////////////////////////////////////////////-----------.```` + .//-::////////////////////////////////////:::::////////-...--------...` + -/////////////////////////////////////////////::::----:. `.-::::::-..`` + ``.--:////////////////////////////////////////////////::-..```-///::::///:-` + `.:///::::://////////////////////////////////////:::::::::::::::-----......-:/:. + `-//:-----::::://///////////////////////////////:///////////////////:-::::---..-//:` + `:/:---://+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//+++//::--//: + `//:-/+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++oooo+//://. + :///ossssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssosssssso+//: + `//+sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss+/- + `//+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++++/. + `````````````````````````````````````````````````````````````````````````````````````` Cloudflare DNS Enumeration Tool v1.2 By mandatory """ @@ -201,15 +201,19 @@ def get_cookie_from_file( self, cookie_file ): for i, item in enumerate(data): if " " in data[i]: pew = data[i].split( " " ) - return_dict[ pew[5] ] = pew[6] + return_dict[ pew[5] ] = pew[6] return return_dict if __name__ == "__main__": - if len( sys.argv ) < 3: - print "Usage: " + sys.argv[0] + " username@email.com password domain.com" - else: + parser = argparse.ArgumentParser(description='Process Cloudflare Enum arguments.') + parser.add_argument("-e", "--email", help="Cloudflare account email", required=True) + parser.add_argument("-p", "--password", help="Cloudflare account password", required=True) + parser.add_argument("-d", "--domain", help="Target domain", required=True) + parser.add_argument("-o", "--output", help="Output filename", required=True) + args = parser.parse_args() + cloud = cloudflare_enum() cloud.print_banner() - cloud.log_in( sys.argv[1], sys.argv[2] ) - cloud.get_spreadsheet( sys.argv[3] ) + cloud.log_in( args.email, args.password ) + cloud.get_spreadsheet( args.domain, args.output ) From d3797c0a6ebe2ca826de7470237db25ff5a4a7da Mon Sep 17 00:00:00 2001 From: Anshuman Bhartiya Date: Fri, 4 Aug 2017 13:37:10 -0700 Subject: [PATCH 2/4] Added Dockerfile --- .gitignore | 3 ++- Dockerfile | 13 +++++++++++++ README.md | 10 +++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 Dockerfile diff --git a/.gitignore b/.gitignore index 972062a..356cfa5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ env/ -.vscode/ \ No newline at end of file +.vscode/ +*.csv \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f1d0e34 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:2.7 + +MAINTAINER anshuman.bhartiya@gmail.com + +RUN mkdir /opt/cloudflare-enum +WORKDIR /opt/cloudflare-enum + +RUN pip install requests +RUN pip install bs4 + +ADD cloudflare_enum.py /opt/cloudflare-enum/ + +ENTRYPOINT ["./cloudflare_enum.py"] \ No newline at end of file diff --git a/README.md b/README.md index 2510223..c69a020 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,18 @@ A simple tool to allow easy querying of Cloudflare's DNS data written in Python. ``` +./cloudflare_enum.py -e test@gmail.com -p testing -d test.com -o /tmp/cf.csv +``` + +If you want to run using Docker, +``` +docker run -it abhartiya/tools_cfenum -e test@gmail.com -p testing -d test.com -o /tmp/cf.csv +docker ps -a +docker cp :/tmp/cf.csv . ``` -## Requirements +## Requirements if running without Docker * pip install requests * pip install bs4 From b509c4e99d07ec42cc5baffb2989a60d43267fd8 Mon Sep 17 00:00:00 2001 From: Anshuman Bhartiya Date: Fri, 4 Aug 2017 15:50:11 -0700 Subject: [PATCH 3/4] added code to print csv even when no results --- cloudflare_enum.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cloudflare_enum.py b/cloudflare_enum.py index 28e8791..94ca63d 100755 --- a/cloudflare_enum.py +++ b/cloudflare_enum.py @@ -126,11 +126,19 @@ def get_spreadsheet( self, domain, output ): with open( output, 'wb' ) as csvfile: dns_writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) - dns_writer.writerow( [ "name", "type", "content" ] ) + # dns_writer.writerow( [ "name", "type", "content" ] ) for record in dns_data: dns_writer.writerow( [ record["name"], record["type"], record["content"] ] ) self.statusmsg( "Spreadsheet created at " + output ) + else: + with open( output, 'wb' ) as csvfile: + dns_writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) + # dns_writer.writerow( [ "name", "type", "content" ] ) + dns_writer.writerow( [ domain, "NA", "NA" ] ) + + self.statusmsg( "Spreadsheet created at " + output ) + def print_banner( self ): if self.verbose: From 28c2be26671cad199a77203ff85d31fef8a9ad29 Mon Sep 17 00:00:00 2001 From: Anshuman Bhartiya Date: Wed, 18 Jul 2018 02:56:18 -0700 Subject: [PATCH 4/4] fixed a bug --- cloudflare_enum.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cloudflare_enum.py b/cloudflare_enum.py index 94ca63d..c7aed9f 100755 --- a/cloudflare_enum.py +++ b/cloudflare_enum.py @@ -45,6 +45,7 @@ def log_in( self, username, password ): self.s.headers.update( dict( new_headers.items() + self.global_headers.items() ) ) r = self.s.post('https://www.cloudflare.com/a/login', data=post_data) self.atok = self.find_between_r( r.text, 'window.bootstrap = {"atok":"', '","locale":"' ) # http://xkcd.com/292/ + self.cookie = r.cookies['vses2'] def get_domain_dns( self, domain ): parse_dict = {} @@ -71,7 +72,8 @@ def get_domain_dns( self, domain ): 'X-ATOK': self.atok, } self.s.headers.update( dict( new_headers.items() + self.global_headers.items() ) ) - r = self.s.post('https://www.cloudflare.com/api/v4/zones', data=json.dumps( post_data )) + c = {'vses2': self.cookie} + r = self.s.post('https://www.cloudflare.com/api/v4/zones', data=json.dumps( post_data ), cookies=c) data = json.loads( r.text ) success = data['success'] if not success: