[도닦기] 4단계: 스스로를 가둔 크롬(Chrome Sandbox) (KR)

안녕하세요. OUYA77입니다. 오늘 다룰 내용은 도닦기 프로젝트 4단계로 크롬 샌드박스에 대한 내용입니다.

image.png

지난 연구글
https://hackyboiz.github.io/2026/06/06/OUYA77/Wipeload_step1/kr/
https://hackyboiz.github.io/2026/06/21/ji9umi/Wipeload_step2/kr/
https://hackyboiz.github.io/2026/06/26/ji9umi/Wipeload_step3/kr/

2-3단계에서는 ji9umi님이 Renderer RCE에 대해서 소개를 해주었습니다. 대부분의 경우 한 프로세스에서 RCE를 얻으면 User 권한으로 RCE가 되어야 정상입니다. 하지만, 크롬은 렌더러는 믿을 만한 친구가 아니라고 생각해서 샌드박스라는 이름으로 여러 가지 제약을 가했습니다.

오늘은 그 샌드박스에 대해서 같이 알아봅시다!

1. Chrome Sandbox Overview

그동안 이야기해왔던 대로 크롬은 멀티 프로세스 구조를 채택하고 있으며, 애초에 ‘렌더러 프로세스’를 신뢰하지 않습니다. 외부의 신뢰할 수 없는 JavaScript 코드를 무조건 실행해야만 하는 브라우저의 태생적 숙명 때문입니다.

image.png

Tai Lung (Renderer): “Why isolate me?”

Shifu (Browser):“Because you execute untrusted JS.”

기존의 단일 프로세스 환경에서는 렌더러가 장악당하면 시스템 전체가 고스란히 털리는 치명적인 구조였습니다. 하지만 크롬은 이를 해결하기 위해 Broker/Target 구조를 도입했습니다. 핵심적인 권한이 필요한 작업은 오직 Broker(브라우저 프로세스)를 통해서만 수행할 수 있도록 철저히 분리한 것입니다.

이 구조에서 렌더러 프로세스는 격리(Isolation)의 최후의 보루인 ‘샌드박스(Sandbox)’라는 감옥에 완벽히 갇히게 됩니다.

image.png

“털려도 상관없다, 다만 나가지 못하게 할 뿐”이라는 철학 아래, Restricted Token으로 프로세스 권한을 바닥까지 낮추고, Job Object로 프로세스 생성을 억제하며, AppContainer / Low Integrity Level (IL)을 통해 파일 시스템과 네트워크 접근을 원천 차단합니다.

이제 렌더러는 보안 관점에서 철저히 무력화된 채, 오직 샌드박스 안에서만 자기의 원래 역할(웹페이지 렌더링 등)을 귀엽고 뽀짝하게 수행할 뿐입니다. 덕분에 설령 렌더러 프로세스가 완전히 따이더라도, 해커는 격리된 벽을 뚫지 못해 시스템 전체를 뒤흔드는 크리티컬한 위협으로 이어지지 않습니다.

논문에 좋은 Figure가 있어서 갖고 와봤습니다.

image.png

위 내용에 대한 예를 들면, 렌더러 프로세스는 브라우저(또는 네트워크) 프로세스가 네트워크나 로컬 파일 시스템으로부터 안전하게 받아와 전달해 준 HTML, CSS, JS 파일을 Input으로 받습니다.

그 후 렌더러 내부의 렌더링 엔진(Blink)과 V8 엔진을 통해 이 내용들을 파싱하고 시각화 데이터(Compositor Frame)를 Output으로 생성합니다.

하지만 샌드박스에 가두어진 렌더러 프로세스는 화면에 직접 이 데이터를 디스플레이할 권한이 없습니다. 따라서 브라우저 프로세스(Broker)에게 “내가 다 계산했으니, 이 데이터를 화면에 띄워줘!”라고 IPC를 통해 요청하며, 최종적인 화면 출력은 브라우저 및 GPU 프로세스의 통제 하에 안전하게 이루어집니다.

이런 식으로 렌더러와 브로커 프로세스는 통신합니다. 샌드박스 안에 있는 렌더러 프로세스는 이렇게 중요 기능을 직접 할 수 없을 뿐만 아니라, OS에서의 API를 이용하여 기능을 제한받는데요. Linux에서는 Seccomp 같은 정책을 적용하고 윈도우에서는 다음과 같습니다.

  • Restricted Token — 모든 privilege 제거, Untrusted IL
  • App Container (LPAC)
  • Job Object로 프로세스 능력 봉쇄
  • Desktop / Window Station 격리 (GUI 격리)

