블로그

포켓몬 고 API – 자동화된 공격에 대한 자세한 살펴보기

F5 썸네일
F5
2016년 8월 16일 게시

수천만 명의 사람들이 포켓몬 고의 새로운 세계를 탐험하고 있습니다. 그런데 그 사용자 중 상당수는 사람이 아니라 자동화된 에이전트, 즉 봇인 것으로 나타났습니다. 게임을 플레이하는 봇은 새로운 현상이 아니지만, 포켓몬 고는 봇에 대한 몇 가지 새로운 사용 사례를 제공합니다. 이러한 봇은 자동화된 트래픽으로 Pokémon Go 서버를 과부하시켜 모든 사람의 즐거움을 방해하기 시작했습니다. 포켓몬 고는 모바일 API에서 자동화된 공격과 방어가 어떻게 작동하는지 보여주는 완벽한 사례 연구입니다. Shape에서는 매일 이런 유형의 공격을 다루고 있기 때문에 Pokémon Go API 공격에서 무슨 일이 일어났는지 자세히 살펴보기로 했습니다.

포켓몬 고 API 공격

Niantic은 최근 블로그 게시물을 게시하여 봇이 자동화된 트래픽을 생성하여 발생시키는 문제로 인해 실제로 라틴 아메리카 출시가 방해를 받았다고 설명했습니다. 게시물에 포함된 차트는 Niantic이 08월 3일 오후 1시(태평양 표준시)에 자동화에 대한 대책을 도입한 이후 공간 쿼리 트래픽이 크게 감소했음을 보여줍니다. 자동화된 트래픽은 실제 인간 플레이어의 트래픽의 약 2배인 것으로 나타났습니다. 최근 몇 주 동안 포켓몬 GO 서버가 심하게 과부하된 것은 당연한 일이었습니다.

 

서버 리소스
그림 1. Niantic이 스크래퍼를 차단하기 시작한 이래로 공간 쿼리 트래픽이 50% 이상 감소했습니다. 원천: Niantic 블로그 게시물

포켓몬 봇을 알아가다

포켓몬 봇에는 두 가지 유형이 있습니다. 첫 번째 유형의 봇은 일반적인 게임 플레이를 자동화하며, 다른 게임 앱에서도 흔히 볼 수 있는 유형으로, 돌아다니거나 포켓몬을 잡는 등의 활동을 자동화합니다. 이러한 봇의 예로는 MyGoBot과 PokemonGo-Bot이 있습니다. 하지만 포켓몬 고는 포켓몬의 위치를 제공하는 트래커 또는 매퍼라는 새로운 유형의 봇의 개발에 영감을 주었습니다. 이러한 봇은 PokevisionGo Radar 와 같은 Pokémon Go 매핑 서비스를 지원합니다.

포켓몬 고 봇 작동 방식

모바일 API 봇은 모바일 앱과 백엔드 서버(이 경우 Niantic의 서버) 간의 통신을 모방하는 프로그램입니다. 봇은 단순히 서버에 어떤 작업이 수행되었는지 알리고 서버의 응답을 사용합니다.

그림 2는 주어진 위치에서 3피트 범위 내에 있는 근처 포켓몬을 표시하는 포켓몬 고 지도의 스크린샷을 보여줍니다. 이를 달성하기 위해 봇 제작자는 일반적으로 다음 단계를 따릅니다.

  1. 모바일 앱과 백엔드 서버 간의 통신 프로토콜을 리버스 엔지니어링합니다. 봇 제작자는 게임을 하고 앱과 서버 간의 통신을 캡처하고 프로토콜 형식을 해독합니다.
  2. 백엔드 서버에 일련의 "합법적인" 요청을 하여 작업을 수행하는 프로그램을 작성하세요. 이 경우, 근처에 있는 포켓몬의 위치를 알아내는 것은 실제 위치까지 걸어가는 과정이 없이, 특정 GPS 좌표를 이용한 단일 요청으로 끝납니다. 봇의 과제는 서버의 감지를 우회하여 실제 사람처럼 보이는 것입니다 .
  3. Google Maps와의 통합과 같은 관련 기능을 제공하거나 사용자를 위한 봇 자체의 매핑 기능을 포함합니다.

지도
그림 2. 포켓몬 고 맵의 스크린샷

모바일 앱 크랙 및 방어

포켓몬 고 앱을 예로 들어, 모바일 앱이 역엔지니어링을 통해 어떻게 크랙되어 비밀을 드러내는지 살펴보겠습니다. 공격자들은 주로 포켓몬 고의 안드로이드 앱을 악용했으므로 안드로이드 앱 크랙과 방어에 집중해 보겠습니다.

