반응형

게임 보안: 허들 넘기…
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaruhttp://www.jiniya.net

사용자들은 언제 게임보안 제품을 느낄까? 해킹툴을 잘 잡아서 게임 내 해킹이 줄었을 때? 아니다. 사실 일반 게이머들은 게임보안 제품이 해킹툴을 잡는다는 사실을 모르는 경우가 대부분이다. 그들이 게임보안 제품을 느끼는 대표적인 순간은 바로 잘되던 게임이 안되기 시작하는 순간이다. 게임보안 제품이 게임 구동을 방해하는 허들이 되는 그 지점인 것이다. 이 순간이 되면 모든 게이머들이 안티치트 솔루션 이름에 대해서 알게된다. 더불어 그 게임이 진짜 인기있는 게임이라면 네이버 실시간 검색어 1위에서 10위까지 휩쓰는 기염을 토하기도 한다. 이 모든 일들과 함께 안티치트 솔루션에 대한 욕과 비방이 범람한다. 한마디로 아찔한 순간이다.

XIGNCODE라는 제품을 처음 만들 때 사실 별 생각이 없었다. ㅋㅋ~ 후에 제품의 틀을 잡으면서는 크게 두 가지 다짐을 했다. 하나는 아이러니하게도 진짜 해킹툴을 잡는 제대로 된 솔루션을 만들자는 생각이었고, 다른 하나는 절대로 게임의 허들이 되는 제품을 만들지는 말자는 생각이었다. 하지만 시간이 흘렀고, 우리 제품도 게임에 속속 탑재되기 시작했고, 해킹툴과 전쟁도 뻘짓나게 많이 하면서 자연스럽게 허들이 되는 순간도 생기게 됐다. 그렇게 장애물은 되지 말자고 했는데 애물단지가 되는 순간이 발생한 것이다. 그럴때면 나 또한 똑같은 한명의 게이머로서 한없이 죄송함을 느끼곤 한다. 그리곤 또 다짐한다. 정신차리고 똑바로 만들자고 말이다.

그렇다면 왜 그렇게 모든 게임보안 제품은 하나같이 다 허들이 되는 것일까? 또 그 허들은 왜 생기는 것일까? 피할 순 없는 것일까? 또 반대로 게이머 입장에서는 조금이라도 허들을 피하기 위해서는 어떤 점들에 주의해야 할까? 역설적이게도 게임보안 제품이 허들이 되는 이유는 그들에게 봉착한 허들을 제대로 넘지 못했기 때문이다. 여기서는 게임보안 제품 개발을 하면서 겪게 되는 허들에 대해서 살펴보고 작게나마 앞선 질문들에 대한 해답을 찾아보는 시간을 가져보도록 하자.

#0 운영체제 허들
일단 게임보안 제품에게는 운영체제 하나가 거대한 산맥으로 다가온다. 왜 그럴까? 게임도 똑같이 다양한 운영체제 위에서 구동되는 프로그램이고 게임보안 프로그램도 그럴 뿐인데 왜 게임보안 제품에게는 운영체제 자체가 허들이 되는 것일까? 그 이유는 게임보안 제품의 특성상 운영체제에서 공개하지 않은 다양한 기능들을 사용하기 때문이다. 왜? 도대체 왜? 많은 이유가 있는데 주된 이유만 들어보자면 하나는 해킹툴이 그런 기능을 사용하기 때문에 탐지하기 위해서 부득이하게 사용하는 경우고, 다른 하나는 해킹툴로부터 자신을 보호하기 위한 목적으로 사용한다. 이렇게 공개되지 않은 부분들을 사용하는 것이 호환성을 떨어뜨리는 대표적인 요인이다. 여러분이 생각하는 그 모든 호환성 이슈는 다 이 하나의 사실에 기인한다고 할 수 있다. 그렇다면 이건 어떻게 해결해야 할까? 테스트만 열심히 한다고 해결될까? 물론 문제가 그렇게 쉽진 않다.


우리가 생각하는 것 이상으로 게임이 실행되는 운영체제는 게임 종류와 국가에 따라 천차만별이다.

XIGNCODE는 기본적으로 Windows 2000 SP4, Windows XP SP2, Windows XP SP3, Windows Vista SP1, Windows Vista SP2, Windows 7 RTM, Windows 7 SP1, Windows 8 CP에서 게임 구동 테스트를 거친다. 우와 장난 아니다. 그런데 여기서 놀라면 안된다. 저 모든 운영체제를 한중일영으로 테스트 한다. 보면 알겠지만 서팩별로도 많이 사용되는 것들은 분리해서 테스트 한다. 그 이유가 서팩별로도 많은 차이를 가지기 때문이다. 이런 복잡한 테스트를 몇 시간씩 하고, 일주일 내내하고, 또 하고, 또 하고, 제품 릴리즈를 함에도 문제는 발생한다. 왜 그럴까?

그 이유는 바로 우리가 기대고 있는 언덕이 그만큼 부실하기 때문이다. 공개되지 않은 부분이라는 그 사소하지만 절대 사소하지 않은 사실 때문이다. 즉, 오전까지는 잘되다가 오후에는 안되도 전혀 이상할 이유가 없는 단서들에 제품이 기반하고 있기 때문이다. 우리가 이 사실에 대해서 어떤 불평을 한다면 운영체제를 만든 MS에서는 이렇게 대답할 것이다. “야, 그건 우리가 그래서 공개안한거야. 니네들 쓰라고 만든건 아니거든.” 이라고 말이다. 어쨌든 그래서 테스트 만으로는 이 허들을 넘기가 쉽지 않다. 우리가 관찰한 100시간 동안은 운영체제가 A라는 방식으로 동작했겠지만 그건 단지 우리가 관찰한 100시간 동안만 그랬기 때문일 수도 있기 때문이다.

이 허들을 넘기 위해서는 테스트 보다는 운영체제에 대해서 보다 더 정확하게 알 수 있는 방법이 필요하다. 즉, 100시간의 관찰보다는 실제로 그렇게 돼 있는지 안 돼 있는지를 판단할 수 있어야 한다는 말이다. 그래서 운영체제를 직접 리버싱 하는 것이 더 도움이 된다. 맞다. 그런데 리버싱도 한계가 있다. 그래서 이 허들을 넘는 궁극의 도구는 MS 소스 코드 라이선싱 프로그램이다. 바로 그 놈이 답지고 그 놈이 갑이기 때문이다.


내가 곧 진리요. 답이고, 갑이다.

이 허들과 관련해서 사용자가 겪게 되는 또 다른 불편 중에 하나는 다양한 환경에서 게임을 즐기지 못한다는 요소다. 우리 제품도 종종 불만사항으로 올라오는 내용 중에 하나가 와인에서 실행되지 않는다는 것들이다. 이럴때면 늘 우리는 갈등한다. 사실 와인에서 실행되도록 만들어주는 것은 전혀 어려울 게 없다. (<== 어려울 수도 있다 ㅋㅋ) 그런데 문제는 와인을 통해서 해킹을 한다면 문제가 복잡해지기 시작한다. 물론 나는 선량한 리눅서가 와인을 통해서 게임을 즐기기 위함이지 절대 해킹을하기 위해서 리눅스를 깔고 와인을 올려서 게임을 구동하리라곤 생각하지 않는다. 그래도 만에 하나의 경우 그래 버린다면 문제가 될 수도 있다는 것이다. 어쨌든 우리는 이 옵션에 대해서 심각하게 고민하고 있다. 벤더 정책에 따라서 옵션으로 와인 호환성을 제공할까도 고려중이다.

#1 시스템 허들
다음으로 우리가 넘어야 할 허들은 게임 시스템이다. 이 또한 정말 다양한 시스템들이 있다. 이제는 우리가 시중에서 구하기도 힘든 시스템으로 게임을 하는 유저들이 적지 않다. 특히 오래된 게임들은 더 그렇다. 이 부분은 사실 테스트도 어렵다. 우리는 다양한 환경이라고 테스트 시스템 수십대를 구비해 놓지만 정작 유저들이 사용하는 시스템에 비한다면 그 수십대는 샘플 수량조차 되지 못한다. 그만큼 다양한 환경이 존재한다. 그리고 그 다양한 시스템을 게이머들은 우리가 상상도 못한 방식으로 변형시켜 사용한다.

여튼 이런 다양한 시스템이 문제가 되는 주된 요소들은 시스템 버그에 대한 패치를 사용자가 하지 않는다는 점이다. 대표적인 예를 들어보자면 AMD CPU의 Cool’n Quiet 기능 버그가 있다. 해당 기능을 사용하면 특정 운영체제에서는 시간을 측정하는 함수가 비정상적으로 동작하는 문제가 있다. 이건 패치를 해야 하는데 사용자들이 그러한 패치를 알리가 만무하고 또 그 패치를 하지 않더라도 일반 프로그램 사용에는 문제가 없기 때문에 하지 않는 경우가 많다.

하지만 우리에게는 그러한 것들이 굉장히 크리티컬하게 다가온다. 게이머가 해킹툴을 설치해서 시간이 이상한지 아니면 패치를 안해서 이상한지를 구분해야 하기 때문이다. 그래서 온갖 꼼수들이 동원된다. 당연히 그 꼼수들로 인해서 프로그램의 호환성은 더 떨어지고, 테스트는 더 힘들어지고, 제품은 더 쉽게 부서진다.

#2 오진 허들
여기부터는 이제 우리가 우리 발목을 잡기 시작하는 허들이다. 해킹툴 차단 방식은 크게 나누자면 패턴 방식과 로직 방식으로 나눌 수 있다. 패턴 방식은 사람 지문으로 누군가를 구분하는 것처럼 해킹툴의 특정 시그니처로 해당 해킹툴을 차단하는 방식을 말한다. 지문이 데이터베이스에 없다면 인식이 안되는 것처럼 이 경우도 수집이 안 된 해킹툴에 대해서는 차단을 하지 못한다는 문제가 있다. 그래서 도입된 개념이 로직 방식이다. 이건 이렇게 행동하는 사람은 A 밖에는 없다고 우리가 추론하는 것과 똑같은 원리로 해킹툴을 진단한다. 즉, 어떤 프로그램이 a, b, c라는 동작을 하면 해킹툴로 간주하는 것이다. 당연히 우리가 인식하는 세계처럼 여기에는 맹점이 생길 수 밖에 없다. 그 사람이 아닌데, 내지는 해킹툴이 아닌데도 a, b, c라고 동작을 하는 경우가 있기 때문이다. 이게 우리 발목을 잡는다. 물론 대놓고 난 정상 프로그램이라고 말하면 문제는 한결 가벼워 지는데 그 정상 프로그램이 각종 꼼수 꼼수에 꼼수를 사용해서 마치 해킹툴처럼 판단하기 어렵게 만든 경우에는 허용 처리가 안드로메다로 가버린다.

