'프로토콜'에 해당되는 글 1건

  1. 2010.09.26 게임 등의 어플리케이션 개발 시 바람직한 프로토콜 설계 1 (1)
2010.09.26 00:58

개요: 해킹의 취약한 유형의 프로토콜이 무엇인지,  안전한 프로토콜을 작성하기 위한 전략엔 어떤 것이 있는지 소개합니다.
필독: X
조건: 패킷의 개념 정도만 이해하시면 됩니다
난이도: 하 

 *틀린 부분은 지적해주시면 바로 수정하겠습니다(코딩오류, 오타 등).
게임 핵을 만든다고 개설된 커뮤니티들에서는 이러한 이름의 익스플로이팅을 자주 볼 수 있습니다:

미스핵
강화핵
데미지핵
etc..


 말인즉 데미지를 받아도 항상 0으로 받고, 강화나 인챈트 등을 하면 무조건 성공하며, 상대에게 주는 데미지를 마음대로 수정할 수 있다는 것입니다.

 이런 종류의 취약점은 전에 작성하였던 해킹 방지 프로그래밍 기법 1 에서 사용하였던 방법대로  변수에 대한 메모리 접근 보호를 클라이언트 측에서 수행하여 방어할 수도 있습니다.

 하지만 이 방법은 100퍼센트 안전한 방법이라고 말할 수 없습니다. 리버싱에 불가능은 없다고 가정하는 것이 좋습니다. 해커가 충분한 노력과 시간을 들인다면 개발자가 제작한 게임이나 기타 어플리케이션의 기계어 코드와 리소스를 가지고 거의 똑같거나 완벽하게 똑같은 프로그램을 직접 작성하는 것도 아예 불가능하지는 않습니다. 또 이런 극단적인 상황에서 아무리 메모리 해킹에 대한 방어를 철저히 한다고 해도 소용은 없을 것입니다.

 가장 확실한 방법은 프로토콜 자체의 취약점을 없애는 것입니다. 개발자가 정말로 신용할 수 있는 모든 정보는 서버에 있습니다. 클라이언트가 어떤 정보를 보내오든, 그것을 바로 신용해서는 절대로 안됩니다.

 위에서 언급한 익스플로이팅 중 '데미지핵'에 대한 간략한 시나리오를 세워보자면 다음과 같습니다.

 개발자는 클라이언트가 몬스터에게 데미지를 입으면 그 데미지를 클라이언트가 계산하여 서버에 보낸다. 그리고 서버는 클라이언트가 보낸 데미지 정보를 토대로 몬스터의 체력을 깎는 등의 연산을 수행하는 구조이다.

 해커는 보호되어있는 '데미지 계산 루틴'을 찾아 입맛에 맞게 수정한다, 혹은 패킷을 보내는 루틴을 후킹하여 데미지 부분의 정보만 수정한다.

 서버는 클라이언트에게서 도착한 데미지 정보를 신용하고, 해커가 공격했던 무☆적의 보스몹은 짧은 인생을 마감하게된다.

 이러한 익스플로이팅이 가능한 이유는 서버가 클라이언트가 보낸 정보를 그대로 신용한다는 점에 있습니다. 하지만 데미지 연산에는 (아마)랜덤한 상수가 포함되어있을 것이고, 그 랜덤한 상수를 포함하였을때 가장 데미지가 큰 경우'를 가지고 서버 측에서 데미지를 검증하는 방법이 이 프로토콜을 사용하였을 때 가장 바람직한 방법입니다만, 그것 역시 문제가 있습니다.

 '해커는 무조건 최대데미지를 서버에 보낸다' 라는 상황이 발생할 수 있습니다.

 결국 개발자는 이러한 프로토콜 자체를 뜯어고쳐야 할 필요가 있습니다. 근본적인 원인은 클라이언트가 데미지의 수치를 계산할 수 있다는 점에 있습니다. 클라이언트가 데미지를 계산할 수 없는 프로토콜을 제작한다면 아무리 뛰어난 리버서라도 서버 내부에서 연산되는 데미지의 수치를 바꿀 수는 없습니다. 

 다음과 같은 프로토콜에는 이러한 익스플로이팅이 불가능합니다.

개발자는 클라이언트가 몬스터에게 데미지를 주었다는 사실만 서버에 알린다.

서버는 그 정보를 받아 들고 데미지를 알☆맞★게 계산하여 몬스터의 데미지를 깎아 내리고 데미지가 얼마인지 클라이언트에게 통보해줍니다.

 물론 모든 데미지의 수치를 서버가 계산해야 된다는 점에서 서버의 부하가 늘어나는 것은 어쩔 수 없습니다. 하지만 그러한 부하도 서버의 설계만 잘 해놓았다면 쉽게 줄일 수 있습니다.

 일반적으로 데미지를 계산할 때 필요한 상수는 쉽게 바뀌지 않습니다. 일단 클라이언트가 착용한 장비의 영향을 받을 것이고, 간혹 소지품의 영향을 받는 경우도 있을 것이고, 마법같은 시스템이 있다면 그것의 영향 역시 받을 수 있습니다.

 부하를 줄일 전략을 세워보자면 이렇습니다.

 데미지에 필요한 상수를 그 상수에 영향을 끼치는 요소(장비, 마법 등의 효과로 인하여)가 바뀔때마다 미리 계산해두고 랜덤한 상수의 범위를 계산해둡니다. 장비나 마법등에 의해 상태가 바뀌는 경우는 그렇게 많지 않습니다.

 하지만 이 두가지 정보만 계산해 두면 서버는 데미지를 아래와 같은 아주 단순한 방법으로 구할 수 있습니다.

Dmg  = 계산된고정상수 + rand() % 랜덤상수의최대값
 이정도 연산에서 생기는 부하가 아깝지는 않을 것입니다. 이제 개발자의 서버에서는 절대로 '데미지핵'과 같은 익스플로이팅이 불가능합니다.




 2편에서는 아마도 시간 계산에 관련된 익스플로이팅(공격속도, 스킬 쿨타임이나 '스피드핵' 유틸리티 등)에 관하여 포스팅하게 될 것 같습니다.
 졸리네요 바이바이 ><
Posted by 라이에