프로토콜 역엔지니어링

Pokémon Go 앱과 백엔드 서버는 SSL을 통한 ProtoBuf를 사용하여 통신합니다. ProtoBuf는 네트워크에서 전송되는 데이터 형식을 정의합니다. 예를 들어, 플레이어 통계에 대한 ProtoBuf 정의의 일부는 다음과 같습니다.

플레이어 통계에 대한 ProtoBuf 정의

포켓몬 고는 POGOProtos 에 의해 역공학을 거쳐 단 2주 만에 온라인에 공개되었습니다. 어떻게 이렇게 빨리 일이 일어났을까? Niantic은 처음에 인증서 고정 기능을 사용하지 않았습니다.

인증서 고정은 중간자 공격에 대항하는 데 일반적으로 사용되는 방법입니다. 간단히 말해서, 모바일 앱은 앱 자체에 내장된 서버 인증서만 신뢰합니다. 인증서 고정 보호가 없으면 공격자는 MitmproxyFiddler 와 같은 프록시를 쉽게 설정하고 공격자가 만든 인증서를 해당 휴대폰에 설치할 수 있습니다. 다음으로 그녀는 프록시를 통해 트래픽을 라우팅하고 Pokémon Go 앱과 Niantic 서버 간의 트래픽을 탐지하도록 휴대폰을 구성할 수 있습니다. 실제로 이를 가능하게 해주는 포켓몬 고 전용 프록시 도구가 있는데, 바로 pokemon-go-mitm 입니다.

7월 31일, Niantic은 서버와 Pokémon Go 앱 모두에 큰 변화를 주었습니다. Pokémon Go 0.31.0은 인증서 고정 보호와 함께 출시되었습니다. 안타깝게도 아직 그 정보가 공개되지 않았고, 통신 프로토콜은 이미 GitHub에 공개적으로 공개되어 있었습니다. 게다가 인증서 고정을 올바르게 구현하는 것은 항상 쉬운 일이 아닙니다. 이후 섹션에서는 공격자가 인증서 고정을 우회하는 데 일반적으로 사용하는 몇 가지 기술에 대해 살펴보겠습니다.

APK 정적 분석

Android 애플리케이션 패키지 (APK)는 Android 에서 모바일 앱을 설치하는 데 사용되는 패키지 파일 형식입니다. Android 앱은 주로 Java로 작성되며, Java 코드는 dex 형식 으로 컴파일되어 apk 파일로 빌드됩니다. 또한 Android 앱은 네이티브 코드( Android NDK )로 작성된 공유 라이브러리를 호출할 수도 있습니다.

Dex 파일은 Baksmali 와 같은 도구를 사용하면 SMALI 언어로 쉽게 분해되는 것으로 알려져 있습니다. 그런 다음 dex2jarjd-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의 인증서 값으로 변경합니다. 즉, 프록시가 어떤 승인되지 않은 인증서를 사용하든 포켓몬 고 앱은 인증서를 신뢰하도록 속아넘어간다는 뜻입니다.

공격자의 분해 및 정적 분석을 어렵게 만드는 데 도움이 되는 도구가 많이 있습니다. ProGuardDexGuard는 Java 코드와 dex 파일에 난독화를 적용하는 도구입니다. 난독화로 인해 코드를 읽기 어려워지며, 이는 디컴파일된 형태에서도 마찬가지입니다. 또 다른 방법은 Android 패커를 사용하여 Android 앱의 원본 classes.dex 파일을 암호화하는 것입니다. 암호화된 dex 파일은 런타임에 메모리에서 암호 해독되므로 대부분의 공격자에게 정적 분석은 극히 어렵거나 불가능합니다. 네이티브 라이브러리를 사용하는 것은 앱의 리버스 엔지니어링을 크게 어렵게 만드는 또 다른 방법입니다.

네이티브 라이브러리 역엔지니어링

pokemongodev 해커와 Niantic 사이에서 가장 흥미로웠던 고양이와 쥐 놀이는 "Unknown6"이라는 필드 주변에서 벌어졌는데, 이는 인근 포켓몬을 특정 위치에서 가져오기 위한 맵 요청으로 전송된 서명에 포함되어 있었습니다. “Unknown6”은 역엔지니어링된 protobuf의 식별되지 않은 필드 중 하나입니다. 처음에는 Unknown6에 어떤 값이 주어지든 상관없었습니다. Niantic 서버가 그냥 그것을 수락했습니다. 08/03 오후 1시(태평양 표준시 기준)부터 모든 포켓몬 고 봇이 갑자기 포켓몬을 하나도 찾을 수 없게 되었고, 결국 그림 1에서 볼 수 있는 쿼리가 크게 감소했습니다.