그럼 어떤 프로그램이 주로 오진 케이스에 말려들까? 가장 대표적인 프로그램들은 아이러니하게도 게임 유틸리티다. 게임 동영상 촬영 도구라던지, 게임 내에서 채팅 기능을 구현한 메신저 프로그램이 대표적이다. 이들 프로그램은 게임과 동시에 동작한다는 것이 특징인 것들이지만 내부 구현 방식은 해킹툴의 그것과 상당히 유사하기 때문이다. 또 이 프로그램들이 진화하면서 이 프로그램들 나름대로 탐지를 회피하기 위해서 각종 테크닉을 사용하기 때문에 요즘은 허용 처리도 참 쉽지 않은 경우가 많다.

그 다음 대표적인 유틸리티 들로는 가상화 유틸리티들 SandBox, Vmware, Virtual PC부터 네트워크 프록시 도구들이 있다. 이런 프로그램들은 해킹툴과 동작 방식이 유사히진 않지만 벤더 요청으로 차단하는 경우가 있다. 그렇게 차단된 것임에도 사용자 입장에서는 정상 프로그램을 오진한다고 생각하기도 한다.

벤더 정책으로 누명을 쓰는 또 하나의 대표적인 프로그램으로는 또 JoyToKey가 있다. 이름에서 볼 수 있듯이 조이스틱을 컴퓨터에서 매핑해서 사용할 수 있게 해주고, 또는 매크로 기능을 사용할 수 있게 해주는 프로그램이다. 그런데 이게 왜 문제인고 하면 게임 벤더에 따라서 어떤 쪽은 이 프로그램을 허용처리하고 어떤 곳은 차단 처리를 하기 때문이다. 유저들의 반응은 딱 갈리게 된다. 저걸 해킹툴로 많이 사용하는 게임인데 벤더에서 허용을 해주면 어떤 반응이냐면 우와 XIGNCODE는 쓰레기다. JoyToKey도 차단이 안된다. 이런 반응들이 올라온다. 사실 우리가 못 막아서 안 막는 경우는 아님에도 말이다. 또 반대로 이 프로그램을 별로 해킹툴로 사용하지도 않는 게임인데 벤더 정책상 차단하게 되면 와 이런 정상 프로그램을 왜 차단하냐. 미친거 아니냐. 라는 반응들이 올라온다. 마찬가지로 우리가 차단하고 싶어서 차단한건 아님에도 말이다. 즉, 가끔은 중간에 끼여서 욕을 먹는 경우에는 조금 억울한 생각이 들 때도 있다.

#3 충돌 허들
충돌은 정말 장난아닌 문제다. 게임보안 제품은 그 모든 것들과 충돌을 일으키지만 특히 안티바이러스 이슈가 많다. 가장 최근에 겪었던 충돌 문제를 한 번 살펴보자. 이 문제는 안티바이러스의 코드 에뮬레이션 기능과의 충돌이었다. 처음 보고가 들어온 제품은 AVAST였다. 이런 문제의 99.8971234%는 서로 같은 포인트를 후킹하거나 후킹하려고 하는 것이 문제이기 때문에 그 체크를 먼저 했다. 어라? 근데 깨끗하다. 아무 문제가 없어 보였다. 근데 게임이 크래시가 난다. 그래서 AVAST의 이 옵션, 저 옵션 조정하면서 왜 크래시가 나는지를 관찰했다. 그랬더니 아니나 다를까 AVAST의 코드 에뮬레이션 기능을 켜면 크래시가 발생하는 것이었다. 게임이!!! 도대체 왜? 아마 우리의 코드가 그 코드 에뮬레이터가 이해하기는 힘들었는지도 모르겠다. 여튼 QA팀에게 AVAST에 충돌 보고를 하라고 했다. 내가 보기에는 AVAST에서 봐야 할 문제였기 때문이었다. 그러고 끝일까? 당연히 아니다. 게이머한테 이건 AVAST 버그니 코드 에뮬레이션 끄고 게임하세요. 이렇게 말할수는 없기 때문이다. 그래서 우리는 그 코드를 AVAST가 켜진 경우에는 AVAST가 딱 이해할만한 수준으로 낮춰서 동작시키도록 했다.

이 문제가 억울한 이유는 사실 이런 경우는 우리쪽 버그가 아니다. AVAST 코드 에뮬레이터 버그지 않겠는가? 결국 AVAST에서 해당 기능을 고쳤다는 보고를 해왔다. 하지만 게임사나 유저들은 우리 잘못으로 오인하는 경우가 많다. 안타까운 현실이다. AVAST만 거론해서 그렇는데 동일한 이슈를 겪은 다른 3종의 백신이 더 있었다. MS SE, ESET Smart Security, McAfee였다. 물론 다른 벤더엔 귀찮아서 오류 보고도 하지 않았다.

그렇다면 우리는 왜 AVAST 코드 에뮬레이터도 이해하지 못하는 그런 코드를 써야 했을까? 첨부터 그냥 다 평이한 걸 사용했으면 문제가 없지 않을까라고 생각할 수도 있겠다. 근데 이게 딜레마다. 우리 제품은 해커로부터 우리 코드를 보호해야 한다. 또 해커가 우리 코드를 이해하는 것을 막아야 한다. 그러니 당연히 복잡하게 꼬아 놓을 수 밖에는 없는 것이다. 그게 경쟁력이니 포기할 수가 없는 것이다. 충돌을 감수하더라도 그 코드를 계속 써야만 하는 이유다.

그리고 이런 충돌 이슈는 충돌을 넘어서 좀 더 복잡한 문제들을 야기 시킨다. 충돌때문에 작성한 특수 코드가 우리 발목을 잡는 경우가 생기는 것이다. 해커가 만약 백신 때문에 작성한 특수한 코드에 대한 사실을 눈치채면 그걸 이용해 먹을 수 있다는 말이다. 그런 방법을 공유한다고 사용자들이 백신을 설치할까라고 생각할 수 있다. 근데 뻥안치고 방법만 있다면 게임핵을 사용하고 싶은 모든 사용자는 어디서 구하든 다 구해서 그 백신을 설치한다. 그 정도로 게임핵의 유혹은 강하기 때문이다. 실제로 예전에 중국에서 KAV를 이용해서 해킹 시도를 하는 사례가 있었다. 그래서 귀찮더라도 보고하고 무조건 백신을 고쳐야 한다.

여기까지 생각하면 이제 게임보안 1-2년 정도 해본 사람이라고 할 수 있겠다. 좀 더 해보면 알겠지만 저거 고쳤다고 원래 코드를 쓸 순 없다. 세상이 그렇게 순수하진 않은 탓이다. 백신 업체가 고쳤다고 그걸 업데이트하는 유저도 있지만 하지 않는 유저도 부지기수기 때문이다. 우리가 백신 업체가 고쳤다는 소리만 듣고 순진하게 원래 코드로 원복시켰다가는 다시 똑같은 문제가 생긴다는 소리만 듣는다. 모든 사용자는 업데이트를 하지 않는다고 생각하는게 속편하다. 그래서 그 특수 코드를 이용하는 놈들이 나타나면 다시 그 특수 코드에 대한 특수 코드를 만들어야 한다. 이렇게 소스 코드는 걸레가 되고 로직은 38.7차원 어딘가에 위치하게 된다.

#4 버그 허들
이거야말로 우리가 피해야 할 허들이다. 그런데 가장 많으면서 제일 피하기 힘든 허들이다. 누구 말처럼 이건 명백히 프로그래머의 실수다. 그런데 버그라는 말을 만들어서 책임 회피를 하는 것처럼 보일 수 있다. 어쨌든 맞다. 명백한 우리 실수, 잘못이다. 인정한다.

그럼에도 변명을 좀 대보자면 이렇다. 우선 게임보안 제품은 생각보다 빌드가 굉장히 많이 있다. 왜냐하면 해킹툴이 자주 나오기 때문에 그 취약점도 고쳐야 하고 새로운 방식에 대응도 해야 하기 때문이다. 심한 시기에는 풀빌드가 일주일에 두세 번씩 되기도 한다. 이런 경우에는 머 QA팀은 초죽음이 된다고 보면 된다. 또한 이러한 풀빌드가 전혀 계획되지 않은 상황에서 발생하기도 한다. 왜? 해킹툴을 막아야 하기 때문이다. 자잘한 빌드는 말도 못 할 정도로 많다. 하루 밤에 24번 모듈을 빌드하고 업데이트 한 적도 있었다. 당연히 그 해킹툴 제작자는 그 다음주에 학교로 돌아갔다. 그래서 때로는 이런 어처구니 없는 실수들도 자주 발생한다.

이렇게 아무 문제도 없어 보이는 배열 속에…

NULL이 하나 빠진 이런 말도 안 되는 버그가 숨어있는 상황. 때로는 깔맞춤이 필요한 이유.

물론 당연하다. 똑똑하다면, 진짜 실력이 있다면 빨리 만들면서도 잘 만들어야 하고, 또 문제가 없어야 한다. 우리가 항상 이런 버그 앞에서 한없이 초라해지고 숙연해지는 이유이기도 하다. 그럼 우린 어떻게 해야 하는가? 프랙티스, 프랙티스, 프랙티스… practice makes perfect를 외치며 항상 연습하는 수 밖에는 없다. 빨리 고치고, 급하게 고치고, 막 바꾸면서도 실수하지 않도록 말이다. 라이브는 말 그대로 전쟁터다.

#5 필요악???
문제가 한두 가지가 아니다. 한 게임보안 프로그램은 국내 대형 MMORPG에 탑재됐다가 북미에서는 유저들 원성으로 제거되는 굴욕을 겪기도 했었다. 사람들은 늘 말한다. 100% 막지도 못하고, 그렇다고 문제가 0%인 것도 아닌데 왜 필요한가라고 말이다.

하지만 정작 실제 내용을 살펴보면 그런 이야기를 하기는 힘들다. 왜냐하면 게임보안 솔루션을 사용해서 유통되는 유료핵툴 한두 개만 차단하더라도 연간 구독료 값어치는 하고도 남기 때문이다. 특히 MMORPG같이 컨텐츠가 생명인 게임은 더 그렇다. 아래는 한 게임에 오토 유료핵이 나온 경우의 상황을 보여주고 있다. 여러분이 보는 그대로 전체 게이머의 60%가 그 핵툴을 사용하는 시간대도 있다. 이 정도로 말도 안 되게 온라인 게임의 핵은 심하고, 또 게임보안 제품은 여러분이 생각하는 것보다 훨씬 더 쓸모있다. 저 오토들이 컨텐츠 소모에 들어갔다면 어땠을까? 단순히 유저들이 느끼는 불균형의 문제가 아니다. 비싼 돈주고 개발한 컨텐츠가 유저가 아닌 기계에 의해서 순식간에 소모되는 말도 안 되는 일이 벌어질 수 있는 것이다.

