iOS Pentesting
Trickest를 사용하여 세계에서 가장 진보된 커뮤니티 도구로 구동되는 워크플로우를 쉽게 구축하고 자동화하세요. 지금 바로 액세스하세요:
iOS 기본 사항
iOS Basics테스트 환경
이 페이지에서는 iOS 시뮬레이터, 에뮬레이터 및 탈옥에 대한 정보를 찾을 수 있습니다:
iOS Testing Environment초기 분석
기본 iOS 테스트 작업
테스트 중에 여러 작업이 제안될 것입니다 (장치에 연결, 파일 읽기/쓰기/업로드/다운로드, 일부 도구 사용...). 따라서 이러한 작업을 수행하는 방법을 모른다면 페이지를 읽기 시작하세요:
iOS Basic Testing Operations다음 단계에서는 앱이 장치에 설치되어 있어야 하며, 애플리케이션의 IPA 파일을 이미 확보해야 합니다. 이 작업을 수행하는 방법을 배우려면 기본 iOS 테스트 작업 페이지를 읽으세요.
기본 정적 분석
IPA 파일에 대해 자동 정적 분석을 수행하기 위해 MobSF 도구를 사용하는 것이 좋습니다.
이진 파일에 존재하는 보호 식별:
PIE (위치 독립 실행 파일): 활성화되면 애플리케이션이 실행될 때마다 무작위 메모리 주소에 로드되어 초기 메모리 주소를 예측하기 어렵게 만듭니다.
스택 카나리: 스택의 무결성을 검증하기 위해 함수 호출 전에 스택에 '카나리' 값을 배치하고 함수가 끝난 후 다시 검증합니다.
ARC (자동 참조 카운팅): 일반적인 메모리 손상 결함을 방지합니다.
암호화된 이진 파일: 이진 파일은 암호화되어야 합니다.
민감한/취약한 함수 식별
약한 해싱 알고리즘
취약한 랜덤 함수
취약한 ‘Malloc’ 함수
취약하고 취약한 함수들
기본 동적 분석
MobSF가 수행하는 동적 분석을 확인하세요. 다양한 뷰를 탐색하고 상호작용해야 하지만, 다른 작업을 수행하는 동안 여러 클래스를 후킹하고 작업이 완료되면 보고서를 준비합니다.
설치된 앱 나열하기
frida-ps -Uai
명령을 사용하여 설치된 앱의 번들 식별자를 확인하세요:
기본 열거 및 후킹
애플리케이션의 구성 요소를 열거하는 방법과 objection을 사용하여 메서드와 클래스를 쉽게 후킹하는 방법을 배웁니다:
iOS Hooking With ObjectionIPA 구조
IPA 파일의 구조는 본질적으로 압축된 패키지의 형태입니다. 확장자를 .zip
으로 변경하면 압축 해제하여 내용을 확인할 수 있습니다. 이 구조 내에서 Bundle은 설치 준비가 완료된 완전 패키지 애플리케이션을 나타냅니다. 내부에는 애플리케이션의 리소스를 캡슐화하는 <NAME>.app
이라는 디렉토리가 있습니다.
Info.plist
: 이 파일은 애플리케이션의 특정 구성 세부정보를 포함합니다._CodeSignature/
: 이 디렉토리에는 서명을 포함하는 plist 파일이 있어 번들 내 모든 파일의 무결성을 보장합니다.Assets.car
: 아이콘과 같은 자산 파일을 저장하는 압축 아카이브입니다.Frameworks/
: 이 폴더에는.dylib
또는.framework
파일 형식의 애플리케이션의 네이티브 라이브러리가 포함되어 있습니다.PlugIns/
: 이 폴더에는 애플리케이션의 확장인.appex
파일이 포함될 수 있지만 항상 존재하는 것은 아닙니다. *Core Data
: 애플리케이션의 영구 데이터를 오프라인에서 저장하고, 임시 데이터를 캐시하며, 단일 장치에서 앱의 실행 취소 기능을 추가하는 데 사용됩니다. 단일 iCloud 계정의 여러 장치 간에 데이터를 동기화하기 위해 Core Data는 자동으로 스키마를 CloudKit 컨테이너에 미러링합니다.PkgInfo
:PkgInfo
파일은 애플리케이션 또는 번들의 유형 및 작성자 코드를 지정하는 대체 방법입니다.en.lproj, fr.proj, Base.lproj: 특정 언어에 대한 리소스를 포함하는 언어 팩이며, 지원되지 않는 언어의 경우 기본 리소스를 포함합니다.
보안:
_CodeSignature/
디렉토리는 디지털 서명을 통해 번들된 모든 파일의 무결성을 검증하여 앱의 보안에서 중요한 역할을 합니다.자산 관리:
Assets.car
파일은 압축을 사용하여 그래픽 자산을 효율적으로 관리하며, 이는 애플리케이션 성능 최적화 및 전체 크기 감소에 중요합니다.프레임워크 및 플러그인: 이러한 디렉토리는 iOS 애플리케이션의 모듈성을 강조하며, 개발자가 재사용 가능한 코드 라이브러리(
Frameworks/
)를 포함하고 앱 기능을 확장(PlugIns/
)할 수 있도록 합니다.현지화: 이 구조는 여러 언어를 지원하여 특정 언어 팩에 대한 리소스를 포함함으로써 글로벌 애플리케이션 도달을 촉진합니다.
Info.plist
Info.plist는 iOS 애플리케이션의 초석으로, 키-값 쌍 형태로 주요 구성 데이터를 캡슐화합니다. 이 파일은 애플리케이션뿐만 아니라 번들 내의 앱 확장 및 프레임워크에도 필수적입니다. XML 또는 이진 형식으로 구조화되어 있으며, 앱 권한에서 보안 구성에 이르기까지 중요한 정보를 포함합니다. 사용 가능한 키에 대한 자세한 탐색은 Apple Developer Documentation를 참조할 수 있습니다.
이 파일을 보다 접근 가능한 형식으로 작업하려는 경우, macOS에서 plutil
을 사용하여 XML 변환을 쉽게 수행할 수 있습니다(버전 10.2 이상에서 기본적으로 제공됨) 또는 Linux에서 plistutil
을 사용할 수 있습니다. 변환 명령은 다음과 같습니다:
macOS의 경우:
리눅스를 위한:
Info.plist 파일이 공개할 수 있는 수많은 정보 중에서 주목할 만한 항목으로는 앱 권한 문자열(UsageDescription
), 사용자 정의 URL 스킴(CFBundleURLTypes
), 그리고 앱 전송 보안 설정(NSAppTransportSecurity
)이 있습니다. 이러한 항목들은 내보내기/가져오기 사용자 정의 문서 유형(UTExportedTypeDeclarations
/ UTImportedTypeDeclarations
)과 같은 다른 항목들과 함께 파일을 검사하거나 간단한 grep
명령을 사용하여 쉽게 찾을 수 있습니다:
데이터 경로
iOS 환경에서는 디렉토리가 시스템 애플리케이션과 사용자 설치 애플리케이션을 위해 특별히 지정됩니다. 시스템 애플리케이션은 /Applications
디렉토리에 위치하고, 사용자 설치 앱은 /var/mobile/containers/Data/Application/
아래에 배치됩니다. 이러한 애플리케이션은 128비트 UUID라는 고유 식별자가 할당되어, 디렉토리 이름의 무작위성으로 인해 수동으로 앱의 폴더를 찾는 것이 어려워집니다.
iOS의 애플리케이션은 샌드박스화되어야 하므로, 각 앱은 $HOME/Library/Containers
내에 앱의 **CFBundleIdentifier
**를 폴더 이름으로 가진 폴더도 갖습니다.
그러나 두 폴더(데이터 및 컨테이너 폴더) 모두 .com.apple.mobile_container_manager.metadata.plist
파일을 가지고 있으며, 이 파일은 키 MCMetadataIdentifier
에서 두 파일을 연결합니다.
사용자 설치 앱의 설치 디렉토리를 발견하기 위해, objection tool은 유용한 명령어인 env
를 제공합니다. 이 명령어는 해당 앱에 대한 자세한 디렉토리 정보를 보여줍니다. 아래는 이 명령어를 사용하는 방법의 예입니다:
대안으로, 앱 이름은 find
명령어를 사용하여 /private/var/containers
내에서 검색할 수 있습니다:
ps
및 lsof
와 같은 명령어는 각각 앱의 프로세스를 식별하고 열린 파일을 나열하는 데 사용될 수 있으며, 애플리케이션의 활성 디렉토리 경로에 대한 통찰력을 제공합니다:
Bundle directory:
AppName.app
이것은 IPA에서 이전에 본 애플리케이션 번들이며, 필수 애플리케이션 데이터, 정적 콘텐츠 및 애플리케이션의 컴파일된 바이너리를 포함합니다.
이 디렉토리는 사용자에게 보이지만 사용자는 여기에 쓸 수 없습니다.
이 디렉토리의 콘텐츠는 백업되지 않습니다.
이 폴더의 내용은 코드 서명을 검증하는 데 사용됩니다.
Data directory:
Documents/
모든 사용자 생성 데이터를 포함합니다. 애플리케이션 최종 사용자가 이 데이터의 생성을 시작합니다.
사용자에게 보이며 사용자는 여기에 쓸 수 있습니다.
이 디렉토리의 콘텐츠는 백업됩니다.
앱은
NSURLIsExcludedFromBackupKey
를 설정하여 경로를 비활성화할 수 있습니다.Library/
사용자 특정이 아닌 모든 파일을 포함하며, 캐시, 환경 설정, 쿠키 및 속성 목록(plist) 구성 파일이 포함됩니다.
iOS 앱은 일반적으로
Application Support
및Caches
하위 디렉토리를 사용하지만, 앱은 사용자 정의 하위 디렉토리를 생성할 수 있습니다.Library/Caches/
반영구적인 캐시 파일을 포함합니다.
사용자에게 보이지 않으며 사용자는 여기에 쓸 수 없습니다.
이 디렉토리의 콘텐츠는 백업되지 않습니다.
OS는 앱이 실행되지 않고 저장 공간이 부족할 때 이 디렉토리의 파일을 자동으로 삭제할 수 있습니다.
Library/Application Support/
앱 실행에 필요한 영구적인 파일을 포함합니다.
사용자에게 보이지 않으며 사용자는 여기에 쓸 수 없습니다.
이 디렉토리의 콘텐츠는 백업됩니다.
앱은
NSURLIsExcludedFromBackupKey
를 설정하여 경로를 비활성화할 수 있습니다.Library/Preferences/
애플리케이션이 재시작된 후에도 유지될 수 있는 속성을 저장하는 데 사용됩니다.
정보는 암호화되지 않은 상태로 애플리케이션 샌드박스 내의 [BUNDLE_ID].plist라는 plist 파일에 저장됩니다.
NSUserDefaults
를 사용하여 저장된 모든 키/값 쌍은 이 파일에서 찾을 수 있습니다.tmp/
앱 실행 간에 유지될 필요가 없는 임시 파일을 작성하는 데 이 디렉토리를 사용합니다.
비영구적인 캐시 파일을 포함합니다.
사용자에게 보이지 않습니다.
이 디렉토리의 콘텐츠는 백업되지 않습니다.
OS는 앱이 실행되지 않고 저장 공간이 부족할 때 이 디렉토리의 파일을 자동으로 삭제할 수 있습니다.
iGoat-Swift의 애플리케이션 번들(.app) 디렉토리를 번들 디렉토리( /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
)에서 자세히 살펴보겠습니다:
Binary Reversing
<application-name>.app
폴더 안에는 <application-name>
이라는 이진 파일이 있습니다. 이것이 실행될 파일입니다. otool
도구를 사용하여 이진 파일에 대한 기본 검사를 수행할 수 있습니다:
앱이 암호화되어 있는지 확인하세요
다음에 대한 출력이 있는지 확인하세요:
이진 파일 분해하기
텍스트 섹션 분해하기:
샘플 애플리케이션의 Objective-C 세그먼트를 인쇄하려면 다음을 사용할 수 있습니다:
보다 간결한 Objective-C 코드를 얻기 위해 class-dump를 사용할 수 있습니다:
그러나 이진 파일을 분해하는 가장 좋은 옵션은: Hopper와 IDA입니다.
Trickest를 사용하여 세계에서 가장 진보된 커뮤니티 도구로 구동되는 워크플로우를 쉽게 구축하고 자동화하세요. 오늘 바로 접근하세요:
데이터 저장
iOS가 장치에 데이터를 저장하는 방법에 대해 알아보려면 이 페이지를 읽으세요:
iOS Basics정보를 저장할 다음 장소는 애플리케이션 설치 직후, 애플리케이션의 모든 기능을 확인한 후 및 한 사용자에서 로그아웃한 후 다른 사용자로 로그인한 후에 확인해야 합니다. 목표는 현재 사용자와 이전에 로그인한 사용자의 보호되지 않은 민감한 정보(비밀번호, 토큰)를 찾는 것입니다.
Plist
plist 파일은 키-값 쌍을 포함하는 구조화된 XML 파일입니다. 이는 지속적인 데이터를 저장하는 방법이므로 때때로 이 파일에서 민감한 정보를 찾을 수 있습니다. 앱을 설치한 후 및 집중적으로 사용한 후에 이러한 파일을 확인하는 것이 좋습니다.
plist 파일에 데이터를 지속적으로 저장하는 가장 일반적인 방법은 NSUserDefaults를 사용하는 것입니다. 이 plist 파일은 **Library/Preferences/<appBundleID>.plist
**의 앱 샌드박스 내에 저장됩니다.
NSUserDefaults
클래스는 기본 시스템과 상호작용하기 위한 프로그래밍 인터페이스를 제공합니다. 기본 시스템은 애플리케이션이 사용자 기본 설정에 따라 동작을 사용자화할 수 있도록 합니다. NSUserDefaults
에 의해 저장된 데이터는 애플리케이션 번들에서 볼 수 있습니다. 이 클래스는 plist 파일에 데이터를 저장하지만, 소량의 데이터와 함께 사용되도록 설계되었습니다.
이 데이터는 신뢰할 수 있는 컴퓨터를 통해 더 이상 직접 접근할 수 없지만, 백업을 수행하여 접근할 수 있습니다.
**NSUserDefaults
**를 사용하여 저장된 정보를 덤프하려면 objection의 ios nsuserdefaults get
을 사용하세요.
애플리케이션에서 사용된 모든 plist를 찾으려면 /private/var/mobile/Containers/Data/Application/{APPID}
에 접근하고 다음을 실행하세요:
XML 또는 이진 (bplist) 형식의 파일을 XML로 변환하기 위해, 운영 체제에 따라 다양한 방법이 있습니다:
macOS 사용자용: plutil
명령어를 사용하세요. 이는 macOS (10.2+)에 내장된 도구로, 이 목적을 위해 설계되었습니다:
리눅스 사용자용: 먼저 libplist-utils
를 설치한 후, plistutil
을 사용하여 파일을 변환하세요:
Objection 세션 내에서: 모바일 애플리케이션을 분석하기 위해, 특정 명령어를 사용하여 plist 파일을 직접 변환할 수 있습니다:
Core Data
Core Data
는 애플리케이션의 객체 모델 계층을 관리하기 위한 프레임워크입니다. Core Data는 SQLite를 지속적인 저장소로 사용할 수 있습니다, 하지만 프레임워크 자체는 데이터베이스가 아닙니다.
CoreData는 기본적으로 데이터를 암호화하지 않습니다. 그러나 CoreData에 추가적인 암호화 계층을 추가할 수 있습니다. 자세한 내용은 GitHub Repo를 참조하세요.
애플리케이션의 SQLite Core Data 정보는 경로 /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support
에서 찾을 수 있습니다.
SQLite를 열고 민감한 정보에 접근할 수 있다면, 잘못된 구성 설정을 발견한 것입니다.
YapDatabase
YapDatabase는 SQLite 위에 구축된 키/값 저장소입니다. Yap 데이터베이스는 sqlite 데이터베이스이므로 이전 섹션에서 제안된 명령을 사용하여 찾을 수 있습니다.
Other SQLite Databases
응용 프로그램이 자체 sqlite 데이터베이스를 생성하는 것은 일반적입니다. 그들은 민감한 데이터를 저장하고 이를 암호화하지 않을 수 있습니다. 따라서 응용 프로그램 디렉토리 내의 모든 데이터베이스를 확인하는 것이 항상 흥미롭습니다. 따라서 데이터가 저장된 응용 프로그램 디렉토리로 이동하십시오 (/private/var/mobile/Containers/Data/Application/{APPID}
)
Firebase Real-Time Databases
개발자는 Firebase Real-Time Databases를 통해 NoSQL 클라우드 호스팅 데이터베이스 내에서 데이터를 저장하고 동기화할 수 있습니다. JSON 형식으로 저장된 데이터는 모든 연결된 클라이언트에 실시간으로 동기화됩니다.
잘못 구성된 Firebase 데이터베이스를 확인하는 방법은 여기에서 찾을 수 있습니다:
Firebase DatabaseRealm databases
Realm Objective-C 및 Realm Swift는 Apple에서 제공하지 않는 데이터 저장을 위한 강력한 대안을 제공합니다. 기본적으로 데이터를 암호화되지 않은 상태로 저장하며, 특정 구성으로 암호화가 가능합니다.
데이터베이스는 다음 위치에 있습니다: /private/var/mobile/Containers/Data/Application/{APPID}
. 이러한 파일을 탐색하려면 다음과 같은 명령을 사용할 수 있습니다:
이 데이터베이스 파일을 보려면 Realm Studio 도구를 권장합니다.
Realm 데이터베이스 내에서 암호화를 구현하려면 다음 코드 스니펫을 사용할 수 있습니다:
Couchbase Lite Databases
Couchbase Lite는 경량 및 임베디드 데이터베이스 엔진으로 설명되며, 문서 지향 (NoSQL) 접근 방식을 따릅니다. iOS 및 macOS에 네이티브로 설계되어 데이터 동기화를 원활하게 수행할 수 있는 기능을 제공합니다.
장치에서 잠재적인 Couchbase 데이터베이스를 식별하려면 다음 디렉토리를 검사해야 합니다:
Cookies
iOS는 각 앱 폴더의 **Library/Cookies/cookies.binarycookies
**에 앱의 쿠키를 저장합니다. 그러나 개발자는 때때로 백업에서 접근할 수 있는 쿠키 파일 대신 키체인에 저장하기로 결정합니다.
쿠키 파일을 검사하려면 이 파이썬 스크립트를 사용하거나 objection의 **ios cookies get
**을 사용할 수 있습니다.
또한 objection을 사용하여 이러한 파일을 JSON 형식으로 변환하고 데이터를 검사할 수 있습니다.
Cache
기본적으로 NSURLSession은 HTTP 요청 및 응답을 Cache.db 데이터베이스에 저장합니다. 이 데이터베이스는 토큰, 사용자 이름 또는 기타 민감한 정보가 캐시된 경우 민감한 데이터를 포함할 수 있습니다. 캐시된 정보를 찾으려면 앱의 데이터 디렉토리(/var/mobile/Containers/Data/Application/<UUID>
)를 열고 /Library/Caches/<Bundle Identifier>
로 이동합니다. WebKit 캐시도 Cache.db 파일에 저장됩니다. Objection은 sqlite connect Cache.db
명령어로 데이터베이스를 열고 상호작용할 수 있습니다. 이는 normal SQLite 데이터베이스입니다.
이 데이터를 캐싱하지 않는 것이 권장됩니다, 요청 또는 응답에 민감한 정보가 포함될 수 있기 때문입니다. 아래의 목록은 이를 달성하는 다양한 방법을 보여줍니다:
로그아웃 후 캐시된 응답을 제거하는 것이 권장됩니다. 이는 Apple에서 제공하는
removeAllCachedResponses
메서드를 사용하여 수행할 수 있습니다. 이 메서드는 다음과 같이 호출할 수 있습니다:
URLCache.shared.removeAllCachedResponses()
이 메서드는 Cache.db 파일에서 모든 캐시된 요청 및 응답을 제거합니다. 2. 쿠키의 이점을 사용할 필요가 없다면, URLSession의 .ephemeral 구성 속성을 사용하는 것이 좋습니다. 이는 쿠키 및 캐시 저장을 비활성화합니다.
일시적인 세션 구성 객체는 기본 세션 구성(기본 참조)과 유사하지만, 해당 세션 객체는 캐시, 자격 증명 저장소 또는 세션 관련 데이터를 디스크에 저장하지 않습니다. 대신, 세션 관련 데이터는 RAM에 저장됩니다. 일시적인 세션이 디스크에 데이터를 쓰는 유일한 경우는 URL의 내용을 파일에 쓰라고 지시할 때입니다.
3. 캐시 정책을 .notAllowed로 설정하여 캐시를 비활성화할 수도 있습니다. 이는 메모리나 디스크에 캐시를 저장하는 것을 비활성화합니다.
Snapshots
홈 버튼을 누를 때마다 iOS는 현재 화면의 스냅샷을 찍습니다. 이는 애플리케이션으로의 전환을 훨씬 부드럽게 할 수 있게 해줍니다. 그러나 민감한 데이터가 현재 화면에 존재하는 경우, 이는 이미지에 저장됩니다 (이 이미지는 재부팅 후에도 존재합니다). 이러한 스냅샷은 홈 화면을 두 번 탭하여 앱 간 전환할 때에도 접근할 수 있습니다.
아이폰이 탈옥되지 않는 한, 공격자는 이러한 스크린샷을 보기 위해 장치에 차단되지 않은 접근이 필요합니다. 기본적으로 마지막 스냅샷은 애플리케이션의 샌드박스에 Library/Caches/Snapshots/
또는 Library/SplashBoard/Snapshots
폴더에 저장됩니다 (신뢰할 수 있는 컴퓨터는 iOX 7.0부터 파일 시스템에 접근할 수 없습니다).
이러한 나쁜 행동을 방지하는 한 가지 방법은 ApplicationDidEnterBackground()
함수를 사용하여 스냅샷을 찍기 전에 빈 화면을 표시하거나 민감한 데이터를 제거하는 것입니다.
다음은 기본 스크린샷을 설정하는 샘플 수정 방법입니다.
Swift:
Objective-C:
이것은 애플리케이션이 백그라운드로 전환될 때마다 배경 이미지를 overlayImage.png
로 설정합니다. 이는 overlayImage.png
가 항상 현재 뷰를 덮어쓰므로 민감한 데이터 유출을 방지합니다.
Keychain
iOS 키체인에 접근하고 관리하기 위해 Keychain-Dumper와 같은 도구가 사용 가능하며, 이는 탈옥된 장치에 적합합니다. 또한, Objection은 유사한 목적을 위해 ios keychain dump
명령을 제공합니다.
자격 증명 저장
NSURLCredential 클래스는 NSUserDefaults나 다른 래퍼를 우회하여 민감한 정보를 키체인에 직접 저장하는 데 이상적입니다. 로그인 후 자격 증명을 저장하기 위해 다음 Swift 코드를 사용합니다:
To extract these stored credentials, Objection의 명령 ios nsurlcredentialstorage dump
가 사용됩니다.
커스텀 키보드 및 키보드 캐시
iOS 8.0 이상부터 사용자는 설정 > 일반 > 키보드 > 키보드에서 관리할 수 있는 커스텀 키보드 확장을 설치할 수 있습니다. 이러한 키보드는 확장된 기능을 제공하지만, 키스트로크 로깅 및 외부 서버로 데이터 전송의 위험이 있으며, 네트워크 접근이 필요한 키보드에 대해 사용자에게 알림이 제공됩니다. 앱은 민감한 정보 입력을 위해 커스텀 키보드 사용을 제한할 수 있으며, 제한해야 합니다.
보안 권장 사항:
보안을 강화하기 위해 서드파티 키보드를 비활성화하는 것이 좋습니다.
기본 iOS 키보드의 자동 수정 및 자동 제안 기능이 민감한 정보를
Library/Keyboard/{locale}-dynamic-text.dat
또는/private/var/mobile/Library/Keyboard/dynamic-text.dat
에 캐시 파일로 저장할 수 있으므로 주의해야 합니다. 이러한 캐시 파일은 민감한 데이터를 위해 정기적으로 확인해야 합니다. 캐시된 데이터를 지우기 위해 설정 > 일반 > 초기화 > 키보드 사전 초기화를 통해 키보드 사전을 재설정하는 것이 권장됩니다.네트워크 트래픽을 가로채면 커스텀 키보드가 원격으로 키스트로크를 전송하는지 여부를 확인할 수 있습니다.
텍스트 필드 캐싱 방지
UITextInputTraits 프로토콜은 민감한 정보 캐싱을 방지하는 데 필수적인 자동 수정 및 보안 텍스트 입력을 관리하는 속성을 제공합니다. 예를 들어, 자동 수정을 비활성화하고 보안 텍스트 입력을 활성화하는 것은 다음과 같이 수행할 수 있습니다: