모바일 취약점 점검/iOS

[iOS] 무결성(앱 위변조) 검증 코드

서쪽곰 2023. 5. 15. 16:49

목 차

     

    해시 비교 무결성 검증

    iOS 해시 비교 무결성 검증은 앱의 암호화 해시를 알려지고 신뢰할 수 있는 해시 값과 비교하여 iOS 앱의 무결성과 신뢰성을 보장하는 보안 메커니즘입니다. 이 메커니즘은 앱 개발자가 서명하고 게시한 이후 앱이 수정되거나 변조되지 않았는지 확인합니다.

    iOS 앱이 서명되면 앱의 이진 파일 내용을 기반으로 고유한 암호화 해시 값이 생성됩니다. 그런 다음 이 해시 값은 앱 개발자의 개인 키를 사용하여 암호화되어 앱의 진위와 무결성을 확인하는 디지털 서명을 생성합니다.

    해시 비교를 통해 앱의 무결성을 확인하기 위해 iOS 시스템은 설치된 앱에 대한 해시 값을 생성하고 앱 개발자가 제공한 신뢰할 수 있는 해시 값과 비교합니다. 해시 값이 일치하면 앱을 신뢰할 수 있는 것으로 간주하고 기기에 설치 및 실행할 수 있습니다. 해시 값이 일치하지 않으면 앱을 신뢰할 수 없는 것으로 간주하여 설치 또는 실행이 차단될 수 있습니다.

    해시 비교는 개인 정보를 손상시키거나 데이터를 도용하거나 기기를 손상시킬 수 있는 잠재적으로 유해한 앱으로부터 사용자를 보호하는 데 도움이 되므로 iOS 기기의 중요한 보안 기능입니다. 사용자는 신뢰할 수 있는 출처의 앱만 설치하고 해시 비교 또는 기타 보안 메커니즘을 사용하여 기기에 다운로드 및 설치한 앱의 ​​무결성을 확인하는 것이 좋습니다.

     

    솔루션을 통한 무결성 검증

    솔루션 무결성 검증


    솔루션의 경우 Random값을 통한 해시값 변조 방지 및 2차 인증을 위한 토큰 전송 등으로 무결성 검증의 프로세스 우회를 방지하고 있습니다.

     

    일반적인 무결성 검증

    모바일 전자정부서비스 앱 소스코드 검증 가이드라인 - 앱 위변조 탐지 프로세스


    일반적으로는 앱 바이너리의 해시값을 생성 후 서버에서 원본 해시값과 비교하는 간단한 로직으로 구현됩니다.

    아래의 코드는 일반적인 무결성 검증 코드로 해시값을 생성하는 코드입니다.

     

    바이너리의 해시값을 비교하는 무결성 검증 코드

        // 번들에 있는 파일 중 앱 바이너리 파일의 해시값을 비교하여 무결성 검증
        func verifyIntegrity() -> Bool {
            let mainBundle = Bundle.main
            let bundlePath = mainBundle.bundlePath
            let filesEnumerator = FileManager.default.enumerator(atPath: bundlePath)!
            while let file = filesEnumerator.nextObject() as? String {
                let filePath = "\(bundlePath)/\(file)"
                if FileManager.default.fileExists(atPath: filePath) {
                    if let data = FileManager.default.contents(atPath: filePath) {
                        let hash = sha256(data: data)
                        if file == "Integrity" {
                            textCurrent.text = "[Current Hash]\n" + hash;
                            if hash == "45aac298ed374d8721e923ebe5c9b300cb18b5507036aba1bfd76c3c4833d1da" {
                                return true
                            }
                        }
                    }
                }
            }
            return false
        }
    
        func sha256(data: Data) -> String {
            var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
            data.withUnsafeBytes {
                _ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &digest)
            }
            let hexBytes = digest.map { String(format: "%02hhx", $0) }
            return hexBytes.joined()
        }

    번들을 통해 iOS 바이너리의 해시값을 구하여 비교하는 코드로 해당 코드를 사용할 경우 iOS는 resource 파일도 바이너리에 포함되므로 웹 통신을 통해 원본 해시 값과 비교하는 코드를 추가해야 합니다.

    변경되는 코드는 if hash == "45aac298ed374d8721e923ebe5c9b300cb18b5507036aba1bfd76c3c4833d1da" 해당 부분의 코드를 현재 해시 값과 서버의 해시값을 비교하는 로직으로 변경해야 합니다.

     

    2023.05.15 - [보안/모바일 취약점 점검] - [Android, iOS] OS변조(루팅/탈옥), 무결성 검증, 디버깅 탐지 프로젝트 파일

     

    [Android, iOS] OS변조(루팅/탈옥), 무결성 검증, 디버깅 탐지 프로젝트 파일

    1. 프로젝트 실행결과 Android_Integrity.zip - Android 프로젝트 파일 iOS_Integrity.zip - iOS 프로젝트 파일 Integrity.apk - Android 프로젝트 빌드 파일 Integrity.ipa - iOS 프로젝트 빌드 파일 1) Android Android 프로젝트

    seo-security.tistory.com

     

    반응형