- Lupin과 Justin은 Google의 2024 Las Vegas LLM bugSWAT에서 Gemini 프리뷰의 Python 샌드박스를 조사해
/usr/bin/entry/entry_point와 내부 파일 구조를 추출했고, 이 취약점으로 Most Valuable Hacker를 수상함 - 샌드박스는 gVisor와 GRTE 기반으로 외부 네트워크가 막혀 있었지만, 사용자 코드가
os모듈로 파일시스템을 순회할 수 있어 내부 바이너리를 콘솔 출력 청크로 빼낼 수 있었음 - 579MB짜리
entry_point는 직접 출력하면 타임아웃이 발생해seek()와 base64 인코딩으로 10MB 단위 청크를 만들고, Caido Automate로 반복 요청해 로컬에서 재조립함 - Binwalk 분석에서
google3디렉터리와 Gemini 샌드박스 관련 Python 코드가 드러났고, 공개 승인된 코드와 달리classification.proto및 여러 보안 proto 정의는 의도치 않게 포함된 기밀 내부 정보였음 - 샌드박스가 Google Flights 같은 도구와 RPC로 연결되는 구조와 더 권한 있는 에이전트 샌드박스 접근 가능성이 확인됐지만, 의심한 내부 파일 읽기 핸들러는 RPC로 사용할 수 없고 외부에서만 호출 가능했음
bugSWAT 2024와 Gemini 프리뷰 접근
- Lupin과 Justin은 2024년 Las Vegas의 Google LLM bugSWAT 이벤트에서 Gemini의 다음 업데이트 프리뷰에 조기 접근함
- Google 팀은 새 기능과 의도된 동작을 담은 문서를 제공했고, 연구자들의 목표는 공격자 관점에서 기능을 탐색하고 테스트하는 것이었음
- 간단한 프롬프트
run hello world in python3로 시작하자 Gemini는 코드를 생성하고 인터페이스에 Run in Sandbox 버튼을 제공함 - 이 취약점 연구 결과로 두 사람은 해당 Las Vegas bugSWAT에서 Most Valuable Hacker 타이틀을 받음
Gemini Python 샌드박스의 기본 구조
- 당시 Gemini는 AI가 생성한 Python 코드나 사용자가 직접 작성한 스크립트를 Gemini 환경 안에서 실행하는 Python Sandbox Interpreter를 제공함
- 샌드박스는 Google의 gVisor와 GRTE(Google Runtime Environment) 기반으로 구성됨
- gVisor는 컨테이너화된 애플리케이션과 호스트 운영체제 사이에서 시스템 호출을 가로채는 사용자 공간 커널임
- 전통적인 OS 수준 격리에만 의존하지 않고 최소화된 커널 기능 하위 집합을 구현해 공격 표면을 줄임
- 연구자들은 gVisor 샌드박스 탈출을 별도의 고난도 문제로 봤고, 샌드박스 탈출은 최대 $100k 바운티 대상이 될 수 있었음
- 이번 접근은 샌드박스를 탈출하는 대신, 샌드박스 내부에 외부로 노출되면 안 되는 데이터가 있는지 찾는 방식이었음
- 핵심 제약은 샌드박스가 커스텀 컴파일된 Python 바이너리만 실행할 수 있다는 점이었음
파일시스템 매핑과 entry_point 발견
- 프런트엔드에서 Python 코드를 완전히 다시 작성해 샌드박스에서 임의 버전을 실행할 수 있었음
- 셸은 띄울 수 없었지만, 커스텀 Python 바이너리에
os모듈이 포함돼 있어 파일시스템 매핑이 가능했음 - 연구자들은 재귀적으로 파일과 디렉터리를 나열하고 크기와 권한을 출력하는 Python 함수를 작성함
lslR("/usr")호출 결과/usr/bin/entry/entry_point에 있는 바이너리 파일을 발견함- 이 파일은 크기가 579MB였고, 이후 분석의 핵심 대상이 됨
네트워크 없이 바이너리를 유출한 방식
entry_point를 바로 base64 인코딩해 프런트엔드에 출력하려 하자 샌드박스가 멈추고 결국 타임아웃됨- TCP, HTTP, DNS를 통한 외부 유출 시도는 모두 실패했고, 샌드박스는 외부 네트워크와 완전히 격리된 것처럼 보였음
- 외부 호출이 막힌 상황에서 연구자들은 콘솔 출력으로 바이너리를 조각내 유출하는 방식을 선택함
seek()로 바이너리 위치를 이동하며 읽고, base64로 인코딩한 뒤 10MB 단위 청크로 출력함- Caido를 프록시로 사용해 샌드박스 호출 요청과 결과를 잡고, Automate 기능으로 요청을 반복 전송함
- Automate는 요청을 대량으로 보내고 특정 파라미터를 빠르게 바꿀 수 있는 기능임
- 모든 base64 청크를 모은 뒤 로컬에서 전체 파일을 재구성함
entry_point 분석 결과
file명령은 해당 파일을ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)형식의 동적 링크 바이너리로 식별함strings명령 출력에는 Google 내부 저장소를 가리키는 google3 참조가 여러 번 등장함- 이 참조들은 내부 데이터 경로와 코드 조각의 존재를 시사했고, 바이너리에 Google 독점 소프트웨어 흔적이 들어 있음을 보여줌
- Binwalk가 결정적 단서를 제공함
- 바이너리 안에서 전체 파일 구조를 추출함
- 추출 결과 샌드박스 레이아웃과 내부 구성요소가 드러남
google3 디렉터리와 Gemini 관련 Python 코드
- Binwalk로 추출한 디렉터리 안에는
google3디렉터리가 있었고,assistant,base,devtools,file,google,net,pyglib,testing,third_party,util같은 하위 디렉터리가 포함됨 assistant디렉터리에는 YouTube, Google Flights, Google Maps 같은 도구 요청 처리에 쓰이는 RPC 관련 Gemini 코드가 발견됨- 특히
google3/assistant/boq/lamda/execution_box/아래에는 샌드박스 실행, 이미지 처리, 도구 사용, RPC 인터페이스와 관련된 Python 파일들이 있었음 google3/assistant/boq/lamda/execution_box/images/py_interpreter.py에는 무단 스크립트 덤프 탐지를 위한 문자열로 보이는 코드가 포함됨- 문자열은
"3AVp#dzcQj$U?uLOj+Gl]GlY<+Z8DnKh"였음
- 문자열은
- 이후 검토에서 이 Python 코드의 내부 Google3 포함은 Google Security Team이 출시 전 공개 노출을 승인한 선택으로 정리됨
- 해당 코드에는 덤프 방지 메커니즘처럼 보이는 요소가 있었지만, 공개 노출 자체는 승인된 상태였음
샌드박스와 Google 도구 RPC 구조
- 더 깊은 분석에서 샌드박스가 Google Flights 같은 Google 서비스 데이터를 가져오기 위해 외부 Google 서버와 통신하는 구조가 확인됨
- 이 통신은
google3.assistant.boq.lamda.execution_box.sandbox_interface의 Python 클래스를 통해 구현됨 _set_reader_and_writer같은 함수는 RPC용 reader와 writer 핸들을 설정함- 기본 동작은
/dev/fd/3과/dev/fd/4를 사용하는 방식으로 나타남
- 기본 동작은
run_tool(name, operation_id, parameters)는 도구 이름, 작업 ID, 파라미터를 받아RunToolRequest를 만들고 RPC 요청으로 전달함- 함수들은 데이터를 protobuf 호환 형식으로 직렬화한 뒤 로컬 파일 디스크립터
5에 쓰고, 응답은 파일 디스크립터7에서 읽는 방식으로 동작함 - 대형 바이너리에서 찾은 proto를 이용해 연구자들은 RPC 서버와 주고받는 메시지를 만들고 Google 도구를 직접 호출할 수 있었음
에이전트 샌드박스와 권한 차이
- 모든 샌드박스가 같은 Google 서비스 집합에 접근할 수 있는 것은 아니었음
- 차이는 샌드박스가 프런트엔드에서 Python 소스 코드를 실행하기 위해 생성됐는지, Google Agent가 생성했는지에 따라 달라졌음
- Google 팀은 Gemini가 기반으로 삼은 연구로 REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS를 보여줌
- ReAct 접근은 언어 모델이 추론 흔적을 생성하고 특정 행동을 실행하는 과정을 번갈아 수행하는 구조임
- 모델은 문제를 해결하며 계획을 만들고 외부 소스와 상호작용해 필요한 데이터를 가져옴
- 질의응답, 사실 검증, 텍스트 기반 게임, 웹 탐색 같은 작업에 적용되는 프레임워크로 소개됨
- 사용자가 Toronto와 New York 사이의 가장 이른 항공편을 묻는 경우 Gemini는 대략 다음 흐름을 가질 수 있음
- 사용자의 의도를 항공편 검색으로 해석함
- Google Flights 도구에 연결할 Python 코드를 계획함
- YYZ에서 JFK까지 오늘부터 다음 주까지의 항공편을 찾고 날짜순으로 정렬하는 코드를 생성함
- 필요한 권한을 가진 샌드박스를 생성하고 코드를 실행함
- 출력 결과를 처리해 사용자에게 응답함
보조 프롬프트 인젝션 실험과 한계
- 연구자들은 Gemini의 계획 단계에 2차 프롬프트 인젝션을 걸어 더 권한 있는 샌드박스에 접근할 수 있는지 실험함
- Google Security Team의 도움으로 테스트한 결과, 생성 시드와 temperature 같은 확률적 요소에 따라 더 권한 있는 샌드박스로 보이는 환경에 가끔 접근할 수 있었음
- 여기서 더 권한 있는 샌드박스는 확장 기능에 접근하는 두 개의 새 파일 디스크립터를 사용할 수 있는 환경을 뜻함
- 파일 디스크립터 자체는 항상 존재하지만 항상 실제로 listen하는 것은 아니었음
- 에이전트가 샌드박스를 호출할 때는 Google 서비스 확장 호출을 감시해 API와 상호작용할 수 있음
- Python 인터프리터에서 접근하면 해당 확장 기능은 접근할 수 없었음
- 연구자들은 특정 메시지 핸들러가 Google 내부 인프라에서 파일 읽기를 허용할 수 있다고 보고 P0 가능성을 기대함
- Google Security Team 검토 결과, 해당 의심 핸들러는 RPC로 사용할 수 없고 외부에서만 호출 가능한 것으로 확인됨
- 실험은 제한적이었지만, 코드 실행은 다음 가능성을 열 수 있었음
- Reliability: 코드를 실행하면 행동을 더 일관되게 트리거할 수 있음
- Chaining/Complexity: 여러 도구 제어나 파라미터 조정을 텍스트보다 복잡하게 구성할 수 있음
- Tool Output Poisoning: 도구 출력 조작을 더 효과적으로 시도할 수 있음
- Leaks: 환경의 숨겨진 부분이 노출되면 추가 이점을 줄 수 있음
실제로 노출된 proto 파일
- 연구자들은 여러 방식으로 proto 파일을 유출할 수 있음을 확인함
- proto 파일은 Protocol Buffer 파일로, 시스템의 메시지 구조와 정보 교환 방식을 정의하는 청사진 역할을 함
strings entry_point > stringsoutput.txt를 실행한 뒤Dogfood를 검색해 내부 proto 일부를 찾아냄- 추출된 일부 내용에는 매우 민감한 proto의 메타데이터 설명이 포함됨
- 사용자 데이터 자체는 포함하지 않았음
- Google이 사용자 데이터를 분류하는 데 쓰는 내부 카테고리였음
Dogfood는 Google에서 공개 출시 전 자사 제품과 프로토타입을 내부적으로 사용해 테스트하고 개선하는 관행을 뜻함- 노출된 파일 중 하나는
privacy/data_governance/attributes/proto/classification.proto였음- 이 파일은 Google 내부에서 데이터가 어떻게 분류되는지 다룸
- 관련 문서 참조도 포함됐지만, 해당 문서들은 기밀이며 공개 접근 대상이 아니었음
내부 보안 proto 정의 노출
- 같은
strings출력에서 공개되지 않아야 할 여러 내부 proto 파일도 드러남 cat stringsoutput.txt| grep '\.proto' | grep 'security'명령으로 다음과 같은 민감한 파일 경로가 나타남security/thinmint/proto/core/thinmint_core.protosecurity/thinmint/proto/thinmint.protosecurity/credentials/proto/authenticator.protosecurity/data_access/proto/standard_dat_scope.protosecurity/loas/l2/proto/credstype.protosecurity/credentials/proto/end_user_credentials.protosecurity/loas/l2/proto/usertype.protosecurity/credentials/proto/iam_request_attributes.protosecurity/util/proto/permission.protosecurity/loas/l2/proto/common.protoops/security/sst/signalserver/proto/ss_data.protosecurity/credentials/proto/data_access_token_scope.protosecurity/loas/l2/proto/identity_types.protosecurity/credentials/proto/principal.protosecurity/loas/l2/proto/instance.protosecurity/credentials/proto/justification.proto
- 바이너리 문자열에서
security/credentials/proto/authenticator.proto를 확인하면 해당 데이터가 실제로 노출됐음을 볼 수 있었음
왜 proto가 바이너리에 들어갔나
- Google Security Team은 샌드박스 안의 내용을 검토했고 공개 disclosure에 대한 승인을 준 상태였음
- 그러나 샌드박스 바이너리 컴파일 빌드 파이프라인에는 내부 규칙 집행에 필요할 수 있다고 판단되면 security proto 파일을 바이너리에 추가하는 자동 단계가 있었음
- 이번 경우에는 그 단계가 필요하지 않았지만, 결과적으로 매우 기밀인 내부 proto가 의도치 않게 포함됨
- 연구자들은 Google이 이런 proto를 공개되면 안 되는 고기밀 정보로 취급한다는 점을 알고 있었기 때문에 이를 버그로 보고함
- 타깃 조직의 비즈니스 규칙과 보안 우선순위를 깊이 이해해야 이런 미묘한 노출을 식별하고 보고할 수 있음
결론과 실무적 시사점
- 출시 전 첨단 AI 시스템은 기능 동작뿐 아니라 내부 산출물까지 철저히 테스트해야 함
- 단순해 보이는 샌드박스도 여러 확장 기능과 연결되면 예상치 못한 노출 경로가 생길 수 있음
- 여러 구성요소가 함께 동작할 때 작은 누락이 새로운 문제 경로를 만들 수 있음
- 이번 사례에서는 공개 승인된 내부 코드와 의도치 않게 포함된 기밀 proto가 구분됐고, 후자가 실제 보안 보고의 핵심이 됨
- AI 에이전트, 샌드박스 실행, 도구 호출, 내부 RPC가 결합된 환경에서는 실행 격리뿐 아니라 샌드박스 내부 자산과 빌드 산출물까지 검토해야 함