
IOSSecuritySuite v2.3.0
Библиотека Swift для безопасности платформы iOS и защиты от взлома
⭐️ Хотите стать сертифицированным инженером по безопасности iOS-приложений? ⭐️
Ознакомьтесь с нашим практическим и полностью онлайн-курсом: https://courses.securing.pl/courses/iase

Описание ISS

by @_r3ggi
🌏 iOS Security Suite — это продвинутая и простая в использовании библиотека для обеспечения безопасности платформы и защиты от взлома, написанная на чистом Swift! Если вы разрабатываете приложения для iOS и хотите защитить их в соответствии со стандартом OWASP MASVS, глава v8, эта библиотека может сэкономить вам много времени. 🚀
Что обнаруживает ISS:
- Jailbreak 🧨
- Подключённый отладчик 👨🏻🚀
- Запуск приложения в эмуляторе 👽
- Популярные инструменты для реверс-инжиниринга, запущенные на устройстве 🔭
Установка
Есть 4 способа начать использовать IOSSecuritySuite
1. Добавление исходников
Добавьте файлы IOSSecuritySuite/*.swift в ваш проект
2. Установка через CocoaPods
pod 'IOSSecuritySuite'
3. Установка через Carthage
github "securing/IOSSecuritySuite"
4. Установка через Swift Package Manager
.package(url: "https://github.com/securing/IOSSecuritySuite.git", from: "1.5.0")
Обновление Info.plist
После добавления ISS в проект вам также потребуется обновить ваш основной Info.plist. В модуле обнаружения jailbreak используется метод canOpenURL(_:), требующий указания URL, которые будут проверяться.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>undecimus</string>
<string>sileo</string>
<string>zbra</string>
<string>filza</string>
</array>
Ценообразование
Ознакомьтесь с нашей лицензией EULA для подробной информации.
Кратко: Если в вашей компании работает:
- 0-99 человек — бесплатно
- 100-1000 — 3 000 евро/год
- 1000+ — 10 000 евро/год
Если вы хотите продавать модуль, использующий iOS Security Suite (но не используемый непосредственно в вашем приложении) — 10 000 евро/год
Примечание
iOS Security Suite предназначен для использования на iOS/iPadOS. Его не следует использовать на Mac с Apple Silicon.
Как использовать
Модуль обнаружения jailbreak
- Простейший метод возвращает True/False, если вы просто хотите узнать, взломано устройство или нет
if IOSSecuritySuite.amIJailbroken() {
print("This device is jailbroken")
} else {
print("This device is not jailbroken")
}
- Подробный, если вы также хотите узнать, какие признаки были обнаружены
let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailMessage()
if jailbreakStatus.jailbroken {
print("This device is jailbroken")
print("Because: \(jailbreakStatus.failMessage)")
} else {
print("This device is not jailbroken")
}
Параметр failMessage — это строка, содержащая признаки, разделённые запятыми, как показано в примере ниже:
sileo:// URL scheme detected, Suspicious file exists: /Library/MobileSubstrate/MobileSubstrate.dylib, Fork was able to create a new process
- Подробный и фильтруемый, если вы также хотите, например, идентифицировать устройства, которые были взломаны в прошлом, но сейчас находятся в защищённом состоянии
let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailedChecks()
if jailbreakStatus.jailbroken {
if (jailbreakStatus.failedChecks.contains { $0.check == .existenceOfSuspiciousFiles }) && (jailbreakStatus.failedChecks.contains { $0.check == .suspiciousFilesCanBeOpened }) {
print("This is real jailbroken device")
}
}
Модуль обнаружения отладчика
let amIDebugged: Bool = IOSSecuritySuite.amIDebugged()
Запретить отладчик полностью
IOSSecuritySuite.denyDebugger()
Модуль обнаружения эмулятора
let runInEmulator: Bool = IOSSecuritySuite.amIRunInEmulator()
Модуль обнаружения инструментов реверс-инжиниринга
- Простейший метод возвращает True/False, если вы просто хотите узнать, есть ли на устройстве признаки реверс-инжиниринга
if IOSSecuritySuite.amIReverseEngineered() {
print("This device has evidence of reverse engineering")
} else {
print("This device hasn't evidence of reverse engineering")
}
- Подробный и фильтруемый, если вы также хотите получить список выполненных проверок
let reverseStatus = IOSSecuritySuite.amIReverseEngineeredWithFailedChecks()
if reverseStatus.reverseEngineered {
// check for reverseStatus.failedChecks for more details
}
Модуль обнаружения системного прокси
Теперь вы также можете определить, подключено ли приложение к VPN
let amIProxied: Bool = IOSSecuritySuite.amIProxied(considerVPNConnectionAsProxy: true)
Модуль обнаружения режима блокировки
let amIInLockdownMode: Bool = IOSSecuritySuite.amIInLockdownMode()
Экспериментальные функции
Модуль обнаружения перехвата во время выполнения
let amIRuntimeHooked: Bool = amIRuntimeHook(dyldWhiteList: dylds, detectionClass: SomeClass.self, selector: #selector(SomeClass.someFunction), isClassMethod: false)
Модуль запрета перехвата символов
// If we want to deny symbol hook of Swift function, we have to pass mangled name of that function
denySymbolHook("$s10Foundation5NSLogyySS_s7CVarArg_pdtF") // denying hooking for the NSLog function
NSLog("Hello Symbol Hook")
denySymbolHook("abort")
abort()
Модуль обнаружения MSHook
// Function declaration
func someFunction(takes: Int) -> Bool {
return false
}
// Defining FunctionType : @convention(thin) indicates a “thin” function reference, which uses the Swift calling convention with no special “self” or “context” parameters.
typealias FunctionType = @convention(thin) (Int) -> (Bool)
// Getting pointer address of function we want to verify
func getSwiftFunctionAddr(_ function: @escaping FunctionType) -> UnsafeMutableRawPointer {
return unsafeBitCast(function, to: UnsafeMutableRawPointer.self)
}
let funcAddr = getSwiftFunctionAddr(someFunction)
let amIMSHooked = IOSSecuritySuite.amIMSHooked(funcAddr)
Модуль запрета MSHook
// Function declaration
func denyDebugger(value: Int) {
}
// Defining FunctionType : @convention(thin) indicates a “thin” function reference, which uses the Swift calling convention with no special “self” or “context” parameters.
typealias FunctionType = @convention(thin) (Int)->()
// Getting original function address
let funcDenyDebugger: FunctionType = denyDebugger
let funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self)
if let originalDenyDebugger = denyMSHook(funcAddr) {
// Call the original function with 1337 as Int argument
unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337)
} else {
denyDebugger()
}
Модуль проверки целостности файлов
// Determine if application has been tampered with
if IOSSecuritySuite.amITampered([.bundleID("biz.securing.FrameworkClientApp"),
.mobileProvision("2976c70b56e9ae1e2c8e8b231bf6b0cff12bbbd0a593f21846d9a004dd181be3"),
.machO("IOSSecuritySuite", "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc")]).result {
print("I have been Tampered.")
}
else {
print("I have not been Tampered.")
}
// Manually verify SHA256 hash value of a loaded dylib
if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.custom("IOSSecuritySuite")), hashValue == "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc" {
print("I have not been Tampered.")
}
else {
print("I have been Tampered.")
}
// Check SHA256 hash value of the main executable
// Tip: Your application may retrieve this value from the server
if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.default), hashValue == "your-application-executable-hash-value" {
print("I have not been Tampered.")
}
else {
print("I have been Tampered.")
}
Модуль обнаружения точек останова
func denyDebugger() {
// Set breakpoint here
}
typealias FunctionType = @convention(thin) ()->()
let func_denyDebugger: FunctionType = denyDebugger // `: FunctionType` is a must
let func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)
let hasBreakpoint = IOSSecuritySuite.hasBreakpointAt(func_addr, functionSize: nil)
if hasBreakpoint {
print("Breakpoint found in the specified function")
} else {
print("Breakpoint not found in the specified function")
}
Модуль обнаружения точек наблюдения
// Set a breakpoint at the testWatchpoint function
func testWatchpoint() -> Bool{
// lldb: watchpoint set expression ptr
var ptr = malloc(9)
// lldb: watchpoint set variable count
var count = 3
return IOSSecuritySuite.hasWatchpoint()
}
Соображения безопасности
Прежде чем использовать это и другие средства проверки безопасности платформы, вы должны понимать:
- Включение этого инструмента в ваш проект — не единственное, что нужно сделать для повышения безопасности приложения! Вы можете прочитать общее руководство по мобильной безопасности здесь.
- Обнаружение джейлбрейка производится локально на устройстве. Это означает, что любой детектор джейлбрейка может быть обойдён (даже этот)!
- Считается, что код на Swift труднее динамически модифицировать, чем на Objective-C. Поскольку эта библиотека написана на чистом Swift, методы IOSSecuritySuite не должны быть доступны среде выполнения Objective-C (что затрудняет их обход ✅). Вы должны знать, что злоумышленник всё ещё может использовать MSHookFunction/MSFindSymbol для перехвата символов Swift и динамически изменять поток выполнения кода Swift.
Вклад ❤️
Да, пожалуйста! Если у вас есть идея получше или вы просто хотите улучшить этот проект, напишите мне в Twitter или LinkedIn. Pull request'ы приветствуются!
Особая благодарность: 👏🏻
- kubajakowski за указание проблемы с методом
canOpenURL(_:) - olbartek за ревью кода и pull request
- benbahrenburg за различные улучшения ISS
- fotiDim за добавление новых путей к файлам для проверки
- gcharita за добавление поддержки Swift Package Manager
- rynaardb за создание метода
amIJailbrokenWithFailedChecks() - undeaDD за различные улучшения ISS
- fnxpt за добавление множества детекций JB
- TannerJin за модули обнаружения MSHook, RuntimeHook, SymbolHook и Watchpoint
- NikoXu за добавление модуля целостности файлов
- hellpf за исправление проблемы с висящим сокетом
- Ant-tree за улучшение устойчивости к перехвату
- izmcm за реализацию метода
amIReverseEngineeredWithFailedChecks() - sanu за предоставление новых проверок файлов
- marsepu за качественно выполненный PR с новыми улучшениями
- mkj-is за PR, улучшающий производительность ISS 🚄
- LongXiangGuo за PR с добавлением манифеста конфиденциальности
- Coeur за улучшения ISS и исправления ошибок
- Adobels за адаптацию ISS к новым требованиям Apple
TODO
- Исследовать обнаружение Installer5 и Zebra Package Manager (альтернативы Cydia)
- Детектор Dopamine hidejb
Лицензия
Смотрите файл LICENSE.
Ссылки
При создании этого инструмента я использовал:
- 🔗 https://github.com/TheSwiftyCoder/JailBreak-Detection
- 🔗 https://github.com/abhinashjain/jailbreakdetection
- 🔗 https://gist.github.com/ddrccw/8412847
- 🔗 https://gist.github.com/bugaevc/4307eaf045e4b4264d8e395b5878a63b
- 📚 "iOS Application Security" by David Thiel