그래서 결론으로는 OS syscall 등 민감한 작업은 모두 브라우저 프로세스에서 수행하게 됩니다.

앞서 살펴본 프로세스 간 통신 구조와 보안 메커니즘이 실제 운영체제에서 어떻게 적용되는지는 chrome://sandbox 페이지에서 한눈에 확인할 수 있습니다.

image.png

가장 먼저 눈에 띄는 것은 RendererUtility 프로세스입니다. 이들은 외부에서 전달되는 HTML, JavaScript, 이미지 등 신뢰할 수 없는 데이터를 직접 처리하기 때문에, Untrusted Integrity Level(S-1-16-0) 과 강력한 Lockdown 정책이 적용됩니다. 따라서 설령 렌더러가 완전히 장악되더라도 로컬 파일 시스템에 접근하거나 민감한 시스템 콜을 호출하는 등의 행위는 운영체제 수준에서 원천적으로 차단됩니다.

반면 모든 프로세스가 동일한 수준으로 제한되는 것은 아닙니다. GPU 프로세스는 화면 출력과 그래픽 자원 접근이 필요하기 때문에 Low Integrity Level에서 동작하며, Network Service와 같이 네트워크 자원에 직접 접근해야 하는 프로세스는 구조적으로 Not Sandboxed 상태로 실행됩니다. 대신 이들 역시 각각 독립된 프로세스로 분리되어 있어 서로의 메모리나 권한을 침범할 수 없도록 설계되어 있습니다. 즉, 필요한 기능만 최소한으로 허용하는 최소 권한 원칙(Least Privilege)이 크롬 전체에 일관되게 적용되는 것입니다.

또 하나 흥미로운 항목은 Mitigations 열입니다. 이곳에 표시되는 32비트 또는 64비트 길이의 이진수(011011...)는 Windows Process Mitigation Policies의 활성화 상태를 나타냅니다. 다시 말해 크롬의 브로커 프로세스가 렌더러를 생성하면서 “이 프로세스에는 이러한 보안 정책을 모두 적용하라.”고 Windows 커널에 요청한 결과가 그대로 표시되는 것입니다.

이 완화 정책들은 공격자가 렌더러 프로세스에서 RCE를 획득하더라도 이후의 공격을 매우 어렵게 만드는 역할을 합니다.

2. Chrome Sandbox Internals

조금 더 Windows 내부의 이야기를 살펴보며 실제 샌드박스의 구현을 봅시다. (체인을 더 잘 이해하기 위해, 샌드박스 정책이 적용되는 다른 프로세스도 있지만 특히 렌더러 프로세스에 대해 살펴보도록 하겠습니다.)

Chrome Sandbox는 Browser Process가 Renderer를 생성하는 순간부터 적용됩니다. 따라서 Browser Process가 Renderer를 생성하는 과정을 먼저 따라가 보면 Sandbox가 어떻게 만들어지는지 자연스럽게 이해할 수 있습니다.

Chrome Sandbox는 Chromium의 sandbox 라이브러리를 이용하여 Renderer를 생성하며, Windows에서는 최종적으로 CreateProcess()를 호출하기 전에 여러 보안 정책을 설정합니다.

대략적인 흐름은 다음과 같습니다.

Browser Process
        │
        ▼
SandboxWin::StartSandboxedProcess()
        │
        ▼
BrokerServicesBase::SpawnTarget()
        │
        ▼
CreateProcessInternalW()
        │
        ├── Restricted Token 생성
        ├── Integrity Level 설정
        ├── AppContainer 생성
        ├── Job Object 연결
        ├── Process Mitigation 설정
        ▼
Renderer 시작

Chrome Docs에서도 Broker Process의 역할을 다음과 같이 설명합니다.

  • Sandbox Policy 생성
  • Target(Renderer) Process 생성
  • Sandbox IPC Service 제공
  • Policy가 허용한 작업을 대신 수행(Broker)

즉, Sandbox는 Renderer 내부에서 만들어지는 것이 아니라 Browser Process가 Renderer를 생성하는 과정에서 완성되는 것입니다.

