DEF CON 33 Review: 포켓몬 GO 안티 치트 메커니즘 분석과 리버싱의 정수
서론: 게임이라는 이름의 보안 전장, 포켓몬 GO
정보보호학을 전공하며 시스템의 내부 로직을 파고드는 일은 설레는 중 하나입니다. 버퍼 오버플로우나 SQL Injection 같은 고전적인 취약점들이 실제 필드에서 어떻게 다뤄지는지 궁금했습니다. 하지만 이론적으로 배우는 ‘정답이 있는 문제’와 현실 세계의 ‘보안 실무’ 사이에는 메우기 힘든 간극이 존재합니다.
이번 DEF CON 33의 “Breakin ‘Em All – Overcoming Pokemon Go’s Anti Cheat Mechanism” 강연을 선택한 이유는 바로 그 지점에 있습니다. 단순히 제가 포켓몬을 좋아하고 아직까지도 포켓몬고를 즐겨하는것만이 이 강의를 선택한 전부는 아닙니다. 이 강연은 글로벌 규모의 서비스가 클라이언트의 무결성을 지키기 위해 얼마나 다층적인 방어막을 구축했는지 그리고 그 로직을 무너뜨리기 위해 리버싱이 어떻게 쓰였는지를 보여주는 완벽한 ‘실전 케이스 스터디’였기 때문에 선택했습니다.
포켓몬 GO의 안티 치트 메커니즘 분석은 단순한 게임 변조를 넘어, 현대 모바일 보안의 핵심 의제들을 포함하고 있습니다
- Protobuf를 이용한 효율적인 데이터 직렬화와 그 이면의 가독성 문제
- SSL Pinning을 통한 통신 채널의 신뢰성 확보
- Native Library 내부에 숨겨진 독자적인 암호화 알고리즘
- 기기 센서 데이터를 활용한 행위 기반 무결성 검증
강연을 시청하는 동안 실무적인 리버싱 기법의 깊이에 정말 이해가 안가면서도, 동시에 그러한 이론들이 실무에서 어떻게 무기로 변하는지 확인하였습니다. 이제 이 컨퍼런스 리뷰를 통해, 한 보안 연구원이 거쳐야 했던 기술적 여정을 저의 시선에서 리뷰해 보고자 합니다.
2. 기술 분석 I
2.1 데이터의 골격: Protobuf의 decode_raw 분석
포켓몬 GO의 서버-클라이언트 통신은 효율성을 극대화하기 위해 Google의 Protocol Buffers(Protobuf)를 채택하고 있습니다. 예전에 배운 XML이나 JSON이 인간이 읽기 편한 텍스트 기반이라면, Protobuf는 기계 친화적인 바이너리 형식입니다. 이는 속도 면에서는 유리하지만, 정의 파일(.proto) 없이는 패킷의 구조를 파악하기 매우 어렵게 만듭니다.
발표자는 .proto 파일이 없는 상태에서 decode_raw 방식을 사용하여 패킷의 스키마를 역추적했습니다. -스키마란? 스키마(Schema)라는 용어는 데이터의 ‘설계도’ 혹은 ‘구조’를 의미합니다. 쉽게 비유하자면, 우리가 택배 상자를 받았을 때 상자 안에 무엇이 들어있는지, 어떤 순서로 배치되어 있는지를 정의해 놓은 목록표와 같습니다.
- Field Number 추론: 바이너리 데이터 스트림에서 각 필드의 번호와 와이어 타입을 식별하고, 반복적으로 나타나는 패턴을 통해 특정 데이터가 위경도 좌표인지 정보를 매핑했습니다.
- 느낀점: 보안 전공자로서 이 과정을 지켜보며 바이트 단위 분석(Byte-level Analysis)의 중요성을 다시금 체감했습니다. 암호화되지 않은 필드라도 구조를 모르면 ‘데이터’는 그저 ‘노이즈’에 불과합니다. 하지만 바이트의 흐름 속에서 특정 오프셋의 값이 변화하는 규칙을 찾아내는 순간 노이즈는 공격의 실마리가 됩니다.
2.2 공간의 정수: S2 Geometry와 Level 15 셀 ID
지구상의 수많은 포켓몬 위치 정보를 효율적으로 요청하기 위해, Niantic은 Google의 S2 Geometry 라이브러리를 사용했습니다. 이는 지구를 힐베르트 곡선(Hilbert Curve) 기반의 64비트 정수 형태인 ‘Cell ID’로 매핑하는 기술입니다. -힐베르트 곡선이란? 힐베르트 곡선(Hilbert Curve)은 수학에서 말하는 ‘공간을 채우는 곡선’의 한 종류입니다. 쉽게 설명하자면, 아주 긴 선 하나를 꼬고 비틀어서 2차원 평면 전체를 빈틈없이 지나가게 만드는 방법입니다. 포켓몬 GO에서 이 알고리즘을 쓴 이유는 “가까운 곳은 데이터상에서도 가깝게 관리하기 위해서”입니다.
- S2 Cell Level 15: 강연에서 가장 핵심적인 포인트는 포켓몬 GO가 Level 15 셀을 기본 데이터 단위로 사용한다는 사실을 발견한 것입니다.
- 데이터 수집 메커니즘: 발표자는 특정 좌표를 입력하면 해당 위치를 포함하는 Level 15 Cell ID를 생성하고, 이를 서버에
GetMapObjects(Request 106) 패킷에 담아 전송했습니다. 서버는 해당 셀 범위 내에 존재하는 포켓몬의 정확한 위경도 정보를 응답합니다. - 공격적 활용: 이 메커니즘을 파악함으로써, 해커들은 실제 이동 없이도 전 세계의 셀 ID를 서버에 전송하는 것만으로 ‘실시간 포켓몬 지도’를 구축할 수 있게 되었습니다.
3. 기술 분석II
3.1 통신 채널의 신뢰성 파괴: SSL Pinning 우회
Niantic은 중간자 공격(MITM)을 방어하기 위해 SSL Pinning을 강력하게 적용했습니다. 이는 클라이언트가 서버의 공개키를 미리 알고 있어 신뢰할 수 없는 인증서가 개입될 경우 통신을 차단하는 기술입니다.
checkServerTrusted후킹: 발표자는 Frida와 Xposed 프레임워크를 활용하여 안드로이드 프레임워크의 SSL 검증 로직을 타겟팅했습니다. 특히checkServerTrusted메서드를 가로채어 무조건 통과시키도록 로직을 변조했습니다.- 메모리 상의 인증서 교체: 단순한 로직 우회를 넘어, 메모리에 로드된 신뢰할 수 있는 인증서 저장소를 직접 조작했습니다. 앱이 자신의 공격자를 ‘신뢰할 수 있는 서버’로 오인하게 만드는 기법은 시스템 해킹의 ‘권한 상승’ 과정과 매우 유사했습니다.
3.2 네이티브 계층의 침투: libniantic_manager.so와 IDA Pro
Java 계층의 방어선을 뚫고 나니, Native Library가 나타났습니다. Niantic은 핵심 로직을 성능과 보안을 위해 C/C++로 작성된 .so 파일에 은닉해 두었습니다.
- IDA Pro를 활용한 정적 분석: 발표자는 IDA Pro를 이용해
libniantic_manager.so를 분석했습니다. 심볼이 제거된 바이너리였기에 특정 오프셋을 기점으로 코드의 흐름을 추적했습니다. - 함수 오프셋 추적: 바이너리 내부의 간접 분기와 함수 포인터 테이블을 분석하며 시그니처 생성 핵심 서브루틴을 식별했습니다. 이는 Pwnable 문제에서 ROP 가젯을 찾는 과정처럼 정교했습니다.
4. 기술 분석III
4.1 무결성의 심장: Unknown6 시그니처와 xxHash
포켓몬 GO 보안의 정점은 Protobuf의 6번 필드, ‘Unknown6’에 있었습니다. 이는 클라이언트가 보낸 전체 패킷이 변조되지 않았음을 증명하는 ‘시그니처’였습니다.
- xxHash 기반의 고속 해싱: 바이너리 분석 결과, 클라이언트는 데이터 스트림을 xxHash 알고리즘을 통해 해싱합니다. 해커들은 알고리즘의 상수를 추적하여 로직을 재현했습니다. -해싱이란? 해싱(Hashing)은 임의의 길이를 가진 데이터를 고정된 길이의 고유한 값(해시값)으로 변환하는 과정을 말합니다. 쉽게 비유하면, 어떤 물건을 가져와도 그 물건만의 ‘지문’이나 ‘디지털 요약본’을 만들어내는 기술이라고 생각하면 됩니다.
- 시드와 타임스탬프: 암호화 과정에서
time함수를 호출하여 얻은 값과 특정 상수를 결합해 시드를 생성하는 로직이 발견되었습니다. 타임라인 분석을 통해 서버가 기대하는 해시값을 생성해내는 과정은 포렌식적 분석력이 필요한 순간이었습니다.
4.2 암호화 연쇄: AES-CBC 모드와 IV의 활용
해시된 데이터는 그대로 전송되지 않고 AES-CBC(Cipher Block Chaining) 모드로 암호화되었습니다.
- Chain 구조 분석: 발표자는 메모리 덤프를 통해 32바이트의 키와 초기화 벡터가 생성되는 오프셋을 특정했고, 각 블록이 어떻게 연쇄적으로 암호화되는지 완벽하게 복원했습니다.
4.3 행위 기반 검증: 센서 데이터 무결성
가장 놀라운 부분은 Unknown6 내부에 포함된 기기 센서 데이터였습니다. Niantic은 가속도계, 자이로스코프, 고도계 등의 미세한 변화를 수집하고 있었습니다.
- Anti-Bot Mechanism: 이는 “기기가 지표면에서 인간의 보폭과 관성에 따라 실제로 움직이고 있는가?”를 검증하기 위한 텔레메트리 데이터였습니다. 해커들은 이 방대한 데이터 중 서버가 실제로 검증하는 필수 필드를 구분해냈습니다.
4.4 14,000줄의 경이: 로직의 완전한 복제
결국 전 세계의 리버서들은 협업을 통해 14,000줄에 달하는 C 코드로 이 모든 과정을 복제해냈습니다. 아무리 견고한 암호화로 무장하더라도 실행 주도권이 공격자에게 있는 클라이언트 사이드 보안은 결국 시간 문제라는 점을 보여주었습니다.
5. 결론 및 회고
보안의 지능적 설계의 필요성
이번 강연은 보안이란 단순히 시스템을 ‘잠그는 것’이 아니라, 공격자의 비용을 극대화하는 지능적인 설계라는 사실을 일깨워주었습니다. 또한 강의를 들으며 실전 리버싱의 현장은 훨씬 더 유연하고 집요하다고 생각이 들었습니다. 공격자가 분석에 투입해야 할 시간과 자원을 기계적으로 늘려 공격의 실익을 상쇄시키는 것 또한 현대 보안 엔지니어링의 핵심임을 깨달았습니다.