가로축은 시간이고, 세로축은 해킹툴 유저 비율(%)이다. 유료핵의 파괴력은 생각보다 훨씬 심하다.

해킹툴로 서비스되는 게임을 내려본 게임사는 게임보안 솔루션의 필요성에 대해서 절절하게 실감한다. 몇 백억이 투입된 게임도 해킹으로 난장돼서 서비스가 불가능할 수도 있기 때문이다. 여러분이 생각하는 것 이상으로 반드시 필요하고, 또 좋은 솔루션이 필요하다. 그래야 문제는 낮추고, 탐지율은 높아지기 때문이다.

#6 허들을 넘어서
참 문제도 많고 탈도 많다. 프로그래머는 어떨까? 이런 수많은 허들을 마주하면 게임보안 프로그래머는 위축될 수 밖에 없다. 공격적인 탐지 방식보다는 느슨한 탐지 방식을 사용할 수 밖에 없다. 좀 더 복잡한 숨김 방식보다는 노멀한 방식을 사용할 수 밖에 없다. 자신감이 없어지기 때문이다. 하지만 이런 것들에 위축돼서 쪼는 순간 게임보안 프로그래머로써의 생명은 끝이고, 그 제품 생명도 끝이다. 왜냐하면 그런 자신감이 없어지는 순간 제품과 코드의 경쟁력은 순식간에 사라지기 때문이다. 진짜 프로라면 이 모든 허들을 웃으면서 사뿐히 뛰어넘으면서도 위험한 방법을 과감하게 선택하는 강단이 필요하다.

게이머에게 유쾌한 느낌을 주는 게임보안 솔루션이고 싶다. 물론 쉽진 않다.

적어도 XIGNCODE를 사용하는 게임에게 짐이고 싶진 않다. 또 적어도 XIGNCODE가 탑재된 게임을 하는 게이머들에겐 공정하다는 느낌을 주고 싶다. XIGNCODE 팀은 매 순간 그 시소의 양 극단에서 갈등하고 고민한다. 지금까지 우리는 항상 가장 위험한 방법에 과감하게 도전했고, 그걸 제일 안전하게 구현했다. 또 실수를 최소화하기 위해서 매일 연습했다. 그것만이 우리 제품을 사용하는 모든 이들에게 신뢰를 줄 수 있는 방법이고, 또 우리가 이 수많은 허들을 뛰어넘은 방법이기 때문이다.

새로운 기능이 잔뜩 준비됐다. QA팀은 긴장한다. 그 쏘 쿨한 기능들은 늘 그랬듯이 허들을 하나씩 넘을 것이고, 그걸 다 넘으면 게임에 탑재돼서 새로운 핵들에 대한 대응력을 강화해 나갈 것이다. 이렇게 우리는 매일 조금씩 전진한다. 제품도, 팀도, 회사도 말이다.

가장 공격적인 방법을 선택하되 가장 안전하게 구현해야 한다. 왜? 우리는 프로니까.



Read more: http://www.jiniya.net/wp/archives/6414#ixzz3NCUh77K7

반응형
반응형

게임 보안: 커플링에 관한 오해들…
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaruhttp://www.jiniya.net

게임사 미팅을 해보면 흔하게 겪는 일 중에 하나가 커플링에 관한 오해들입니다.
반지는 아니구요. ㅋㅋ 게임과의 결합도가 높은 보안 코드에 대한 이야깁니다.

소프트웨어 공학에서는 모듈간의 의존도 내지는 결합도를 나타내는 척도로 커플링이란 단어를 쓰거든요. 결합도가 낮으면 느슨한 결합이라고 하고 결합도가 높으면 강한 결합이라고 한답니다. 어떤게 좋을까요? 당연히 소프트웨어 공학에서는 커플링이 낮은 수준이 닥치고 갑입니다. 결합도가 높다는 건 덜 모듈화 됐고, 고치기 쉽지 않으며, 수정할 때 오류가 발생하기 쉽고, 유지보수 하기가 까다롭다는 그 모든 것을 의미합니다. 그래서 커플링을 피해야 할 그것으로 간주하죠.

하지만 요사이 많은 부분에서 게임보안 제품과 게임은 커플링이 높아지는 것이 필연적일 수 밖에 없다는 주장이 제기되는 것 같아서 몇 가지 사례별로 생각을 정리해 보았습니다. 자 그럼 과연 커플링이 높아야 해킹툴을 잘 잡는다는 말이 진실인지 아닌지 한 번 살펴볼까요? ㅎㅎ~

#0
언제부턴가 게임보안 업체들 사이에서 서버에 게임보안 코드를 탑재하는 것이 일반화 됐습니다. 저희가 XIGNCODE라는 제품을 개발하던 초기만 해도 서버 쪽에 코드를 탑재하는 것을 두고 게임 서버 개발자들 사이에서 반감이 굉장히 많았습니다. 그랬던 것이 요즘은 대부분 다 기본적으로 코드를 탑재해야 된다고 생각하시니 감사할 따름입니다. 격세지감도 좀 느끼고 그래요. 여튼 이러한 서버 코드 탑재와 함께 따라온 잘못된 관습(?!) 중에 하나가 클라이언트가 빌드될 때마다 서버에 클라이언트 해시 데이터를 업로드하는 것입니다. 보안 코드에서는 서버 쪽과 클라이언트를 비교해서 다른 경우에 끊겠다는 것을 목표로 개발된 기능인 것 같습니다. 매우 강한 결합 중에 하나죠.

이 경우에 실수가 발생할 소지는 굉장히 다분합니다. 관리자가 서버 쪽에 해시 데이터를 업로드 하는 것을 빼먹거나, 서버에 올린 해시 데이터와 다른 클라이언트가 패치 된다거나 하는 등의 실수 개입 요지가 많습니다. 근데 뭐 실수는 안한다고 차치하더라도 이 방법이 그다지 좋지 않은 이유는 대부분의 게임에서는 이런 조치가 전혀 필요하지 않기 때문입니다. 도둑이 모두 창문으로 넘나드는데 창문은 지키지 않고 정문을 유지보수 한다는 느낌일까요? 이런 이야기를 하면 꼭 그럼 정문은 안지켜도 되는거냐? 라고 물으시는 분들이 계신데 현실 세계에서 리소스는 항상 제한적입니다. 따라서 그 정문 지키는 리소스로 도둑이 드나드는 다른 곳을 지키는 것이 백배 더 현명하다는 이야기입니다.

그렇다면 게임 서버에 탑재되는 코드에서 해야 하는 일은 무엇일까요? 바로 실행 보장입니다. 게임보안 제품은 외부 라이브러리 형태로 제공되기 때문에 인터페이스가 노출되면 손쉽게 바이패스될 수 있습니다. 이런 경우를 검증하기 위함입니다. 즉, 모든 것들이 다 제거되고 우회되고 변경되더라도 단 하나 이거는 그래도 실행된다고 보장할 것이 필요하다는 것이죠. 그게 바로 서버에 적용된 코드가 해야 하는 일입니다. 실행 보장만 되면 변경된 지점을 찾아내는 것은 언제든지 할 수 있거든요. 하지만 실행 보장이 되지 않으면 백날 변경 지점을 찾는 코드를 넣어봐야 효과도 없습니다. 변경 지점을 찾는 그 코드가 변경될꺼거든요.

그리고 뭔가를 변경한다는 자체가 굉장히 오래된 발상입니다. 요즘 트렌드는 노모디피케이션입니다. 즉 아무것도 바꾸지 않고 바꾼 것과 동일한 효과를 내는 방법들이라는 것이죠. 왜냐면 해커들도 이제는 다들 알거든요. 뭔가를 바꿔서는 너무 쉽게 탐지된다는 사실을요.

#1
오토, 매크로 프로그램과 특정 기술을 무한대로 사용하게 하는 핵들은 게임 내 특정 함수를 불법적으로 호출하는 기능을 통해서 많이 구현됩니다. 예를 들어서 레이싱 게임이라면 부스터 가속을 시키는 함수를 들 수 있습니다. 외부 해킹툴은 그런 함수를 불법적으로 계속 호출합니다. 이렇게 만들어진 것이 무한 부스터 핵입니다. 이런 기법이 게임 개발자들 사이에도 많이 퍼져서 요즘 흔하게 나오는 질문 중에 하나가 보안 프로그램이 특정 함수를 보호할 수 있는 기능을 제공하는가 물어보십니다. 이 기능이 제공되면 게임 개발자가 생각하기에 위험하다고 생각하는 함수 주소를 전달해서 불법 호출을 막겠다는 생각인거죠.

과연 효과적인 전략일까요? 솔직히 무용지물입니다. 게임 내 랙만 증가시킨다고 보시면 됩니다.

일단 기본적으로 반환 주소 체크 기법은 return address morphing이란 테크닉에 의해서 너무 쉽게 무력화됩니다. 그런 기법을 방어하기 위해서는 코드를 트레이싱해서 추적해야 하는데 해당 게임 함수 런타임에 이런 체크를 깊이 하게 되면 부하가 증가됩니다. 따라서 일정 범위 밖에 체크를 못하죠. 즉 우리가 N Depth를 추척하는데 상대가 N+1 Depth를 사용하면 그냥 우회된다는 겁니다. 참고로 이런 것들을 인식하고 N Depth를 검사하도록 넣은 보안제품도 잘 없답니다. 안타까운 현실이죠.

근데 더 안타까운 사실은 이러한 체크 기법이 후킹이란 방식에 의존하는데 제작자 입장에서는 해당 후킹 포인트를 지나서 함수를 호출하는 것 또한 너무 쉽다는 겁니다. 물론 이것도 방어하기 위해서 동적 코드 분석을 한 다음에 애매한 위치에 알박기를 할 수도 있지만 소프트웨어의 견고성만 떨어질 뿐 크게 효과적이진 못합니다.

진짜 최고로 안습한 사실은 해당 함수 주소를 차단하면 해커는 다른 함수를 찾아낸다는 겁니다. 100% 말이죠. 그래서 효과적이지 않습니다. 여러분이 해커와 같은 속도 내지는 해커보다 빠른 속도로 해커가 다시 찾아낸 그 함수를 찾아낸다 해도 효과는 없습니다. 그냥 하나의 경쟁 루프를 만들어낼 뿐이거든요. 상호 패치 공방 밖에는 벌어질 수 없는 방식이란 거죠.