2.1 Restricted Token

Windows에서 모든 프로세스는 Access Token이라는 객체를 하나씩 가지고 있습니다. 이 Token에는 프로세스의 SID(Security Identifier), Privilege(권한), Group SID, Integrity Level 등이 저장되어 있으며, 운영체제가 “이 프로세스를 어떤 사용자로 취급할 것인가”를 결정하는 신분증 역할을 합니다.

일반적으로 프로그램은 부모 프로세스의 Token을 그대로 상속받아 실행됩니다.

explorer.exe
      │
      ▼
chrome.exe
      │
      ▼
renderer.exe

만약 Chrome도 일반 프로그램처럼 Token을 그대로 상속했다면 Renderer 역시 사용자의 권한을 그대로 갖게 됩니다. 이는 Renderer에서 RCE를 획득하는 것만으로도 사용자의 파일을 읽거나 삭제하고, 다른 프로세스에 접근하는 등 사용자 권한으로 가능한 대부분의 행위를 수행할 수 있다는 의미입니다.

이를 막기 위해 Chrome는 Renderer를 생성할 때 부모의 Token을 그대로 사용하지 않고 Restricted Token을 새롭게 생성합니다. Chromium Docs에 따르면 Renderer의 Token은 대부분의 Privilege가 제거되고, 일반 SID는 Deny-Only로 변경되며, Restricted SID가 추가된 형태로 생성됩니다.

Privileges
None

Restricted SID
S-1-0-0

Logon SID
Mandatory

즉, Renderer는 생성되는 순간부터 일반 사용자 프로세스와는 다른 권한을 갖게 되며, 운영체제는 이를 강하게 제한된 프로세스로 취급합니다.

2.2 Integrity Level

Restricted Token이 “무엇을 할 수 있는가”(권한)를 결정한다면, Integrity Level은 “어디까지 접근할 수 있는가”를 결정합니다. Windows는 Mandatory Integrity Control(MIC)이라는 보안 모델을 사용하며, 모든 프로세스에는 다음과 같은 Integrity Level이 부여됩니다.

System
 ↑
High
 ↑
Medium
 ↑
Low
 ↑
Untrusted

우리가 실행하는 대부분의 프로그램은 Medium Integrity에서 동작하며, 관리자 권한으로 실행하면 High, Windows 서비스는 System 권한을 사용합니다. 반면 Chrome Renderer는 가장 낮은 등급인 Untrusted Integrity를 부여받습니다.

Untrusted Integrity에서는 대부분의 파일 접근, Registry 수정, 다른 프로세스 접근, 시스템 객체 접근 등이 운영체제 수준에서 차단됩니다. 다시 말해 Renderer가 완전히 장악되더라도 Windows는 “신뢰할 수 없는 프로세스”로 판단하여 대부분의 요청을 거부하게 됩니다.

image.png

실제로 Renderer의 Token을 확인해 보면 Chrome Docs에서 설명한 것과 동일하게 대부분의 Privilege가 제거되어 있으며, Integrity 역시 Untrusted로 설정되어 있는 것을 확인할 수 있습니다.

이처럼 Browser Process는 Renderer를 생성하는 순간부터 일반 사용자 프로세스와는 완전히 다른 권한을 부여하며, 이것이 Chrome Sandbox의 첫 번째 보안 계층이 됩니다.

2.3 AppContainer

Restricted Token과 Integrity Level만으로도 Renderer는 상당한 제약을 받지만, Chromium Docs에서는 여기에 AppContainer(Lowbox Token) 를 추가로 적용한다고 설명합니다.

AppContainer는 Windows 8부터 도입된 격리 기술로, 일반 Access Token에 CapabilityPackage SID를 추가하여 파일 시스템, Registry, Device, Network 등에 대한 접근 권한을 더욱 세밀하게 제어합니다.

특히 Chromium Docs에서는 Renderer가 기존 Restricted Token 위에 Lowbox(AppContainer) Token 을 추가로 적용하며, 네트워크 접근에 필요한 INTERNET_CLIENT Capability를 부여하지 않아 Renderer가 직접 네트워크를 사용할 수 없도록 설계했다고 설명합니다.

