수천만 명의 사람들이 Pokémon Go의 새로운 세계를 탐험하고 있습니다. 그런데 이 사용자들 중 상당수는 실제 사람이 아니라 자동화된 에이전트, 즉 봇인 것으로 드러났습니다. 게임을 플레이하는 봇은 새로운 현상이 아니지만, Pokémon Go는 봇의 새로운 활용 사례를 보여 줍니다. 이러한 봇은 자동화된 트래픽으로 Pokémon Go 서버에 과부하를 일으켜 모두의 즐거움을 방해하기 시작했습니다. Pokémon Go는 모바일 API에서 자동화된 공격과 방어가 어떻게 이루어지는지를 보여 주는 완벽한 사례입니다. Shape에서는 매일 이러한 유형의 공격에 대응하고 있기에, Pokémon Go API 공격에서 어떤 일이 벌어졌는지 자세히 살펴보기로 했습니다.
Pokémon Go API 공격
Niantic은 최근 블로그 게시물을 통해 봇이 자동화된 트래픽을 생성하면서 일으킨 문제를 자세히 설명했습니다. 이 문제는 실제로 중남미 지역 출시에도 차질을 빚게 했습니다. 게시물에 포함된 차트를 보면 Niantic이 8월 3일 오후 1시(태평양 표준시)에 자동화 대응 조치를 시행한 이후 공간 쿼리 트래픽이 크게 감소했습니다. 자동화된 트래픽은 실제 사용자들이 발생시킨 트래픽의 약 두 배에 달했던 것으로 보입니다. 최근 몇 주 동안 Pokémon Go 서버에 심각한 과부하가 걸린 것도 무리가 아닙니다.

그림 1. Niantic이 스크레이퍼를 차단하기 시작한 이후 공간 쿼리 트래픽이 50% 이상 감소했습니다. 출처: Niantic 블로그 게시물
포켓몬 봇 알아보기
포켓몬 봇에는 두 가지 유형이 있습니다. 첫 번째 유형은 일반적인 게임 플레이를 자동화하는 봇으로, 다른 게임 앱에서도 흔히 문제가 됩니다. 돌아다니거나 포켓몬을 잡는 등의 활동을 자동으로 수행합니다. 이러한 봇의 예로는 MyGoBot과 PokemonGo-Bot이 있습니다. 하지만 Pokémon Go는 포켓몬의 위치를 알려 주는 트래커(Tracker) 또는 매퍼(Mapper)라는 새로운 유형의 봇 개발을 촉진했습니다. 이러한 봇은 Pokevision과 Go Radar 같은 Pokémon Go 지도 서비스를 구동합니다.
Pokémon Go 봇의 작동 방식
모바일 API 봇은 모바일 앱과 백엔드 서버(이 경우에는 Niantic의 서버) 간의 통신을 모방하는 프로그램입니다. 봇은 어떤 작업이 수행되었는지 서버에 전달하고 서버의 응답을 받아 처리합니다.
그림 2는 특정 위치에서 발자국 3개 거리 이내에 있는 포켓몬을 표시한 Pokémon Go 지도 스크린샷입니다. 이를 구현하기 위해 봇 제작자는 일반적으로 다음 단계를 따릅니다:
- 모바일 앱과 백엔드 서버 간의 통신 프로토콜을 리버스 엔지니어링합니다. 봇 제작자는 게임을 플레이하면서 앱과 서버 간의 통신 내용을 캡처하고 프로토콜 형식을 분석합니다.
- 백엔드 서버에 일련의 ‘정상적인’ 요청을 보내 작업을 수행하는 프로그램을 작성합니다. 이 경우 실제로 해당 장소까지 걸어가지 않고도 특정 GPS 좌표를 지정해 한 번만 요청하면 근처 포켓몬의 위치를 확인할 수 있습니다. 봇이 해결해야 할 과제는 서버의 탐지를 피하면서 실제 사람처럼 보이는 것입니다.
- Google 지도와의 통합 같은 관련 기능을 제공하거나, 사용자를 위해 봇 자체의 지도 기능을 포함하세요.