저희도 중국 유료 해킹툴에 이 기법을 몇 차례 적용했었는데 별 재미를 못 봤습니다. 왜 재미를 못봤냐구요? 우리는 일주일이 걸려 겨우 그 함수를 찾았습니다. 그래서 이제 막으면 원천 차단이 되겠다 생각했죠. 근데 넣고 하루만에 다른 함수를 호출하더군요. 다시 일주일을 분석하느니 그냥 그런 방법은 개나 주는 편이 낫겠다고 생각했습니다. 저희는 다른 방법을 선택했고 그 해킹툴은 3월 2일부로 영원한 수면에 들어가셨습니다. ㅋㅋ~ 이 사례를 통해서 전 교과서에 나오는 방법들이 생각보다 훨씬 더 실전에서 쓸모가 없다는 저의 생각을 좀 더 굳히게 됐습니다.

XINGCODE로 인하여 3월 2일부로 영면하신 그 비운의 해킹툴…

저희가 커플링 높은 인터페이스를 게임 개발자들에게 권하지 않는 이유는 이런 겁니다. 첫째는 게임 개발자가 스터디를 해야하는 보안 제품을 만들어서는 안 된다고 생각하기 때문입니다. 여려분이 자동차를 사는데 그 엔진 구조를 모르고는 시동도 걸 수 없는 차라면 사시겠습니까? 저같으면 그런 건 개나 줄 것 같거든요. 다른 하나는 이러한 테크닉의 경우 자칫 남용되거나 내부 구현을 모르고 사용했다가는 게임 내 부하만 증대 시키고 해킹툴을 막는대는 하나도 보탬이 되지 않기 때문입니다. 결국 출혈을 감수해 가면서까지 가져간 높은 커플링으로 볼 수 있는 재미는 하나도 없다는 이야기입니다.

물론 잘 아시겠지만 여러분이 모르는 그런 곳에 이 반환 주소 체크 기법을 사용해서 재미를 볼 수 있는 곳은 많이 있습니다. 당연히 그런 건 여기다 적진 않겠죠? 단물 좀 더 빼먹고 누구나 알게 될 즈음에 마치 제가 처음 발견한 마냥 교과서에다 공개하겠습니다. ㅋㅋ~

#2
끝으로 요즘 가장 핫한 데이터 중에 하나인 DirectX 인터페이스 주소를 좀 살펴보겠습니다. DirectX 가상 함수 변조를 체크하기 위해서 해당 인터페이스의 포인터를 전달 받는 것이 이 커플링 높은 방식의 골격같습니다. 하지만 이 또한 안타깝게도 큰 의미는 없습니다. 우선 전달받지 않고도 주소를 획득할 수 있고, 무조건 전달을 받아야만 막을 수 있는 방식이 한가지 있긴 한데 그 방식은 속도 상의 이유로 실전에서 거의 사용되지 않습니다. 또한 사용한다 하더라도 다른 루트를 통해서 검출할 수 있습니다.

전 이런 방식을 사용해 본 업체들에게 페르미의 역설처럼 한 번 여쭤보고 싶습니다. 달라고 하는 DirectX 인터페이스 주소를 가르쳐 주셔서 재미 좀 보셨습니까? 라구요. 아마 그닥 재미를 못 보셨을 겁니다. 인터페이스를 조작하는 해킹 방식은 제가 지난 번에 썼던 것처럼 Visual C++ 일주일 배우고 게임 커뮤니티에서 DirectX Hook Toolkit을 받아서 월핵 샘플따라 코딩하는 경우 외에는 잘 없거든요. 참 올드 패션드한 테크닉이란 이야기죠. 요즘은 저런 방식 자체가 전문 해커들에게는 거의 사용되지 않습니다. 물론 사용하는 해커가 있다면 그건 B급 해커겠죠. 그리고 그런 B급 해커가 조작하는 것들은 인터페이스를 받지 않아도 다 차단할 수 있답니다. 그러라고 비싼 돈주고 솔루션 사서 쓰는 것 아니겠습니까?

#3
게임보안 제품을 왜 사용하는 걸까요? 해킹툴을 막기 위함일겁니다. 그런데 요 근래에 몇몇 게임 업체와 미팅을 하면서 느낀 점은 보안 제품을 해킹툴을 막는 본연의 목적이 아니라 보안 제품한테서 컨설팅을 받고 계시더군요. 그것도 잘못된 보안 컨설팅을요. 그럴 때 마다 정말 안스러움을 느낀답니다.

해킹툴을 막는 데에는 여러 수천가지 방법이 있습니다. 제가 생각하는 가장 상책은 개발사나 운영사 모두가 전혀 신경 쓸 필요가 없는 방법입니다. 중책은 개발사에서 뭔가 정보를 알려줘야 하는 방법이고, 가장 하책은 게임 업데이트를 보안 업체에 신고해야 하는 방법입니다. 왠만하면 상책을 사용하는 업체와 일을 하세요. 그게 여러분에게도 보안 업체에게도 정신 건강에 이롭습니다. 물론 저희도 과거에 ‘나는 보안이다’라면서 하책을 남발했던 경험이 있습니다. 결과는요? 상호 멘붕상태가 오더군요. 그 때 깨달았습니다. ‘아 진짜 이거 없이는 답이 없겠다 하는 경우를 제외하고는 절대로 하책을 써서는 안되겠다’라고 말이죠.

다시 한 번 기억하세요. 여러분이 사용하는 솔루션은 해킹툴을 차단하기 위한 솔루션입니다. 게임의 보안 결함을 찾아서 나열해 주는 솔루션이 아니라는 이야기죠. 더 나아가서는 해킹툴 분석 보고서를 그럴듯하게 쓰는 솔루션도, 특허를 나열하는 솔루션도 아닙니다. 단지 여러분의 그 지긋지긋하게 골치아픈 해킹툴들을 알아서 잘 차단해 줄 솔루션을 선택하세요. 그럼 게임 내 보안 결함을 찾을 필요도, 해킹툴 분석 보고서를 쓸 필요도, 특허를 나열할 필요도 없거든요. 맞습니다. 카드를 쥐고 있는 한 여러분이 갑입니다. 이제는 갑의 권리를 다시 찾아 올 때 입니다. ㅋㅋ~



right now는 빼도 된다는 거 아시죵? ㅎㅎ~



Read more: http://www.jiniya.net/wp/archives/5823#ixzz3NCTcq8SA

반응형
반응형

끝나지 않은 전쟁: 논클라이언트 봇
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaruhttp://www.jiniya.net

보안 프로그래밍
끝나지 않은 전쟁: 논클라이언트 봇

소개
영겁의 세월을 두고 진화하는 우주처럼 보안에서의 창과 방패의 싸움도 영원히 이어질 수 밖에 없는 구조로 되어 있다. 여기서는 그런 이슈 중에 하나인 논클라이언트 봇과의 전쟁에 대해서 살펴본다. 논클라이언트 봇의 정의 및 구조적 특징과 함께 그간 논클라이언트 봇에 대응하기 위해서 논의되었던 전략들에 대해서 알아보도록 하자.

필자소개
신영진 codewiz@gmail.com, http://www.jiniya.net
웰비아닷컴을 창업해 게임보안 제품을 개발하고 있다. 시스템 프로그래밍에 관심이 많고 다수의 PC 보안 프로그램 개발에 참여했다. Microsoft Visual C++ MVP, 데브피아 Visual C++ 섹션 시삽으로 활동하고 있다. Steve Barakatt과 그레이 아나토미의 광팬이며 한때는 WoW에 미쳤다. 한마디로 괴짜다.

필자 메모
“보안 프로그래밍”이라는 주제로 글을 부탁 받고는 어떤 내용을 담을지를 한참 고민했다. 정수 연산의 위험성 이라든지, 포맷 스트링 버그 라든지, 버퍼 오버플로우와 같은 보안 프로그래밍을 생각했을 때 누구나 떠올리는 다소 식상한 내용은 담고 싶지 않았다. 달리 생각하면 PC 클라이언트 보안을 하는 업체에서 10년 가까운 세월을 일했지만 감히 “보안”이라는 주제로 글을 쓰기가 두려웠는지도 모르겠다. “보안”이라는 것은 너무도 넓고 너무도 방대한 내용들을 포함하고 있기 때문이다.

식상한 주제는 피하고 싶고, 모르는 것에 대해서 글을 쓰는 것만큼 멍청한 일도 없으니 결국은 내가 그간 했던 고민 중에서 한 꼭지를 끄집어 내 보기로 결정했다. 여기서 설명할 논클라이언트 봇은 과거에도 심각한 문제였고, 현재에도 계속 문제가 되고 있다. 그럼에도 글을 쓰고 있는 지금 이 시점에도 완벽한 대응 전략은 부재중인 상태다. 이 글을 읽고 여러분이 다소 자극을 받아서 혁신적인 새로운 대응 방법을 생각해 낸다면 그 또한 엄청나게 의미 있는 일이 아닐까라는 생각을 하면서 글을 시작해 보려고 한다.

혹시 앞서 언급했던 일반적인 “보안 프로그래밍”이라는 주제에 대해서 공부하고 싶은 독자라면 이 세 권의 책을 꼭 일독하기를 권한다. Writing Secure Code 2/e, 윈도우 비스타 보안 프로그래밍, Secure Coding in C and C++이 그 세 권의 책이다. 그 어떤 책보다도 여러분에게 일반적인 보안 프로그래밍의 관점에 대해서는 가장 많은 영감을 줄 수 있는 책이라고 감히 자부한다.

Introduction
이 문제는 여러분이 잘 알고 있는 튜링 테스트와 유사하다. 여러분의 여자친구 내지는 남자친구를 생각해 보자. 없다면 부모님을 생각해도 되겠다. 벽이 하나 있고, 반대편에 여러분의 사랑스런 그 사람이 앉아 있는 것이다. 여러분은 상대에게 질문을 할 수 있고, 상대는 여러분에게 대답을 할 수 있다. 이 질문과 답변 과정은 대리인을 통해서 이루어지며 그 사람은 벽 반대편 사람이 여러분이 알고 있는 사람인 것처럼 보이게 하기 위해서 질문과 답변 내용을 조작할 수 있다. 과연 이런 상황에서 여러분은 벽 반대편에 있는 상대가 여러분이 알고 있는 그 사람인지 아닌지를 구분할 수 있을까라는 것이 문제다. 물론 질문은 여러분이 확신이 들 때까지 계속 할 수 있다.

이러한 이야기를 하면 대다수 사람들은 제일 먼저 하고 싶은 질문으로 상대와 나만 알고 있는 은밀한 내용을 꼽는다. 처음 데이트 했던 장소 라던지, 상대의 신체적 특징, 기호 등을 묻는 것이다. 하지만 이는 벽 반대편에 어떤 엉뚱한 존재가 우리의 사랑스런 사람을 인질로 잡고 있다면 전혀 의미가 없다. 협박을 해서 답을 얻어낼 수도 있기 때문이다. 이런 극단적인 상황까지 고려한다면 우리는 이 문제를 풀기 위해서 상대에게 어떤 질문을 던져야 할까? 또 과연 그러한 질문을 통해서 벽 반대편에 있는 보이지 않는 대상의 정체를 판별할 수 있을까?