해커들은 프로토콜에서 "Unknown6" 필드의 중요성을 알아차리고 처음에는 Unknown6가 요청의 무결성을 검증하기 위한 일종의 다이제스트 또는 HMAC일 것이라고 의심했습니다. 이는 pokemongodev 커뮤니티에서 엄청난 관심을 불러일으켰고 "Unknown6" 팀이 신속하게 구성되어 신비한 분야를 개척하려고 시도했습니다. 코더와 비프로그래머의 폭넓은 관심으로 Discord 채널은 비공개로 전환되었지만, 라이브 업데이트 채널을 통해 모든 사람에게 해킹 작업의 진행 상황을 알렸습니다. 3일 5시간 후인 08/06 오후, Unknown6팀이 승리를 거두었고, 근처의 포켓몬을 다시 찾을 수 있는 업데이트된 Pokémon Go API를 출시했습니다.

해킹에 대한 세부 사항에 대한 기술적 설명은 아직 공개되지 않았지만 , 포럼과 라이브 업데이트 에서 많은 관련 도구와 기술이 언급되었습니다. IDA-프로 Hex-Rays의 ARM 코드는 네이티브 라이브러리의 코드를 분해할 수 있는 전문 도구이며 새로운 Hex-Rays 디컴파일러 바이너리 코드 파일을 C 스타일 형식으로 디컴파일할 수 있습니다. 이러한 도구를 사용하면 공격자는 동적 분석을 수행하고 런타임에 모바일 앱과 라이브러리를 디버깅할 수 있습니다. 물론, 그렇게 강력한 도구를 사용하더라도 바이너리 프로그램의 리버스 엔지니어링은 여전히 엄청나게 어렵습니다. 의도적인 난독화가 없다면, 역어셈블링이나 디컴파일된 코드는 이미 이해하기 어렵고, 코드 크기도 종종 엄청납니다. 복잡하고 예측할 수 없는 작업의 예로, 라이브 업데이트 채널과 그에 따른 인터뷰 에서는 "Unknown6"의 암호화 기능이 몇 시간 내에 식별되었지만, 팀은 Unknown6와 관련이 없는 것으로 밝혀진 "Unknown22"라는 또 다른 필드를 분석하는 데 추가 시간을 많이 보냈다고 설명했습니다.

결과적으로, 난독화는 여전히 네이티브 라이브러리를 보호하는 데 많은 실질적인 이점을 제공합니다. 바이너리의 난독화 수준이 높으면 역엔지니어링의 어려움이 엄청나게 높아질 수 있습니다. 그러나 윈도우와 윈도우 애플리케이션의 직렬 코드를 성공적으로 해독한 사례에서 알 수 있듯이, 동기가 있는 모바일 해독자는 종종 성공합니다.

서버 측 보호

서버 측 방어는 클라이언트 측 방어와 완전히 다른 방식으로 작동합니다. 포켓몬 고 모바일 API를 보호하는 맥락에서 사용되는 몇 가지 기술은 다음과 같습니다.

속도 제한

속도 제한은 자동화된 교통을 멈추거나 적어도 속도를 늦추기 위해 일반적으로 사용되는 접근 방식입니다. 초창기의 포켓몬 스캐너는 초당 수십 개의 요청을 보내고, 수십 개의 셀을 스캔하고, 모든 포켓몬을 찾을 수 있었습니다.

07/31에 Niantic은 속도 제한 보호 기능을 추가했습니다. 한 계정이 약 5초 이내에 여러 개의 맵 요청을 보낸 경우 Niantic 서버는 첫 번째 요청만 수락하고 나머지는 삭제합니다. 공격자는 다음과 같이 이러한 속도 제한에 대응했습니다. a) 스캐닝 프로그램의 맵 요청 사이에 지연(5초) 추가 b) 여러 계정 및 여러 스레드를 사용하여 속도 제한을 우회

포켓몬 고의 경우, 속도 제한을 사용함으로써 자동화된 공격을 위한 또 다른 전장이 생겼습니다. 바로 자동화된 계정 생성입니다. 그들은 속도 제한이 지나치게 공격적인 스크래퍼나 초보 공격자로부터 자동화를 제어하는 데 있어 훌륭한 기본 기술이기는 하지만, 고급 공격자가 자동화된 요청을 통과시키는 것을 막을 수는 없다는 사실을 빨리 발견했습니다.

IP 차단

IP 차단은 표준 네트워크 방화벽이나 웹 애플리케이션 방화벽 (WAF)에서 의심스러운 IP의 요청을 차단하는 데 사용하는 기존 기술입니다. IP 평판을 추적하는 데이터베이스는 많이 있으며 방화벽과 WAF는 이러한 정보를 주기적으로 검색할 수 있습니다.