또한 최신 Windows에서는 일반 AppContainer보다 더욱 제한적인 LPAC(Less Privileged AppContainer) 를 지원하며, Chromium 역시 LPAC 사용을 권장하고 있습니다.

하지만 실제 Chrome Stable 환경에서 chrome://sandbox를 확인한 결과는 조금 달랐습니다.

image.png

여기서 흥미로운 점은 Lowbox/AppContainer 열이 비어 있다는 것입니다.

즉, 현재 분석 환경에서는 Renderer가 Restricted Token과 Untrusted Integrity Level, Lockdown 등의 정책은 적용받고 있지만 AppContainer(Lowbox)는 활성화되어 있지 않은 것으로 확인되었습니다.

이는 Chromium Docs가 설명하는 최신 Sandbox 정책과 실제 Stable Chrome의 적용 상태가 항상 일치하는 것은 아니라는 점을 보여줍니다.

Chromium에서는 운영체제 버전, Feature Flag, 프로세스 종류 등에 따라 Sandbox 정책이 달라질 수 있으므로, 실제 분석 시에는 문서뿐 아니라 chrome://sandbox나 Token 정보를 함께 확인하는 것이 중요합니다.

2.4 Job Object

앞에서 살펴본 Restricted Token, Integrity Level, AppContainer가 프로세스가 어떤 권한을 가지는지를 제한하는 기술이었다면, Job Object프로세스가 어떤 행동을 할 수 있는지를 제한하는 기술입니다.

Windows의 Job Object는 하나 이상의 프로세스를 하나의 그룹으로 묶고 공통된 정책을 적용하는 커널 객체입니다. Chromium에서는 Renderer를 생성할 때 이를 Job Object에 포함시키고 운영체제가 제공하는 여러 기능에 대한 사용을 제한합니다.

Chromium Docs에 따르면 Renderer에는 자식 프로세스 생성, Desktop 생성 및 전환, Global Hook 등록, Broadcast Message 전송 등 프로세스가 수행할 수 있는 작업을 제한하는 정책이 함께 적용됩니다.

실제로 Renderer의 Job Object를 확인해 보면 다양한 제한이 적용되어 있는 것을 확인할 수 있습니다.

image.png

Chrome는 단순히 새로운 프로세스 생성을 제한하는 것뿐만 아니라, Desktop 접근, USER Handle 사용, Clipboard 읽기 및 쓰기, Global Atom 접근, Display 설정 변경 등 운영체제와 직접 상호작용하는 기능도 함께 제한합니다.

즉, 공격자가 Renderer를 장악하더라도 운영체제에 영향을 줄 수 있는 대부분의 기능은 Job Object 단계에서 한 번 더 차단되는 것입니다.

공격자 입장에서 가장 체감되는 제약 중 하나는 새로운 프로세스를 생성할 수 없다는 점입니다.

공격자 시나리오

“Renderer를 장악했으니 cmd.exepowershell.exe를 실행해서 리버스 쉘을 띄우자.”

커널의 방어

Chrome는 Renderer가 새로운 프로세스를 생성하지 못하도록 정책을 적용합니다. 따라서 Renderer에서 RCE를 획득하더라도 CreateProcess()를 이용해 cmd.exepowershell.exe를 실행하는 일반적인 공격은 사용할 수 없습니다.

참고로 비교를 위해 Low Integrity Level 프로세스의 Job Object도 함께 확인해 보았습니다.

image.png

2.5 Process Mitigation Policy

앞에서 살펴본 Restricted Token, Integrity Level, AppContainer, Job Object는 프로세스가 어떤 권한을 가지고 어떤 행동을 수행할 수 있는지를 제한하는 보안 계층이었습니다.

반면 Process Mitigation Policy는 공격자가 이미 Renderer에서 RCE를 획득했다는 가정 아래, 그 이후에 사용하는 익스플로잇 기법 자체를 어렵게 만드는 마지막 방어선입니다.

Chrome는 Renderer를 생성하는 과정에서 Windows가 제공하는 다양한 Process Mitigation Policy를 함께 적용합니다. 이러한 정책은 SetProcessMitigationPolicy() 등의 API를 통해 설정되며, chrome://sandboxMitigations 열에서 활성화 여부를 확인할 수 있습니다.

image.png

