{{#include ../../banners/hacktricks-training.md}} iOS 기기에서 애플리케이션 간 데이터 공유는 [`UIPasteboard`](https://developer.apple.com/documentation/uikit/uipasteboard) 메커니즘에 의해 촉진되며, 이는 두 가지 주요 범주로 나뉩니다: - **시스템 전반의 일반 클립보드**: 이는 **모든 애플리케이션**과 데이터를 공유하는 데 사용되며, iOS 10부터 제공된 기능으로, 장치 재시작 및 앱 삭제 후에도 데이터를 지속적으로 유지하도록 설계되었습니다. - **사용자 정의 / 명명된 클립보드**: 이는 **앱 내 또는 동일한 팀 ID를 공유하는 다른 앱과의 데이터 공유**를 위해 특별히 설계되었으며, 이를 생성하는 애플리케이션 프로세스의 생명 주기를 넘어 지속되도록 설계되지 않았습니다. 이는 iOS 10에서 도입된 변경 사항을 따릅니다. **보안 고려사항**은 클립보드를 사용할 때 중요한 역할을 합니다. 예를 들어: - 사용자가 **클립보드**에 접근할 수 있는 앱 권한을 관리할 수 있는 메커니즘이 없습니다. - 클립보드에 대한 무단 배경 모니터링의 위험을 완화하기 위해, 접근은 애플리케이션이 전경에 있을 때로 제한됩니다(이것은 iOS 9부터 적용됨). - 개인 정보 보호 문제로 인해 지속적인 명명된 클립보드의 사용은 공유 컨테이너를 선호합니다. - iOS 10에서 도입된 **유니버설 클립보드** 기능은 일반 클립보드를 통해 장치 간 콘텐츠를 공유할 수 있게 하며, 개발자가 데이터 만료를 설정하고 자동 콘텐츠 전송을 비활성화할 수 있도록 관리할 수 있습니다. **민감한 정보가 우연히 전역 클립보드에 저장되지 않도록 하는 것**이 중요합니다. 또한, 애플리케이션은 전역 클립보드 데이터를 의도하지 않은 작업에 악용되지 않도록 설계되어야 하며, 개발자는 민감한 정보를 클립보드에 복사하는 것을 방지하기 위한 조치를 구현하도록 권장됩니다. ### 정적 분석 정적 분석을 위해 소스 코드나 바이너리에서 다음을 검색합니다: - `generalPasteboard`를 사용하여 **시스템 전반의 일반 클립보드** 사용을 식별합니다. - `pasteboardWithName:create:` 및 `pasteboardWithUniqueName`을 사용하여 **사용자 정의 클립보드**를 생성합니다. 지속성이 활성화되어 있는지 확인하되, 이는 더 이상 사용되지 않습니다. ### 동적 분석 동적 분석은 특정 메서드를 후킹하거나 추적하는 것을 포함합니다: - 시스템 전반의 사용을 위해 `generalPasteboard`를 모니터링합니다. - 사용자 정의 구현을 위해 `pasteboardWithName:create:` 및 `pasteboardWithUniqueName`을 추적합니다. - 지속성 설정을 확인하기 위해 더 이상 사용되지 않는 `setPersistent:` 메서드 호출을 관찰합니다. 모니터링해야 할 주요 세부 사항은 다음과 같습니다: - **클립보드 이름** 및 **내용**(예: 문자열, URL, 이미지 확인). - 존재하는 **항목 수** 및 **데이터 유형**, 표준 및 사용자 정의 데이터 유형 검사를 활용합니다. - `setItems:options:` 메서드를 검사하여 **만료 및 로컬 전용 옵션**을 확인합니다. 모니터링 도구 사용의 예로는 **objection의 클립보드 모니터**가 있으며, 이는 일반 클립보드를 5초마다 폴링하여 변경 사항을 확인하고 새로운 데이터를 출력합니다. 다음은 objection의 접근 방식에서 영감을 받아 클립보드의 변경 사항을 5초마다 읽고 기록하는 간단한 JavaScript 스크립트 예제입니다: ```javascript const UIPasteboard = ObjC.classes.UIPasteboard const Pasteboard = UIPasteboard.generalPasteboard() var items = "" var count = Pasteboard.changeCount().toString() setInterval(function () { const currentCount = Pasteboard.changeCount().toString() const currentItems = Pasteboard.items().toString() if (currentCount === count) { return } items = currentItems count = currentCount console.log( "[* Pasteboard changed] count: " + count + " hasStrings: " + Pasteboard.hasStrings().toString() + " hasURLs: " + Pasteboard.hasURLs().toString() + " hasImages: " + Pasteboard.hasImages().toString() ) console.log(items) }, 1000 * 5) ``` ## 참고문헌 - [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8) - [https://hackmd.io/@robihamanto/owasp-robi](https://hackmd.io/@robihamanto/owasp-robi) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0073/](https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0073/) {{#include ../../banners/hacktricks-training.md}}