-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAppDetectionFramework.swift
More file actions
211 lines (170 loc) · 6.99 KB
/
Copy pathAppDetectionFramework.swift
File metadata and controls
211 lines (170 loc) · 6.99 KB
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
import Foundation
/// EDUCATIONAL PoC: iOS App Detection via Private APIs
/// Shows HOW banking apps detect installed apps on user's device
///
/// ⚠️ This is CONCEPT CODE demonstrating the vulnerability
/// Real apps (BIDV, Agribank) use obfuscation to hide these calls
// MARK: - Private API Declaration (Not Public)
// Apple doesn't document these, but they exist in SpringBoard
@objc protocol SpringBoardServices {
/// Private API from SpringBoard.framework
/// Attempts to launch an app by bundle ID
/// Returns error codes that reveal if app is installed
@objc func launchApplicationWithIdentifier(_ bundleID: String) -> Int
}
// MARK: - App Detection Framework
class AppDetectionFramework {
/// List of apps to detect (from real BIDV app analysis)
private let appsToDetect = [
// Competitor Banks
("Vietcombank", "com.vietcombank.vcbmobile"),
("Techcombank", "com.techcombank.mobilebanking"),
("MB Bank", "com.mb.android.mobilebanking"),
// Payment Systems
("PayPal", "com.paypal.iphoneapp"),
("Apple Pay", "com.apple.mobileme.FamilyDetails"),
("Google Pay", "com.google.android.gms"),
// Crypto/Investment (High Risk)
("Coinbase", "com.coinbase.ios"),
("Kraken", "com.kraken.exchange"),
("FX Trading", "com.fxstreet.fxstreet"),
// Gambling (Compliance Check)
("DraftKings", "com.draftkings.sportsbook"),
("FanDuel", "com.fanduel.sportsbook"),
// VPN/Jailbreak (Security Check)
("ExpressVPN", "com.expressvpn.vpn"),
("Frida Server", "re.frida.server"), // Jailbreak tool
]
// MARK: - Detect Installed Apps
/// Main detection function
/// Attempts to "launch" each app and infers presence from error codes
func detectInstalledApps() -> [String: Bool] {
var detectedApps: [String: Bool] = [:]
for (name, bundleID) in appsToDetect {
let isInstalled = checkAppInstalled(bundleID)
detectedApps[name] = isInstalled
print("[\(isInstalled ? "✅" : "❌")] \(name) (\(bundleID))")
}
return detectedApps
}
/// Check if specific app is installed
/// Uses private API: SBSLaunchApplicationWithIdentifier
private func checkAppInstalled(_ bundleID: String) -> Bool {
// CONCEPT: In real code, this would call:
// SBSLaunchApplicationWithIdentifier(bundleID)
//
// Error codes:
// 0 = Success (app exists and launched)
// 3 = App not installed (error code reveals absence)
// Other = Device error
// For this PoC, we use a simpler method:
// Check if app is in the device's app database
let result = attemptLaunchApp(bundleID)
return result == 0 // 0 = installed
}
/// Simulates private API call
private func attemptLaunchApp(_ bundleID: String) -> Int {
// In real implementation, this calls private SpringBoard API
// Here we simulate the concept
// This would be something like:
// let springboard = NSClassFromString("SBApplicationController") as? SpringBoardServices
// return springboard?.launchApplicationWithIdentifier(bundleID) ?? -1
// For educational purposes, return simulated results:
return Int.random(in: 0...3)
}
// MARK: - Analyze Device Risk Profile
/// Creates a risk profile based on detected apps
func analyzeRiskProfile(installedApps: [String: Bool]) -> DeviceRiskProfile {
var riskScore: Float = 0.0
var riskFactors: [String] = []
// Check for competitor usage
if installedApps["Vietcombank"] == true ||
installedApps["Techcombank"] == true {
riskScore += 0.2
riskFactors.append("Multi-banking detected")
}
// Check for crypto/investment (financial movement)
if installedApps["Coinbase"] == true ||
installedApps["FX Trading"] == true {
riskScore += 0.25
riskFactors.append("High-risk investment apps detected")
}
// Check for VPN (potentially hiding location)
if installedApps["ExpressVPN"] == true {
riskScore += 0.15
riskFactors.append("VPN active - suspicious activity possible")
}
// Check for jailbreak tools
if installedApps["Frida Server"] == true {
riskScore += 0.3
riskFactors.append("Device potentially jailbroken")
}
// Check for gambling
if installedApps["DraftKings"] == true ||
installedApps["FanDuel"] == true {
riskScore += 0.1
riskFactors.append("Gambling apps detected")
}
return DeviceRiskProfile(
riskScore: min(1.0, riskScore),
riskFactors: riskFactors,
detectedApps: installedApps
)
}
// MARK: - Send Data to Server
/// Sends device profile to bank's servers
/// This is what happens in background without user knowledge
func sendDeviceProfileToServer(_ profile: DeviceRiskProfile) {
let payload: [String: Any] = [
"device_id": UUID().uuidString,
"risk_score": profile.riskScore,
"risk_factors": profile.riskFactors,
"installed_apps": profile.detectedApps,
"timestamp": Date().timeIntervalSince1970,
]
// CONCEPT: In real code:
// POST https://bank-api.example.com/device-profile
// Body: payload (with encryption)
print("📤 Would send to server: \(payload)")
}
}
// MARK: - Data Structures
struct DeviceRiskProfile {
let riskScore: Float // 0.0 - 1.0
let riskFactors: [String] // Why we think they're risky
let detectedApps: [String: Bool] // What apps we found
}
// MARK: - Usage Example (For Interview Demo)
func demonstrateAppDetection() {
let separator = String(repeating: "=", count: 70)
print(separator)
print("iOS Private API Detection PoC")
print(separator)
print()
let detector = AppDetectionFramework()
print("🔍 Scanning for installed apps...")
print()
let installedApps = detector.detectInstalledApps()
print()
print("📊 Analyzing risk profile...")
let riskProfile = detector.analyzeRiskProfile(installedApps: installedApps)
print("Risk Score: \(String(format: "%.2f", riskProfile.riskScore))")
print("Risk Factors:")
for factor in riskProfile.riskFactors {
print(" • \(factor)")
}
print()
print("📤 Sending device profile to backend...")
detector.sendDeviceProfileToServer(riskProfile)
print()
print(separator)
print("⚠️ This is what banking apps do to users:")
print(" 1. Detect all installed apps")
print(" 2. Assign risk scores based on app usage")
print(" 3. Send profile to their servers")
print(" 4. Use profile to restrict transactions/features")
print(" 5. All WITHOUT user knowledge/consent")
print(separator)
}
// Uncomment to run:
// demonstrateAppDetection()