Mitigations 열에 표시되는 긴 이진수(011011...)는 하나의 숫자가 아니라 여러 Process Mitigation Policy의 활성화 상태를 비트 단위로 표현한 값입니다. 즉, Chrome는 Renderer를 생성하는 순간 Windows 커널에게 “이 프로세스에는 이러한 보안 정책들을 모두 적용하라.”고 요청하는 것입니다.

이러한 정책들은 공격자가 Renderer를 장악한 이후 가장 먼저 시도하는 공격 기법들을 운영체제 수준에서 차단합니다. 대표적인 정책들을 살펴보겠습니다.

① Arbitrary Code Guard (ACG)

  • 공격자 시나리오

    “메모리에 쉘코드를 올리고 실행 권한(RWX)을 부여하면 되겠네.”

  • 커널의 방어

    일반적인 쉘코드 공격은 실행 가능한 메모리를 확보하는 것부터 시작합니다. 하지만 ACG가 적용된 프로세스에서는 새로운 실행 가능 메모리를 생성하거나 기존 메모리를 실행 가능하도록 변경하는 작업이 차단됩니다. 따라서 VirtualAlloc()이나 VirtualProtect()를 이용한 일반적인 쉘코드 인젝션은 운영체제 수준에서 실패하게 됩니다.

    물론 Chrome은 JavaScript 실행을 위해 V8 JIT 컴파일러를 사용하므로 일부 예외가 존재합니다. 하지만 이러한 영역 역시 Chrome이 별도로 관리하며 일반적인 메모리 인젝션과는 다른 방식으로 동작합니다.

② Win32k Lockdown

  • 공격자 시나리오

    “Renderer에서 win32k.sys 취약점을 이용해 SYSTEM 권한으로 상승해야겠다.”

  • 커널의 방어

    win32k.sys는 Windows의 GUI 서브시스템으로, 과거부터 권한 상승 취약점이 자주 발견되던 영역입니다. 하지만 Renderer는 화면을 직접 출력하지 않고 Browser Process와 GPU Process에 IPC를 통해 작업을 요청하기 때문에 Win32k 시스템 콜을 사용할 이유가 없습니다.

    Chrome는 이러한 특성을 이용해 Renderer에서 Win32k 관련 시스템 콜 자체를 사용할 수 없도록 제한합니다. 그 결과 GUI 커널을 대상으로 한 공격 표면이 크게 감소하게 됩니다.

③ Binary Signing & Font Blocking

  • 공격자 시나리오

    “악성 DLL을 로드하거나 취약한 폰트 파일을 이용해 추가 공격을 수행하자.”

  • 커널의 방어

    Renderer는 신뢰할 수 있는 기관이 디지털 서명한 DLL만 로드할 수 있으며, 임의의 DLL을 메모리에 적재하는 것이 제한됩니다. 또한 과거 수많은 브라우저 취약점의 원인이 되었던 외부 폰트 역시 직접 로드하여 파싱하지 못하도록 제한됩니다. 이를 통해 실행 가능한 바이너리와 입력 데이터 모두의 공격 표면을 줄일 수 있습니다.

④ Control Flow Guard (CFG)

  • 공격자 시나리오

    “함수 포인터를 덮어써 실행 흐름을 원하는 곳으로 바꾸자.”

  • 커널의 방어

    CFG(Control Flow Guard)는 간접 호출이 발생할 때 호출 대상이 운영체제가 미리 허용한 정상적인 함수 시작 주소인지를 검증하는 Windows의 제어 흐름 보호 기법입니다. 따라서 함수 포인터나 vtable을 변조하는 공격, 일반적인 ROP, Control Flow Hijacking 등의 난이도가 크게 증가합니다.

지금까지 살펴본 정책들은 각각 독립적으로 동작하는 것이 아닙니다. Chrome는 여러 Process Mitigation Policy를 함께 적용하여 메모리 인젝션, 제어 흐름 변조, GUI 커널 공격, 악성 DLL 로딩 등 공격자가 일반적으로 사용하는 기법을 다층적으로 차단합니다. 결국 Renderer에서 RCE를 획득하더라도 곧바로 시스템 장악으로 이어지지 않는 이유가 바로 여기에 있습니다.

3. Chrome SBX의 Attack Surface: 성벽의 틈새

앞 장에서는 Chrome Sandbox가 어떻게 구성되어 있는지 살펴봤습니다.

