android-persistence 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,378 @@
1
+ """
2
+ Defensive Mitigations - Mitigation strategies and defensive recommendations.
3
+
4
+ Provides comprehensive mitigation strategies for Android persistence mechanisms
5
+ and security vulnerabilities. Includes defensive techniques for system hardening.
6
+
7
+ DISCLAIMER: These mitigations are intended for defensive purposes on authorized
8
+ systems only. Improper implementation may affect system functionality.
9
+
10
+ Author: Security Research Team
11
+ License: Apache-2.0
12
+ """
13
+
14
+ from typing import Dict, List, Optional, Set
15
+ from dataclasses import dataclass
16
+ from enum import Enum
17
+
18
+
19
+ class MitigationType(Enum):
20
+ """Types of mitigation strategies."""
21
+ DETECTION = "detection"
22
+ PREVENTION = "prevention"
23
+ HARDENING = "hardening"
24
+ MONITORING = "monitoring"
25
+ RESPONSE = "response"
26
+
27
+
28
+ @dataclass
29
+ class Mitigation:
30
+ """Single mitigation strategy."""
31
+ name: str
32
+ description: str
33
+ mitigation_type: MitigationType
34
+ implementation: str
35
+ effectiveness: int # 0-100
36
+ difficulty: int # 0-100 (implementation difficulty)
37
+ references: List[str] = None
38
+
39
+
40
+ class MitigationStrategies:
41
+ """
42
+ Central repository of defensive mitigation strategies.
43
+
44
+ Provides tailored recommendations based on detected persistence mechanisms
45
+ and threat profiles.
46
+
47
+ Example:
48
+ >>> mitigations = MitigationStrategies()
49
+ >>> strategies = mitigations.get_mitigations_for_threat('broadcast_receiver')
50
+ """
51
+
52
+ def __init__(self):
53
+ """Initialize mitigation strategies database."""
54
+ self.mitigations = self._load_mitigations()
55
+
56
+ def _load_mitigations(self) -> Dict[str, List[Mitigation]]:
57
+ """
58
+ Load comprehensive mitigation strategies database.
59
+
60
+ Returns:
61
+ Dictionary mapping threat types to mitigation lists
62
+ """
63
+ return {
64
+ 'broadcast_receiver': [
65
+ Mitigation(
66
+ name="Explicit Intent Usage",
67
+ description="Replace implicit broadcasts with explicit intents",
68
+ mitigation_type=MitigationType.PREVENTION,
69
+ implementation="""
70
+ // Instead of implicit broadcast:
71
+ // Intent i = new Intent("com.example.ACTION");
72
+
73
+ // Use explicit broadcast:
74
+ Intent intent = new Intent(context, MyReceiver.class);
75
+ intent.setAction("com.example.ACTION");
76
+ context.sendBroadcast(intent);
77
+ """,
78
+ effectiveness=95,
79
+ difficulty=30,
80
+ ),
81
+ Mitigation(
82
+ name="Permission-Based Access Control",
83
+ description="Restrict receiver access with signature-level permissions",
84
+ mitigation_type=MitigationType.PREVENTION,
85
+ implementation="""
86
+ <receiver android:name=".MyReceiver"
87
+ android:permission="com.example.permission.RECEIVE_EVENT">
88
+ <intent-filter>
89
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>
90
+ </intent-filter>
91
+ </receiver>
92
+
93
+ <!-- In another app that needs to send: -->
94
+ <uses-permission android:name="com.example.permission.RECEIVE_EVENT"/>
95
+ """,
96
+ effectiveness=80,
97
+ difficulty=25,
98
+ ),
99
+ Mitigation(
100
+ name="Context-Aware Receiver Registration",
101
+ description="Register receivers dynamically only when needed",
102
+ mitigation_type=MitigationType.HARDENING,
103
+ implementation="""
104
+ // Register in onCreate:
105
+ IntentFilter filter = new IntentFilter();
106
+ filter.addAction(Intent.ACTION_BOOT_COMPLETED);
107
+ registerReceiver(myReceiver, filter);
108
+
109
+ // Unregister in onDestroy:
110
+ unregisterReceiver(myReceiver);
111
+ """,
112
+ effectiveness=85,
113
+ difficulty=40,
114
+ ),
115
+ ],
116
+ 'service': [
117
+ Mitigation(
118
+ name="Implement StartId Management",
119
+ description="Properly handle service stopSelf() with correct startId",
120
+ mitigation_type=MitigationType.HARDENING,
121
+ implementation="""
122
+ @Override
123
+ public int onStartCommand(Intent intent, int flags, int startId) {
124
+ // Do work
125
+
126
+ // Only stop if this is the latest request
127
+ if (shouldStop) {
128
+ stopSelf(startId);
129
+ }
130
+
131
+ return START_NOT_STICKY; // Don't restart
132
+ }
133
+ """,
134
+ effectiveness=90,
135
+ difficulty=20,
136
+ ),
137
+ Mitigation(
138
+ name="Background Service Limitations",
139
+ description="Use WorkManager or JobScheduler with constraints",
140
+ mitigation_type=MitigationType.HARDENING,
141
+ implementation="""
142
+ // Use WorkManager instead of Service:
143
+ PeriodicWorkRequest workRequest =
144
+ new PeriodicWorkRequest.Builder(
145
+ MyWorker.class,
146
+ 15, // minimum interval
147
+ TimeUnit.MINUTES)
148
+ .addTag("background_work")
149
+ .build();
150
+
151
+ WorkManager.getInstance(context)
152
+ .enqueueUniquePeriodicWork(
153
+ "work_name",
154
+ ExistingPeriodicWorkPolicy.REPLACE,
155
+ workRequest);
156
+ """,
157
+ effectiveness=85,
158
+ difficulty=35,
159
+ ),
160
+ Mitigation(
161
+ name="Service Permission Declaration",
162
+ description="Declare services with explicit permissions",
163
+ mitigation_type=MitigationType.PREVENTION,
164
+ implementation="""
165
+ <service android:name=".MyService"
166
+ android:permission="com.example.INTERNAL_SERVICE">
167
+ <intent-filter>
168
+ <action android:name="com.example.MY_ACTION"/>
169
+ </intent-filter>
170
+ </service>
171
+ """,
172
+ effectiveness=80,
173
+ difficulty=15,
174
+ ),
175
+ ],
176
+ 'native_library': [
177
+ Mitigation(
178
+ name="Native Code Validation",
179
+ description="Use runtime code integrity verification for native libs",
180
+ mitigation_type=MitigationType.DETECTION,
181
+ implementation="""
182
+ // Compute hash of loaded native library
183
+ public boolean verifyNativeLibrary(String libName) {
184
+ try {
185
+ System.loadLibrary(libName);
186
+ String libPath = findLoadedLibraryPath(libName);
187
+ String hash = calculateFileHash(libPath);
188
+ return hash.equals(expectedHash);
189
+ } catch (Exception e) {
190
+ return false;
191
+ }
192
+ }
193
+ """,
194
+ effectiveness=75,
195
+ difficulty=60,
196
+ ),
197
+ Mitigation(
198
+ name="Selinux Policy Enforcement",
199
+ description="Implement strict SELinux policy for native code",
200
+ mitigation_type=MitigationType.HARDENING,
201
+ implementation="""
202
+ # SELinux policy for native library access
203
+ type app_native_t;
204
+ type app_data_t;
205
+
206
+ allow app_native_t app_data_t:file { read write };
207
+ deny app_native_t kernel_t:capability sys_ptrace;
208
+ neverallow app_native_t device_t:chr_file write;
209
+ """,
210
+ effectiveness=90,
211
+ difficulty=80,
212
+ ),
213
+ Mitigation(
214
+ name="Address Space Layout Randomization (ASLR)",
215
+ description="Enable ASLR to prevent memory exploitation",
216
+ mitigation_type=MitigationType.HARDENING,
217
+ implementation="""
218
+ # ASLR is enabled by default on modern Android
219
+ # Verify via:
220
+ adb shell cat /proc/sys/kernel/randomize_va_space
221
+ # Should output: 2 (full ASLR)
222
+ """,
223
+ effectiveness=85,
224
+ difficulty=5,
225
+ ),
226
+ ],
227
+ 'job_scheduler': [
228
+ Mitigation(
229
+ name="Job Constraints Implementation",
230
+ description="Enforce strict constraints on scheduled jobs",
231
+ mitigation_type=MitigationType.HARDENING,
232
+ implementation="""
233
+ JobInfo job = new JobInfo.Builder(JOB_ID, componentName)
234
+ .setRequiresDeviceIdle(true)
235
+ .setRequiresCharging(true)
236
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
237
+ .setPeriodic(24 * 60 * 60 * 1000) // 24 hours minimum
238
+ .build();
239
+ """,
240
+ effectiveness=80,
241
+ difficulty=25,
242
+ ),
243
+ Mitigation(
244
+ name="Job Execution Monitoring",
245
+ description="Monitor and log all job executions",
246
+ mitigation_type=MitigationType.MONITORING,
247
+ implementation="""
248
+ public class MonitoredJobService extends JobService {
249
+ @Override
250
+ public boolean onStartJob(JobParameters params) {
251
+ logJobExecution("started", params.getJobId());
252
+ doWork();
253
+ logJobExecution("completed", params.getJobId());
254
+ return false;
255
+ }
256
+ }
257
+ """,
258
+ effectiveness=70,
259
+ difficulty=30,
260
+ ),
261
+ ],
262
+ 'intent_filter': [
263
+ Mitigation(
264
+ name="Explicit Component Targeting",
265
+ description="Always use explicit intents instead of implicit",
266
+ mitigation_type=MitigationType.PREVENTION,
267
+ implementation="""
268
+ // Bad: implicit intent
269
+ Intent intent = new Intent("com.example.ACTION");
270
+ startActivity(intent);
271
+
272
+ // Good: explicit intent
273
+ Intent intent = new Intent(this, TargetActivity.class);
274
+ startActivity(intent);
275
+ """,
276
+ effectiveness=95,
277
+ difficulty=20,
278
+ ),
279
+ Mitigation(
280
+ name="Intent Filter Export Control",
281
+ description="Carefully control intent filter export attribute",
282
+ mitigation_type=MitigationType.HARDENING,
283
+ implementation="""
284
+ <!-- Only export if truly necessary -->
285
+ <activity android:name=".PublicActivity"
286
+ android:exported="true">
287
+ <intent-filter>
288
+ <action android:name="android.intent.action.MAIN"/>
289
+ </intent-filter>
290
+ </activity>
291
+
292
+ <!-- Default: not exported -->
293
+ <activity android:name=".PrivateActivity">
294
+ </activity>
295
+ """,
296
+ effectiveness=85,
297
+ difficulty=15,
298
+ ),
299
+ ],
300
+ }
301
+
302
+ def get_mitigations_for_threat(self, threat_type: str) -> List[Mitigation]:
303
+ """
304
+ Get mitigations for specific threat type.
305
+
306
+ Args:
307
+ threat_type: Type of threat (e.g., 'broadcast_receiver')
308
+
309
+ Returns:
310
+ List of applicable mitigations
311
+ """
312
+ threat_type = threat_type.lower().replace(' ', '_')
313
+ return self.mitigations.get(threat_type, [])
314
+
315
+ def get_mitigations_by_type(self, mitigation_type: MitigationType) -> List[Mitigation]:
316
+ """
317
+ Get all mitigations of specific type.
318
+
319
+ Args:
320
+ mitigation_type: Type of mitigation to filter by
321
+
322
+ Returns:
323
+ List of mitigations
324
+ """
325
+ results = []
326
+ for mitigations in self.mitigations.values():
327
+ results.extend([m for m in mitigations if m.mitigation_type == mitigation_type])
328
+ return results
329
+
330
+ def get_highest_effectiveness_mitigation(
331
+ self,
332
+ threat_type: str
333
+ ) -> Optional[Mitigation]:
334
+ """Get most effective mitigation for threat."""
335
+ mitigations = self.get_mitigations_for_threat(threat_type)
336
+ if not mitigations:
337
+ return None
338
+ return max(mitigations, key=lambda m: m.effectiveness)
339
+
340
+ def get_easiest_mitigations(self, threat_type: str, count: int = 3) -> List[Mitigation]:
341
+ """Get easiest-to-implement mitigations."""
342
+ mitigations = self.get_mitigations_for_threat(threat_type)
343
+ sorted_mitigations = sorted(mitigations, key=lambda m: m.difficulty)
344
+ return sorted_mitigations[:count]
345
+
346
+ def generate_mitigation_report(self, threats: List[str]) -> str:
347
+ """
348
+ Generate mitigation recommendations report.
349
+
350
+ Args:
351
+ threats: List of detected threat types
352
+
353
+ Returns:
354
+ Formatted mitigation report
355
+ """
356
+ lines = ["MITIGATION RECOMMENDATIONS REPORT", "=" * 70]
357
+ lines.append("")
358
+
359
+ all_mitigations: Set[str] = set()
360
+
361
+ for threat in threats:
362
+ mitigations = self.get_mitigations_for_threat(threat)
363
+ if mitigations:
364
+ lines.append(f"\n{threat.upper()}")
365
+ lines.append("-" * 50)
366
+
367
+ for mitigation in mitigations:
368
+ lines.append(f"\n {mitigation.name}")
369
+ lines.append(f" Type: {mitigation.mitigation_type.value}")
370
+ lines.append(f" Effectiveness: {mitigation.effectiveness}%")
371
+ lines.append(f" Difficulty: {mitigation.difficulty}/100")
372
+ lines.append(f" Description: {mitigation.description}")
373
+ all_mitigations.add(mitigation.name)
374
+
375
+ lines.append("\n" + "=" * 70)
376
+ lines.append(f"Total Unique Mitigations: {len(all_mitigations)}")
377
+
378
+ return "\n".join(lines)