frida-fusion 0.1.9__tar.gz → 0.1.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of frida-fusion might be problematic. Click here for more details.
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/PKG-INFO +1 -1
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/__meta__.py +2 -2
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/fusion.py +23 -3
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/libs/database.py +11 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/libs/helpers.js +29 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/libs/logger.py +1 -1
- frida_fusion-0.1.11/frida_fusion/modules/android_setings/settings.js +172 -0
- frida_fusion-0.1.11/frida_fusion/modules/android_setings/settings.py +106 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/modules/crypto/crypto.js +41 -48
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/modules/crypto/crypto.py +185 -66
- frida_fusion-0.1.11/frida_fusion/modules/tls_unpinning/__init__.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion.egg-info/PKG-INFO +1 -1
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion.egg-info/SOURCES.txt +3 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/LICENSE +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/README.md +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/__init__.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/__main__.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/args.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/config.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/libs/__init__.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/libs/color.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/libs/scriptlocation.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/module.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/modules/__init__.py +0 -0
- {frida_fusion-0.1.9/frida_fusion/modules/crypto → frida_fusion-0.1.11/frida_fusion/modules/android_setings}/__init__.py +0 -0
- {frida_fusion-0.1.9/frida_fusion/modules/tls_unpinning → frida_fusion-0.1.11/frida_fusion/modules/crypto}/__init__.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion/modules/tls_unpinning/frida_multiple_unpinning.py +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion.egg-info/dependency_links.txt +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion.egg-info/entry_points.txt +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion.egg-info/requires.txt +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/frida_fusion.egg-info/top_level.txt +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/pyproject.toml +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/setup.cfg +0 -0
- {frida_fusion-0.1.9 → frida_fusion-0.1.11}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frida-fusion
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.11
|
|
4
4
|
Summary: Hook your mobile tests with Frida
|
|
5
5
|
Author-email: "Helvio Junior (M4v3r1ck)" <helvio_junior@hotmail.com>
|
|
6
6
|
Maintainer-email: "Helvio Junior (M4v3r1ck)" <helvio_junior@hotmail.com>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
__version__ = '0.1.
|
|
1
|
+
__version__ = '0.1.11'
|
|
2
2
|
__title__ = "Frida Fusion"
|
|
3
3
|
__description__ = "📱 frida-fusion - runtime mobile exploration"
|
|
4
4
|
__url__ = "https://github.com/helviojunior/frida-fusion"
|
|
5
|
-
__build__ =
|
|
5
|
+
__build__ = 0xc8879a3
|
|
6
6
|
__author__ = "Helvio Junior (M4v3r1ck)"
|
|
7
7
|
__author_email__ = "helvio_junior@hotmail.com"
|
|
8
8
|
__license__ = "GPL-3.0"
|
|
@@ -194,9 +194,29 @@ class Fusion(object):
|
|
|
194
194
|
s.on("message", self.make_handler("fusion_bundle.js")) # register the message handler
|
|
195
195
|
s.load()
|
|
196
196
|
except Exception as e:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
|
|
198
|
+
try:
|
|
199
|
+
err = str(e)
|
|
200
|
+
pattern = re.compile(r'script\(line (\d+)\):')
|
|
201
|
+
matches = [
|
|
202
|
+
(
|
|
203
|
+
m.group(0),
|
|
204
|
+
self.translate_location(dict(
|
|
205
|
+
file_name="fusion_bundle.js",
|
|
206
|
+
line=m.group(1),
|
|
207
|
+
))
|
|
208
|
+
)
|
|
209
|
+
for m in pattern.finditer(err)
|
|
210
|
+
]
|
|
211
|
+
for m in matches:
|
|
212
|
+
err = err.replace(m[0], f"{m[1].file_name}(line {m[1].line})")
|
|
213
|
+
Logger.pl('{!} {R}Error:{O} %s{W}' % err)
|
|
214
|
+
print("")
|
|
215
|
+
sys.exit(1)
|
|
216
|
+
except Exception:
|
|
217
|
+
Logger.pl('{!} {R}Error:{O} %s{W}' % str(e))
|
|
218
|
+
print("")
|
|
219
|
+
sys.exit(1)
|
|
200
220
|
|
|
201
221
|
def attach(self, pid: int):
|
|
202
222
|
self.running = True
|
|
@@ -81,6 +81,17 @@ class Database(object):
|
|
|
81
81
|
conn.execute(sql, values)
|
|
82
82
|
conn.commit()
|
|
83
83
|
|
|
84
|
+
@connect
|
|
85
|
+
def insert_if_not_exists(self, conn: Connection, table_name, **kwargs):
|
|
86
|
+
table_name = self.scrub(table_name)
|
|
87
|
+
|
|
88
|
+
if self.select_count(table_name=table_name, **kwargs) == 0:
|
|
89
|
+
(columns, values) = self.parse_args(kwargs)
|
|
90
|
+
sql = "INSERT INTO {} ({}) VALUES ({})" \
|
|
91
|
+
.format(table_name, ','.join(columns), ', '.join(['?'] * len(columns)))
|
|
92
|
+
conn.execute(sql, values)
|
|
93
|
+
conn.commit()
|
|
94
|
+
|
|
84
95
|
@connect
|
|
85
96
|
def insert_ignore_one(self, conn: Connection, table_name, **kwargs):
|
|
86
97
|
table_name = self.scrub(table_name)
|
|
@@ -214,6 +214,35 @@ function fusion_printMethods(targetClass)
|
|
|
214
214
|
});
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
function fusion_getClassName(obj)
|
|
218
|
+
{
|
|
219
|
+
if (obj === null || obj === undefined) return "";
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
// Caso seja um objeto Java real
|
|
223
|
+
if (obj.$className !== undefined) {
|
|
224
|
+
// Objetos instanciados via Java.use
|
|
225
|
+
return obj.$className;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Caso seja uma instância Java (não necessariamente via Java.use)
|
|
229
|
+
if (Java.isJavaObject(obj)) {
|
|
230
|
+
return obj.getClass().getName();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Caso seja uma classe Java carregada (Java.use)
|
|
234
|
+
if (Java.isJavaClass(obj)) {
|
|
235
|
+
return obj.class.getName();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Se for algo não Java, apenas retorna tipo do JS
|
|
239
|
+
return typeof obj;
|
|
240
|
+
} catch (err) {
|
|
241
|
+
fusion_sendMessage("W", err);
|
|
242
|
+
return '';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
}
|
|
217
246
|
|
|
218
247
|
Java.perform(function () {
|
|
219
248
|
const Thread = Java.use('java.lang.Thread');
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Documentation
|
|
3
|
+
https://developer.android.com/reference/android/provider/Settings
|
|
4
|
+
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const SET_MODULES = {
|
|
8
|
+
Global: true,
|
|
9
|
+
Secure: true,
|
|
10
|
+
System: true,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
setTimeout(function() {
|
|
14
|
+
Java.perform(function() {
|
|
15
|
+
|
|
16
|
+
// Bypass Settings
|
|
17
|
+
var androidSettings = [
|
|
18
|
+
['adb_enabled', 0],
|
|
19
|
+
['development_settings_enabled', 0],
|
|
20
|
+
['play_protect_enabled', 1],
|
|
21
|
+
['adb_enabled', 0]
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
function settings_bypassValue(name, originalValue) {
|
|
25
|
+
androidSettings.forEach(function(item) {
|
|
26
|
+
let name = item[0];
|
|
27
|
+
let value = item[1];
|
|
28
|
+
|
|
29
|
+
if (name === name) {
|
|
30
|
+
fusion_sendMessage('D', `Bypassing ${name}`)
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return originalValue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (SET_MODULES.System) {
|
|
38
|
+
|
|
39
|
+
fusion_sendMessage('D', "Module attached: android.provider.Settings.System");
|
|
40
|
+
const settingsSystem = Java.use("android.provider.Settings$System");
|
|
41
|
+
|
|
42
|
+
settingsSystem.getString.overload('android.content.ContentResolver', 'java.lang.String').implementation = function (cr, name) {
|
|
43
|
+
var data = this.getString.overload('android.content.ContentResolver', 'java.lang.String').call(this, cr, name);
|
|
44
|
+
fusion_sendKeyValueData("Settings$System.getString", [
|
|
45
|
+
{key: "Name", value: name},
|
|
46
|
+
{key: "Result", value: data}
|
|
47
|
+
]);
|
|
48
|
+
return data
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
settingsSystem.putString.overload('android.content.ContentResolver', 'java.lang.String', 'java.lang.String').implementation = function (cr, name, value) {
|
|
52
|
+
fusion_sendKeyValueData("Settings$System.putString", [
|
|
53
|
+
{key: "Name", value: name},
|
|
54
|
+
{key: "Value", value: value}
|
|
55
|
+
]);
|
|
56
|
+
return this.putString.overload('android.content.ContentResolver', 'java.lang.String', 'java.lang.String').call(this, cr, name, value);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
settingsSystem.getUriFor.overload('java.lang.String').implementation = function (name) {
|
|
60
|
+
var data = this.getUriFor.overload('java.lang.String').call(this, name);
|
|
61
|
+
fusion_sendKeyValueData("Settings$System.getUriFor", [
|
|
62
|
+
{key: "Name", value: name},
|
|
63
|
+
{key: "Result", value: data}
|
|
64
|
+
]);
|
|
65
|
+
return data
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
settingsSystem.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').implementation = function(cr, name, flag) {
|
|
69
|
+
var data = this.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').call(this, cr, name, flag);
|
|
70
|
+
fusion_sendKeyValueData("Settings$System.getInt", [
|
|
71
|
+
{key: "Name", value: name},
|
|
72
|
+
{key: "Flag", value: flag},
|
|
73
|
+
{key: "Result", value: data}
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
return settings_bypassValue(name, data);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
settingsSystem.getInt.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) {
|
|
80
|
+
var data = this.getInt.overload('android.content.ContentResolver', 'java.lang.String').call(this, cr, name);
|
|
81
|
+
fusion_sendKeyValueData("Settings$System.getInt", [
|
|
82
|
+
{key: "Name", value: name},
|
|
83
|
+
{key: "Result", value: data}
|
|
84
|
+
]);
|
|
85
|
+
return settings_bypassValue(name, data);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (SET_MODULES.Secure) {
|
|
91
|
+
|
|
92
|
+
fusion_sendMessage('D', "Module attached: android.provider.Settings.Secure");
|
|
93
|
+
const settingsSecure = Java.use("android.provider.Settings$Secure");
|
|
94
|
+
|
|
95
|
+
settingsSecure.getString.overload('android.content.ContentResolver', 'java.lang.String').implementation = function (cr, name) {
|
|
96
|
+
var data = this.getString.overload('android.content.ContentResolver', 'java.lang.String').call(this, cr, name);
|
|
97
|
+
fusion_sendKeyValueData("Settings$Secure.getString", [
|
|
98
|
+
{key: "Name", value: name},
|
|
99
|
+
{key: "Result", value: data}
|
|
100
|
+
]);
|
|
101
|
+
return data
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
settingsSecure.putString.overload('android.content.ContentResolver', 'java.lang.String', 'java.lang.String').implementation = function (cr, name, value) {
|
|
105
|
+
fusion_sendKeyValueData("Settings$Secure.putString", [
|
|
106
|
+
{key: "Name", value: name},
|
|
107
|
+
{key: "Value", value: value}
|
|
108
|
+
]);
|
|
109
|
+
return this.putString.overload('android.content.ContentResolver', 'java.lang.String', 'java.lang.String').call(this, cr, name, value);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
settingsSecure.getUriFor.overload('java.lang.String').implementation = function (name) {
|
|
113
|
+
var data = this.getUriFor.overload('java.lang.String').call(this, name);
|
|
114
|
+
fusion_sendKeyValueData("Settings$Secure.getUriFor", [
|
|
115
|
+
{key: "Name", value: name},
|
|
116
|
+
{key: "Result", value: data}
|
|
117
|
+
]);
|
|
118
|
+
return data
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
settingsSecure.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').implementation = function(cr, name, flag) {
|
|
122
|
+
var data = this.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').call(this, cr, name, flag);
|
|
123
|
+
fusion_sendKeyValueData("Settings$Secure.getInt", [
|
|
124
|
+
{key: "Name", value: name},
|
|
125
|
+
{key: "Flag", value: flag},
|
|
126
|
+
{key: "Result", value: data}
|
|
127
|
+
]);
|
|
128
|
+
|
|
129
|
+
return settings_bypassValue(name, data);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
settingsSecure.getInt.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) {
|
|
133
|
+
var data = this.getInt.overload('android.content.ContentResolver', 'java.lang.String').call(this, cr, name);
|
|
134
|
+
fusion_sendKeyValueData("Settings$Secure.getInt", [
|
|
135
|
+
{key: "Name", value: name},
|
|
136
|
+
{key: "Result", value: data}
|
|
137
|
+
]);
|
|
138
|
+
return settings_bypassValue(name, data);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (SET_MODULES.Global) {
|
|
144
|
+
|
|
145
|
+
fusion_sendMessage('D', "Module attached: android.provider.Settings.Global");
|
|
146
|
+
const settingGlobal = Java.use('android.provider.Settings$Global');
|
|
147
|
+
|
|
148
|
+
settingGlobal.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').implementation = function(cr, name, flag) {
|
|
149
|
+
var data = this.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').call(this, cr, name, flag);
|
|
150
|
+
fusion_sendKeyValueData("Settings$Global.getInt", [
|
|
151
|
+
{key: "Name", value: name},
|
|
152
|
+
{key: "Flag", value: flag},
|
|
153
|
+
{key: "Result", value: data}
|
|
154
|
+
]);
|
|
155
|
+
return settings_bypassValue(name, data);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
settingGlobal.getInt.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) {
|
|
159
|
+
var data = this.getInt.overload('android.content.ContentResolver', 'java.lang.String').call(this, cr, name);
|
|
160
|
+
fusion_sendKeyValueData("Settings$Global.getInt", [
|
|
161
|
+
{key: "Name", value: name},
|
|
162
|
+
{key: "Result", value: data}
|
|
163
|
+
]);
|
|
164
|
+
return settings_bypassValue(name, data);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fusion_sendMessage("W", "Android Settings hook module have been successfully initialized.")
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
}, 0);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os.path
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import base64
|
|
5
|
+
import string
|
|
6
|
+
|
|
7
|
+
from frida_fusion.libs.logger import Logger
|
|
8
|
+
from frida_fusion.libs.database import Database
|
|
9
|
+
from frida_fusion.libs.scriptlocation import ScriptLocation
|
|
10
|
+
from frida_fusion.module import ModuleBase
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Settings(ModuleBase):
|
|
14
|
+
class SettingsDB(Database):
|
|
15
|
+
dbName = ""
|
|
16
|
+
|
|
17
|
+
def __init__(self, db_name: str):
|
|
18
|
+
super().__init__(
|
|
19
|
+
auto_create=True,
|
|
20
|
+
db_name=db_name
|
|
21
|
+
)
|
|
22
|
+
self.create_db()
|
|
23
|
+
|
|
24
|
+
def create_db(self):
|
|
25
|
+
super().create_db()
|
|
26
|
+
conn = self.connect_to_db(check=False)
|
|
27
|
+
|
|
28
|
+
# definindo um cursor
|
|
29
|
+
cursor = conn.cursor()
|
|
30
|
+
|
|
31
|
+
# criando a tabela (schema)
|
|
32
|
+
cursor.execute("""
|
|
33
|
+
CREATE TABLE IF NOT EXISTS [android_settings] (
|
|
34
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
|
+
module TEXT NULL,
|
|
36
|
+
name TEXT NULL,
|
|
37
|
+
flag INTEGER NULL DEFAULT (0),
|
|
38
|
+
data TEXT NULL,
|
|
39
|
+
created_date datetime not null DEFAULT (datetime('now','localtime')),
|
|
40
|
+
UNIQUE (module, name, flag, data)
|
|
41
|
+
);
|
|
42
|
+
""")
|
|
43
|
+
|
|
44
|
+
conn.commit()
|
|
45
|
+
|
|
46
|
+
# Must get the constraints
|
|
47
|
+
self.get_constraints(conn)
|
|
48
|
+
|
|
49
|
+
def __init__(self):
|
|
50
|
+
super().__init__('Settings', 'Hook Android Settings functions')
|
|
51
|
+
self._settings_db = None
|
|
52
|
+
self.mod_path = str(Path(__file__).resolve().parent)
|
|
53
|
+
|
|
54
|
+
def start_module(self, **kwargs) -> bool:
|
|
55
|
+
if 'db_path' not in kwargs:
|
|
56
|
+
raise Exception("parameter db_path not found")
|
|
57
|
+
|
|
58
|
+
self._settings_db = Settings.SettingsDB(db_name=kwargs['db_path'])
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
def js_files(self) -> list:
|
|
62
|
+
return [
|
|
63
|
+
os.path.join(self.mod_path, "settings.js")
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
def key_value_event(self,
|
|
67
|
+
script_location: ScriptLocation = None,
|
|
68
|
+
stack_trace: str = None,
|
|
69
|
+
module: str = None,
|
|
70
|
+
received_data: dict = None
|
|
71
|
+
) -> bool:
|
|
72
|
+
|
|
73
|
+
if module in ["Settings$Secure.getString",
|
|
74
|
+
"Settings$Secure.putString",
|
|
75
|
+
"Settings$Secure.getUriFor",
|
|
76
|
+
"Settings$Secure.getInt",
|
|
77
|
+
"Settings$System.getString",
|
|
78
|
+
"Settings$System.putString",
|
|
79
|
+
"Settings$System.getUriFor",
|
|
80
|
+
"Settings$System.getInt",
|
|
81
|
+
"Settings$Global.getInt"
|
|
82
|
+
]:
|
|
83
|
+
name = received_data.get('name', None)
|
|
84
|
+
flag = received_data.get('flag', 0)
|
|
85
|
+
value = received_data.get('value', None)
|
|
86
|
+
result = received_data.get('result', value)
|
|
87
|
+
|
|
88
|
+
self._settings_db.insert_ignore_one(
|
|
89
|
+
table_name='android_settings',
|
|
90
|
+
module=module,
|
|
91
|
+
name=name,
|
|
92
|
+
flag=flag,
|
|
93
|
+
data=result
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return True
|
|
97
|
+
|
|
98
|
+
def data_event(self,
|
|
99
|
+
script_location: ScriptLocation = None,
|
|
100
|
+
stack_trace: str = None,
|
|
101
|
+
received_data: str = None
|
|
102
|
+
) -> bool:
|
|
103
|
+
#Nothing by now
|
|
104
|
+
return True
|
|
105
|
+
|
|
106
|
+
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
const
|
|
2
|
+
const CRYPTO_MODULES = {
|
|
3
3
|
KeyGenerator: true,
|
|
4
4
|
KeyPairGenerator: true,
|
|
5
5
|
SecretKeySpec: true,
|
|
@@ -20,7 +20,7 @@ setTimeout(function() {
|
|
|
20
20
|
|
|
21
21
|
const System = Java.use("java.lang.System");
|
|
22
22
|
|
|
23
|
-
if (
|
|
23
|
+
if (CRYPTO_MODULES.KeyGenerator) {
|
|
24
24
|
fusion_sendMessage('*', "Module attached: javax.crypto.KeyGenerator");
|
|
25
25
|
const keyGenerator = Java.use("javax.crypto.KeyGenerator");
|
|
26
26
|
|
|
@@ -54,7 +54,7 @@ setTimeout(function() {
|
|
|
54
54
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
if (
|
|
57
|
+
if (CRYPTO_MODULES.KeyPairGenerator) {
|
|
58
58
|
fusion_sendMessage('*', "Module attached: java.security.KeyPairGenerator");
|
|
59
59
|
const keyPairGenerator = Java.use("java.security.KeyPairGenerator");
|
|
60
60
|
keyPairGenerator.getInstance.overload("java.lang.String").implementation = function (arg0) {
|
|
@@ -81,20 +81,21 @@ setTimeout(function() {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
if (
|
|
84
|
+
if (CRYPTO_MODULES.SecretKeySpec) {
|
|
85
85
|
fusion_sendMessage('*', "Module attached: javax.crypto.spec.SecretKeySpec");
|
|
86
86
|
const secretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
|
|
87
87
|
secretKeySpec.$init.overload("[B", "java.lang.String").implementation = function (key, cipher) {
|
|
88
88
|
const keyBase64 = fusion_bytesToBase64(key);
|
|
89
|
-
fusion_sendKeyValueData("
|
|
89
|
+
fusion_sendKeyValueData("SecretKeySpec.init", [
|
|
90
90
|
{key: "Key", value: keyBase64},
|
|
91
|
-
{key: "Algorithm", value: cipher}
|
|
91
|
+
{key: "Algorithm", value: cipher},
|
|
92
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
92
93
|
]);
|
|
93
94
|
return secretKeySpec.$init.overload("[B", "java.lang.String").call(this, key, cipher);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
if (
|
|
98
|
+
if (CRYPTO_MODULES.MessageDigest) {
|
|
98
99
|
fusion_sendMessage('*', "Module attached: java.security.MessageDigest");
|
|
99
100
|
const messageDigest = Java.use("java.security.MessageDigest");
|
|
100
101
|
messageDigest.getInstance.overload("java.lang.String").implementation = function (arg0) {
|
|
@@ -141,42 +142,20 @@ setTimeout(function() {
|
|
|
141
142
|
return output;
|
|
142
143
|
};
|
|
143
144
|
|
|
144
|
-
/*
|
|
145
|
-
messageDigest.digest.overload("[B").implementation = function (input) {
|
|
146
|
-
const inputBase64 = fusion_bytesToBase64(input);
|
|
147
|
-
fusion_sendKeyValueData("messageDigest.digest", [
|
|
148
|
-
{key: "Input", value: inputBase64},
|
|
149
|
-
{key: "Algorithm", value: this.getAlgorithm()}
|
|
150
|
-
]);
|
|
151
|
-
return this.digest.overload("[B").call(this, input);
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
messageDigest.digest.overload("[B", "int", "int").implementation = function (input, offset, len) {
|
|
155
|
-
const inputBase64 = fusion_bytesToBase64(input);
|
|
156
|
-
fusion_sendKeyValueData("messageDigest.digest", [
|
|
157
|
-
{key: "Input", value: inputBase64},
|
|
158
|
-
{key: "Algorithm", value: this.getAlgorithm()},
|
|
159
|
-
{key: "Offset", value: offset},
|
|
160
|
-
{key: "Length", value: len}
|
|
161
|
-
]);
|
|
162
|
-
return this.digest.overload("[B", "int", "int").call(this, input, offset, len);
|
|
163
|
-
};*/
|
|
164
|
-
|
|
165
|
-
|
|
166
145
|
}
|
|
167
146
|
|
|
168
|
-
if (
|
|
147
|
+
if (CRYPTO_MODULES.SecretKeyFactory) {
|
|
169
148
|
fusion_sendMessage('*', "Module attached: javax.crypto.SecretKeyFactory");
|
|
170
149
|
const secretKeyFactory = Java.use("javax.crypto.SecretKeyFactory");
|
|
171
150
|
secretKeyFactory.getInstance.overload("java.lang.String").implementation = function (arg0) {
|
|
172
|
-
fusion_sendKeyValueData("
|
|
151
|
+
fusion_sendKeyValueData("SecretKeyFactory.getInstance", [
|
|
173
152
|
{key: "Algorithm", value: arg0}
|
|
174
153
|
]);
|
|
175
154
|
return this.getInstance(arg0);
|
|
176
155
|
};
|
|
177
156
|
|
|
178
157
|
secretKeyFactory.getInstance.overload("java.lang.String", "java.lang.String").implementation = function (arg0, arg1) {
|
|
179
|
-
fusion_sendKeyValueData("
|
|
158
|
+
fusion_sendKeyValueData("SecretKeyFactory.getInstance", [
|
|
180
159
|
{key: "Algorithm", value: arg0},
|
|
181
160
|
{key: "Provider", value: arg1}
|
|
182
161
|
]);
|
|
@@ -184,7 +163,7 @@ setTimeout(function() {
|
|
|
184
163
|
};
|
|
185
164
|
|
|
186
165
|
secretKeyFactory.getInstance.overload("java.lang.String", "java.security.Provider").implementation = function (arg0, arg1) {
|
|
187
|
-
fusion_sendKeyValueData("
|
|
166
|
+
fusion_sendKeyValueData("SecretKeyFactory.getInstance", [
|
|
188
167
|
{key: "Algorithm", value: arg0},
|
|
189
168
|
{key: "Provider", value: arg1}
|
|
190
169
|
]);
|
|
@@ -192,7 +171,7 @@ setTimeout(function() {
|
|
|
192
171
|
};
|
|
193
172
|
}
|
|
194
173
|
|
|
195
|
-
if (
|
|
174
|
+
if (CRYPTO_MODULES.Signature) {
|
|
196
175
|
fusion_sendMessage('*', "Module attached: java.security.Signature");
|
|
197
176
|
const signature = Java.use("java.security.Signature");
|
|
198
177
|
signature.getInstance.overload("java.lang.String").implementation = function (arg0) {
|
|
@@ -219,7 +198,7 @@ setTimeout(function() {
|
|
|
219
198
|
};
|
|
220
199
|
}
|
|
221
200
|
|
|
222
|
-
if (
|
|
201
|
+
if (CRYPTO_MODULES.Cipher) {
|
|
223
202
|
fusion_sendMessage('*', "Module attached: javax.crypto.Cipher");
|
|
224
203
|
var iv_parameter_spec = Java.use("javax.crypto.spec.IvParameterSpec");
|
|
225
204
|
var pbe_parameter_spec = Java.use("javax.crypto.spec.PBEParameterSpec");
|
|
@@ -229,6 +208,7 @@ setTimeout(function() {
|
|
|
229
208
|
fusion_sendKeyValueData("cipher.init", [
|
|
230
209
|
{key: "HashCode", value: this.hashCode().toString()},
|
|
231
210
|
{key: "Key", value: fusion_keyToBase64(key)},
|
|
211
|
+
{key: "KeyType", value: fusion_getClassName(key)},
|
|
232
212
|
{key: "Opmode", value: this.getOpmodeString(opmode)},
|
|
233
213
|
{key: "Algorithm", value: this.getAlgorithm()}
|
|
234
214
|
]);
|
|
@@ -238,7 +218,9 @@ setTimeout(function() {
|
|
|
238
218
|
cipher.init.overload("int", "java.security.cert.Certificate").implementation = function (opmode, certificate) {
|
|
239
219
|
fusion_sendKeyValueData("cipher.init", [
|
|
240
220
|
{key: "HashCode", value: this.hashCode().toString()},
|
|
221
|
+
{key: "Key", value: fusion_keyToBase64(certificate)},
|
|
241
222
|
{key: "Certificate", value: fusion_keyToBase64(certificate)},
|
|
223
|
+
{key: "KeyType", value: fusion_getClassName(certificate)},
|
|
242
224
|
{key: "Opmode", value: this.getOpmodeString(opmode)},
|
|
243
225
|
{key: "Algorithm", value: this.getAlgorithm()}
|
|
244
226
|
]);
|
|
@@ -249,6 +231,7 @@ setTimeout(function() {
|
|
|
249
231
|
fusion_sendKeyValueData("cipher.init", [
|
|
250
232
|
{key: "HashCode", value: this.hashCode().toString()},
|
|
251
233
|
{key: "Key", value: fusion_keyToBase64(key)},
|
|
234
|
+
{key: "KeyType", value: fusion_getClassName(key)},
|
|
252
235
|
{key: "Opmode", value: this.getOpmodeString(opmode)},
|
|
253
236
|
{key: "Algorithm", value: this.getAlgorithm()}
|
|
254
237
|
]);
|
|
@@ -261,6 +244,7 @@ setTimeout(function() {
|
|
|
261
244
|
var data = [
|
|
262
245
|
{key: "HashCode", value: this.hashCode().toString()},
|
|
263
246
|
{key: "Key", value: fusion_keyToBase64(key)},
|
|
247
|
+
{key: "KeyType", value: fusion_getClassName(key)},
|
|
264
248
|
{key: "Opmode", value: this.getOpmodeString(opmode)},
|
|
265
249
|
{key: "Algorithm", value: this.getAlgorithm()}
|
|
266
250
|
];
|
|
@@ -381,7 +365,7 @@ setTimeout(function() {
|
|
|
381
365
|
}
|
|
382
366
|
|
|
383
367
|
|
|
384
|
-
if (
|
|
368
|
+
if (CRYPTO_MODULES.Mac) {
|
|
385
369
|
fusion_sendMessage('*', "Module attached: javax.crypto.Mac");
|
|
386
370
|
const mac = Java.use("javax.crypto.Mac");
|
|
387
371
|
mac.getInstance.overload("java.lang.String").implementation = function (arg0) {
|
|
@@ -408,7 +392,7 @@ setTimeout(function() {
|
|
|
408
392
|
};
|
|
409
393
|
}
|
|
410
394
|
|
|
411
|
-
if (
|
|
395
|
+
if (CRYPTO_MODULES.KeyGenParameterSpec) {
|
|
412
396
|
fusion_sendMessage('*', "Module attached: android.security.keystore.KeyGenParameterSpec$Builder");
|
|
413
397
|
const useKeyGen = Java.use("android.security.keystore.KeyGenParameterSpec$Builder");
|
|
414
398
|
useKeyGen.$init.overload("java.lang.String", "int").implementation = function (keyStoreAlias, purpose) {
|
|
@@ -482,12 +466,13 @@ setTimeout(function() {
|
|
|
482
466
|
}
|
|
483
467
|
}
|
|
484
468
|
|
|
485
|
-
if (
|
|
469
|
+
if (CRYPTO_MODULES.IvParameterSpec) {
|
|
486
470
|
fusion_sendMessage('*', "Module attached: javax.crypto.spec.IvParameterSpec");
|
|
487
471
|
const ivParameter = Java.use("javax.crypto.spec.IvParameterSpec");
|
|
488
472
|
ivParameter.$init.overload("[B").implementation = function (ivKey) {
|
|
489
473
|
fusion_sendKeyValueData("IvParameterSpec.init", [
|
|
490
|
-
{key: "IV_Key", value: fusion_bytesToBase64(ivKey)}
|
|
474
|
+
{key: "IV_Key", value: fusion_bytesToBase64(ivKey)},
|
|
475
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
491
476
|
]);
|
|
492
477
|
return this.$init.overload("[B").call(this, ivKey);
|
|
493
478
|
}
|
|
@@ -496,19 +481,21 @@ setTimeout(function() {
|
|
|
496
481
|
fusion_sendKeyValueData("IvParameterSpec.init", [
|
|
497
482
|
{key: "IV Key", value: fusion_bytesToBase64(ivKey)},
|
|
498
483
|
{key: "Offset", value: offset},
|
|
499
|
-
{key: "Length", value: len}
|
|
484
|
+
{key: "Length", value: len},
|
|
485
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
500
486
|
]);
|
|
501
487
|
return this.$init.overload("[B", "int", "int").call(this, ivKey, offset, len);
|
|
502
488
|
}
|
|
503
489
|
}
|
|
504
490
|
|
|
505
|
-
if (
|
|
491
|
+
if (CRYPTO_MODULES.GCMParameterSpec) {
|
|
506
492
|
fusion_sendMessage('*', "Module attached: javax.crypto.spec.GCMParameterSpec");
|
|
507
493
|
const gcmParameter = Java.use("javax.crypto.spec.GCMParameterSpec");
|
|
508
494
|
gcmParameter.$init.overload("int", "[B").implementation = function (tLen, ivKey) {
|
|
509
495
|
fusion_sendKeyValueData("GCMParameterSpec.init", [
|
|
510
496
|
{key: "IV_Key", value: fusion_bytesToBase64(ivKey)},
|
|
511
|
-
{key: "Auth_Tag_Length", value: tLen.toString()}
|
|
497
|
+
{key: "Auth_Tag_Length", value: tLen.toString()},
|
|
498
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
512
499
|
]);
|
|
513
500
|
return this.$init.overload("int", "[B").call(this, tLen, ivKey);
|
|
514
501
|
}
|
|
@@ -518,19 +505,21 @@ setTimeout(function() {
|
|
|
518
505
|
{key: "IV_Key", value: fusion_bytesToBase64(ivKey)},
|
|
519
506
|
{key: "Auth_Tag_Length", value: tLen.toString()},
|
|
520
507
|
{key: "Offset", value: offset},
|
|
521
|
-
{key: "Length", value: len}
|
|
508
|
+
{key: "Length", value: len},
|
|
509
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
522
510
|
]);
|
|
523
511
|
return this.$init.overload("int", "[B", "int", "int").call(this, tLen, ivKey, offset, len);
|
|
524
512
|
}
|
|
525
513
|
}
|
|
526
514
|
|
|
527
|
-
if (
|
|
515
|
+
if (CRYPTO_MODULES.PBEParameterSpec) {
|
|
528
516
|
fusion_sendMessage('*', "Module attached: javax.crypto.spec.PBEParameterSpec");
|
|
529
517
|
const pbeParameter = Java.use("javax.crypto.spec.PBEParameterSpec");
|
|
530
518
|
pbeParameter.$init.overload("[B", "int").implementation = function (salt, iterationCount) {
|
|
531
519
|
fusion_sendKeyValueData("PBEParameterSpec.init", [
|
|
532
520
|
{key: "PBE_Salt", value: fusion_bytesToBase64(salt)},
|
|
533
|
-
{key: "Iteration_Count", value: iterationCount.toString()}
|
|
521
|
+
{key: "Iteration_Count", value: iterationCount.toString()},
|
|
522
|
+
{key: "ClassType", value: fusion_getClassName(this)},
|
|
534
523
|
]);
|
|
535
524
|
return this.$init.overload("[B", "int").call(this, salt, iterationCount);
|
|
536
525
|
}
|
|
@@ -539,7 +528,8 @@ setTimeout(function() {
|
|
|
539
528
|
|
|
540
529
|
var data = [
|
|
541
530
|
{key: "PBE_Salt", value: fusion_bytesToBase64(salt)},
|
|
542
|
-
{key: "Iteration_Count", value: iterationCount.toString()}
|
|
531
|
+
{key: "Iteration_Count", value: iterationCount.toString()},
|
|
532
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
543
533
|
|
|
544
534
|
]
|
|
545
535
|
|
|
@@ -547,6 +537,7 @@ setTimeout(function() {
|
|
|
547
537
|
data = data.concat([
|
|
548
538
|
{key: "Algorithm", value: paramSpec.getAlgorithm()},
|
|
549
539
|
{key: "ParamSpec", value: fusion_keyToBase64(paramSpec)},
|
|
540
|
+
{key: "ParamSpecType", value: fusion_getClassName(paramSpec)},
|
|
550
541
|
{key: "Provider", value: paramSpec.getProvider()}
|
|
551
542
|
]);
|
|
552
543
|
} catch (err) { }
|
|
@@ -556,12 +547,14 @@ setTimeout(function() {
|
|
|
556
547
|
}
|
|
557
548
|
}
|
|
558
549
|
|
|
559
|
-
if (
|
|
550
|
+
if (CRYPTO_MODULES.X509EncodedKeySpec) {
|
|
560
551
|
fusion_sendMessage('*', "Module attached: java.security.spec.X509EncodedKeySpec");
|
|
561
552
|
const x509EncodedKeySpec = Java.use("java.security.spec.X509EncodedKeySpec");
|
|
562
553
|
x509EncodedKeySpec.$init.overload("[B").implementation = function (encodedKey) {
|
|
563
554
|
fusion_sendKeyValueData("X509EncodedKeySpec.init", [
|
|
564
|
-
{key: "Key", value: fusion_bytesToBase64(encodedKey)}
|
|
555
|
+
{key: "Key", value: fusion_bytesToBase64(encodedKey)},
|
|
556
|
+
{key: "ClassType", value: fusion_getClassName(this)}
|
|
557
|
+
|
|
565
558
|
]);
|
|
566
559
|
return this.$init.overload("[B").call(this, encodedKey);
|
|
567
560
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import os.path
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
import base64
|
|
@@ -31,10 +32,10 @@ class Crypto(ModuleBase):
|
|
|
31
32
|
cursor.execute("""
|
|
32
33
|
CREATE TABLE IF NOT EXISTS [crypto] (
|
|
33
34
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
hashcode TEXT NOT NULL,
|
|
36
|
+
algorithm TEXT NULL,
|
|
37
|
+
init_key TEXT NULL,
|
|
36
38
|
iv TEXT NULL,
|
|
37
|
-
hashcode TEXT NULL,
|
|
38
39
|
flow TEXT NULL,
|
|
39
40
|
key TEXT NULL,
|
|
40
41
|
clear_text TEXT NULL,
|
|
@@ -48,6 +49,22 @@ class Crypto(ModuleBase):
|
|
|
48
49
|
|
|
49
50
|
conn.commit()
|
|
50
51
|
|
|
52
|
+
cursor.execute("""
|
|
53
|
+
CREATE TABLE IF NOT EXISTS [crypto_key] (
|
|
54
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
55
|
+
key TEXT NULL,
|
|
56
|
+
printable_key TEXT NULL,
|
|
57
|
+
salt TEXT NULL,
|
|
58
|
+
iteration_count INTEGER NULL DEFAULT (0),
|
|
59
|
+
key_class TEXT NULL DEFAULT ('<unknown>'),
|
|
60
|
+
additional_data TEXT NULL,
|
|
61
|
+
created_date datetime not null DEFAULT (datetime('now','localtime')),
|
|
62
|
+
UNIQUE (key, key_class)
|
|
63
|
+
);
|
|
64
|
+
""")
|
|
65
|
+
|
|
66
|
+
conn.commit()
|
|
67
|
+
|
|
51
68
|
cursor.execute("""
|
|
52
69
|
CREATE TABLE IF NOT EXISTS [digest] (
|
|
53
70
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -80,7 +97,8 @@ class Crypto(ModuleBase):
|
|
|
80
97
|
return ''
|
|
81
98
|
|
|
82
99
|
def update_crypto(self, iv=None, hashcode=None, flow=None, key=None, before_final=None,
|
|
83
|
-
after_final=None, stack_trace=None, id=None
|
|
100
|
+
after_final=None, stack_trace=None, id=None, algorithm=None,
|
|
101
|
+
status=None):
|
|
84
102
|
|
|
85
103
|
conn = self.connect_to_db(check=False)
|
|
86
104
|
cursor = conn.cursor()
|
|
@@ -116,6 +134,11 @@ class Crypto(ModuleBase):
|
|
|
116
134
|
update += " hashcode = ?,"
|
|
117
135
|
data.append(hashcode)
|
|
118
136
|
|
|
137
|
+
if flow is not None:
|
|
138
|
+
integrity = True
|
|
139
|
+
update += " algorithm = ?,"
|
|
140
|
+
data.append(algorithm)
|
|
141
|
+
|
|
119
142
|
if flow is not None:
|
|
120
143
|
integrity = True
|
|
121
144
|
update += " flow = ?,"
|
|
@@ -136,6 +159,11 @@ class Crypto(ModuleBase):
|
|
|
136
159
|
update += " stack_trace = ?,"
|
|
137
160
|
data.append(stack_trace)
|
|
138
161
|
|
|
162
|
+
if status is not None:
|
|
163
|
+
integrity = True
|
|
164
|
+
update += " status = ?,"
|
|
165
|
+
data.append(status)
|
|
166
|
+
|
|
139
167
|
if before_final is not None:
|
|
140
168
|
integrity = True
|
|
141
169
|
if dbflow == "enc":
|
|
@@ -169,6 +197,16 @@ class Crypto(ModuleBase):
|
|
|
169
197
|
|
|
170
198
|
cursor.execute(update, data)
|
|
171
199
|
|
|
200
|
+
cursor = conn.cursor()
|
|
201
|
+
cursor.execute("""
|
|
202
|
+
delete from [crypto]
|
|
203
|
+
where algorithm is null and init_key is null and key is null and clear_text is null
|
|
204
|
+
and hashcode in (
|
|
205
|
+
select hashcode from [crypto]
|
|
206
|
+
where id = ?
|
|
207
|
+
)
|
|
208
|
+
""", (id,))
|
|
209
|
+
|
|
172
210
|
conn.commit()
|
|
173
211
|
|
|
174
212
|
# Color.pl('{+} {W}Crypto atualizada. {C}ID: {O}%s{W}' % id)
|
|
@@ -215,56 +253,59 @@ class Crypto(ModuleBase):
|
|
|
215
253
|
|
|
216
254
|
# Color.pl('{+} {W}Inserindo crypto. {C}Algorithm: {O}%s{W}' % algorithm)
|
|
217
255
|
|
|
218
|
-
def insert_crypto(self, algorithm, init_key):
|
|
219
|
-
|
|
220
|
-
conn = self.connect_to_db(check=False)
|
|
221
|
-
|
|
222
|
-
cursor = conn.cursor()
|
|
223
|
-
cursor.execute("""
|
|
224
|
-
update [crypto] set status = 'incomplete' where status = 'open';
|
|
225
|
-
""")
|
|
226
|
-
|
|
227
|
-
cursor = conn.cursor()
|
|
228
|
-
cursor.execute("""
|
|
229
|
-
insert into [crypto] ([algorithm], [init_key])
|
|
230
|
-
VALUES (?,?);
|
|
231
|
-
""", (algorithm, init_key,))
|
|
232
|
-
|
|
233
|
-
conn.commit()
|
|
234
|
-
|
|
235
|
-
conn.close()
|
|
236
|
-
|
|
237
|
-
# Color.pl('{+} {W}Inserindo crypto. {C}Algorithm: {O}%s{W}' % algorithm)
|
|
238
|
-
|
|
239
|
-
def insert_crypto2(self, algorithm, key, iv, clear_text, cipher_data, flow='enc'):
|
|
240
|
-
|
|
241
|
-
conn = self.connect_to_db(check=False)
|
|
242
|
-
|
|
243
|
-
if isinstance(clear_text, bytes):
|
|
244
|
-
clear_text = clear_text.decode("UTF-8")
|
|
245
|
-
|
|
246
|
-
if isinstance(cipher_data, bytes):
|
|
247
|
-
cipher_data = cipher_data.decode("UTF-8")
|
|
248
|
-
|
|
249
|
-
if isinstance(key, bytes):
|
|
250
|
-
key = base64.b64encode(key).decode("UTF-8")
|
|
251
|
-
|
|
252
|
-
if isinstance(iv, bytes):
|
|
253
|
-
iv = base64.b64encode(iv).decode("UTF-8")
|
|
256
|
+
def insert_crypto(self, hashcode, algorithm, init_key):
|
|
254
257
|
|
|
255
|
-
|
|
258
|
+
if hashcode is None:
|
|
259
|
+
return
|
|
256
260
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
261
|
+
rows = self.select(
|
|
262
|
+
table_name='crypto',
|
|
263
|
+
hashcode=hashcode,
|
|
264
|
+
status='open'
|
|
265
|
+
)
|
|
266
|
+
if len(rows) == 0 or not any(iter([
|
|
267
|
+
True
|
|
268
|
+
for r in rows
|
|
269
|
+
if (
|
|
270
|
+
(algorithm is not None and algorithm == r['algorithm'])
|
|
271
|
+
or (r['algorithm'] is None or r['algorithm'].strip() == "")
|
|
272
|
+
) and (
|
|
273
|
+
(
|
|
274
|
+
(init_key is not None and init_key != '' and init_key != 'IA==')
|
|
275
|
+
and (init_key == r['init_key'] or init_key == r['key'])
|
|
276
|
+
)
|
|
277
|
+
or (r['init_key'] is None or r['init_key'].strip() == "")
|
|
278
|
+
)
|
|
279
|
+
])):
|
|
280
|
+
if init_key is not None and init_key != '' and init_key != 'IA==':
|
|
281
|
+
self.insert_one(
|
|
282
|
+
table_name='crypto',
|
|
283
|
+
hashcode=hashcode,
|
|
284
|
+
algorithm=algorithm,
|
|
285
|
+
init_key=init_key,
|
|
286
|
+
status='open')
|
|
287
|
+
else:
|
|
288
|
+
self.insert_one(
|
|
289
|
+
table_name='crypto',
|
|
290
|
+
hashcode=hashcode,
|
|
291
|
+
algorithm=algorithm,
|
|
292
|
+
status='open')
|
|
293
|
+
|
|
294
|
+
def insert_crypto_key(self, key, key_class, salt=None,
|
|
295
|
+
iteration_count=0, module="<unknown>", additional_data=dict):
|
|
296
|
+
if key is not None and key != '' and key != 'IA==':
|
|
297
|
+
self.insert_ignore_one(
|
|
298
|
+
table_name='crypto_key',
|
|
299
|
+
key=key,
|
|
300
|
+
printable_key=self.get_printable(key),
|
|
301
|
+
key_class=key_class,
|
|
302
|
+
salt=salt,
|
|
303
|
+
iteration_count=iteration_count,
|
|
304
|
+
additional_data=json.dumps({
|
|
305
|
+
**{"module": module},
|
|
306
|
+
**(additional_data if additional_data is not None and isinstance(additional_data, dict) else {})
|
|
307
|
+
}, default=Logger.json_serial)
|
|
308
|
+
)
|
|
268
309
|
|
|
269
310
|
def __init__(self):
|
|
270
311
|
super().__init__('Crypto', 'Hook cryptography/hashing functions')
|
|
@@ -290,31 +331,109 @@ class Crypto(ModuleBase):
|
|
|
290
331
|
received_data: dict = None
|
|
291
332
|
) -> bool:
|
|
292
333
|
|
|
293
|
-
if module
|
|
334
|
+
if module in ["X509EncodedKeySpec.init", "GCMParameterSpec.init", "PBEParameterSpec.init"]:
|
|
335
|
+
|
|
336
|
+
key_class = received_data.get('classtype', module)
|
|
337
|
+
salt = None
|
|
338
|
+
iteration_count = 0
|
|
339
|
+
|
|
340
|
+
key = received_data.get('key', None)
|
|
341
|
+
if module == "GCMParameterSpec.init":
|
|
342
|
+
key = received_data.get('iv_key', None)
|
|
343
|
+
|
|
344
|
+
if module == "PBEParameterSpec.init":
|
|
345
|
+
key = "None"
|
|
346
|
+
salt = received_data.get('pbe_salt', None)
|
|
347
|
+
iteration_count = received_data.get('iteration_count', None)
|
|
348
|
+
|
|
349
|
+
self._crypto_db.insert_crypto_key(
|
|
350
|
+
key=key,
|
|
351
|
+
key_class=key_class,
|
|
352
|
+
salt=salt,
|
|
353
|
+
iteration_count=iteration_count,
|
|
354
|
+
module=module,
|
|
355
|
+
additional_data=received_data
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
if module == "SecretKeySpec.init":
|
|
294
359
|
algorithm = received_data.get('algorithm', None)
|
|
295
|
-
|
|
296
|
-
|
|
360
|
+
key = received_data.get('key', None)
|
|
361
|
+
hashcode = received_data.get('hashcode', None)
|
|
362
|
+
key_class = received_data.get('classtype', "SecretKeySpec")
|
|
363
|
+
self._crypto_db.insert_crypto(
|
|
364
|
+
hashcode=hashcode,
|
|
365
|
+
algorithm=algorithm,
|
|
366
|
+
init_key=key)
|
|
367
|
+
|
|
368
|
+
self._crypto_db.insert_crypto_key(
|
|
369
|
+
key=key,
|
|
370
|
+
key_class=key_class,
|
|
371
|
+
module=module,
|
|
372
|
+
additional_data=received_data
|
|
373
|
+
)
|
|
297
374
|
|
|
298
375
|
elif module == "IvParameterSpec.init":
|
|
299
376
|
bData = received_data.get('iv_key', None)
|
|
377
|
+
key_class = received_data.get('classtype', "IvParameterSpec")
|
|
300
378
|
# print("IV: %s" % bData)
|
|
301
|
-
self._crypto_db.update_crypto(bData)
|
|
379
|
+
self._crypto_db.update_crypto(iv=bData)
|
|
380
|
+
|
|
381
|
+
self._crypto_db.insert_crypto_key(
|
|
382
|
+
key=bData,
|
|
383
|
+
key_class=key_class,
|
|
384
|
+
module=module,
|
|
385
|
+
additional_data=received_data
|
|
386
|
+
)
|
|
302
387
|
|
|
303
388
|
elif module == "cipher.init":
|
|
304
389
|
hashcode = received_data.get('hashcode', None)
|
|
305
390
|
opmode = received_data.get('opmode', "")
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
391
|
+
key_class = received_data.get('keytype', "")
|
|
392
|
+
key = received_data.get('key', None)
|
|
393
|
+
algorithm = received_data.get('algorithm', None)
|
|
394
|
+
|
|
395
|
+
self._crypto_db.insert_crypto(
|
|
396
|
+
hashcode=hashcode,
|
|
397
|
+
algorithm=algorithm,
|
|
398
|
+
init_key=key
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
self._crypto_db.update_crypto(
|
|
402
|
+
hashcode=hashcode,
|
|
403
|
+
flow='enc' if 'encrypt' in opmode else ('dec' if 'decrypt' in opmode else str(opmode)),
|
|
404
|
+
key=key,
|
|
405
|
+
algorithm=algorithm
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
self._crypto_db.insert_crypto_key(
|
|
409
|
+
key=key,
|
|
410
|
+
key_class=key_class,
|
|
411
|
+
module=module,
|
|
412
|
+
additional_data=received_data
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
Logger.print_message(
|
|
416
|
+
level="W",
|
|
417
|
+
message=f"Cipher init received\nHashcode: {hashcode}\nOpmode: {opmode}\nKeytype: {key_class}",
|
|
418
|
+
script_location=script_location
|
|
419
|
+
)
|
|
310
420
|
|
|
311
421
|
elif module == "cipher.doFinal":
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
422
|
+
hashcode = received_data.get('hashcode', None)
|
|
423
|
+
|
|
424
|
+
self._crypto_db.insert_crypto(
|
|
425
|
+
hashcode=hashcode,
|
|
426
|
+
algorithm=None,
|
|
427
|
+
init_key=None
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
self._crypto_db.update_crypto(
|
|
431
|
+
hashcode=hashcode,
|
|
432
|
+
before_final=received_data.get('input', ''),
|
|
433
|
+
after_final=received_data.get('output', ''),
|
|
434
|
+
stack_trace=stack_trace,
|
|
435
|
+
status="complete"
|
|
436
|
+
)
|
|
318
437
|
|
|
319
438
|
Logger.print_message(
|
|
320
439
|
level="D",
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frida-fusion
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.11
|
|
4
4
|
Summary: Hook your mobile tests with Frida
|
|
5
5
|
Author-email: "Helvio Junior (M4v3r1ck)" <helvio_junior@hotmail.com>
|
|
6
6
|
Maintainer-email: "Helvio Junior (M4v3r1ck)" <helvio_junior@hotmail.com>
|
|
@@ -22,6 +22,9 @@ frida_fusion/libs/helpers.js
|
|
|
22
22
|
frida_fusion/libs/logger.py
|
|
23
23
|
frida_fusion/libs/scriptlocation.py
|
|
24
24
|
frida_fusion/modules/__init__.py
|
|
25
|
+
frida_fusion/modules/android_setings/__init__.py
|
|
26
|
+
frida_fusion/modules/android_setings/settings.js
|
|
27
|
+
frida_fusion/modules/android_setings/settings.py
|
|
25
28
|
frida_fusion/modules/crypto/__init__.py
|
|
26
29
|
frida_fusion/modules/crypto/crypto.js
|
|
27
30
|
frida_fusion/modules/crypto/crypto.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|