Restricted Token으로 권한을 제거하고, Integrity Level과 AppContainer로 접근을 제한하며, Job Object와 Process Mitigation Policy를 통해 공격 가능한 범위를 극단적으로 줄였습니다.

그렇다면 공격자의 입장에서 가장 먼저 떠오르는 질문은 하나입니다.

“도대체 어디를 공격해야 샌드박스 밖으로 나갈 수 있을까?”

Sandbox는 높은 벽을 세운다고 해서 완성되는 보안 기술이 아닙니다. 아무리 견고한 성벽이라도 문이 존재한다면, 그리고 그 문을 통해 외부와 통신해야 한다면 그곳은 언제나 공격 대상이 됩니다.

image.png

Chrome 역시 마찬가지입니다. Renderer는 샌드박스 안에 갇혀 있지만 완전히 고립되어 있는 것은 아닙니다. 화면을 출력하고, 파일을 읽고, 네트워크를 사용하기 위해서는 반드시 샌드박스 밖의 프로세스와 통신해야 합니다. 공격자는 바로 이 통로를 노립니다.

또는 샌드박스를 구성하는 OS API의 허점을 노립니다.

3.1 Sandbox Escape

먼저 이 글에서 사용할 용어를 정의하고 넘어가겠습니다.

샌드박스를 우회하는 방법은 “제가 생각하기로는” 크게 두 가지로 나눌 수 있습니다.

SBX Escape

샌드박스 안에 있는 프로세스가 브라우저 프로세스가 제공하는 정상적인 기능(IPC 통신 등)을 이용하는 과정에서의 취약점을 이용하여 샌드박스를 벗어나는 방법입니다.

대표적으로 Mojo IPC, Browser Service 등을 대상으로 한 공격이 여기에 해당합니다.

공격자는 Renderer에서 Browser Process로 전달되는 과정의 취약점을 이용하여 Sandbox 밖의 상위 권한 프로세스에서 코드 실행 권한을 획득합니다.

마치 성문의 경비병을 속여 정문으로 걸어 나가는 것과 비슷한 방식입니다.

SBX Bypass

반대로 Browser Process 자체를 공격하지 않고 운영체제의 취약점을 이용하는 방법도 존재합니다. 이를 이 글에서는 SBX Bypass라고 부르겠습니다.

대표적으로 Windows Kernel의 권한 상승(Local Privilege Escalation, LPE), Device Driver, System Service 취약점 등이 여기에 해당합니다.

이 경우에는 Browser Process를 공격하지 않고도 Windows Kernel이나 시스템 구성 요소의 취약점을 이용하여 샌드박스를 우회할 수 있습니다. Renderer에서 곧바로 Windows 커널의 취약점을 이용하여 권한을 상승시키고 샌드박스를 무시하는 것입니다.

성벽을 통과하는 것이 아니라 지하를 파서 성 밖으로 나가는 셈입니다.

성벽이 아무리 견고해도 내부의 작은 틈을 이용하면 탈출할 수 있습니다. 이런 개념을 가장 재미있게 보여주는 장면이 바로 「쿵푸팬더」의 타이렁 탈옥 장면입니다.

image.png

image.png

영화 속 타이렁은 하늘에서 떨어진 깃털 하나로 족쇄의 잠금장치를 풀고, 이어서 자신에게 날아오는 창을 이용해 감옥을 탈출합니다.

image.png

물론 현실의 샌드박스는 타이렁의 감옥처럼 깃털 하나로 탈출할 수 있을 만큼 허술하지 않습니다(혹은 그럴 수도?). 하지만 모든 샌드박스에는 반드시 외부와 연결되는 통로가 존재합니다. 공격자는 그 통로를 이용하거나, 그 과정에서 발생하는 아주 작은 틈을 찾아 탈출을 시도합니다.

그렇다면 Chrome Sandbox에서 공격자의 ‘깃털’은 무엇일까요?

계속해서 같이 알아봅시다!

3.2 Renderer는 어떻게 바깥과 통신하는가?

앞에서 살펴본 것처럼 Chrome Renderer는 Restricted Token, Integrity Level, Job Object 등 다양한 보안 정책이 적용되어 있습니다. 그 결과 Renderer는 운영체제의 대부분의 기능을 직접 사용할 수 없습니다.

