From d8d9bb1046507db088be07e573b7c11fc4d4fb30 Mon Sep 17 00:00:00 2001 From: 0c0c0f <892850447@qq.com> Date: Fri, 23 Dec 2016 15:21:44 +0800 Subject: [PATCH] Create cloudflare_enum.py https://github.com/mandatoryprogrammer/cloudflare_enum --- info/cloudflare_enum.py | 215 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 info/cloudflare_enum.py diff --git a/info/cloudflare_enum.py b/info/cloudflare_enum.py new file mode 100644 index 0000000..6f52e06 --- /dev/null +++ b/info/cloudflare_enum.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Created using Metafidv2 by Matthew Bryant (mandatory) +# Unauthorized use is stricly prohibited, please contact mandatory@gmail.com with questions/comments. +import requests +import json +import time +import csv +import sys +import os +from bs4 import BeautifulSoup + +class cloudflare_enum: + def __init__( self ): + # Master list of headers to be used in each connection + self.global_headers = { + } + self.verbose = True + + self.s = requests.Session() + self.s.headers.update( self.global_headers ) + self.atok = '' + + def log_in( self, username, password ): + parse_dict = {} + + r = self.s.get('https://www.cloudflare.com/', ) + + new_headers = { + 'Referer': 'https://www.cloudflare.com/', + } + self.s.headers.update( dict( new_headers.items() + self.global_headers.items() ) ) + r = self.s.get('https://www.cloudflare.com/a/login', ) + parse_dict[ 'security_token_0' ] = self.find_between_r( r.text, '"security_token":"', '"}};' ) # http://xkcd.com/292/ + + post_data = { + 'email': username, + 'password': password, + 'security_token': parse_dict[ 'security_token_0' ], + } + new_headers = { + 'Referer': 'https://www.cloudflare.com/a/login', + 'Content-Type': 'application/x-www-form-urlencoded', + } + 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/ + + def get_domain_dns( self, domain ): + parse_dict = {} + post_data = { + "betas": [], + "created_on": "2015-08-24T00:27:16.048Z", + "development_mode": False, + "jump_start": True, + "meta": {}, + "modified_on": 'null', + "name": domain, + "owner": {}, + "paused": False, + "status": "initializing", + "type": "full" + } + + new_headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Requested-With': 'XMLHttpRequest', + 'Referer': 'https://www.cloudflare.com/a/add-site', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + '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 )) + data = json.loads( r.text ) + success = data['success'] + if not success: + print r.text + return False + + request_id = data['result']['id'] + time.sleep( 60 ) + + get_data = { + 'per_page': '100', + 'direction': 'asc', + 'page': '1', + 'order': 'type', + } + new_headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'Referer': 'https://www.cloudflare.com/a/setup/' + domain + '/step/2', + 'X-ATOK': self.atok, + } + self.s.headers.update( dict( new_headers.items() + self.global_headers.items() ) ) + r = self.s.get('https://www.cloudflare.com/api/v4/zones/' + request_id + '/dns_records', params=get_data) + return_data = json.loads( r.text ) + + new_headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'Referer': 'https://www.cloudflare.com/a/setup/' + domain + '/step/2', + 'X-ATOK': self.atok, + } + self.s.headers.update( dict( new_headers.items() + self.global_headers.items() ) ) + r = self.s.delete('https://www.cloudflare.com/api/v4/zones/' + request_id, ) + + get_data = { + 'status': 'initializing,pending', + 'per_page': '50', + 'page': '1', + } + new_headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'Referer': 'https://www.cloudflare.com/a/add-site', + 'X-ATOK': self.atok, + } + self.s.headers.update( dict( new_headers.items() + self.global_headers.items() ) ) + r = self.s.get('https://www.cloudflare.com/api/v4/zones', params=get_data) + + return return_data['result'] + + def get_spreadsheet( self, domain ): + dns_data = self.get_domain_dns( domain ) + if dns_data: + filename = domain.replace( ".", "_" ) + ".csv" + + with open( filename, '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 ) + + def print_banner( self ): + if self.verbose: + print """ + + `..--------..` + .-:///::------::///:.` + `-//:-.`````````````.-://:.` ` ` + .://-.```````````````````.-://-` : `- . + `-//:.........................-://. /. -: `:` `` + `://--------:::://////:::--------://-::.::`:- .:. + ``.---..` `///::::::///////////////////:::::::///::::::--:.`.-. + .://::::///::///::///////////////////////////:::///:-----::--:-` ` + `:/:-...--:://////////////////////////////////////////----------.--.` + `:/:..-:://////////////////////////////////////////////-----------.```` + .//-::////////////////////////////////////:::::////////-...--------...` + -/////////////////////////////////////////////::::----:. `.-::::::-..`` + ``.--:////////////////////////////////////////////////::-..```-///::::///:-` + `.:///::::://////////////////////////////////////:::::::::::::::-----......-:/:. + `-//:-----::::://///////////////////////////////:///////////////////:-::::---..-//:` + `:/:---://+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//+++//::--//: + `//:-/+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++oooo+//://. + :///ossssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssosssssso+//: + `//+sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss+/- + `//+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++++/. + `````````````````````````````````````````````````````````````````````````````````````` + Cloudflare DNS Enumeration Tool v1.2 + By mandatory + """ + + + def pprint( self, input_dict ): + print json.dumps(input_dict, sort_keys=True, indent=4, separators=(',', ': ')) + + def statusmsg( self, msg ): + if self.verbose: + print "[ STATUS ] " + msg + + def errormsg( self, msg ): + if self.verbose: + print "[ ERROR ] " + msg + + def successmsg( self, msg ): + if self.verbose: + print "[ SUCCESS ] " + msg + + def find_between_r( self, s, first, last ): + try: + start = s.rindex( first ) + len( first ) + end = s.rindex( last, start ) + return s[start:end] + except ValueError: + return "" + + def find_between( s, first, last ): + try: + start = s.index( first ) + len( first ) + end = s.index( last, start ) + return s[start:end] + except ValueError: + return "" + + def get_cookie_from_file( self, cookie_file ): + return_dict = {} + with open( cookie_file ) as tmp: + data = tmp.readlines() + tmp_data = [] + for i, item in enumerate(data): + if " " in data[i]: + pew = data[i].split( " " ) + 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: + cloud = cloudflare_enum() + cloud.print_banner() + cloud.log_in( sys.argv[1], sys.argv[2] ) + cloud.get_spreadsheet( sys.argv[3] )