forked from Jul10l1r4/SPO-Sneak-Peek-OSINT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
391 lines (314 loc) · 13.1 KB
/
main.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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# -*- coding:UTF-8 -*-
__author__ = 'Victor de Queiroz'
"""
██████ ██▓███ ▒█████
▒██ ▒ ▓██░ ██▒▒██▒ ██▒
░ ▓██▄ ▓██░ ██▓▒▒██░ ██▒
▒ ██▒▒██▄█▓▒ ▒▒██ ██░
▒██████▒▒▒██▒ ░ ░░ ████▓▒░
▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░░ ▒░▒░▒░
░ ░▒ ░ ░░▒ ░ ░ ▒ ▒░
░ ░ ░ ░░ ░ ░ ░ ▒
░ ░ ░
S n e a k P e e k O S I N T
SPO is a software for search OSINT content.
SPO is a opensource code, please don't use this with
other license different than GPLv2.
Developed by Victor de Queiroz
Contact: CATx003@protonmail.com
+------------- ♥ For donations ♥ -----------------+
| |
| ŁTC = LPE5DsjA2YcMuGGZspvRzEEvdoAjvTRzvF |
| ɃTC = 1FtBj9QbT7gDcxSCygTnUop4N3bd75bwRZ |
| ɃCH = qr6gn0r20p9s9kjm5yuvqw53mhmzx87q0vecqn6xhj|
| |
+-------------------------------------------------+
"""
from datetime import timedelta
from flask import Flask, render_template, url_for, session, request, redirect, flash
from controller import spoDAO
from controller import Whois
from controller import CNPJ
from controller import Jurisprudence
from controller import Subdomain
from controller import Facebook
# spo is a instance of flask,
# template_folder is a directory of contents html sources from view
# static_folder is a static contents like a css, js, etc...
spo = Flask(__name__, template_folder="templates", static_folder="static")
# key of access for wsgi
# use if necessary, we are running spo in a local daemon
# but u can use spo as server, if u don't want use a mod_proxy
# on apache for example, use this key for wsgi
spo.secret_key = 'ˆˆß∂……å¬ßøøøø∑߈ˆß∆˚¬˜˜≤'
# instance of data access object
dao = spoDAO.SpoDAO()
# instance of Whois
whois = Whois.Whois()
# instance of cnpj api
cnpj = CNPJ.CNPJ()
# instance of jurisprudence
lawyer = Jurisprudence.Jurisprudence()
# instance of subdomains
subdomain = Subdomain.Subdomains()
# instance of Facebook
facebook = Facebook.Facebook
# for timeout session on 2 minutes
@spo.before_request
def make_session_permanent():
session.permanent = True
spo.permanent_session_lifetime = timedelta(minutes=15)
# for logout
@spo.route("/exit")
def exit():
session.pop('user', None)
return redirect(url_for("login"))
# errors
@spo.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@spo.errorhandler(403)
def page_not_found(e):
return render_template('403.html'), 403
@spo.errorhandler(500)
def page_not_found(e):
return render_template('500.html'), 500
"""
+-------------------------------------------------+
| |
| Login screen |
| |
+-------------------------------------------------+
Function that is responsible for managing login and
user creation for the first access by opening the cookie
session and dealing with sqli attacks ex: a ' or 1 = 1#
"""
@spo.route("/", methods=['GET', 'POST'])
def login():
# on first access redirect to firstLogin
if dao.testFirstAccess() == True:
return redirect('wellcome')
else:
if request.method == 'POST':
# recive user from html
getUser = request.form.get('user')
# recive password from html
getPasswd = request.form.get('password')
# test login
if dao.testLogin(getUser, getPasswd) == True:
# open a session
session['user'] = getUser
session['isAuthenticated'] = True
session['id'] = dao.getIDUser(getUser)
return redirect('dashboard')
else:
return render_template("passwordFail.html")
# render login.html
return render_template("login.html")
# for first login
@spo.route("/wellcome")
def wellcome():
# wellcome screen
return render_template('wellcome.html')
@spo.route("/firstLogin", methods=['GET', 'POST'])
def firstLogin():
if request.method == 'POST':
# recive user from html
getUser = request.form.get('user')
# recive password from html
getPasswd = request.form.get('password')
# insert in to DB
dao.insertUser(getUser, getPasswd)
return render_template("ok_registration.html")
return render_template("firstLogin.html")
"""
+-------------------------------------------------+
| |
| User Dashboard |
| |
+-------------------------------------------------+
Function that is responsible for principal page
"""
@spo.route("/dashboard", methods=['GET', 'POST'])
def dashboard():
# test if is authenticated
if session['isAuthenticated'] == True:
return render_template("dashboard.html")
"""
+-------------------------------------------------+
| |
| Company Investigation |
| |
+-------------------------------------------------+
Function that is responsible for start a new Company investigation.
"""
@spo.route("/companyInvestigation", methods=['GET', 'POST'])
def companyInvestigation():
# test if is authenticated
if session['isAuthenticated'] == True:
if request.method == 'POST':
# start a new project
nameOfProject = request.form.get('nameOfProject')
# send a informa
if request.form.get('domain'):
# getDomain
domain_name = request.form.get('domain')
# get whois info
ownerDomainInfo = whois.owner(domain_name)
if ownerDomainInfo['ownerid'] is None:
domainInfo = ""
else:
# if owner is cnpj
if len(ownerDomainInfo['ownerid']) == 18:
# get cnpj info
domainInfo = cnpj.getCNPJ(ownerDomainInfo['ownerid'])
# get process info
process = lawyer.jurisprudence(ownerDomainInfo['ownerid'])
# treat cnpj
TreatCNPJ = cnpj.treat(ownerDomainInfo['ownerid'])
subdomains = subdomain.getSubdomains(domain_name)
else:
domainInfo = ''
return render_template('companyInvestigation.html', subdomain=subdomains, domain_name=domain_name,
cnpj=TreatCNPJ, ownerDomainInfo=ownerDomainInfo, domainInfo=domainInfo,
jurisprudence=process)
return render_template("companyInvestigation.html", subdomain='', domain_name='', ownerDomainInfo='', domainInfo='',
jurisprudence="", cnpj="")
"""
+-------------------------------------------------+
| |
| Personal Investigation |
| |
+-------------------------------------------------+
Function that is responsible for start a new Personal investigation.
"""
@spo.route("/personalInvestigation", methods=['GET','POST'])
def personalInvestigation():
# test if is authenticated
if session['isAuthenticated'] == True:
if request.method == 'POST':
# for facebook crawler
profile_facebook = request.form.get('profile_facebook')
# get profile picture
photo_perfil = facebook.perfil_picture(profile_facebook)
# get likes
likes_by_facebook = facebook.likes(profile_facebook)
# get location by facebook
location_by_facebook = facebook.location_by_facebook(profile_facebook)
return render_template("personalInvestigation.html", photo_perfil=photo_perfil, likes_by_facebook=likes_by_facebook,location_by_facebook=location_by_facebook)
return render_template("personalInvestigation.html", photo_perfil='', likes_by_facebook='',location_by_facebook='')
"""
+-------------------------------------------------+
| |
| Search Servers |
| |
+-------------------------------------------------+
Function that is responsible for search a servers and services.
Here we'll use the shodan key and others tools for search,
and crawlers and etc..
"""
@spo.route("/searchServers")
def searchServers():
# test if is authenticated
if session['isAuthenticated'] == True:
return render_template("searchServers.html")
"""
+-------------------------------------------------+
| |
| Personal Trace |
| |
+-------------------------------------------------+
Function that is responsible for search a person, on facebook
instagram, twitter and whatever public data allow on internet
about especific people.
"""
@spo.route("/personalTrace")
def personalTrace():
# test if is authenticated
if session['isAuthenticated'] == True:
return render_template("personalInvestigation.html")
"""
+-------------------------------------------------+
| |
| About OSINT |
| |
+-------------------------------------------------+
Function about educational articles
"""
@spo.route("/aboutOSINT")
def aboutOSINT():
# test if is authenticated
if session['isAuthenticated'] == True:
return render_template("aboutOSINT.html")
"""
+-------------------------------------------------+
| |
| Manual |
| |
+-------------------------------------------------+
Function for help
"""
@spo.route("/manual")
def manual():
# test if is authenticated
if session['isAuthenticated'] == True:
return render_template("manual.html")
"""
+-------------------------------------------------+
| |
| Insert Keys |
| |
+-------------------------------------------------+
Function that is responsible for insert a credentials
for social media when we using for search on crawlers
"""
@spo.route("/insertKeys", methods=['GET', 'POST'])
def insertKeys():
# test if is authenticated
if session['isAuthenticated'] == True:
# test existent keys
if dao.getShodanKey(session['id']) is None:
pass
else:
flash('Shodan Key inserted: ' + dao.getShodanKey(session['id'])['key_value'], 'info')
if request.method == 'POST':
shodanKey = request.form.get('shodan')
if dao.getShodanKey(session['id']) is None:
dao.insertShodanKey(session['id'], shodanKey)
flash('Shodan Key inserted: ' + dao.getShodanKey(session['id'])['key_value'], 'info')
return redirect('insertKeys')
else:
dao.updateShodanKey(session['id'], shodanKey)
flash('Shodan Key updated: ' + dao.getShodanKey(session['id'])['key_value'], 'info')
return render_template("insertKeys.html")
return render_template("insertKeys.html")
"""
+-------------------------------------------------+
| |
| About US |
| |
+-------------------------------------------------+
The best function on this software, because here is
a bitcoin wallet ♥ ♥ ♥ ♥ uheuheuheu
"""
@spo.route("/about")
def aboutUS():
# test if is authenticated
if session['isAuthenticated'] == True:
return render_template("aboutus.html")
"""
+-------------------------------------------------+
| |
| Run SPO |
| |
+-------------------------------------------------+
Function that is responsible for start SPO, on documentation
is describled how to configure a daemon spod and execute.
We disponibilizing a web service for SPO, send-me a email
for talk about this!
"""
if __name__ == '__main__':
# spo run in 1337 port tcp
# For real use disallow debug mode, set False
spo.run(port=1337, debug=True)
__author__ = 'Victor de Queiroz'