그림 2. Pokémon Go 지도 스크린샷
모바일 앱 크랙 및 방어
Pokémon Go 앱을 예로 들어, 리버스 엔지니어링을 통해 모바일 앱의 비밀을 밝혀내는 크래킹 과정을 살펴보겠습니다. 공격자들은 주로 Pokémon Go의 Android 앱을 악용했으므로, Android 앱의 크래킹과 방어에 초점을 맞추겠습니다.
프로토콜 리버스 엔지니어링
Pokémon Go 앱과 백엔드 서버는 ProtoBuf를 사용해 SSL을 통해 통신합니다. ProtoBuf는 네트워크에서 전송되는 데이터 형식을 정의합니다. 예를 들어, 다음은 플레이어 통계에 대한 ProtoBuf 정의의 일부입니다:

Pokémon Go는 불과 2주 만에 POGOProtos에 의해 리버스 엔지니어링되어 온라인에 공개되었습니다. 어떻게 이렇게 빨리 가능했을까요? 초기에는 Niantic이 인증서 고정을 사용하지 않았기 때문입니다.
인증서 고정은 중간자 공격을 방지하는 데 흔히 사용되는 방식입니다. 간단히 말해, 모바일 앱은 앱 자체에 내장된 서버 인증서만 신뢰합니다. 인증서 고정으로 보호하지 않으면 공격자는 Mitmproxy 또는 Fiddler 같은 프록시를 손쉽게 설정하고 자신이 만든 인증서를 휴대폰에 설치할 수 있습니다. 그런 다음 휴대폰의 트래픽이 프록시를 거치도록 설정하여 Pokémon Go 앱과 Niantic 서버 간의 트래픽을 가로채 분석할 수 있습니다. 이를 쉽게 해 주는 Pokémon Go 전용 프록시 도구도 있는데, 바로 pokemon-go-mitm입니다.
7월 31일, Niantic은 서버와 Pokémon Go 앱 모두에 큰 변화를 적용했습니다. 인증서 고정 보호 기능이 적용된 Pokémon Go 0.31.0이 출시되었습니다. 안타깝게도 이미 비밀이 알려진 뒤였고, 통신 프로토콜도 GitHub에 공개된 상태였습니다. 또한 인증서 고정을 올바르게 구현하는 일이 항상 쉬운 것은 아닙니다. 이후 섹션에서는 공격자가 인증서 고정을 우회하기 위해 흔히 사용하는 몇 가지 기법을 살펴보겠습니다.
APK 정적 분석
The Android 애플리케이션 패키지(APK)는 Android에서 모바일 앱을 설치하는 데 사용하는 패키지 파일 형식입니다. Android 앱은 주로 Java로 작성되며, Java 코드는 dex 형식으로 컴파일되어 apk 파일로 빌드됩니다. 또한 Android 앱은 네이티브 코드로 작성된 공유 라이브러리(Android NDK)를 호출할 수도 있습니다.
Dex 파일은 Baksmali와 같은 도구를 사용하면 SMALI 언어로 쉽게 디스어셈블할 수 있는 것으로 알려져 있습니다. 그런 다음 dex2jar와 jd-gui 같은 도구를 사용해 dex 파일을 읽기 쉬운 Java 코드로 추가 디컴파일할 수 있습니다. 공격자들은 이러한 기법을 사용하여 Pokémon Go Android 앱(버전 0.29.0 및 0.31.0)을 Java 코드로 디컴파일했습니다. 아래에 표시된 예제 코드는 com.nianticlabs.nia.network.NianticTrustManager 클래스의 인증서 고정을 구현합니다.

