
이 도구는 Windows 11의 Recall 기능에서 데이터를 추출하여 표시하며, PC 활동 스냅샷 정보에 쉽게 접근할 수 있는 방법을 제공합니다.
Breaking Windows Recall. Again.
image
Microsoft가 VBS 엔클레이브, AES-256-GCM 암호화, Windows Hello 인증, Protected Process Light 호스트를 사용하여 Recall을 재설계했을 때, 메시지는 분명했습니다: 데이터는 금고에 잠겨 있다는 것입니다.
금고는 견고합니다. 그러나 배달 트럭은 그렇지 않습니다.
Recall 타임라인을 렌더링하는 프로세스인 AIXHost.exe에는 PPL, AppContainer, 코드 무결성 강화 기능이 없습니다. 로그인한 사용자로 실행되는 모든 프로세스는 이 프로세스에 코드를 주입하고 합법적인 UI가 사용하는 동일한 COM API를 호출할 수 있습니다. 사용자가 Windows Hello로 인증하면, 복호화된 스크린샷, OCR 텍스트 및 메타데이터가 라이브 COM 객체로 AIXHost.exe를 통해 흐릅니다. TotalRecall Reloaded는 해당 프로세스 내부에 위치하여 모든 것을 추출합니다.
관리자 권한 불필요. 표준 사용자. 커널 익스플로잇 없음. 암호화 우회 없음. 단지 COM 호출만으로 가능합니다.
TotalRecall Reloaded는 두 개의 파일로 구성됩니다: 인젝터(totalrecall.exe)와 페이로드 DLL(totalrecall_payload.dll).
인젝터는 CreateToolhelp32Snapshot을 통해 AIXHost.exe를 찾고, VirtualAllocEx로 대상 프로세스에 메모리를 할당하고, WriteProcessMemory로 DLL 경로를 작성한 다음, LoadLibraryW를 가리키는 원격 스레드를 생성합니다. 고전적인 DLL 인젝션입니다. 특별할 것 없는 방식인데, 특별한 것이 필요하지 않기 때문입니다. AIXHost.exe는 이에 대한 어떤 보호 조치도 갖추고 있지 않습니다.
이는 표준 사용자 권한으로 작동합니다. 상승된 권한이나 SeDebugPrivilege가 필요하지 않습니다. 기본 Windows DACL은 동일한 사용자 프로세스가 서로에 대해 완전한 접근 권한을 갖도록 허용합니다. 확인 결과: 토큰은 Medium 필수 수준에서 실행되며 BUILTIN\Administrators는 거부 전용으로 설정됩니다.
VBS 엔클레이브는 Windows Hello 없이는 어떤 것도 복호화하지 않습니다. 이 도구는 이를 우회하지 않습니다. 사용자가 인증하도록 하거나, 사용자가 인증할 때 조용히 따라가거나, 사용자가 인증할 때까지 기다립니다.
--launch는 keybd_event를 통해 Win+J를 시뮬레이션합니다. Recall 타임라인을 여는 키보드 단축키입니다. 사용자는 Hello 프롬프트(얼굴, 지문 또는 PIN)를 보고 인증하며, 엔클레이브는 복호화된 데이터를 제공하기 시작합니다. 사용자 관점에서는 Recall이 정상적으로 열린 것처럼 보입니다. 우리 관점에서는 페이로드가 이미 내부에 있으며 대기 중입니다.
--stealth는 완전 무음 모드입니다. 다음과 같이 작동합니다:
AIXHost.exe(항상 실행 중)에 인젝션하고 DiscardDataAccess를 No-op으로 패치합니다.AIXHost.exe가 종료되고 다시 생성됩니다. 도구가 재시작을 감지하고 새 프로세스에 다시 인젝션합니다.aihost.exe에 인증 권한이 지속됩니다(취소가 차단됨). 추출이 즉시 시작됩니다.--wait는 --launch의 수동적 대응 모드입니다. Win+J를 시뮬레이션하는 대신, 도구는 사용자가 작업 표시줄, 바로 가기 또는 다른 경로를 통해 직접 Recall을 열 때까지 대기합니다. AIXHost.exe가 나타나고 사용자가 자연스럽게 Hello를 완료하면 페이로드가 인젝션되고 추출이 시작됩니다. 관찰 중인 시스템에서 유용하거나, 합성 키보드 입력 없이 Recall 세션이 전적으로 사용자에 의해 시작된 것처럼 보여야 하는 경우에 적합합니다.
일단 AIXHost.exe 내부에 들어가면, 페이로드는 CoInitializeEx(COINIT_APARTMENTTHREADED)로 COM 아파트먼트를 초기화하고 CoSetProxyBlanket(EOAC_DYNAMIC_CLOAKING)으로 프록시 ID 전달을 설정합니다. 이는 매우 중요합니다. 동적 클로킹이 없으면 COM 프록시가 인증된 ID를 서버로 전달하지 않습니다.
추출은 합법적인 Recall UI가 사용하는 동일한 경로를 따릅니다:
엔클레이브 초기화: DataManager.Load()가 엔클레이브 키 로딩을 트리거합니다. DataStoreManager.DecryptDatabase()(슬롯 37)가 복호화된 뷰를 준비합니다. 페이로드는 DataManager.DataStatus를 폴링하여 3(잠금 해제됨)이 반환될 때까지 기다립니다.
엔티티 열거: MemoryEntityStatics.GetLightMemoryItemsBefore() (슬롯 9)가 경량 엔티티 참조의 벡터를 반환합니다. 각 참조는 오프셋 +8에 컨텍스트 ID를 가지고 있습니다. 일반적인 시스템에서는 수백 개의 엔티티가 반환되며, 며칠 또는 몇 주 간의 활동을 포괄합니다.
엔티티별 추출: 각 컨텍스트 ID에 대해 페이로드는 ContextEngine2.TryGetEntityForId()(슬롯 6)를 통해 전체 엔티티를 로드하고, IEntityWrapper(슬롯 6)를 통해 언랩한 다음, QueryInterface로 IMemoryEntity를 얻습니다. 그런 다음:
TryGetBitmapCaptureAsync()(슬롯 19)가 SoftwareBitmap을 반환합니다. 로 하고, 를 호출하여 WIC 비트맵을 얻은 다음, 를 통해 PNG로 인코딩합니다.모든 호출은 __try/__except로 래핑됩니다. 그 이유는 COM 프록시 호출에서 단일 액세스 위반이 발생하면 aihost.exe에 대한 RPC 채널이 영구적으로 끊어지기 때문입니다. 복구 방법이 없습니다. AIXHost.exe를 다시 시작해야 합니다. SEH 래퍼는 잘못된 매개변수 유형으로 인한 충돌을 포착하고 세션을 유지합니다.
여러 작업은 Hello 인증 없이도 작동합니다:
스크린샷 추출: RecallPrivacyIndicatorSettings(CLSID {42C63551-...})는 슬롯 13에서 GetRecentCaptureThumbnail(width, height)를 노출합니다. 메서드 이름은 "썸네일"이라고 되어 있지만 서버는 해상도 상한을 적용하지 않습니다. 3840x3840을 전달하면 최근 Recall 캡처가 전체 해상도로 반환됩니다. IRandomAccessStream 결과는 CreateStreamOverRandomAccessStream(shcore.dll)을 통해 IStream으로 변환되어 BMP로 덤프됩니다.
데이터 파괴: IDataStoreManager::DeleteEvents()(슬롯 12)는 전체 캡처 기록을 지웁니다. 매개변수 없음, 인증 불필요. Ghidra 분석 결과: FUN_1802ddd10의 삭제 핸들러에는 권한 부여 게이트 함수에 대한 호출이 전혀 포함되어 있지 않습니다. 인증 검사는 원래부터 연결되지 않았습니다.
메타데이터 공개: 저장 경로(사용자 특정 UKP GUID 포함), 데이터베이스 크기, 보존 정책, 캡처 상태, 최근 캡처 컨텍스트 ID는 모두 인증 없이 IDataStoreManagerStatics 및 RecallPrivacyIndicatorSettings를 통해 읽을 수 있습니다.
image``` totalrecall.exe --launch Open Recall, trigger Hello, extract everything totalrecall.exe --stealth Silent extraction (patches auth revocation, waits) totalrecall.exe --wait Wait for user to manually open Recall totalrecall.exe --preauth Grab latest screenshot + settings (no Hello) totalrecall.exe --search "password" Search OCR text in latest extraction totalrecall.exe --destroy Wipe all Recall data (confirmation required, no Hello)
| Mode | Auth Required | What It Does |
|------|:---:|-------------|
| `--launch` | Hello | Win+J 시뮬레이션, 사용자 인증, 전체 추출 |
| `--stealth` | Passive | 인증 취소 패치, 사용자가 Recall 인증할 때까지 대기, 자동 추출 |
| `--wait` | Hello | 사용자가 Recall을 자연스럽게 열 때까지 대기 후 추출 |
| `--preauth` | **아니요** | 최신 스크린샷 + 모든 설정 |
| `--search` | 아니요 | 대소문자 구분 없는 OCR 텍스트 검색 (최신 추출 대상) |
| `--destroy` | **아니요** | `DeleteEvents()`, 되돌릴 수 없음, DESTROY 입력 확인 필요 |
### 예제 출력
**`--stealth` (첫 실행, 사용자 대기 중):**```
[+] Target: AIXHost.exe PID 8648 (stealth mode)
[*] Patching auth revocation...
[+] Waiting for Recall session...
[+] Recall session detected
[*] Waiting for user to close Recall...
[*] Recall closed, waiting for AIXHost to respawn...
[+] Extracting from AIXHost PID 26208
[+] Payload active
[*] Extracting
[##############################] 384/384 entities
EXTRACTION COMPLETE 6 min 51 sec
Screenshots 192 328.8 MB
OCR Text 184 535.2 KB
Metadata (CSV) 384 97.4 KB
--stealth (후속 실행, 캐시된 세션):```
[+] Target: AIXHost.exe PID 27532 (stealth mode)
[] Patching auth revocation...
[+] Waiting for Recall session...
[+] Cached session found, extracting...
[] Extracting
[##############################] 398/398 entities
**`--launch`:**```
[+] Target: AIXHost.exe PID 14636 Memory 60 MB
[*] Triggering Recall via Win+J...
[*] Waiting for Hello authentication authenticating
[+] Recall ready PID 14636 Memory 242 MB
[*] Extracting
[##############################] 212/212 entities
EXTRACTION COMPLETE 3 min 59 sec
Screenshots 104 184.0 MB
--preauth (Hello 필요 없음):```
[+] Target: AIXHost.exe PID 27532 (pre-auth mode)
[*] Injecting payload (pre-auth only)...
[+] Payload active
PRE-AUTH EXTRACTION COMPLETE 0 min 1 sec
Screenshot 4K (3840x2464) 36.1 MB
Settings Storage Path C:\Users<user>\AppData\Local\CoreAIPlatform.00\UKP{...} Storage Size 178.3 MB Capture Count 0 Retention Days 90
**`--search`:**```
Searching for: "password"
In: extraction_20260406_152736
[1] === [12] ctxId=90443 Settings | Chrome ===
Saved passwords and passkeys
[2] === [47] ctxId=91201 inbox | Thunderbird ===
Your temporary password has been reset
extraction_20260404_143052/ screenshots/ Full-resolution decrypted PNGs screenshots/*.txt Per-image OCR text thumbnails/ Thumbnail PNGs (fallback when full screenshot unavailable) ocr_text.txt Combined OCR text for all captures recall_data.csv Structured metadata settings.txt Storage path, size, retention, capture state latest_capture_4k.bmp Pre-auth screenshot of most recent capture extraction.log Detailed extraction log with timing
## Building
**요구 사항:** ARM64 C++ 도구가 포함된 Visual Studio, Recall이 활성화된 Windows 11 ARM64.```
make.bat
totalrecall.exe와 totalrecall_payload.dll을 생성합니다. 실행 시 두 파일은 동일한 디렉터리에 있어야 합니다.
VTL1 (Secure World) +--------------------------------------------------+ | VBS Enclave: AES-256-GCM, sealed keys | | snapshot_support.dll / storage_support.dll | | Keys never leave here. Crypto is sound. | +--------------------------------------------------+ ^ CallEnclave | VTL0 (Normal World) +--------------------------------------------------+ | aihost.exe (PPL, Signer=5) | | +-- Microsoft.Windows.AI.Platform.dll (6.9 MB) | | 44 methods on IDataStoreManager alone | | Enclave bridge. Protected. Can't touch it. | | | | AIXHost.exe (NO PROTECTION) | | +-- Baker.dll: OCR, NER, AI classification | | +-- Receives decrypted data for rendering | | +-- CreateRemoteThread = game over | +--------------------------------------------------+
키 계층: Hello -> NGC ECDH P-384 (TPM 기반) -> VTL1 상호 인증 -> 엔클레이브 봉인된 키 자료 -> 페이지별 AES-256-GCM (임의 nonce 및 페이지 번호 AAD 사용). 총 6계층의 키 유도가 사용됩니다. 암호화는 확실히 견고합니다.
문제는 복호화 이후에 발생합니다. 평문은 보호되지 않고, 인젝션이 가능하며, 동일 사용자 프로세스인 `AIXHost.exe`로 전달됩니다. 엔클레이브는 `Baker.dll`과 주입된 코드를 구분하지 못합니다. 할 수 없습니다.
---
## 주요 발견사항
### 신뢰 경계가 너무 일찍 끝남
마이크로소프트의 [아키텍처 블로그](https://blogs.windows.com/windowsexperience/2024/09/27/update-on-recall-security-and-privacy-architecture/)에 따르면 "VBS 엔클레이브 외부의 프로세스는 스냅샷이나 암호화 키에 직접 액세스할 수 없으며", 설계상 "데이터를 훔치기 위해 사용자 인증을 따라오려는 잠재적 멀웨어의 시도를 제한합니다"라고 명시되어 있습니다.
실제로는 `AIXHost.exe`가 복호화된 모든 스크린샷과 OCR 결과를 라이브 COM 객체로 수신합니다. 프로세스 내부에는 호출자별 검증이 없습니다. "너 Baker.dll이니?"라는 확인도 없습니다. 프로세스 안에 있으면 신뢰받습니다. 보안 경계는 VBS 엔클레이브와 PPL이지, 렌더링 프로세스가 아닙니다. 복호화된 데이터는 동일 사용자 애플리케이션에서 `CreateRemoteThread` 하나만 있으면 접근 가능합니다.
### IResponse4 접근 제어 우회
직접적인 인가 결함입니다.
`ContextDataSource.Search()`를 호출하여 `IResponse`를 반환받으면, 자연스러운 경로는 결과를 얻기 위해 `IResponse.get_Items()`(슬롯 9)를 호출하는 것입니다. 새로운 세션에서는 이 호출이 `0x80005473`, 즉 Recall 전용 사용자 정의 오류 코드를 반환합니다. 서버가 의도적으로 호출을 거부하는 것입니다. `IResponse2.ItemsAfterIndex()`도 동일한 오류를 반환합니다. 접근 제어가 작동하고 있습니다.
하지만 `IResponse` 객체는 네 가지 인터페이스 버전을 구현합니다. `IResponse4.get_UnfilledItems()`(다른 IID의 슬롯 9)는 접근 확인 없이 동일한 기본 데이터 컬렉션을 반환합니다.```
IResponse.get_Items() -> 0x80005473 (ACCESS DENIED)
IResponse2.ItemsAfterIndex() -> 0x80005473 (ACCESS DENIED)
IResponse4.get_UnfilledItems() -> S_OK (all entities returned)
동일한 데이터. 다른 인터페이스 버전. 인증 없음. 이 메서드는 검색 파이프라인에서 내부 지연 로딩을 위해 의도되었습니다. 보안 검토에서 get_Items 및 ItemsAfterIndex는 발견했지만 get_UnfilledItems는 놓쳤습니다. 이는 보안 엔지니어링을 어렵게 만드는 패턴입니다. 한 코드 경로에는 검사가 존재하지만(누군가 필요하다고 판단했다는 의미) 다른 경로에는 누락되어 있습니다.
해당 항목들에서 각 엔티티의 컨텍스트 ID는 ContextEngine2.TryGetEntityForId()로 이어지며, 이는 전체 엔티티를 스크린샷, OCR 및 메타데이터와 함께 로드합니다. 엔클레이브는 요청 시 모든 것을 복호화합니다.
사용자가 Recall 창을 닫으면 Baker.dll이 IDataProtectionManager3::DiscardDataAccess()를 호출하여 aihost.exe의 데이터 액세스 권한을 명시적으로 취소합니다. 이것이 일반적인 Recall 세션 후에 인증이 지속되지 않는 이유입니다. Baker.dll이 스스로 정리합니다.
우회 방법: AIXHost.exe 내부에 주입된 코드가 COM 프록시 vtable을 패치하여 DiscardDataAccess(슬롯 8)을 no-op 함수로 대체할 수 있습니다. VirtualProtect 호출 한 번, 포인터 쓰기 한 번. 사용자가 Recall을 닫으면 Baker.dll이 패치된 슬롯을 호출하고, 아무 일도 일어나지 않으며, aihost.exe에 권한이 그대로 유지됩니다. 이후의 AIXHost.exe 인스턴스는 자동으로 캐시된 권한을 상속받습니다.
실제로 --stealth는 패치를 AIXHost.exe(항상 실행 중)에 배포하고 기다립니다. 다음에 사용자가 Recall을 정상적으로 열고 닫으면 정리 작업이 억제되고 데이터 액세스 권한이 지속됩니다. 도구는 액세스를 감지하고, 자동 재주입(각 새 인스턴스 재패치)을 통해 AIXHost 프로세스 재시작을 처리하며, 모든 것을 자동으로 추출합니다. 패치는 프로세스별, 실행별로 적용됩니다. 현재 추출 세션을 보호합니다. 도구가 종료된 후의 후속 Recall 사용은 정상 동작으로 되돌아갑니다.
IDataStoreManager::DeleteEvents()는 Windows Hello 없이 전체 캡처 기록을 삭제합니다. Ghidra 확인 결과: 삭제 핸들러에는 인증 게이트 함수에 대한 호출이 전혀 없습니다. 인증 검사는 삭제 경로에 연결되지 않았습니다. 데이터를 읽을 수 없는 공격자라도 데이터를 파괴할 수 있습니다. 일반 사용자로부터 포렌식 방어 가능.
RecallPrivacyIndicatorSettings.GetRecentCaptureThumbnail은 요청한 해상도로 가장 최근 Recall 스크린샷을 반환합니다. 이 메서드는 작업 표시줄의 작은 개인 정보 표시기를 위해 의도되었습니다. 해상도를 제한하지 않았습니다. 동일한 사용자 프로세스는 Hello 없이도 마지막으로 화면에 표시된 것을 자동으로 가져올 수 있습니다.
GetWindowCaptureCount(슬롯 26)는 Hello 없이 E_ACCESSDENIED를 반환합니다. 그러나 GetSecureStorageInfo(슬롯 27)는 동일한 데이터를 포함하는 StorageInfo 구조체를 인증 없이 반환합니다. 구조체에는 NumberOfItems(캡처 수)와 Size(암호화된 총 저장소 크기, 바이트)가 포함됩니다. 공격자는 이를 모니터링하여 인증 없이 실시간으로 Recall 활동을 추적할 수 있습니다.
Hello가 완료되면 인증 상태는 전체 Windows 세션 동안 aihost.exe(PPL)에 캐시됩니다. AIXHost.exe를 종료하고 다시 시작해도 지워지지 않습니다. 공격자는 사용자가 자연스럽게 Recall을 열 때까지 기다렸다가 몇 시간 후에 자동으로 데이터를 추출할 수 있습니다. 추가 프롬프트 없이 무제한 재추출, 보이는 창 없음, 사용자 인지 없음.
Recall은 단순히 스크린샷만 찍는 것이 아닙니다. 컴퓨터에서 하는 모든 작업에 대한 포괄적인 행동 프로필을 구축합니다. 몇 초마다 스크린샷을 캡처하고, OCR 및 (아마도) AI 분류를 실행하며, 결과를 암호화된 SQLite 데이터베이스에 저장합니다.
아래 내용은 두 개의 독립적인 출처(비공개 WinRT 메타데이터 Microsoft.Windows.AI.Platform.winmd, cppwinrt.exe로 파싱, 그리고 VBS 엔클레이브 바이너리 storage_support.dll, 완전한 데이터베이스 스키마를 일반 텍스트 문자열로 포함)에서 확인되었습니다.
참고: 아래 필드 이름은 WinRT 메타데이터 및 엔클레이브 바이너리 문자열에서 확인되었습니다. 각 필드의 내용 설명은 API 이름과 유형에서 유추되었으며, 런타임에 모두 동적으로 검증되지는 않았습니다.
참고: 위와 동일한 주의 사항. 클래스 및 열거형 이름은 WinRT 메타데이터 및 엔클레이브 DLL 문자열에서 열거되었습니다. 각 항목의 설명은 이름과 컨텍스트에서 유추되었으며, 모든 항목에 대해 동적으로 검증되지는 않았습니다.
원시 캡처 외에도 Recall은 AI 분류를 실행하여 다음을 생성합니다:
PersonName, Organization, Product, Address, Location, DateTime, Event, Duration, WebUrl, EmailAddress. 각각 OCR 텍스트에서 추출되며 소스 위치가 포함됩니다.Topic, Person, Emoji, App, FileKind, , , , , , , , , , , , , , , , , , . 각각 신뢰도 점수와 선택적 경계 상자가 포함됩니다.몇 초마다 Recall의 캡처 서비스는 스크린샷을 찍을지 결정하기 전에 12가지 정책을 평가합니다:
GameModeActive, BatterySaverActive, UserActivityIdle, UserPresenceIdle, StorageLow, PrivateWindow, BlockedByContentProtection, BlockedAppId, BlockedExecutable, BlockedURL, BlockedContentFilePath, BitLockerDisabled
이 중 어느 것도 트리거되지 않으면 캡처합니다. 캡처당 입력 구조(WinRT 메타데이터에서):``` WindowData { WindowId, Foreground, Title, Bounds, Minimized, PrivateState, InputScopePrivacy AppData { AppUserModelId, ProcessPath, IconUri, AppName, TileId RemoteClient, IsBrowserWindow } RestoreData { WebUrl, FilePath, ActivationUri, ActivityId, WebIconUri FileObjectId, VolumeId // NTFS persistent file identifiers SensitivityLabelData { State, Labels } } }
### 데이터베이스
메인 데이터베이스 (`ukg.db`)는 SQLite SEE와 AES-256-GCM 암호화를 사용합니다. 스키마는 `storage_support.dll`(CREATE TABLE 문을 평문으로 포함하는 VBS 엔클레이브 바이너리)에서 확인되었습니다:
**핵심 테이블 (17개):**```
WindowCapture Id, Name, ImageToken, IsForeground, WindowId, WindowBounds,
WindowTitle, Properties, IsProcessed, Retry, ActivationUri,
ActivityId, FallbackUri, TimeStamp, DwellTime
WindowCaptureAppRelation WindowCaptureId, AppId, IsBackground
WindowCaptureWebRelation WindowCaptureId, WebId, IsBackground
WindowCaptureFileRelation WindowCaptureId, FileId
WindowCaptureTopicRelation WindowCaptureId, TopicId, Score (float)
WindowCaptureTextIndex FTS5 virtual table (WindowCaptureId, WindowTitle, OcrText)
App Id, WindowsAppId, IconUri, Name, Path, TileId, Properties
Web Id, Domain, Uri, IconUri, Properties
File Id, Path, Name, Extension, Kind, Type, ObjectId, VolumeId
Topic Id, Title, Properties
ScreenRegion Id, WindowCaptureId, RegionKind, OcrText, Bounds
AppDwellTime Id, WindowsAppId, HourOfDay, DayOfWeek, HourStartTimestamp, DwellTime
WebDomainDwellTime Domain, HourOfDay, DayOfWeek, HourStartTimestamp, DwellTime
SearchHistory SessionId, CorrelationId, TimeStamp, Kind, Text, Language
SearchFeedback SessionId, CorrelationId, TimeStamp, Kind, Text, Language,
ItemChosenEventId, FeedbackType
IdTable NextId
_MigrationMetadata Id, Version
의미론적 검색 인덱스 (SemanticTextStore.sidb / SemanticImageStore.sidb):``` si_items Core embedding storage si_embedding_metadata Embedding type and source mapping si_diskann_graph DiskANN approximate nearest neighbor graph si_diskann_references Graph edge references si_diskann_config Index configuration si_diskann_info Index statistics si_application_values Application-level settings
일반적인 근무일 동안 수백 개의 캡처가 누적됩니다. 기본 보존 기간은 90일이며 저장소 임계값은 75GB입니다. 열어본 모든 이메일, 편집한 모든 문서, 방문한 모든 웹사이트, 화면에 표시된 모든 터미널 명령, 보이는 모든 메시징 대화. 모두 OCR 처리되고, 엔터티가 추출되며, 주제가 분류되고, 의미론적으로 인덱싱됩니다.
전체 디지털 생애, 인덱싱되고 검색 가능합니다. 의도된 대로.
---
## Microsoft이 제대로 구현한 부분
VBS 엔클레이브는 완벽하게 견고합니다. 키 자료가 VTL1을 벗어나지 않습니다. 무작위 nonce를 사용하는 페이지별 AES-256-GCM은 교과서적으로 올바릅니다. `aihost.exe` PPL 보호는 효과적이며, 커널이 인젝션을 차단합니다. ARM64에서 CFG는 포괄적입니다. SQL 쿼리는 완전히 매개변수화됩니다(10개의 인젝션 페이로드, 부작용 0). 인증 모델은 상태 비저장이며 경합 조건이 없습니다(수천 번의 프로브, 우회 0).
근본적인 문제는 암호화, 엔클레이브, 인증 또는 PPL이 아닙니다. 복호화된 콘텐츠를 렌더링을 위해 보호되지 않은 프로세스로 보내는 것입니다. 금고 문은 티타늄입니다. 옆에 있는 벽은 석고보드입니다.
---
## 책임 있는 공개
본 연구는 Microsoft 보안 대응 센터(MSRC)에 책임 있게 공개되었습니다.
### 타임라인
| 날짜 | 이벤트 |
|------|--------|
| 2024-06-07 | 원본 [TotalRecall](https://github.com/xaitax/TotalRecall) 출시 (암호화 이전 Recall) |
| 2024-06-13 | Microsoft Recall 출시 연기, VBS 엔클레이브를 통한 재설계 발표 |
| 2025-04 | VBS 엔클레이브, 암호화, Hello 인증과 함께 Recall 재출시 |
| 2026-03-06 | MSRC 보고서 제출: 전체 보고서, 소스 코드, 빌드 지침 |
| 2026-03-09 | MSRC 케이스 109586 개설, 상태: 검토/재현 |
| 2026-03-27 | MSRC: "엔지니어링 팀이 현재 최종 조사 단계에 있습니다" |
| 2026-04-03 | MSRC 케이스 종결: **취약점 아님**: "현재 문서화된 보안 설계 내에서 작동합니다" |
| 2026-04-09 | TotalRecall Reloaded 공개 출시 |
### Microsoft의 입장
엔지니어링 팀과의 검토 후, MSRC는 "관찰된 동작이 현재 문서화된 Recall의 보안 설계 내에서 작동합니다"며 "시연된 액세스 패턴은 의도된 보호 및 기존 제어와 일치합니다"라고 판단했습니다. 그들은 [아키텍처 블로그](https://blogs.windows.com/windowsexperience/2024/09/27/update-on-recall-security-and-privacy-architecture/)를 인용하며, 특히 권한 부여가 "사용자 인증을 따라잡으려는 잠재 맬웨어의 시도를 제한합니다"고 밝혔습니다. "VBS 엔클레이브 외부의 프로세스는 스냅샷이나 암호화 키에 직접 액세스하지 않으며, 권한 부여 후 엔클레이브에서 반환된 데이터만 수신합니다."
이 케이스는 취약점 아님으로 종결되었습니다.
여기에 문서화된 사전 인증 결과(인증되지 않은 데이터 삭제, 스크린샷 추출)는 케이스 종료 후 후속 연구 중에 발견되었습니다.
---
## 테스트 환경
| | 세부 정보 |
|---|---|
| **OS** | Windows 11 25H2 (빌드 26300.8155) |
| **아키텍처** | ARM64 |
| **AIXHost.exe** | v2126.7602.0.0 |
| **권한** | 표준 사용자 (Medium 무결성, 권한 상승 없음) |
---
## 이전 작업
- [TotalRecall](https://github.com/xaitax/TotalRecall) (2024년 6월), 암호화 이전 Recall을 위한 원본 Python 도구
- [Kevin Beaumont의 분석](https://doublepulsar.com/recall-stealing-everything-youve-ever-typed-or-viewed-on-your-own-windows-pc-is-now-possible-da3e12e9465e), 모든 것을 시작한 연구
## 감사의 말
테스트와 검증을 도와주신 [Jeff McJunkin](https://x.com/jeffmcjunkin)과 [Kevin Beaumont](https://cyberplace.social/@GossiTheDog)께 감사드립니다.
---
**Alexander Hagenah ([@xaitax](https://x.com/xaitax))**
ISoftwareBitmapNativeQueryInterfaceGetData(IID_IWICBitmap)IWICBitmapEncoderContextEngine2.TryGetMemoryEntityDetailsForIdAsync()(슬롯 8)가 엔티티 세부 정보를 반환합니다. IMemoryEntityDetails로 QI하여 OcrLines(슬롯 7), IMemoryEntityDetails2로 QI하여 NER 텍스트 엔티티(사람, 이메일, 주소), IMemoryEntityDetails4로 QI하여 AI 활동 설명을 얻습니다.재시도 라운드: Baker.dll(Recall UI 라이브러리)은 ContextEngine 캐시를 비동기식으로 채웁니다. 초기 패스 후, 페이로드는 3초 동안 Windows 메시지를 펌핑(PeekMessage/DispatchMessage 루프)하고 사용할 수 없었던 엔티티를 재시도합니다. 각 라운드는 일반적으로 약 12개의 추가 엔티티를 생성합니다. 최대 10회 재시도 라운드.
| 데이터 | 출처 | 포함 내용 |
|---|
| 스크린샷 | TryGetBitmapCaptureAsync | 전체 화면의 전체 해상도 PNG |
| 크기 조정된 스크린샷 | TryGetBitmapCaptureAsync(Size, Mode) | 구성 가능한 보간법으로 요청된 모든 해상도의 스크린샷 |
| 썸네일 | TryGetBitmapCaptureThumbnailAsync | 저해상도 미리보기 이미지 |
| OCR 텍스트 | OcrText (Details3) | 화면에 보이는 모든 것의 전체 연결된 OCR |
| OCR 라인 | OcrLines (Details1) | 개별 OCR 라인(별도 문자열) |
| OCR 단어 | OcrWord 구조체 | 픽셀 단위 경계 상자(RectInt32)를 포함한 모든 단어 |
| 창 제목 | get_Title | 활성 창의 제목 표시줄 텍스트 |
| 애플리케이션 | get_AppDisplayName | 포커스된 앱(Chrome, Outlook, Terminal 등) |
| 앱 모델 ID | get_AppUserModelId | UWP/Win32 애플리케이션 ID 문자열 |
| 프로세스 경로 | get_ProcessPath | 전체 실행 파일 경로(C:\Program Files\...\chrome.exe) |
| 앱 아이콘 | IMemoryEntity2.IconUri | 애플리케이션 아이콘 경로 |
| URL | get_WebUrl | 브라우저 주소 표시줄의 전체 URL |
| 도메인 | get_WebDomain | 웹사이트 도메인 |
| 파비콘 | get_WebIconUri | 활성 웹사이트의 파비콘 URL |
| 파일 경로 | get_FileUri | 활성 문서 또는 파일 경로 |
| 창 위치 | get_WindowBounds | 픽셀 단위 화면 좌표: X, Y, Width, Height |
| 타임스탬프 | get_Timestamp | 정확한 캡처 시간(100나노초 정밀도) |
| 앱 체류 시간 | IMemoryEntity3 | 각 애플리케이션에서 보낸 시간(밀리초) |
| 웹 체류 시간 | IMemoryEntity3 | 각 웹사이트에서 보낸 시간(밀리초) |
| 민감도 레이블 | IMemoryEntity5 | Microsoft Purview/DLP 분류: 이름, 색상, 도구 설명 |
| 사용자 활동 ID | IMemoryEntity6 | Windows 타임라인 활동 상관 관계 ID |
| 복원 기능 | IMemoryEntity2 | 비트마스크: 앱 재실행(0x1), URL(0x2), 파일(0x4), URI(0x8), 타임라인(0x10) 가능 |
| 컨텍스트 복원 | TryRestoreContextAsync | 모든 캡처에서 정확한 앱, 페이지 또는 문서 다시 열기 |
DomainUserTagOrganizationProductAddressLocationDateTimeEventDurationMemoryDscSensitivityLabelWebVideoMeetingChatMailingPackageTextRatioSkipTopicsAnyText, Image, Table, Container, Menu, ToolBar, AddressBar, Toolpane, TabBar, TitleBar. 각각 픽셀 단위 경계 상자와 포함된 OCR 텍스트가 있습니다.L1Description(AI가 생성한 수행 중인 작업의 산문 요약), L1Activity(분류: 브라우징, 코딩, 글쓰기, 이메일 읽기), L1Application(AI 분류된 애플리케이션 컨텍스트).Meeting(회의 통화), Chat(메시징), WebVideo(비디오 재생), MailingPackage(이메일/뉴스레터). 여러 캡처를 논리적 활동 세션으로 그룹화합니다.UserActivity, KMeansCluster, LobeTopicCluster, ApplicationDwellTime, WebsiteDwellTime, ClipboardImageCopied, Topic.IAutomatedCaptureController6 인터페이스의 IsContentFilteringEnabled를 통해 제어됩니다.