가볍게 설명한 이 문제가 오랫동안 보안 업계에서 이슈가 되고 있는 원격 클라이언트의 인증 문제다. 인증이라는 말만 듣고 반사적으로 아이디와 비밀번호를 생각했다면 번지수를 잘못 짚었다. 여기서는 원격 사용자에 대한 인증이 아니라 원격에서 실행되고 있는 클라이언트 프로그램 그 자체에 대한 인증이기 때문이다. 그렇다면 원격 사용자도 아닌 원격지 클라이언트의 인증이 왜 그토록 중요할까?

이 문제가 주요 이슈로 부각된 분야는 다름아닌 게임이다. 게임의 경우에는 게임 플레이를 사람이 할 수도 있지만 기계가 할 수도 있기 때문이다. 생각해 보자. 여러분이 온라인으로 철수와 바둑을 두고 있는데 사실은 알고 봤더니 철수가 둔 것이 아니라 철수 컴퓨터가 뒀다면 어떨까? 물론 여러분은 졌다고 가정했을 때 말이다. 별 느낌이 들지 않는다면 다른 사례를 생각해보자. 요즘 유행하는 MMORPG 게임은 해당 가상 세계 속에서의 행위를 통해서 캐릭터를 육성하는 방식으로 진행되는 게임이다. 이러한 캐릭터 육성 과정에는 필연적으로 시간과 노력이 들어간다. 그런데 여러분은 그런 것들을 실제 여러분의 시간과 노력을 투입해서 얻은 반면에 철수는 철수 컴퓨터가 대신 게임을 해서 그런 것들을 자동으로 얻었다고 한다면 어떤 느낌이 들까?

물론 두 가지 사례 모두 여러분이 게임을 하지 않는다면 단지 기분 나쁜 사건 정도로 생각할 수 있는 문제다. 자본주의 세상답게 진짜 문제는 머니(money)가 개입했을 때 발생한다. MMORPG같은 온라인 게임의 경우에는 해당 가상 세계에서 통용되는 화폐가 실제 화폐와 교환 가지를 가진다. 즉, 가상 세계의 1골드가 실제 세계에서 100원에 팔릴 수 있다는 말이다. 실제로 소위 유명한 게임들의 경우에는 이를 환율과 같은 시세로 표기하는 사례도 있다. 이러한 가상 세계에서 골드를 획득하는 방법은 보통의 경우 사냥을 통해서인데, 이는 상당히 단순한 반복 작업을 필요로 한다. 이러한 반복 작업을 기계가 대신하고 그것을 운영한 사람이 부가적인 수익을 얻는다면 그것은 과연 공정한 일일까? 더욱이 이런 기계 때문에 가상 세계 속에서 사람이 획득할 수 있는 리소스가 줄어든다면 말이다.

여기에는 두 가지 중요한 이슈가 내포되어 있는데 하나는 이러한 부정 게임 방식이 게임 운영에 나쁜 영향을 미친다는 점이다. 생각해 보자. 누구나 부정 행위를 통해서 게임을 한다면 과연 그 게임을 누가 멍청하게 자신의 힘으로 하려고 하겠는가? 아마 아무도 하지 않고 전부 기계들만 게임을 하다가 결국 그 게임은 아무도 하지 않는 게임이 되고 말 것이다. 다른 한 가지는 이런 프로그램들이 아이템 거래 시장을 왜곡 시킨다는 점이다. 아이템 거래 시장이란 앞서 말했던 게임 머니를 실제 머니와 교환하는 시장을 말한다. 일반적인 경우라면 그 시장을 통해서 통용될 수 있는 게임 리소스는 제한적일 수 밖에 없다. 하지만 봇 프로그램의 등장으로 그 속에서 획득할 수 있는 게임 리소스가 폭발적으로 증가했고, 그것들은 별 노력 없이 획득한 것이기 때문에 아이템 거래 시장에서 낮은 가격에 팔릴 수 있다. 이는 결과적으로 정직하게 노력해서 해당 리소스를 획득한 사용자들에게는 자신이 획득한 리소스에 대한 가치를 불법적으로 하락 시키는 행위가 되는 셈이고 결국 시장은 공정하지 않은 상태가 되고 만다.

앞서 언급한 여러 가지 이유로 부정 클라이언트 프로그램이 자동으로 게임을 하는 행위는 좁게는 게임 업체에게 그리고 넓게는 게임 사용자들에게 다시 피해가 가기도 하는 것이다. 따라서 이런 부정 클라이언트 프로그램을 막는 것은 게임 업체에게는 굉장히 중요한 당면 과제라고 할 수 있다.

논클라이언트 봇
게임 업계에서는 앞서 설명한 것과 같이 벽 반대 편에 앉아서 마치 우리가 알고 있는 사람인척 하는 나쁜 프로그램을 두고 논클라이언트 봇(Non-client Bot)이라고 부른다. 좀더 엄밀히 말하자면 논클라이언트 봇이란 게임 프로토콜을 모방해 게임 클라이언트가 아닌 별도의 클라이언트가 게임 서버에 접속해서 플레이어와 같은 행위를 하는 것을 말한다. 즉, 논클라이언트라는 말은 클라이언트가 없다는 것을 봇이라는 말은 자동으로 게임 플레이를 한다는 것을 의미한다.

이렇게 복잡하게 프로토콜을 모방해서 논클라이언트 봇을 제작하는 이유는 게임 클라이언트에서 로딩하는 복잡한 그래픽 리소스 등이 필요하지 않아서 한 PC에서도 여러 개의 논클라이언트 봇 프로그램을 띄워서 동시 작업을 원활하게 할 수 있기 때문이다. 동시 실행이 원활하다는 말은 달리 표현하면 단위 시간당 더 많은 게임 리소스를 획득할 수 있음을 의미한다. 이러한 이유로 논클라이언트 봇은 주로 작업장이라고 불리는 곳에서 은밀하게 제작되기 때문에 실제로 구동이 되는 프로그램을 구하기는 쉽지 않다.

<그림 1>에는 정상적인 게임 클라이언트와 서버의 통신 구조가 나와 있다. C는 게임 클라이언트를 S는 게임 서버를 의미한다. 이 그림이 나타내는 의미는 서버가 Q라는 패킷을 전달하면 클라이언트가 R이라는 응답을 하는 구조로 통신이 이루어진다는 것이다. <그림 2>에는 이 구조를 도용한 논클라이언트 프로그램의 구조가 나와있다. 클라이언트는 변조되거나 새롭게 만든 NC이지만 통신 구조를 그대로 모방했기 때문에 게임 서버 입장에서는 이 클라이언트가 정상적인 게임 클라이언트 프로그램인지 아닌지를 판별할 방법이 없다. 논클라이언트 봇을 구현하는 핵심 기술은 이러한 게임 서버와 클라이언트의 통신 구조를 도용하는 것이다.


그림 1 정상 클라이언트 통신 구조


그림 2 논클라이언트 통신 구조

프로토콜 변형
이러한 논클라이언트 봇의 등장을 맞이한 게임 개발자들이 취한 그 첫 번째 대응은 프로토콜 변형이었다. <그림 3>에는 이렇게 통신 방법이 변경된 그림이 나와 있다. 기존의 Q와 R이 Qa, Ra라는 새로운 값들로 변경되었다. 따라서 기존 논클라이언트 봇은 이 서버와는 통신을 할 수가 없다.


그림 3 프로토콜 변조 통신 구조

이 방식은 일견 기존의 논클라이언트 봇을 일망타진하면서 동시에 논클라이언트 봇 제작자들에게 새롭게 프로토콜을 분석해야 한다는 짐까지 던져주는 셈이기 때문에 굉장히 효과적인 대응으로 생각되기 쉽다. 하지만 이는 큰 착각이다. 그 사실이 잘못된 가장 큰 이유는 기존의 서비스되고 있는 서버, 클라이언트의 프로토콜 구조 전체를 새롭게 설계하는 작업은 전혀 소프트하지 않기 때문이다. 사실상 이러한 작업을 한다는 것은 거의 미친 짓이나 다름 없다. 보통의 경우에 서비스되고 있는 프로그램에서 선택할 수 있는 방법의 최대치는 새로운 패킷 추가나 기존 패킷의 상수 값을 변경하는 정도가 전부다. 하지만 이러한 것들은 이미 프로토콜 전체가 분석된 논클라이언트 봇 제작자 입장에서는 전혀 어렵지 않은 과제다. 단순히 변경된 부분만 추적하면 되기 때문이다. 결과론적으로 이 방법은 막는 입장에서는 굉장한 노력이 필요하지만 공격하는 입장에서는 그렇게 많은 노력이 필요하지 않다고 할 수 있다.

여기까지 이야기를 듣고 보통 나오는 첫 번째 반응은 그러면 패킷을 암호화하면 되지 않냐는 질문이다. 그런데 이 말은 지금까지의 논의를 전혀 이해하지 못해서 나오는 반응이다. 논클라이언트 봇 제작자가 날패킷(raw packet)을 살펴보지 않는 것은 아니지만 어차피 그들은 게임의 거의 모든 코드를 꿰고 있으므로 암호화는 그들에게 큰 장애물이 되지 못한다. 필연적으로 해독하는 코드가 클라이언트에 같이 존재할 수 밖에 없기 때문이다. 즉, 아주 뛰어난 해커를 가정했을 때 패킷 암호화라는 것은 그 효과가 0이라고 할 수 있다. 물론 현실세계에 존재하는 수많은 어중이떠중이 해커를 고려한다면 하지 않는 것 보다는 하는 것이 효과가 있지만 실제로 논클라이언트 봇을 제작할 수 있는 수준의 실력자들에게는 큰 효과를 보기는 힘들다.

키인증
본격적으로 보안 업체가 관여하면서 나온 첫 번째 생각은 키인증이다. 키인증이란 클라이언트와 서버만이 알고 있는 비밀스런 질문과 답변을 주고 받자는 것이었다. 이 방법은 서버에서 클라이언트로 특정 키를 전송하고 클라이언트에서는 그 키에 대해서 아주 특수한 연산을 한 다음 그 값을 서버로 전송한다. <그림 4>에 이러한 방식의 통신 구조가 나와 있다. 서버와 클라이언트는 사전에 약속된 아주 비밀스러운 연산 E를 각자 가지고 있다. 이 상태에서 서버는 클라이언트에게 Q를 보내고 클라이언트는 그것을 자신이 가진 연산 E의 인자로 전달해서 나온 결과, R을 서버로 전송한다. 서버에서는 다시 동일한 연산을 수행해서 클라이언트가 응답한 R이 자신이 계산한 답과 맞는지를 비교해서 정상 클라이언트인지 아닌지를 판단한다.