일반적으로 IP 기반 차단은 위험하고 비효과적입니다. 트래픽 양이 많은 IP를 무작정 차단하면 대학이나 기업의 NAT가 차단되는 결과를 낳을 수 있습니다. 한편, 많은 포켓몬 봇이나 스캐너는 주거용 동적 IP 주소를 사용할 수도 있습니다. 이러한 IP는 ISP의 고객들이 공유하므로 특정 IP를 장기간 차단하면 합법적인 플레이어도 차단될 수 있습니다.

Amazon Web Services(AWS)와 Digital Ocean 등의 호스팅 서비스는 공격자가 가상 머신과 새로운 IP를 얻는 소스이기도 합니다. 공격자가 훔친 신용카드를 사용하면 이러한 리소스를 무료로 얻을 수도 있습니다. 그러나 합법적인 사용자는 결코 호스팅 서비스를 이용해 웹을 탐색하거나 게임을 하지 않을 것이므로 호스팅 서비스에서 IP를 차단하는 것은 안전한 방어책이며 서버 측에서 일반적으로 사용됩니다. 이 포럼 게시물 에 따르면 Niantic이 AWS에서 IP를 금지하기로 결정할 수도 있습니다.

행동 분석

행동 분석은 일반적으로 다른 방어수단을 우회할 수 있는 첨단 공격자에 대항하는 최후의 방어선입니다. 봇은 인간과 비교해 매우 다른 행동을 보입니다. 예를 들어, 실제 사람은 하루 24시간 내내 게임을 할 수 없고, 1초에 포켓몬 5마리를 잡을 수 없습니다. 행동 분석이 유망한 접근 방식으로 들리지만 포켓몬 고와 같은 엄청난 양의 데이터를 처리할 정확한 탐지 시스템을 구축하는 것은 쉬운 일이 아닙니다.

Niantic은 GPS 스푸핑을 이용해 "순간이동"(즉, 갑자기 불가능할 정도로 빠른 속도로 이동)하는 사기꾼에 대한 소프트 금지 조치를 시행했습니다. 아마도 거짓 양성 반응 때문에 "소프트 금지"였을 겁니다. 가족끼리 계정을 공유하고 GPS 판독값이 정확하지 않을 수 있어서 일부 합법적인 사용 사례가 봇처럼 보일 수 있습니다.

2016년 8월 12일경, Niantic은 자사 웹사이트에 공지사항을 게시하고, 서비스 약관을 위반하면 Pokémon Go 계정이 영구적으로 금지될 수 있다고 설명했습니다. 봇을 타겟으로 하는 여러 금지 규칙도 비공식적으로 공개 되었습니다. 예를 들어, 포켓몬 초과 포획 규칙은 하루에 1,000마리가 넘는 포켓몬을 잡으면 해당 계정을 금지합니다. 또한 Niantic에서는 합법적인 플레이어에게도 사기꾼이나 부적절한 플레이어를 신고해 달라고 권장하고 있습니다.

저희의 경험에 따르면, 행동 모델링 기반 감지 기능은 매우 효과적일 수 있지만, 내부적으로 구축하는 것은 기술적, 경제적으로 불가능한 경우가 많습니다. Niantic이 블로그 게시물에 언급한 대로, "이 문제를 다루는 데는 기회 비용도 있습니다. 개발자는 새로운 기능을 구축하는 것보다 이 문제를 제어하는 데 시간을 투자해야 합니다." 더 큰 문제는 봇넷과 일반적인 방어 수단을 우회하도록 설계된 기타 도구를 갖춘, 전문적이고 기술에 정통한 적대 세력으로부터 방어할 기술을 구축하려면 고도로 특화된 기술과 엄청난 개발 노력이 필요하다는 것입니다.

게임은 끝나지 않았습니다

포켓몬 고가 플레이어들에게 꾸준히 사랑받고 있는 만큼, 봇 제작자와 나이앤틱 간의 경쟁도 계속될 전망이다. 자동화된 트래픽을 방어하는 것은 게임 산업뿐만 아니라 모든 산업에 있어서 과제입니다. 비슷한 공격과 방어 활동이 은행, 항공사, 소매업체 앱에서 일어나고 있으며, 그 위험은 몇 마리의 잠만보를 잃는 것보다 훨씬 더 높습니다. 고객과 사용자가 원치 않는 자동화된 트래픽으로 인해 서비스에 액세스할 수 없게 되면 봇과 관련 공격 도구는 회사에 전혀 도움이 되지 않습니다.