애플리케이션 소스 코드가 노출되면 리버스 엔지니어링은 식은 죽 먹기가 됩니다. Pokemon Go Xposed는 100줄도 안 되는 Java 코드로 Pokémon Go 앱을 속여 MITMProxy의 인증서가 Niantic의 정품 인증서라고 믿게 만들었습니다.
Pokemon Go Xposed는 어떻게 이를 해냈을까요? 아주 간단합니다. 이 도구는 위 코드 조각에 언급된 checkServerTrusted 함수 호출을 후킹하기만 합니다. 이 후크는 함수의 첫 번째 매개변수인 chain의 값을 Niantic의 인증서 값으로 변경합니다. 즉, 프록시가 어떤 비인가 인증서를 사용하더라도 Pokémon Go 앱은 해당 인증서를 신뢰하도록 속게 됩니다.
공격자가 디스어셈블 및 정적 분석을 수행하기 어렵게 만드는 데 도움이 되는 도구는 많습니다. ProGuard와 DexGuard는 Java 코드와 dex 파일에 난독화를 적용하는 도구입니다. 난독화를 적용하면 디컴파일된 상태에서도 코드를 읽기 어려워집니다. 또 다른 방법은 Android 패커를 사용하여 Android 앱의 원본 classes.dex 파일을 암호화하는 것입니다. 암호화된 dex 파일은 런타임에 메모리에서 복호화되므로 대부분의 공격자가 정적 분석을 수행하기가 불가능하지는 않더라도 매우 어려워집니다. 네이티브 라이브러리를 사용하는 것도 앱 리버스 엔지니어링의 난이도를 크게 높이는 방법입니다.
네이티브 라이브러리 리버스 엔지니어링
가장 흥미진진했던 pokemongodev 해커들과 Niantic 간의 쫓고 쫓기는 공방은 특정 위치에서 주변 포켓몬을 찾기 위해 전송하는 지도 요청의 서명에 포함된 “Unknown6”라는 필드를 둘러싸고 벌어졌습니다. “Unknown6”는 리버스 엔지니어링된 protobuf에서 용도가 밝혀지지 않은 필드 중 하나입니다. 처음에는 Unknown6에 어떤 값을 넣어도 상관없이 Niantic 서버가 그대로 받아들였습니다. 하지만 08/03 오후 1시(PT)부터 모든 Pokémon Go 봇이 갑자기 포켓몬을 전혀 찾지 못하게 되었고, 결국 그림 1과 같이 쿼리 수가 크게 감소했습니다.
이후 해커들은 프로토콜에서 “Unknown6” 필드가 중요하다는 사실을 알아차렸고, 처음에는 Unknown6가 요청의 무결성을 검증하기 위한 일종의 다이제스트나 HMAC일 것으로 추정했습니다. 이로 인해 pokemongodev 커뮤니티에서 엄청난 관심이 쏟아졌고, 이 수수께끼의 필드를 해독하기 위해 “Unknown6” 팀이 빠르게 결성되었습니다. Discord 채널은 프로그래머와 비프로그래머 모두의 폭넓은 관심으로 인해 비공개로 전환되었지만, 실시간 업데이트 채널을 통해 해독 작업의 진행 상황이 모두에게 계속 공유되었습니다. 3일 5시간이 지난 08/06 오후, Unknown6 팀은 승리를 선언하며 주변의 포켓몬을 다시 검색할 수 있게 된 업데이트된 Pokémon Go API를 공개했습니다.
해킹 세부 사항에 대한 기술 문서는 아직 공개되지 않았지만, 포럼과 실시간 업데이트에서 관련 도구와 기술이 다수 언급되었습니다. IDA-Pro는 Hex-Rays에서 개발한 전문 도구로, 네이티브 라이브러리의 ARM 코드를 디스어셈블할 수 있으며, 새로운 Hex-Rays 디컴파일러는 바이너리 코드 파일을 C 스타일 형식으로 디컴파일할 수 있습니다. 이러한 도구를 사용하면 공격자는 모바일 앱과 해당 라이브러리를 런타임에 디버깅하는 동적 분석을 수행할 수 있습니다. 물론 이처럼 강력한 도구를 사용하더라도 바이너리 프로그램을 리버스 엔지니어링하는 작업은 여전히 매우 어렵습니다. 의도적인 난독화가 전혀 없어도 디스어셈블되거나 디컴파일된 코드는 이미 이해하기 어렵고, 코드의 규모도 대개 방대합니다. 이 작업이 얼마나 복잡하고 예측하기 어려운지를 보여주는 사례로, 실시간 업데이트 채널과 이후 진행된 인터뷰에서는 “Unknown6”의 암호화 함수는 몇 시간 만에 식별했지만, 팀이 “Unknown22”라는 또 다른 필드를 분석하는 데 훨씬 더 많은 시간을 들였으며, 결국 이 필드는 Unknown6와 관련이 없는 것으로 밝혀졌다고 설명했습니다.
따라서 난독화는 네이티브 라이브러리를 보호하는 데 여전히 실질적으로 많은 이점을 제공합니다. 바이너리에 높은 수준의 난독화를 적용하면 리버스 엔지니어링의 난이도가 몇 자릿수나 높아질 수 있습니다. 하지만 Windows와 Windows 애플리케이션의 시리얼 코드가 수없이 크랙된 사례에서 알 수 있듯이, 의지가 강한 모바일 크래커들은 종종 크랙에 성공합니다.
서버 측 보호
서버 측 방어는 클라이언트 측 방어와 완전히 다른 방식으로 작동합니다. 다음은 Pokémon Go의 모바일 API를 보호하기 위해 사용되는 몇 가지 기법입니다.
요청 속도 제한
속도 제한은 자동화된 트래픽을 차단하거나 적어도 늦추기 위해 흔히 사용되는 방법입니다. 초기에는 포켓몬 스캐너가 초당 수십 건의 요청을 보내고 수십 개의 셀을 스캔하여 모든 포켓몬을 찾아낼 수 있었습니다.
7월 31일, Niantic은 요청 속도 제한 보호 조치를 추가했습니다. 한 계정에서 약 5초 이내에 여러 건의 지도 요청을 보내면 Niantic 서버는 첫 번째 요청만 수락하고 나머지는 무시했습니다. 공격자들은 이러한 속도 제한에 대응해 다음과 같은 방법을 사용했습니다. a) 스캔 프로그램의 지도 요청 사이에 5초의 지연 시간 추가 b) 여러 계정과 여러 스레드를 사용해 속도 제한 우회
Pokémon Go의 경우, 속도 제한을 적용하자 자동화 공격의 또 다른 전장인 자동 계정 생성이 열렸을 뿐입니다. 공격자들은 속도 제한이 지나치게 공격적인 스크레이퍼나 초보 공격자의 자동화를 통제하는 데 유용한 기본 기법이기는 하지만, 고도화된 공격자가 자동화된 요청을 통과시키는 것까지 막지는 못한다는 사실을 빠르게 알아냈습니다.
IP 차단
IP 차단은 표준 네트워크 방화벽이나 웹 애플리케이션 방화벽 (WAF)에서 의심스러운 IP의 요청을 차단하는 데 사용하는 전통적인 기법입니다. IP 평판을 추적하는 데이터베이스가 많이 있으며, 방화벽과 WAF는 이러한 정보를 주기적으로 가져올 수 있습니다.
일반적으로 IP 기반 차단은 위험하고 효과적이지 않습니다. 트래픽이 많다는 이유만으로 IP를 무작정 차단하면 대학이나 기업의 NAT를 차단하게 될 수 있습니다. 한편, 많은 Pokémon 봇이나 스캐너는 가정용 동적 IP 주소를 사용할 수 있습니다. 이러한 IP는 ISP 고객들이 공유하므로, 특정 IP를 장기간 차단하면 정상적인 플레이어까지 접속하지 못할 수 있습니다.
Amazon Web Services(AWS)와 Digital Ocean 같은 호스팅 서비스 역시 공격자가 가상 머신과 새로운 IP를 확보하는 수단입니다. 공격자는 도난당한 신용 카드를 사용해 이러한 리소스를 무료로 얻을 수도 있습니다. 하지만 정상적인 사용자가 웹을 탐색하거나 게임을 플레이하기 위해 호스팅 서비스를 이용하는 일은 없으므로, 호스팅 서비스의 IP를 차단하는 것은 안전한 방어 수단이며 서버 측에서 흔히 사용됩니다. Niantic은 이 포럼 게시물에 따라 AWS의 IP를 차단하기로 결정할 수 있습니다.
행동 분석
행동 분석은 일반적으로 다른 방어 체계를 우회할 수 있는 지능형 공격자에 맞서는 최후의 방어선입니다. 봇은 인간과 매우 다른 행동 양상을 보입니다. 예를 들어, 실제 사람은 게임을 연중무휴 24시간 플레이하거나 1초 만에 포켓몬 5마리를 잡을 수 없습니다. 행동 분석은 유망한 접근 방식으로 보이지만, Pokémon Go처럼 방대한 데이터량을 처리할 수 있는 정확한 탐지 시스템을 구축하는 것은 쉽지 않은 일입니다.
Niantic은 최근 GPS 스푸핑을 사용해 ‘순간이동’(즉, 불가능할 정도로 빠른 속도로 갑자기 이동)하는 부정행위자에게 소프트 밴을 적용했습니다. 오탐 가능성 때문에 ‘소프트 밴’을 적용한 것으로 보입니다. 가족끼리 계정을 공유하기도 하고 GPS 측정값이 부정확할 수도 있어, 일부 정상적인 이용 사례가 봇처럼 보일 수 있기 때문입니다.
2016년 8월 12일경, Niantic은 웹사이트에 공지를 게시하고, 서비스 약관을 위반할 경우 Pokémon Go 계정이 영구 정지될 수 있다고 밝혔습니다. 봇을 겨냥한 여러 계정 정지 규칙도 비공식적으로 공개되었습니다. 예를 들어, Pokémon 과다 포획 규칙에 따라 하루에 Pokémon을 1,000마리 넘게 잡은 계정은 정지됩니다. 또한 Niantic은 정상적인 플레이어들에게 부정행위자나 부적절한 플레이어를 신고하도록 권장합니다.
저희의 경험에 따르면 행동 모델링 기반 탐지는 매우 효과적일 수 있지만, 기술적 또는 경제적인 이유로 자체 구축이 어려운 경우가 많습니다. Niantic이 블로그 게시물에서 언급했듯이, “이 문제에 대응하는 데에도 기회비용이 발생합니다. 개발자는 새로운 기능을 개발하는 대신 이 문제를 통제하는 데 시간을 써야 합니다.” 더 큰 문제는 봇넷과 일반적인 방어 체계를 우회하도록 설계된 기타 도구로 무장한 집요하고 기술에 능숙한 공격자에 맞서 방어 기술을 구축하려면 고도로 전문화된 다양한 역량과 막대한 개발 노력이 필요하다는 점입니다.
게임은 아직 끝나지 않았다
Pokémon Go가 계속해서 플레이어들의 사랑을 받는 한, 봇 제작자와 Niantic 간의 공방도 계속될 것입니다. 자동화된 트래픽에 대한 방어는 게임 업계뿐 아니라 모든 산업이 직면한 과제입니다. 은행, 항공사, 소매업체의 앱에서도 이와 유사한 공격과 방어가 벌어지고 있으며, 여기에는 몇 마리의 잠만보를 잃는 것보다 훨씬 더 큰 이해관계가 걸려 있습니다. 원치 않는 자동화 트래픽으로 인해 고객과 사용자가 서비스에 접근하지 못하게 되면, 봇과 관련 공격 도구는 기업에 결코 가볍게 넘길 문제가 아닙니다.
작성자 소개
관련 블로그 게시물
성평등을 향한 여정: 사이버 보안 분야에서 성공적인 커리어를 개척하는 방법에 관한 Jenn Gile과의 Q&A
F5의 ‘성평등을 향한 여정’ 시리즈 네 번째 Q&A에서는 Rachael Shah와 NGINX 제품 마케팅 책임자 Jenn Gile이 사이버 보안 직종에 대한 오해를 바로잡고, 사이버 보안 분야의 성별 격차를 해소하기 위한 조언과 그 이점에 대해 이야기합니다.
TLS 검사에서 피터 파커 원칙 다루기
“큰 힘에는 큰 책임이 따른다.” 볼테르와 처칠도 이와 비슷한 말을 남겼지만, 이 문구는 스파이더맨 코믹스에서 벤 삼촌의 말로 가장 널리 알려져 있습니다. 물론 이 문구가 문화적으로 널리 통용되는 이유 중 하나는 TLS 검사를 비롯해 수많은 상황과 주제에 적용할 수 있기 때문입니다.
Venafi와 F5를 통한 머신 아이덴티티 보호
‘머신 아이덴티티’란 간단히 말해 자동화된 프로세스가 자신의 신원을 식별할 수 있도록 하고, 다른 자동화 시스템과 프로세스가 관련 리소스에 적절한 수준의 접근 권한을 부여하도록 하는 방법을 의미합니다. 이 개념 자체는 새로운 것이 아닙니다. 비교적 새로운 점은 이를 구현해야 하는 규모입니다.
마이너와 미니언: 데이터 유출만이 비용을 초래하는 것은 아닙니다
물론 데이터 유출은 더 큰 비용을 초래할 수 있고(적어도 지금은), 실패 사실을 세상에 드러낼 수밖에 없게 합니다(통지 의무가 있으니까요). 하지만 보안을 단순히 데이터 노출 문제로만 봐서는 안 됩니다. 요즘은 데이터가...
내 클라우드에서 나가!
F5의 Jay Kelley가 전하는 최신 소식에는 Microsoft Office 365용 신규 ID 및 액세스 솔루션을 배포할 때 고려해야 할 사항이 정리되어 있습니다.
Shift(웹 앱) 보안 레터
웹 앱 보안을 개발 초기 단계로 앞당기세요. F5 블로그에서 DevOps 파이프라인 초기에 보안을 통합하여 취약점을 예방하고 시간을 절약하는 방법을 알아보세요.