Pwn2Own Berlin 2026을 위해 메모리 손상 없이 논리 버그만으로 Microsoft Edge에서 임의 코드 실행까지 이어지는 체인을 구축함
브라우저 내부 탐색 API가 출발 탭을 명시하지 않으면 활성 탭을 사용 하는 동작을 이용해, 다른 사이트에서 JavaScript를 실행하는 범용 크로스 사이트 스크립팅(UXSS)을 확보함
신뢰 출처 검사와 팝업 차단 우회, OneAuth 자동 로그인, 이메일을 노출하는 CORS 설정 오류를 연결해 클릭 없이 UXSS를 실행 하고 CSP도 우회함
Edge 읽기 모드의 read://
보호 누락 과 진단 로그 API의 경로 처리 문제를 결합해, 웹페이지의 JavaScript 실행을 임의 파일 쓰기로 확장함
프로토콜 실행 정책 파일을 덮어쓰고 Windows의 telnet://
실행 경로를 이용해 임의 코드 실행 에 도달함. 전체 익스플로잇은 100줄 미만이며, 연구에는 두 달이 걸림
연구 범위와 탐색 흐름
Pwn2Own Berlin 2026 용 체인은 메모리 손상 없이 버그 5개와 Windows 기능 2개로 구성했으며, Pwnie Awards의 Epic Achievement 를 수상함
버그 발견과 체인 구성 과정은 HITCON과 Hexacon에서도 공유했으며, 발표 자료 를 공개함
조사 출발점은 Chromium의 탐색(navigation) 처리 과정임. 전체 구조를 이해하기 위한 자료로 Chrome University의 Life of a Navigation 을 추천함
Navigation Throttles에서 발견한 내부 탐색 경로
Navigation Throttles 는 브라우저 프로세스에서 실행되며, 브라우저나 렌더러가 시작한 모든 탐색 요청을 가로챔
지난 5년간 Google Chrome이 수정한 CVE 3,000여 개 중 관련 항목은 20개 미만이었음
Edge의 EdgeCAGuidanceNavigationThrottle
는 기업용 Entra ID의 조건부 액세스 기능에 사용되며, Microsoft 사이트에서 업무 계정으로 로그인할 때 적절한 사용자 프로필로 안내함
login.live.com
같은 특정 Microsoft 출처에서 내부 형식의 주소로 탐색해야 작동함
쿼리의 email
과 현재 프로필 이메일이 다르면 계정 전환 안내를 표시함
이메일이 일치하면 원래 탐색을 취소하고, 쿼리의 switch_profile
URL로 내부 Navigate()
API를 호출함
공격자가 제어하는 URL을 브라우저 프로세스가 직접 탐색 하므로, 일반 웹페이지에서는 제한되는 edge://settings
, devtools://
나 javascript:
로 이동할 수 있음
처음에는 더 강력한 오픈 리디렉션 정도로 판단해 몇 주간 보류함
트리거를 위해 이미 login.live.com
실행 컨텍스트가 필요하다면, 같은 컨텍스트에서 javascript:
를 실행해도 권한이 늘어나지 않음
그 상태로는 Self-XSS에 가깝거나, 해당 사이트의 오픈 리디렉션을 XSS로 바꾸는 수준에 그침
출발 탭 없는 탐색이 UXSS로 이어지는 이유
내부 탐색 호출에는 source_contents
지정이 없었으며 , CURRENT_TAB
이 원래 요청을 시작한 탭과 연결되지 않았음
트리거를 8초 지연 한 뒤 활성 탭을 바꾸는 실험에서 google.com
에 대한 UXSS가 작동함
Chromium의 browser_navigator.cc
는 source_contents
가 없으면 현재 활성 탭의 WebContents
를 자동으로 사용함
disposition
이 CURRENT_TAB
이고 source_contents
가 NULL
이면 활성 탭으로 탐색을 전달함
두 값 모두 기본값이며, Chromium의 내부 API 예제 코드 도 출발 탭을 지정하지 않음
이처럼 출발 탭을 연결하지 않는 브라우저 탐색 은 새로운 UXSS 공격 표면이 될 수 있음
클릭 없는 실행을 가로막는 네 가지 조건
신뢰 출처 검사 는 실제 탐색 요청자 대신 대상 창의 마지막 커밋 URL을 확인해 우회할 수 있었음
GetLastCommittedURL()
로 Microsoft 로그인 사이트 여부를 검사하지만, 다른 창에서 시작한 탐색은 구분하지 않음
Microsoft 로그인 페이지를 별도 창으로 연 다음 그 창의 위치를 변경하면, 임의 사이트에서도 스로틀을 작동시킬 수 있음
팝업 차단 은 Edge에 하드코딩된 허용 목록으로 우회함
일반적인 window.open()
은 Chromium의 팝업 차단기 가 막음
예외 주소인 about:blank#quickAuthPopup
으로 창을 연 뒤 다른 사이트로 이동시키면 차단을 피할 수 있었음
로그인된 프로필 요구 조건 은 OneAuth 자동 로그인 기능으로 충족함
OneAuth는 Edge WebView 애플리케이션이 Microsoft 사이트를 방문할 때 현재 Microsoft 계정(MSA) 자격 증명으로 자동 로그인하도록 함
Windows 25H2부터는 로컬 계정 우회 방법을 사용하지 않는 한 Windows 초기 설정(OOBE) 에서 MSA 로그인이 필요함
브라우저 프로필을 만든 적이 없어도 www.microsoft.com
방문만으로 Edge가 프로필을 만들고 로그인할 수 있었음
로그인 이메일 사전 확보 는 Microsoft 사이트의 CORS 설정 오류로 해결함
자동 로그인이 설정한 쿠키를 활용할 수 있어 Burp Suite로 웹 취약점을 조사했고, 몇 시간 동안 여러 Microsoft 사이트에서 XSS도 발견함
edge://new-tab-page-online
에 포함되는 assets.msn.com
이 현재 사용자의 이메일을 반환했으며, 자격 증명을 포함한 교차 출처 요청으로 다른 사이트에서도 이를 읽을 수 있었음
UXSS 완성과 CSP 우회
창 간 요청자 검사 누락 , 팝업 허용 목록, OneAuth, CORS 오류를 연결해 별도 클릭 없이 UXSS를 실행함
JavaScript 실행 요청이 브라우저 프로세스에서 시작되어 Mojo의 HandleRendererDebugURL
경로를 거치므로 CSP를 무시할 수 있었음
google.com
, facebook.com
, icloud.com
등 원하는 웹사이트에서 JavaScript 실행이 가능했음
다만 UXSS만으로 임의 코드 실행(ACE)에 도달하지는 못함 . 브라우저 샌드박스를 벗어나는 추가 경로가 필요했음
특권 WebUI의 방어와 Immersive Reader의 빈틈
처음에는 edge://settings
나 edge://downloads
같은 특권 WebUI 에서 JavaScript를 실행해 네이티브 기능에 접근하려 했지만, Chromium의 별도 방어에 막힘
렌더러의 LocalFrame::LoadJavaScriptURL()
은 SchemeRegistry
의 JavaScript URL 금지 목록 에 포함된 스킴에서는 실행을 무시함
edge://
, chrome-extension://
, chrome://
, chrome-untrusted://
, chrome-distiller://
, chrome-error://
, chrome-native://
, chrome-search://
, devtools://
등이 대상임
Edge의 Immersive Reader 는 독자적인 read://
스킴 을 사용하며, 이 스킴은 금지 목록에서 빠져 있었음
Chrome 읽기 모드와 달리 초기 Chromium 코드에서 분기해 확장한 것으로 보임
기존 chrome-distiller://
나 금지 목록에 있는 chrome-untrusted://
대신 사용하는 이 스킴에서는 UXSS가 작동함
진단 로그 API를 통한 임의 파일 쓰기
read://
특권 WebUI에서는 JavaScript로 여러 네이티브 C++ 객체에 접근할 수 있었으며, 그중 chrome.edgeFeedbackPrivate.zipDiagnosticLogFiles()
를 이용함
이 함수는 파일 이름과 JSON 문자열을 받아 진단 로그 압축 및 업로드 를 수행함
임시 폴더에 로그 값을 .json
파일로 기록하고, 폴더를 ZIP으로 압축해 Microsoft 서버에 업로드한 뒤 정리함
로그 파일 이름에 경로 탐색 문자열 을 넣으면 임시 폴더 밖으로 나갈 수 있었으며, NULL 바이트로 자동 추가되는 .json
확장자도 제거할 수 있었음
이를 통해 파일 이름과 내용을 제어하고 원하는 위치의 파일을 덮어쓰는 수단을 확보함
프로토콜 정책 파일과 Windows 실행 경로 연결
Edge 초기화 시 쓰기 가능한 폴더에서 설정 파일과 DLL을 읽는 동작을 확인했지만, DLL 사이드로딩 은 포기함
파일 내용이 JSON에 들어가므로 유효한 UTF-8 문자열이어야 함
Edge는 64비트 프로세스이므로 64비트 DLL이 필요했으나, 연구 과정에서 UTF-8 조건을 만족하는 유효한 64비트 PE 헤더를 만들지 못함
대신 AutoLaunchProtocolsComponent
가 읽는 protocols.json
을 덮어씀
이 파일은 쓰기 가능한 사용자 데이터 폴더에 있으며, 어떤 출처가 어떤 URL 프로토콜 처리기를 실행할 수 있는지 정의함
기존 설정에는 Microsoft Store 출처의 ms-windows-store
, OneDrive와 SharePoint 출처의 ms-word
허용 규칙 등이 있음
파일을 바꾸면 임의 출처에서 원하는 프로토콜 처리기를 실행할 수 있음
수정한 정책을 다시 읽게 하려면 앞서 확보한 브라우저 탐색으로 edge://restart
에 접근하면 됨
telnet://
에서 임의 코드 실행까지
Windows의 telnet://
처리기 는 telnet.exe
실행을 시도하지만, 해당 바이너리는 기본으로 제공되지 않아 PATH
에 있는 디렉터리를 탐색함
탐색 경로 중 사용자 영역의 AppData\Local\Microsoft\WindowsApps
는 쓰기가 가능했음
수정한 protocols.json
과 작은 32비트 PE 실행 파일을 배치해 임의 코드 실행에 도달함
전체 익스플로잇은 100줄 미만 이며, 실행 시연 영상 을 공개함
재시작은 Pwn2Own에서 필요했지만, 실제 공격에서는 반드시 필요한 단계는 아님
수작업 연구와 AI 활용에 대한 판단
현대 브라우저 익스플로잇 경험이 없는 상태에서 시작해 체인을 완성하기까지 두 달 이 걸렸으며, 전 과정에 LLM이나 AI를 사용하지 않음
Codex와 Claude Code 같은 코딩 에이전트를 사용하기 시작한 시점은 그해 3월경으로, 이미 모든 버그와 어려운 부분을 해결한 뒤였음
이 연구에서 논리 버그의 어려움은 발견 자체 에 있었으며, 모두 발견한 뒤 연결하는 작업은 가장 쉬운 부분이었음
메모리 손상 취약점은 악용 단계가 어려운 경우가 많다는 점과 대비됨
새 UXSS 공격 표면을 AI 기업들과 공유하기 전에 더 탐색하고 싶었던 것도 AI를 사용하지 않은 이유였으며, “Attack Surface is the new 0day” 에 동의함
다만 AI 활용 자체에는 적극적 이며, LLM의 편리함을 경험하면 수작업 취약점 탐색으로 돌아가고 싶지 않을 것이라고 봄
AI 덕분에 미뤄둔 연구를 진행할 시간이 생겼으며, 후속 작업도 이어가고 있음
취약점 연구의 진입 장벽이 얼마나 낮아질지 걱정하기보다, AI로 얼마나 더 높은 수준의 연구와 새로운 해킹이 가능해질지 에 기대를 둠
댓글과 토론