-
Notifications
You must be signed in to change notification settings - Fork 11
/
findmytakeover.py
executable file
·194 lines (156 loc) · 7.41 KB
/
findmytakeover.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env python3
import argparse
import yaml
import click
import os
import pandas as pd
import ipaddress
def readConfig(data):
dnsprovider = {}
infraprovider = {}
exclude = []
# Loading the YAML configuration
cf = open(data, "rt")
try:
config = yaml.safe_load(cf)
except yaml.YAMLError:
print('Invalid YAML file!')
exit(1)
# Reading the configuration file for runtime configuration
try:
if "exclude" in config.keys():
for ipadd in config["exclude"]["ipaddress"]:
for ip in ipaddress.IPv4Network(ipadd):
exclude.append(str(ip))
for domains in config["exclude"]["domains"]:
exclude.append(str(domains))
except KeyError:
click.echo("Invalid Configuration! please check the findmytakeover section in configuration file.")
exit(1)
# Reading the configuration file for DNS providers
try:
if "dns" in config.keys():
for i in config["dns"]:
if config["dns"][i]["enabled"] == True:
dnsprovider[i] = {"credentials": config["dns"][i]["credentials"], "accounts": config["dns"][i]["accounts"]}
if None in dnsprovider[i].values():
raise KeyError
else:
click.echo("Invalid Configuration! please check that DNS provider is configured.")
if dnsprovider == {}:
click.echo("Invalid Configuration! please check atleast one DNS provider needs to be enabled.")
if None in dnsprovider.values():
raise KeyError
except KeyError:
click.echo("Invalid Configuration! please check the DNS section in configuration file.")
exit(1)
# Reading the configuration file for Infrastructure
try:
if "infra" in config.keys():
for i in config["infra"]:
if config["infra"][i]["enabled"] == True:
infraprovider[i] = {"credentials": config["infra"][i]["credentials"], "accounts": config["infra"][i]["accounts"]}
if None in infraprovider[i].values():
raise KeyError
else:
click.echo("Invalid Configuration! please check that Infrastructure provider is configured.")
if infraprovider == {}:
click.echo("Invalid Configuration! please check atleast one Infrastructure provider needs to be enabled.")
if None in infraprovider.values():
raise KeyError
except KeyError:
click.echo("Invalid Configuration! please check the Infrastructure section in configuration file.")
exit(1)
return dnsprovider, infraprovider, exclude
def main():
CLI_PROMPT=r"""
__ _ _ _ _
/ _(_) | | | | | |
| |_ _ _ __ __| |_ __ ___ _ _| |_ __ _| | _____ _____ _____ _ __
| _| | '_ \ / _` | '_ ` _ \| | | | __/ _` | |/ / _ \/ _ \ \ / / _ \ '__|
| | | | | | | (_| | | | | | | |_| | || (_| | < __/ (_) \ V / __/ |
|_| |_|_| |_|\__,_|_| |_| |_|\__, |\__\__,_|_|\_\___|\___/ \_/ \___|_|
__/ |
|___/
"""
click.secho(CLI_PROMPT, bold=True, fg='green')
# Read the arguments that have been passed in to the program.
parser = argparse.ArgumentParser()
parser.add_argument(
"-c",
"--config-file",
default=os.getcwd() + "/findmytakeover.config",
type=str,
help="Enter the path to the configuration file that you want the tool to use."
)
parser.add_argument(
"-d",
"--dump-file",
type=str,
help="Enter the path to where all the DNS and Infrastructre data would be saved."
)
args = parser.parse_args()
click.echo("Reading the config from file - " + args.config_file)
dns, infra, exclude = readConfig(args.config_file)
# print(dns, infra, exclude)
recordlist = []
infrastructurelist = []
# parse the provider and invoke appropriate collector
for d in dns:
if d == "aws":
from collector.aws import aws
awsdns = aws.dns(dns["aws"]["accounts"], dns["aws"]["credentials"])
for f in awsdns:
recordlist.append(["Amazon Web Services", f[0], f[1], f[2]])
elif d == "gcp":
from collector.gcp import gcp
gcpdns = gcp.dns(dns["gcp"]["accounts"], dns["gcp"]["credentials"])
for f in gcpdns:
recordlist.append(["Google Cloud Platform", f[0], f[1], f[2]])
elif d == "azure":
from collector.msazure import azure
azuredns = azure.dns(dns["azure"]["accounts"], dns["azure"]["credentials"])
for f in azuredns:
recordlist.append(["Microsoft Azure", f[0], f[1], f[2]])
else:
print("The DNS provider configured" + d + "is not supported by the tool. Please read the documentation.")
records = pd.DataFrame(recordlist, columns=['csp', 'account', 'dnskey', 'dnsvalue'])
for i in infra:
if i == "aws":
from collector.aws import aws
awsinfra = aws.infra(infra["aws"]["accounts"], infra["aws"]["credentials"])
for f in awsinfra:
infrastructurelist.append(["Amazon Web Services", f[0], f[1], f[2]])
elif i == "gcp":
from collector.gcp import gcp
gcpinfra = gcp.infra(infra["gcp"]["accounts"], infra["gcp"]["credentials"])
for f in gcpinfra:
infrastructurelist.append(["Google Cloud Platform", f[0], f[1], f[2]])
elif i == "azure":
from collector.msazure import azure
azureinfra = azure.infra(dns["azure"]["accounts"], dns["azure"]["credentials"])
for f in azureinfra:
infrastructurelist.append(["Microsoft Azure", f[0], f[1], f[2]])
else:
print("The Infrastructure provider configured" + d + "is not supported by the tool. Please read the documentation.")
infrastructure = pd.DataFrame(infrastructurelist, columns=['csp', 'account', 'service', 'value'])
# Dumping data
if args.dump_file:
print("Dumping data at file at - " + args.dump_file)
infrastructure.to_csv(args.dump_file, mode="a")
with open(args.dump_file, 'a') as f:
f.write("--" * 50)
records.to_csv(args.dump_file, mode="a")
if dns != {} or infra != {}:
result = pd.merge(records, infrastructure, left_on='dnsvalue', right_on='value', how='left').fillna(value="")
# Checking for exclusions in the results
for f in exclude:
df = df[~df['result'].str.contains(i)]
click.echo("Checking for possible dangling DNS records!")
for i in result.index:
if result['value'][i] == "":
click.echo("Found dangling DNS record - " + str(result["dnskey"][i]) + " with the value "+ str(result["dnsvalue"][i]) + " in " + str(result["csp_x"][i]) + " cloud in the account/subscription/project - " + str(result["account_x"][i]))
else:
print("To check for dangling domains, both DNS and Infrastructure provider needs to be configured.")
if __name__ == "__main__":
main()