예를 들어 로컬 파일을 직접 읽거나 네트워크 소켓을 생성할 수 없으며, 화면을 출력하는 작업조차 직접 수행하지 않습니다. 이러한 기능은 모두 샌드박스 밖에 있는 다른 프로세스가 대신 수행합니다.

그렇다면 권한이 극도로 제한된 Renderer는 어떻게 웹 브라우저의 역할을 수행할 수 있을까요?

정답은 IPC(Inter-Process Communication)입니다.

Renderer
    │
    │ IPC
    ▼
Browser Process
    │
    ├── File System
    ├── Network
    ├── GPU
    ├── Clipboard
    └── Download

Renderer는 필요한 작업이 발생할 때마다 Browser Process에게 IPC를 통해 요청(Request)을 전달합니다. Browser Process는 요청을 검증한 뒤, 적절하다고 판단되는 경우에만 운영체제의 기능을 대신 수행하고 그 결과를 다시 Renderer에게 전달합니다.

예를 들어 JavaScript가 파일 다운로드를 요청하면 Browser Process가 파일을 생성하고, 새로운 창을 열면 Browser Process가 탭과 윈도우를 관리합니다. 화면 출력 역시 Renderer가 생성한 Compositor Frame을 GPU Process가 전달받아 최종적으로 화면에 표시하는 구조입니다.

즉, Renderer가 샌드박스 밖과 상호작용할 수 있는 유일한 통로는 IPC입니다.

이 말은 곧 공격자의 관점에서도 중요한 의미를 갖습니다. Renderer는 운영체제를 직접 공격할 수 없지만, Browser Process와 통신하는 IPC는 반드시 사용할 수밖에 없습니다. 따라서 이 통신 과정에서 발생하는 로직 오류나 메모리 손상 취약점은 자연스럽게 Chrome Sandbox의 가장 중요한 공격 표면(Attack Surface)이 됩니다.

3.3 Chrome Sandbox의 Attack Surface

그렇다면 실제 공격 가능한 지점은 어디일까요?

image.png

Chrome에는 Renderer보다 높은 권한을 가진 여러 프로세스가 존재합니다.

Renderer
      │
      ├── Browser
      ├── Utility
      ├── Network
      ├── GPU
      └── OS

Renderer는 이들 프로세스와 지속적으로 IPC를 수행하며 다양한 기능을 제공받습니다. 따라서 공격 표면 역시 이러한 통신 경로를 중심으로 형성됩니다.

대표적으로 다음과 같은 대상들이 존재합니다.

  • IPC Interface : Browser Process와 통신하는 IPC 인터페이스
  • Browser Services : Clipboard, Download, File System 등 브라우저 서비스
  • Utility Process : 이미지, 오디오, PDF 등 다양한 데이터 파서를 담당하는 프로세스
  • Network Service : HTTP, DNS, Cookie 등을 처리하는 네트워크 서비스
  • GPU Process : 그래픽 렌더링과 GPU 자원을 관리하는 프로세스

이 가운데 가장 중요한 공격 표면은 Browser Process와의 IPC입니다. Renderer가 사용할 수 있는 대부분의 브라우저 기능은 IPC를 통해 제공되며, Chromium에서는 현재 이러한 통신의 대부분이 Mojo IPC 프레임워크를 기반으로 구현되어 있습니다.

물론 IPC 자체가 취약점은 아닙니다. IPC는 Browser Process와 Renderer가 정상적으로 통신하기 위해 반드시 필요한 기능입니다. 문제는 이 통신을 처리하는 과정입니다. Browser Process가 Renderer의 요청을 검증하는 과정에서 논리적인 오류가 발생하거나, IPC 메시지를 처리하는 과정에서 메모리 손상 취약점이 존재한다면 공격자는 바로 이 지점을 이용해 샌드박스를 벗어날 수 있습니다.

앞에서 정의한 관점에서 보면 이러한 공격은 크게 SBX EscapeSBX Bypass로 나눌 수 있으며, 공개된 Chrome Sandbox 취약점 역시 대부분 이 두 범주 안에서 설명할 수 있습니다.

① SBX Escape

SBX Escape는 Browser Process가 제공하는 기능을 이용하거나, IPC 처리 과정의 취약점을 악용하는 방식입니다. 현재까지 공개된 Chrome Sandbox Escape 사례의 대부분이 여기에 해당하며, 공격 방법은 다시 두 가지로 나눌 수 있습니다.

  • Logical Bug

