-
Notifications
You must be signed in to change notification settings - Fork 3
/
torScannerDecide.py
339 lines (268 loc) · 9.79 KB
/
torScannerDecide.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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#!/usr/bin/pyton
# coding=<utf-8>
import pprint
import sys
import random
import Queue
import threading
import time
import socket
from math import floor,ceil
from TorCtl import TorCtl
import findexit
import datetime
import sys
import ConfigParser
import decoClass
import pickle
import glob
import os
import db2
from torHelper import *
from logic import *
# sometimes I believe compiler ignores all my comments
configFile = "/opt/config.ini"
configPar = ConfigParser.ConfigParser()
configDic={}
torPortSockList=[]
torPortCtlList=[]
nodesWeb='' # nodi da l'internet
nodesRelevant='' # nodi dal db rileventi
nodesFiltered=[] # nodi (internet intercept rilevanti)
nodesFiltered2=[] # IP x porte - (IP x porte)scannati
scanDate='' # Quella che mi dice la giornata di scan, non il timestamp vero e proprio
workQueueList=[]# la vera e propria lista di code che uso per il lavoro sporco
usedExitRoute=[] #lista per vedere quali ho gia scelto
####################################
####################################
####################################
####################################
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
# Connect to socks proxy tor
#s = socks.socksocket()
#s.setblocking(0)
#s.setproxy(socks.PROXY_TYPE_SOCKS5, 'localhost', 9050)
#s.settimeout(30)
@timeMeasure
def getAndSetConfig():
""" Reading config from file"""
print "-> Reading conf from file",
configDic={}
global torPortSockList
global torPortCtlList
configPar.read(configFile)
options = configPar.options("Scanner")
for option in options:
try:
configDic[option] = configPar.get("Scanner", option)
if configDic[option] == -1:
DebugPrint("skip: %s" % option)
except Exception as e:
print e
print("exception on %s!" % option)
configDic[option] = None
options = configPar.options("Tor")
for option in options:
try:
configDic[option] = configPar.get("Tor", option)
if configDic[option] == -1:
DebugPrint("skip: %s" % option)
except Exception as e:
print e
print("exception on %s!" % option)
configDic[option] = None
options = configPar.options("DB")
for option in options:
try:
configDic[option] = configPar.get("DB", option)
if configDic[option] == -1:
DebugPrint("skip: %s" % option)
except Exception as e:
print e
print("exception on %s!" % option)
configDic[option] = None
configDic["torportsock"]=int(configDic["torportsock"])
configDic["torportctl"]=int(configDic["torportctl"])
return configDic
@timeMeasure
def getPortToScan():
"Legge da file la lista di porte da scannare"
print "-> Reading port from file",
files=open(configDic['portfile'], "r")
ports=files.read()
porte=ports.split( )
return porte[0]
# Remove the first line from the ports.conf file.
# that's because we used the first port in the file for the scan
@timeMeasure
def saveCurrentStatus(configDic):
print "-> Removing port ", port, "from ", configDic['portfile'],
lines = open(configDic['portfile']).readlines()
open(configDic['portfile'], 'w').writelines(lines[1:])
#Estraggo i nodi RILEVANTI per la rete tor
@timeMeasure
def getRelevantNodes(conn):
print "-> Querying DB for discovering relevant nodes",
nodesRelevant = db2.getRelevantNodesDb(conn) #ok
return nodesRelevant
# Leggo i NODI che hanno gia' avuto quella porta scannata
@timeMeasure
def getAlreadyScannedComb(conn, port):
print "-> Reading already scanned results: ",
scannedComb = db2.getScannedCombDb(conn, port) #ok
print " ( ", len(scannedComb), " )",
return scannedComb
#Estraggo i nodi che ho gia' usato per qualche connessione
@timeMeasure
def filterUsedExitNodes(conn, exitLists):
"""
Qui attenzione: seleziono solo i nodi usati per scannare nodi per i quali non ho ancora terminato la scansione.
In questo modo non "perdo" in questo passaggio gli exit usati per scannare un nodo per il quale
ho terminato la scansione. Se ho scannato tutte le porte del nodo A con 100 exit e' inutile che scarti questi
100 exit. Mentre e' utile che scarti gli exit gia' usati per un nodo dove il count distinct delle porte e'
minore del numero di porte che devo scannare.
"""
# This is O(scary), but seems quick enough in practice.
print "-> Querying DB for discovering, and then filtering all used exit nodes",
usedExits = db2.getUsedExitNodesDb(conn) #ok
usedExitsUnicode=[]
# creo una lista decente sulla quale fare il filtro
for i in usedExits:
usedExitsUnicode.append(i[0])
filteredExits=[a for a in exitLists if a[1] not in usedExitsUnicode ]
print "- ExitNodes was", len(exitLists), ", we got from DB ", len(usedExits), ", and now we have: ", len(filteredExits)
#print "exitList"
#print exitLists
#print "usedExits"
#print usedExits
#print "filteredExits"
#print filteredExits
return filteredExits
def deleteExitpickledFiles():
path = '/mnt/ramfs'
for rmfile in glob.glob( os.path.join(path, '*.exits') ):
os.remove(rmfile)
#######################################
#######################################
############# START ###################
# Autogenerated, do not edit. ##
# All changes will be undone. ##
#######################################
#######################################
sys.stdout=Unbuffered(sys.stdout)
scanDate = datetime.datetime.fromtimestamp(time.time())
timestart =time.time()
#When I wrote this, only God and I understood what I was doing
#Now, God only knows
print "-> Start at ", scanDate, " [K]"
# Leggo la configurazione da un file di testo in formato .ini
# contiene le informazioni sull'accesso al db e su tor
#
configDic = getAndSetConfig() #k
# Configure tor for us
# Rimuovo tutti gli exit node impostati automaticamente
# e imposto i parametri in modo che non crei altri circuits
configTor(configDic["torportctl"], configDic["password"])
# Leggiamo da un file le porte da scannare
# Dovrebbero essere 120 circa
# Sono state selezionate da un file di nmap, ordinate per priorita'
port=getPortToScan() #k
print "- The port is: ", port
# Connettiamoci al database
# Questo handle servira' successivamente per prendere
# informazioni che serviranno per decidere che cosa fare.
conn = db2.dbConnectz(configDic["db_host"],configDic["db_user"],configDic["db_pass"],configDic["db_name"]) #ok
# Capiamo quali sono gli host che in assoluto,
# dopo il nostro campionamento, sono meritevoli di scansione.
# I parametri sono impostabili nel file db2
relevantNodes=getRelevantNodes(conn)
if (len(relevantNodes)==0):
sys.exit("[!] There are no relevant nodes to scan...")
# Istanzio un oggetto che servira' per prendere
# tutte le decisioni necessarie alla scansione
#
obj=Logic() #k
# Scarico i nodi che sono attualmente attivi e connessi alla
# rete tor, dal sito onionoo e le sue api json
# i dati sono all'interno dell'oggetto
obj.downlaodNodes_web() #k
# visto che siamo scarsissimi, con i nodi che abbiamo
# scaricato dal web facciamo un dictionary per assicurarci
# di avere i fingerprint che ci servono
assigndict=obj.createDictionary()
filename1="/mnt/ramfs/lookupdict"
output1 = open(filename1, "wb")
pickle.dump(assigndict, output1)
# Trovo l'intersezione tra l'insieme dei nodi attivi
# e dei nodi che devo scannare.
#
obj.filterRelevantAndPresent(relevantNodes) #k
# Creo una struttura dati che mi contiene gli ip
# dei nodi da scannare, ai quali abbino la porta che
# ho deciso di scansionare in questo giro.
obj.cartesian(port)
# Verifico che, per questa determinata porta, in un intervallo di tempo
# deciso a priori, la porta non sia gia' stata scannata e salvata nel db.
# Eventualmente posso filtrare le porte con esito socks error 1
scannedComb = getAlreadyScannedComb(conn, port) #ok
# dato tmp
tmp_oldLen=obj.getLenCombToScan()
# Filtro le porte che ho gia' scannato dalla struttura dati
# creata pochi passi prima.
#
obj.filterScannedComb(scannedComb) # ok
print "- Cartesian product was: ", tmp_oldLen
print "- Scanned combination are: ", len(scannedComb)
print "- Cartesian product are: ", obj.getLenCombToScan()
# Se non ho nulla da fare chiudo.
#
#
if (obj.getLenCombToScan() <= 0):
print "-> Skipping this port (already scanned this port for each host)"
saveCurrentStatus(configDic)
print "Exiting: [K]"
sys.exit()
# Ora che so quali nodi devo raggiungere, mi assicuro
# di poter uscire per degli exit node che me lo permettano
# e uso uno script esterno per poterlo fare.
exitRouteList=findExitRoute(obj.cartProd, configDic["varlibtor"], assigndict)
# Elimino dalla lista di exitnode usabili
# quelli che ho gia' usato di recente, selezionandoli
# dalle scansioni del database.
exitRouteListFiltered=filterUsedExitNodes(conn, exitRouteList)
# se non ho exit, chiudo
if (len(exitRouteListFiltered)<=0):
print "[!] Non abbiamo exit node usabili: chiudo."
sys.exit()
# this one returns the list of exit route selected (2)
# that must be pickled
topickle=setExitRoute(configDic["torportctl"], configDic['torportsock'],configDic["password"], exitRouteListFiltered,assigndict)
# se non ho settato un exit, chiudo
if (len(topickle)<=0):
print "[!] Non abbiamo exit funzionanti testati, chiudo."
sys.exit()
deleteExitpickledFiles()
filename1="/mnt/ramfs/my.exits"
output1 = open(filename1, "wb")
pickle.dump(topickle, output1)
print "Ip da scannare questo giro: ", len(obj.cartProd)
#fileExit="/mnt/ramfs/exit.node"
#outputExit = open(fileExit, "wb")
#pickle.dump(exitRouteListFiltered, outputExit)
print "-> Start serialization with: ", int(ceil(len(obj.cartProd)/30.)), "files"
for k in range(int(ceil(len(obj.cartProd)/30.))):
iplist=obj.cartProd[0:30]
del obj.cartProd[0:30]
filename1="/mnt/ramfs/torscan"+str(k)+".todo"
output1 = open(filename1, "wb")
pickle.dump(iplist, output1)
saveCurrentStatus(configDic)
print "Exiting: [K]"
sys.exit()