그림 4 키인증 통신 구조

은행에서 사용하는 보안카드를 게임 클라이언트에 적용했다고 생각하면 쉽게 이해할 수 있다. 서버가 보내는 Q는 보안 카드의 인덱스를 의미하고 E는 보안 카드에서 인덱스에 대응하는 값을 찾는 과정을 R은 해당 보안 카드에 기록된 보안 코드 4자리 숫자를 의미하는 것이다. 상당히 유사한 만큼 이 방식은 은행 보안카드와 동일한 맹점을 가지고 있다. 보안카드 자체를 분실하면 무용지물이라는 점이다. 즉, 우리가 아주 은밀하다고 앞서 언급했던 연산 E가 도용되면 해킹툴도 얼마든지 정상 클라이언트로 둔갑할 수 있는 것이다. <그림 5>에는 이러한 연산 함수 E 코드를 도용한 논클라이언트 봇의 통신 구조가 나와있다.


그림 5 키인증 함수를 도용한 논클라이언트 통신 구조

연산을 도용한다는 것은 무엇을 의미할까? 컴퓨터에서 말하는 연산은 결과론적으로는 수행되는 코드의 집합. 즉, 함수가 된다. 앞서 <그림 4>에서 살펴본 연산 E가 아주 단순하게는 XOR이라고 생각할 수 있다. Q, R이 4바이트 정수이고 E는 XOR인 것이다. 그 규칙을 모르면 통신 구조가 어려워 보이지만 규칙을 알면 쉽게 도용할 수 있다. 물론 논클라이언트 봇 제작자들이 이렇게 날패킷(raw packet)을 보고 규칙을 추론해 내는 것은 아니다. 그들은 클라이언트 게임 코드를 보고 그 코드를 직접 가져다 사용한다.

<리스트 1>에는 원본 클라이언트에서 사용했다고 생각할 수 있는 SomeFantasticFunction이라는 연산이 나와 있다. 여기서는 간단하게 산술 연산을 수행한 후에 결과 값을 돌려준다. 이 코드를 컴파일해서 실행 코드를 생성하면 해당 코드에 대한 어셈블리어 코드가 어딘가에는 존재한다. 논클라이언트 봇 제작자들은 그 코드를 찾는 것이다.

리스트 1 원본 연산 함수

  1. ULONG SomeFantasticFunction(ULONG Q)  
  2. {  
  3.     ULONG R;  
  4.     R = (Q >> 13) * 34 + 1573;  
  5.     return R;  
  6. }  

<그림 6>에는 IDA와 같은 정적 분석 툴을 사용해서 해당 코드를 찾아본 화면이 나와 있다. 코드를 보면 오른쪽에는 어셈블리어 코드가 나와 있고 왼쪽에는 바이트 코드가 나와있다. 뛰어난 논클라이언트 봇 제작자라면 함수 자체의 기능도 이해하겠지만, 사실은 그럴 필요도 없다. 이 함수가 특정 시점에 수행된다는 사실만 확인하고 나면 그냥 바이트 코드를 그대로 긁어다 사용하면 되기 때문이다. <리스트 2>에는 이렇게 도용한 함수 코드가 나와 있다. 보면 알겠지만 함수는 바이트 코드를 저장해놓고 실행 시점에 가상 메모리에 복사한 다음 해당 함수를 다시 호출하는 구조로 되어 있다. 여기서는 간단하게 컨셉만 보여주기 위해서 이렇게 코드로 만들었지만 실제로는 이렇게 복잡하게 코드로 구성하지 않고도 손쉽게 도용할 수 있는 다양한 방법이 존재한다. 어쨌든 이 이야기의 결론은 특정 코드가 무엇을 하는지, 내지는 어느 시점에 수행되는 지만 판단하고 나면 그 코드를 훔치는 것은 식은 죽 먹기라는 사실이다.


그림 6 IDA로 살펴본 SomeFantasticFunction

리스트 2 도용한 함수 코드

  1. typedef ULONG (*SFFT)(ULONG Q);  
  2. ULONG SomeFantasticFunction(ULONG Q)  
  3. {  
  4.     UCHAR code[] =  "\x55\x8b\xec\x81\xec\xcc\x00\x00\x00"  
  5.                     "\x53\x56\x57\x8d\x8d\x34\xff\xff\xff"  
  6.                     "\xb9\x33\x00\x00\x00\xb8\xcc\xcc\xcc\xcc"  
  7.                     "\xf3\xab\x8b\x45\x08\xc1\xe8\x0d\x6b\xc0\x22"  
  8.                     "\x05\x25\x06\x00\x00\x89\x45\xf8\x8b\x45\xf8"  
  9.                     "\x5f\x5e\x5b\x8b\xe5\x5d\xc3";  
  10.   
  11.     PVOID cptr = VirtualAlloc(NULL  
  12.                                 , sizeof(code)  
  13.                                 , MEM_COMMIT | MEM_RESERVE  
  14.                                 , PAGE_EXECUTE_READWRITE);  
  15.     if(cptr)  
  16.     {  
  17.         memcpy(cptr, code, sizeof(code));  
  18.         SFFT sfft = (SFFT) cptr;  
  19.         ULONG R = sfft(Q);  
  20.         VirtualFree(cptr, 0, MEM_FREE);  
  21.         return R;  
  22.     }  
  23.   
  24.     return 0;  
  25. }  

무결성 검사
E를 도용 당한 보안 업계의 반격은 무결성 검사로 이어졌다. 이는 말 그대로 클라이언트의 내용물을 검사해서 진짜인지 아닌지, 변조가 있었는지 없었는지를 판별하겠다는 말이다. 앞선 키 인증이 사랑하는 사람과 둘만 알고 있는 기억에 대한 질문이었다면, 이는 사랑하는 사람이 가진 고유한 신체적인 특징을 묻는 것이라고 할 수 있겠다.

<그림 7>에는 이러한 경우의 통신 구조가 나와 있다. 서버는 Q라는 랜덤한 값을 보내고 클라이언트는 그 값과 클라이언트 프로그램 자체를 해시 함수 H에 입력으로 넣는다. 그러면 H 함수는 클라이언트에서 Q로 표기된 부분의 해시 값을 구해서 R에 저장한다. 서버에서는 구해진 해시 함수를 가지고 변조된 클라이언트인지 아닌지를 판단하는 것이다.


그림 7 클라이언트 무결성 검사 통신 구조

이 방식의 가장 큰 특징은 연산 H의 입력으로 클라이언트 프로그램 그 자체를 넣도록 만들었다는 점이다. 따라서 클라이언트에 가해진 사소한 수정 사항도 모두 검사할 수 있다. 하지만 과연 이 방법으로 논클라이언트 봇을 막을 수 있었을까? 안타깝게도 아니다. 앞선 키 인증과 마찬가지로 논클라이언트 봇이 클라이언트 프로그램 자체를 도용한다면 여전히 무용지물이 되기 때문이다. <그림 8>에는 이러한 방식으로 게임 클라이언트 프로그램 C와 해시 함수 H를 도용한 논클라이언트 봇의 통신 구조가 나와 있다.


그림 8 클라이언트 및 해시 함수를 도용한 논클라이언트 통신 구조

앞서 함수를 도용하는 것에 대해서는 설명했다. 그렇다면 게임 클라이언트를 도용한다는 것은 무슨 의미일까? 그 말에 대한 해답이 <리스트 3>과 <리스트 4>에 나와 있다. <리스트 3>은 정상 게임 클라이언트의 응답 함수가, <리스트 4>에는 논클라이언트 봇의 응답 함수가 나와 있다. 이 둘의 차이를 보면 알겠지만 정상 클라이언트는 H 함수에 현재 실행되고 있는 프로그램을 입력으로, 논클라이언트 봇은 자신이 도용한 클라이언트 프로그램을 입력으로 넣는 차이를 가지고 있다. 즉, 이 경우에는 앞선 함수 도용처럼 Reply 함수를 통째로 도용하는 경우에는 동작을 하지 않겠지만 <리스트 4>에 나와 있는 것처럼 약간의 수정을 가한 후에 사용한다면 서버와 통신이 가능하다.

리스트 3 원본 응답 함수 코드

  1. ULONG Reply(pvoid received_data)  
  2. {  
  3.     R = H(GetModuleHandle(NULL), data);  
  4.     send(R);  
  5. }  

리스트 4 논클라이언트 봇 응답 함수 코드

  1. GameClient = LoadGameToMemory();  
  2.   
  3. ULONG Reply(pvoid received_data)  
  4. {  
  5.     R = H(GameClient, data);  
  6.     send(R);  
  7. }  

이 방법을 우회하는 논클라이언트 봇의 핵심은 <리스트 4>에 나와 있는 LoadGameToMemory 함수다. 이 함수는 게임 클라이언트를 로딩하는 역할을 한다. Windows 실행 포맷인 PE 파일의 구조는 이미 분석이 많이 되었기 때문에 이러한 별도의 실행 파일을 메모리에 올리는 작업은 무척이나 간단하다. 물론 실행 파일 자체에 자가 수정 코드나 폴리모픽, 메타모픽 등의 기법을 적용해서 단순히 로딩 만으로는 실제 구동되는 단계의 클라이언트와 다르도록 만들 수 있다. 하지만 이 또한 VM 환경을 사용하면 간단하게 해결할 수 있다. VM 환경이란 실제 CPU를 사용해서 구동하는 것이 아닌 가상의 메모리 공간과 가상의 CPU를 사용해서 게임 클라이언트 코드를 에뮬레이팅해서 푸는 작업을 말한다.

타이밍 체크
이 방법은 실상 필드에서는 큰 효과가 없는 방법이나 논문에서는 흔히 등장하는 해법 중에 하나다. <그림 9>에 나온 것처럼 해당 연산을 수행하는데 소요된 시간을 같이 보낸다는 것이 핵심 개념이다. 그림에서는 t가 E라는 연산을 수행하는데 소요된 시간을 나타낸다. 물론 t 값은 R안에 은밀하게 포장될 수도 있다.


그림 9 타이밍 체크를

우선 이 방법의 가장 큰 문제점은 범용 OS가 보통은 RTOS가 아니라는 점이다. 이는 시간 측정이 정확할 수 없다는 이야기다. 모든 스레드나 프로세스는 다른 스레드나 프로세스에 의해서 선점될 수 있고, 이는 곧 정상 환경에서도 실제 동작 시간이 지연될 수 있음을 의미한다. 또한 클라이언트가 구동되는 실행 환경은 천차만별이라는 점도 문제점이다. 같은 게임을 셀러론 CPU에서 실행하는 사용자도 있고, i7 쿼드 코어 컴퓨터에서 실행하는 사용자도 있다. 이 둘의 실행 시간은 아주 당연하게 전혀 같지 않다.