Browser Process가 제공하는 기능 자체에는 문제가 없지만, 권한 검증이나 상태 검증이 올바르게 이루어지지 않는 경우입니다.

대표적으로 Renderer가 접근해서는 안 되는 IPC 인터페이스가 노출되었거나, Browser Process가 요청을 충분히 검증하지 않는 경우가 여기에 해당합니다.

  • Memory Corruption

Renderer가 전송한 IPC 메시지를 Browser Process가 처리하는 과정에서 발생하는 메모리 손상 취약점을 이용하는 방식입니다. 대표적인 취약점은 UAF, Heap Overflow 등이 있습니다.

이러한 취약점을 통해 Browser Process의 실행 흐름을 제어하면 공격자는 Renderer의 Untrusted 권한을 벗어나 Browser Process 수준의 코드 실행 권한을 획득하게 됩니다.

이 시리즈의 첫 번째 글에서 간단히 살펴본 “CVE-2019-5826: IndexedDB에서의 UAF를 이용한 SBX escape” 역시 이러한 유형의 취약점입니다.

② SBX Bypass

SBX Bypass는 Browser Process를 거치지 않고 운영체제 자체를 공격하는 방식입니다. 대표적으로 Windows Kernel의 Local Privilege Escalation(LPE), Device Driver 취약점, 시스템 서비스 취약점 등이 여기에 해당합니다.

Renderer에서 접근 가능한 시스템 콜이나 드라이버를 이용하여 커널 권한을 획득하면 Browser Process를 공격하지 않고도 샌드박스를 우회할 수 있습니다.

물론 Chrome는 Restricted Token, Win32k Lockdown, Process Mitigation Policy 등 다양한 방어 기법을 적용하여 공격 가능한 커널 인터페이스를 최소화하고 있기 때문에 실제 공격 난이도는 매우(x32) 높은 편입니다.

image.png

4. Outro

지금까지 Chrome Sandbox가 어떤 구조로 동작하는지, 그리고 공격자가 어떤 지점을 노리는지 살펴보았습니다. 어찌어찌해서 그 어려운 샌드박스 이스케이프에 성공했다고 해도 단순히 Medium IL의 RCE를 획득한 겁니다.

Renderer RCE를 획득 후 Untrusted IL RCE를 얻고

image.png

Sandbox escape를 해서 Medium IL RCE를 얻어도

조금 과장하면 그냥 내가 원하는 프로그램 하나 실행한 겁니다.

획득하기까지 막대한 시간과 비용이 드는 취약점(값도 그렇고, 인간이 들이는 공수도 그렇고)이 가치 있게 쓰이려면 결국 System IL RCE까지 이어져야 합니다.

JavaScript
      
      
Renderer RCE
      
      ├─────────────┐
                   
SBX Escape      SBX Bypass
(Browser)       (Kernel)
                   
      └──────┬──────┘
             
   Medium / SYSTEM

Pwn2Own이나 실제 Chrome 제로데이에서 여러 개의 CVE가 함께 공개되는 이유도 이 때문입니다. 각각의 취약점이 하나의 체인을 이루어야 비로소 시스템 전체를 장악할 수 있겠죠.

다음 글

다음 글에서는 SBX Escape를 조금 더 깊게 살펴보며, Windows의 ALPC(Advanced Local Procedure Call)를 이용해 Browser Process와 통신하는 구조와 실제 Sandbox Escape 기법을 분석해보겠습니다.

image.png

그리고 시리즈의 마지막에서는 시선을 Chrome에서 Windows Kernel로 옮겨, MDL(Memory Descriptor List) 을 악용한 실제 Windows Kernel LPE 사례를 통해 Renderer에서 시작된 코드 실행이 어떻게 SYSTEM 권한까지 이어지는지 Exploit Chain의 마지막 퍼즐을 함께 맞춰보겠습니다.

image.png

긴 글 읽어주셔서 감사합니다!

Reference.

https://chromium.googlesource.com/chromium/src/+/main/docs/design/sandbox.md

css.csail.mit.edu/6.858/2009/readings/chromium.pdf

https://starlabs.sg/blog/2025/07-fooling-the-sandbox-a-chrome-atic-escape/

chrome://sandbox