-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimple-sinkhole.py
executable file
·148 lines (100 loc) · 3.32 KB
/
simple-sinkhole.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
#!/usr/bin/env python2
import ConfigParser
import argparse
import pdb
import tempfile
import os
import urllib
import re
import sqlite3
def configure_parser():
parser = argparse.ArgumentParser(description='''Simple DNS sinkhole script, for use with dnsmasqd. Meant to be lightweight and fast.''')
parser.add_argument('-c', '--config', help='Config file')
parser.add_argument('-l', '--listsfolder', help='List config folder')
parser.add_argument('-i', '--sinkholeip', help='Destination IP address')
parser.add_argument('-f', '--hostsfile', help='Hosts file')
parser.add_argument('-d', '--database', help="Database file")
parser.add_argument('-o', '--hostsbase', help="Base host file (will be at top of new hosts file)")
return parser
def create_database(file_db):
conn = sqlite3.connect(file_db)
try:
conn.execute('''CREATE TABLE list_data (domain text, url text)''')
except:
pass
return conn
if __name__ == "__main__":
parser = configure_parser()
args = parser.parse_args()
if not args.config:
print("Error: You must at least specify a config file.")
parser.print_help()
exit(1)
config = ConfigParser.ConfigParser()
try:
config.read(args.config)
except:
print("Config file invalid. Please specify a valid config file")
parser.print_help()
exit(1)
if not config.sections():
print("Config file invalid. Please specify a valid config file")
parser.print_help()
exit(1)
config_options = {}
for o in vars(args).keys():
if o != 'config':
if vars(args).get(o, None):
config_options[o] = vars(args).get(o, None)
elif o in config.options('MainConfig'):
config_options[o] = config.get('MainConfig', o)
else:
print("Missing option %s. Please specify a valid config file or specify on command line" % o)
parser.print_help()
exit(1)
conn = create_database(config_options['database'])
cur = conn.cursor()
for f in os.listdir(config_options['listsfolder']):
if f.endswith(".conf"):
cur.execute('delete from list_data where domain = ?', (f,))
listfile = open(os.path.join(config_options['listsfolder'], f), 'r')
list_options = eval(listfile.read())
if not list_options.get('source', False):
print("Missing source in %f. Skipping")
pass
starting_line = list_options.get('prelines', 0)
if list_options.get('pre', False):
started = False
pre = list_options.get('pre')
else:
started = True
pre = None
post = list_options.get('post', False)
regex = list_options.get('regex', False)
u = urllib.urlopen(list_options['source'])
for i, line in enumerate(u):
if i < starting_line:
pass
elif started == False:
if line.rstrip() == pre:
started = True
elif post and post == line.rstrip():
break
else:
# pdb.set_trace()
m = re.search(regex, line.rstrip())
try:
cur.execute("insert into list_data (domain, url) values (?, ?)", (f, m.group(1)))
except:
print("Error inserting line %s: %s" % (i, line))
conn.commit()
cur.execute('select distinct url from list_data')
urls = cur.fetchall()
hosts = open(config_options['hostsfile'], 'w')
hosts_b = open(config_options['hostsbase'], 'r')
hosts_base = hosts_b.read()
hosts_b.close()
hosts.write(hosts_base)
for u in urls:
hosts.write('%s\t%s\n' % (config_options['sinkholeip'], u[0]))
hosts.close()