그리고 결정적으로 앞선 무결성 검사에서 살펴보았던 것처럼 연산 E는 도용뿐만 아니라 변조도 당할 수가 있다. 따라서 이 경우에는 정상의 경우 t가 일정한 값으로 나올 것이기 때문에 조작을 해서 실행 시간에 상관 없이 같은 시간을 보내도록 하면 손쉽게 우회할 수 있다.

물론 이렇게 여러모로 실전에서 사용하기에는 다소 부족한 점이 많은 방법이지만 이 방법을 소개한 이유는 이 방법의 경우 기존 방법과 달리 직접적인 값 보다는 간접적인 값을 통해서 논클라이언트 봇을 진단하려고 했다는 점이다. 즉, 기존 방식들이 예, 아니오의 답을 원하는 닫힌 질문이라면 이 방법은 주관식으로 답할 수 밖에 없는 열린 질문이라는 점이다. 즉, 시간이라는 변수 외에도 이러한 열린 질문을 통해서 정상 클라이언트를 판단을 할 수 있는 방법이 존재한다면 이 테크닉은 논클라이언트 봇에 대한 좋은 대응 방법이 될 수도 있다.

CAPTCHA
지금까지 우리는 이 문제를 논클라이언트와 정상 클라이언트를 판단하는 것으로 파악했다. 하지만 이것들 전혀 새로운 관점에서 기계와 인간을 구분하는 관점에서 바라본 해법이 CAPTCHA다. CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)는 흔히 인터넷에서 자동 가입 방지용으로 사용되는 사람인지 기계인지를 테스트하는 방법을 말한다. <그림 10>와 같이 아주 이상하게 생긴 문자열을 보여주고는 그대로 다시 입력하라고 하는 방법이 대표적이다. 사실 사람도 이해하기가 쉽지 않다.


그림 10 사람도 이해하기 힘든 인증

이 방식을 논클라이언트 봇 문제에 적용하는 것은 간단하다. 위와 같은 이미지 코드가 Q가 되고 사용자가 입력한 문자열이 R이 되는 것이다. 물론 입력 받는 함수가 연산 E가 되겠다. 이 경우에는 CAPTCHA라는 방식 자체가 기계가 자동으로 답을 판단할 수 없도록 고안되었기 때문에 이론적으로는 사람이 개입할 수 밖에 없다. 즉, 자동으로 입력하는 것이 불가능해진다는 의미이고, 그렇다면 논클라이언트 봇은 자연스럽게 의미가 없어진다.

물론 이 방법도 논클라이언트 봇이 작정하고 자동화를 하겠다고 다짐을 한다면 할 수 있는 방법이 전혀 없는 것은 아니다. 서버가 가지고 있는 모든 이미지 코드에 대한 결과 값을 수집한 다음 해당 값들에 대한 매핑 함수를 제작하는 것이다. <그림 11>에 이러한 방법이 나와 있다. 모든 가능한 Q들에 대한 R을 구한 다음 그것 사이를 매핑하는 M 함수를 제작해서 자동으로 대답하는 방법이다. 하지만 이 경우에는 앞선 프로토콜 변경과 마찬가지로 논클라이언트 봇 제작자 입장에서는 무척 힘든 작업이지만 서버 쪽에서 요청의 내용을 교체하는 것은 쉽다는 특징이 있다. 즉, 서버 쪽에서는 데이터만 교체하면 순식간에 모든 논클라이언트 봇이 무력화되고, 논클라이언트 봇 제작자는 모든 요청과 결과에 대한 내용을 다시 수집해야 한다는 말이다. 더욱이 이런 교체 작업은 자동화 시킬 수 있기 때문에 논클라이언트 봇 제작자 입장에서는 이러한 M을 만들어서 대응하는 것은 사실상 의미가 없다.


그림 11 매핑 함수를 사용한 논클라이언트 봇

CAPTCHA 방식이 가지는 문제점은 이러한 논클라이언트 봇에 대한 대응력이 아닌 다른 곳에 있다. 바로 저 문자열을 입력하라는 귀찮은 과정을 게임 플레이 중간 중간에 하게 한다면 과연 어떤 사용자가 그 게임을 하고 있겠냐는 점이다. 사실 인터넷 사이트도 CAPTCHA가 적용된 곳은 진짜 필요한 곳이 아니면 가입이 꺼려지는 것이 사실이다. 더 중요한 사실은 이런 입력의 경우 기계뿐만 아니라 사람도 이해하기 힘들며 종종 틀린다는 점이다. 따라서 실제로 이를 게임이나 특정 클라이언트 프로그램에 적용하는 것은 실용적인 관점에서의 한계가 존재한다.

그렇다면 사람이 귀찮아 하지 않는 CAPTCHA 방식을 사용하면 괜찮을까? 그런 것들 중에 하나가 게임 상에서 GM(Game Master)들이 하는 말걸기가 있다. GM들이 필드에서 이상 행위를 반복하는 사람들을 보면 말을 걸어보고 제대로 된 대답을 하지 않는다면 자동 플레이로 간주하고 해당 사용자를 퇴장 시키는 방법이다. 그럴듯해 보이지만 요즘 나오는 논클라이언트 봇은 GM의 질문에 대한 몇 가지 대답들을 미리 준비해 놓거나 주변에 GM이 오면 자동으로 다른 곳으로 움직이는 기능을 추가하고 있는 경우도 있다. 따라서 이러한 비강제성 CAPTCHA 방식은 효과를 가지기가 쉽지 않다.

그럼에도 이 방식이 의미가 있는 것은 새로운 CAPTCHA 방식이 강제성을 가지지만 사람은 전혀 귀찮음을 느끼지 않고, 오히려 흥미를 느끼며, 사람이라면 거의 99.9%의 확률로 틀리지 않는 방식이라면 논클라이언트 봇을 손쉽게 무력화 시킬 수 있는 가장 강력한 방법이라는 특징 때문이다.

데이터 마이닝
끝으로 소개할 방법은 데이터 마이닝이다. 이 방법은 논클라이언트 봇 문제를 정상 플레이어와 비정상 플레이어의 문제로 바라본 해결책이다. 간단하게 소개하자면 서버 쪽에서 개별 플레이어의 행위를 모두 파악한 다음 그것을 토대로 데이터 마이닝을 해서 해당 플레이어가 정상의 범주에 속하는지 비정상의 범주에 속하는지를 판별한다는 것이다.

이론적으로는 굉장히 깔끔해 보이지만 실상 이 방법은 많은 단점을 가지고 있다. 우선 플레이어의 모든 행위를 기록내지는 실시간으로 판별해야 한다는 점이다. 이를 위해서는 추가적인 많은 리소스가 투입될 수 밖에는 없다. 그리고 그것을 자동적으로 판별하는 함수를 제작하는 것도 쉬운 일은 아니다. 논클라이언트 봇이 문제가 되는 MMORPG 류의 게임에서 정상의 플레이어 임에도 논클라이언트 봇처럼 플레이를 하는 사용자들도 많기 때문이다.

하지만 그런 모든 단점을 극복했다고 하더라도 정말 이 방법이 효과가 없을 수 밖에 없는 마지막 약점이 있다. 논클라이언트 봇이 정상의 범주와 같이 플레이를 한다면 이 방법으로는 절대로 논클라이언트 봇을 잡을 수 없다는 점 때문이다. 물론 그것이 문제가 되지 않을 수 있다고 생각할 수 있겠지만 기계가 사람을 대신하여 게임을 자동으로 플레이한다는 관점에서는 여전히 공평하지 않다.

결론적으로 다시 설명하자면 이렇다. 이 방법에서 생각하는 정상과 비정상을 구분하는 방법을 담고 있는 함수를 P라고 가정하자. 이 P라는 함수가 정상의 범주를 좁히면 좁힐수록 정상 플레이어도 차단되는 경우가 생기는 문제가 발생한다. 반면에 이 P라는 함수가 정상의 범주를 넓히면 넓힐수록 비정상 플레이어가 차단되지 않는 경우도 생긴다. 결정적으로 논클라이언트 봇 제작자는 이 P의 범주를 파악해서 딱 그 범주의 최대치만큼만 부정적인 방법으로 플레이를 한다면 이 방법은 무용지물이 된다. 즉, 이 P의 판단 범주를 어떤 범위에 두더라도 논클라이언트 봇은 항상 그것을 통과할 수 있다는 점에서 이 방법은 좋은 대안이 되기는 힘들다.

끝은 없다
여기까지가 그간 논클라이언트 봇에 대응하는 게임 업계, 보안 업계, 그리고 학계의 생각들이다. 하지만 개별 항목에서 설명한 것처럼 하나같이 단점 없는 방법이 없으며, 완전하게 논클라이언트 봇을 탐지할 수 있는 방법은 더더욱 없다. 그래서 이 문제가 더욱 매력적인지도 모르겠다.

다시 제일 앞 소개 글에서 했던 질문을 해보자. 과연 여러분은 질문을 통해서 벽 반대편에 있는 사람의 정체를 판단할 수 있을까? 결론은 불가능하다. 왜냐하면 질문과 답변이라는 메커니즘 자체가 이미 결정돼 있는 것들이기 때문이다. 여러분이 질문을 던지는 순간 그 해답은 이미 나와 있는 것이라는 말이다. 이는 결국 그 질문들을 미리 다 알고 있는 상대라면 얼마든지 여러분의 판단을 흐리게 만들 수 있다는 것을 의미한다.

하지만 이러한 이론적인 결론 때문에 기죽을 필요는 없다. 실제 현실 세계에 존재하는 논클라이언트 봇 제작자가 우리가 가정한 신적인 존재는 아니라는 점 때문이다. 그들도 결국 사람이기 때문에 모든 코드들을 한번에 다 파악할 수는 없다. 문제는 얼마나 적은 리소스를 사용해서 효과적으로 그들을 괴롭히는가에 달려있다.

이런 이야기가 끝날 즈음엔 사람들은 항상 왜 보안 업체가 완벽하게 막을 수 없는지를 궁금해 한다. 그러면서 잘 생각해 내면 뭔가 마법 같은 방법으로 이 모든 것을 해결해 낼 은탄환(silver bullet)이 있지 않을까라는 생각도 덧붙인다. 이 싸움이 원숭이나 개나 고양이와의 싸움이었다면 그런 은탄환이 존재했을지도 모른다. 하지만 이 싸움은 적어도 우리와 동등한 내지는 우리보다 더 나은 지능을 가진 사람들과의 싸움이다. 우리가 완벽하게 막을 방법을 생각해 낸다는 건 그들이 완벽하게 우회할 방법을 생각해 낼 수 있다는 말과 같은 의미다. 결국 이 싸움은 뫼비우스의 띠처럼 끝없이 반복될 수 밖에 없는 구조로 되어 있는 것이다.



Read more: http://www.jiniya.net/wp/archives/4372#ixzz3NCSwNayB

반응형
반응형

게임 보안: 인력에 관한 불편한 진실…
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaruhttp://www.jiniya.net

국내 게임보안 업체 중에서 우리 회사가 가장 영세하다. 가장 후발 주자다. 그러다보니 업체 미팅을 하다보면 으례 듣는 이야기가 있다. 그 인력을 가지고 지원이 되겠냐는 이야기다. 그런데 아이러니한 사실은 그렇게 이야기 했던 많은 업체들이 사용하고 난 다음에는 지원이 참 좋다는 이야기를 한다. 해킹툴을 잘 잡는다는 이야기도 한다. 왜 그럴까?

여기에는 게임 업체에서는 전혀 생각하지 못하는 정말 불편한 진실이 숨어있기 때문이다. 바로 MPS다. MPS가 뭐냐고? Man Per Site다. 사이트당 몇 명의 인력이 대응하는지를 나타내는 수치라고 생각하면 되겠다. 과연 이 수치가 얼마일까? 1정도는 될까? 당연히 안된다. 1이면 게임보안 업체는 아마 한 십년 전에 모두 망했을 것이다. 그렇다면 어느 정도일까? 여러분이 생각하는 것보다 훨씬 낮다. 0.1이 되는 업체가 잘 없다. 즉, 게임 10개 사이트에 한 명이 채 되지 않는다는 말이다. 반대로 말하면 한 사람이 열 개 이상의 사이트를 커버해야 한다는 말이다. 이러니 무슨 보안이되고 무슨 해킹툴 컨트롤이 되겠는가? 당연히 되지 않을 수 밖에 없다. 메이저 업체들이 그렇게 해킹툴을 못막는 이유가 바로 여기 있는 것이다. 관심이 없어서가 아니다. 사람이 없는데 무슨 수로 해킹툴을 막겠는가? 당연히 우리는 0.1은 넘는다. 아직까지는. 그러니 다른 업체보다는 잘 할 수 밖에 없는 것이다.

그렇다면 이 MPS 수치가 어느 정도면 해킹툴 제어가 가능할까? 내가 생각하는 최소 수치는 0.57이다. 무슨 근거로 그런 이야기를 하느냐고? 바로 4명이서 7개 사이트를 커버하는 수준이다. 그렇다면 그 4명과 7개 사이트는 어디서 나왔을까? 우선 해킹툴이 출몰하는 정도로 인기있는 온라인 게임의 경우 통상 수출하면 7개국 정도는 깔고 가는 경우가 많다. 따라서 7개 사이트라는 말은 하나의 게임을 4명이서 컨트롤 한다는 말과 동일하다. 그렇다면 4명은 어떤 사람일까? 검색 한명, 분석 한명, 개발 한명, QA 한명이다. 이걸로 될까? 뻥안치고 저정도 인력 투입하면 거의 모든 해킹툴 사이트를 다 다운시킬 수 있다. 물론 기반 시스템은 모두 갖추어져 있다는 전제 하에서다. 기반 시스템 없이 4명이서 무얼 하겠는가? 또 물론 그 4명이 겁나 똑똑하다는 전제하에서다.

그런데 정말 안타까운 현실은 많은 게임 업체들이 해킹툴 차단에 관심은 많다고 하지만 MPS 0.57에 대한 투자 조차도 인색한 경우가 많다. 국내 게임보안 업체들은 모두 연간 구독(annual subscription) 형태로 제품을 판매한다. 그런데 이 구독료가 십년 전이나 지금이나 별반 차이가 없기 때문이다. 지금 시세로 따져보면 그 일년 구독료가 통상 MPS 0.1에서 0.2 사이다. 그러니 회사 입장에서 차떼고 포떼고 하면 MPS 0.1 이상 투입하기가 힘든 것이다. 흙. 상황이 이러면 메이저 게임보안 업체에서라도 인식을 바꾸도록 테이블을 새로 구성해야 함에도 현실은 그렇지가 못하다. 같이 치킨 게임을 하는 경우가 다반사다. 이러니 게임보안 제품이 좋아지고 싶어도 좋아질 수가 없는 환경인 것이다.

자자. 여기저기서 웅성 거리는 소리가 들려오는 것 같다. 맞다. 규모의 경제가 있다. 일정 규모를 넘어서면 깔고가는 인력이 당연히 생기게 마련이다. 하지만 그 깔고가는 수많은 인력 중에서 여러분의 게임 게시판 내지는 해킹툴 포럼을 모니터링해주는 인력이 있다고 생각하면 정말 큰 오산이다. 안한다. 왜냐고? 그 깔고가는 수많은 인력은 말 그대로 공유인력이기 때문이다. 그들은 그런 일외에도 할 일이 너무도 많기 때문이다. 그러면 스스로 알아서 한 번은 하지 않을까? 라고 생각할 수도 있는데. 뻥안치고 안한다. 사람이기 때문이다. 잠깐 짬나면 나가서 담배펴야지 그거 모니터링 하겠는가? 난 다른 일도 많이 했는데, 라고 생각하면서 신나게 나가서 담배피게 돼 있다. 그러니 공유인력을 계산에 넣는다는 자체가 넌센스다.

그러면 다음으로 나오는 이야기들이 있다. 기술을 개발해서 원천 차단을 하면 되지 않겠냐는 것이다. 근데 이게 진짜 정말 골때리는 이야기다. 아니면 게임 업체들이 하는 오해일 수도 있겠다. 그런 오해를 하는 많은 분들을 위해서 조금 원천차단이라는 말의 실제 의미를 풀이해보자면 이렇다. 모든 게임보안 업체에서 말하는 원천차단이라는 말은 Visual C++을 일주일 배우고 나서 해킹툴 커뮤니티에서 소스를 퍼다가 변수 오프셋을 조금 수정해서 해킹툴을 만드는 경우에 대한 대응을 자동으로 할 수 있는 기술이라고 이해하면 되겠다. 물론 어러분도 잘 알고 있는 것처럼 안타깝지만 이것 조차도 잘 안되는 경우도 많이 있긴 하다. 그러니 어떤 업체와 미팅을 하는데 원천차단에 대해서 이야기를 한다면 ‘아 이건 코흘리게들을 막는 기술인데 다른 업체는 이것도 안되나 보구나’라고 이해하면 되겠다.

저 수많은 초록색 Undetected!!! 현기증이 ㅠㅜ~
하지만 MPS 0.57에 좋은 게임보안 제품을 사용한다면 저 목록에서 빠지는 것도 불가능 한 일은 아니다. 

그럼 게임 업체들을 고민에 빠뜨리는 진짜 해킹툴들은 어떤 것들일까? 저런 꼬맹이들이 코흘리면서 만드는 장난감일까? 당연히 아니다. 게임 업체를 고민에 빠뜨리고, 게임 서비스 자체를 종료시키게 만드는 유료핵들은 수년간 Visual C++을 갈고 닦았고 (<== 해킹툴 소스가 더럽다고 생각하면 오산이다.) 어셈블리에도 능통하면서, 리버싱도 잘하는 그런 애들이 알바해서 돈을 벌려고 만드는 것들이다. 물론 심한 경우에는 기업에서 하는 경우도 있다. 심지어는 보안회사, 게임회사보다 그 기업이 더 클 수도 있다. 여기에다 원천 차단이란 말을 쓴다는 건 내년까지 단 한번도 비가 오지 않을 거라는 걸 보장하는 것과 주식이 5000까지 쭉 갈거라는 걸 보장하는 것과 똑같은 의미다. 미래에 일어날 일에 대한 보장이란 것이다. 당연히 말도 안되는 소리라는 것을 알 수 있다. 여기엔 원천 차단이란 있을 수도 없고, 그런 말을 쓰는 것도 넌센스다.

그렇다면 무슨 차이가 있는가? 단지 해킹툴이 나왔을 때 얼마나 신속하고 정확하게 대응하느냐의 차이 밖에는 없다. 당연히 여기서 대응한다는 말은 그 지겹도록 매일 올라와 있는 초록색 Undetected라는 말을 적어도 이틀 이상은 빨간색 Detected라는 말로 바꾸는 경우를 말한다. 이 정도 억제력을 우습게 생각할 수 있다. 그렇다면 여러분이 사용하는 보안 제품 업데이트 이후에 해킹툴 페이지를 꼭 방문해 보길 바란다. 그러면 이 이틀이란 시간이 얼마나 영겁의 시간인지를 금방 알 수 있을 것이다. 물론 여러분이 선택한 보안 제품이 진짜 탁월하다면 그 목록에서 여러분의 게임이 영원히 제거되는 기적을 경험케 해 줄 것이다.

누구나 공정한 게임을 하고 싶어한다. 그래야 재미있기 때문이다.

게임 시장은 점점 더 커져가고 있다. 당연히 이러한 블랙마켓도 점점 커지고 있다. 더불어 요즘 온라인 게임의 출시에는 항상 이런 질문이 따라 다닌다. 안티 치트 솔루션은 무엇을 사용하는가? 치트 대책은 무엇인가? 이런 것들이 이제는 일반화 됐다는 이야기고 또 온라인 게임에 있어서는 굉장히 중요한 이슈라는 의미일 것이다. 자 이제 결론을 내려보자. 그렇다. 회사에 직원이 많다는 이야기가 여러분의 게임에 관심을 가지는 사람이 많다는 것을 의미하는 건 아니다. 또 해킹툴을 더 잘 막고 관리하기 위해서는 MPS 0.57이라는 최소한의 투자는 이루어져야 한다. 이런 것들이 이루어진다면 클린한 온라인 게임 환경을 만드는 일이 결코 불가능한 일은 아니다.

아직 이 모든 이야기의 맥락을 눈치채지 못한 분들을 위해서 딱 한 마디만 더 하자면, ㅋㅋ~
게임보안 하면 XIGNCODE, XIGNCODE하면 게임보안이라는 거. 답 딱 나온다. ㅋㅋ~


고기도 먹어 본 놈이 잘 먹고, 연애도 해 본 놈이 잘 하고, 해킹툴도 막아 본 놈이 잘 막는다.
우리는 최고의 팀을 가지고 있다. 그게 바로 우리가 이런 이야기를 들을 수 있는 이유다.





Read more: http://www.jiniya.net/wp/archives/6174#ixzz3NCS7CdOg

반응형

+ Recent posts