목차

반응형

1. 개요

2. ASLR : 메모리 주소는 항상 바뀐다

3. 게임 가디언 VS 유니티 앱

3-1. 메모리 주소 접근 unsafe 코드

4. 게임 가디언 VS 안티 치트 변수 암호화 기능

4-1. 안티 치트 obscured 변수 암호화 원리

5. 게임 가디언 VS 안티 치트 변수 암호화 기능 강화 버전

5-1. 개발 도중 이상한 점(슈뢰딩거의 변수)

6. 게임 가디언 VS 메모리 변조 디텍터

7. 결론

 

 

 

 

 

 

 

1. 개요

와 목차만 봐도 양이 굉장히 많다.

근데 실제로 회사에서 이것만 연구하느라 거의 2일 정도 시간을 소비했다.

회사에서 안티치트라는 무려 50$짜리 해킹 방지 에셋을 사용하는데 쓰는 것은 좋은데 어떤 원리로 작동하는지 그리고 실제로 해커 입장에서 테스트해보면서 해킹 방지가 되는지 누군가는 확인해보고 연구해볼 필요가 있다고 생각이 되어서 연구를 하게 되었다.

유니티 게임 개발자들도 이 글을 읽고 많은 도움이 되었으면 좋겠다.

재밌게 탐구하기도 했고 안티 치트를 뚫어서 메모리 변조를 해보고 싶다는 생각이 들었다. 언젠가 시간이 나보면 해볼 거다.

해킹 개깐지

 

계속해서 언급할 안티 치트 에셋(꼭 없어도 괜찮다. 어떤 식으로 암호화를 하는지 세세하게 보여줄 것이기 때문에 이해만 하면 되겠다.)

https://assetstore.unity.com/packages/tools/utilities/anti-cheat-toolkit-152334

 

Anti-Cheat Toolkit - Asset Store

🌎 demo ▶ videos 💬 forum 📄 API reference 💌 support 🕵 Anti-Cheat Toolkit (ACTk) 🕵 is here to add some extra pain to the guys who cheat / hack / crack something in your game. Includes various anti cheat tricks and techniques in one place, easy to use, with fu

assetstore.unity.com

 

2. ASLR : 메모리 주소는 항상 바뀐다

먼저 본격적으로 실험에 들어가기 전에 한 가지 알아둬야 하는 개념이 있다.

Address Space Layout Randomization

 

간단히 말하자면 앱이 실행될 때마다 메모리 주소가 랜덤 하게 배정되어서 내가 만든 게임에서 gold 변수가 가지는 메모리가 앱을 실행할 때마다 다른 메모리 주소를 갖게 되는 것이다.

이렇게 함으로써 앱의 보안을 강화시킬 수 있다고 한다.

그렇기 때문에 앞으로 있을 메모리 해킹에서 해킹할 변수는 동일하지만 메모리 주소는 계속해서 바뀐다는 것을 알아두도록 하자.

 

ASLR에 대한 자세한 내용은 아래 위키에 잘 나와있다.

https://en.wikipedia.org/wiki/Address_space_layout_randomization

 

Address space layout randomization - Wikipedia

Address space layout randomization (ASLR) is a computer security technique involved in preventing exploitation of memory corruption vulnerabilities. In order to prevent an attacker from reliably jumping to, for example, a particular exploited function in m

en.wikipedia.org

 

좀 특이한 점이라면 생각보다 고안되고 적용된 지 오래된 기술은 아니라는 점

안드로이드는 2015년도에 본격적으로 채택, MAC, 리눅스, 윈도우 전부 2000년대에 본격적으로 도입되었다.

 

 

3. 게임 가디언 VS 유니티 앱

자 그럼 이제 본격적으로 유니티 앱에서 게임 가디언을 통해 메모리 변조를 해볼 건데 간단하게 정말로 게임 가디언이 해킹하는 변수의 주소가 실제 변수의 주소가 맞는지 확인해볼 것이다.

 

해킹할 변수는 InGameGold 인게임 골드다.

코드를 보면 

inGameGold라는 private 변수의 메모리 주소를 받아와서 출력해준다.

이 주소를 유니티의 텍스트에다가 넣어줘서 핸드폰에서 확인이 가능하도록 하였다.

 

그리고 평범하게 게임 가디언으로 쉽게 뚫어서 변수의 주소를 찾았다.

 

게임의 한가운데에 보면 텍스트가 하나 있는데 인게임 골드 변수의 주소다. 둘이 일치하는 것을 확인할 수 있다.

 

그렇다면 궁금증은 풀렸다. 게임 가디언이 접근하는 변수의 주소와 실제 앱에서 할당받는 주소는 동일하구나!

 

3-1. 메모리 주소 접근 unsafe 코드

메모리 주소 접근하는 코드를 사용하기 위해서는 unsafe와 fixed 기능을 사용해야 한다.

 

아래 게시물을 참고하자

https://ajh322.tistory.com/223

 

유니티 오류 Unsafe code may only appear if compiling with /unsafe. Enable "Allow 'unsafe' code" in Player Settings to fix this error.

유니티에서 메모리 주소에 접근하는 코드를 사용하면 unsafe 관련하여 아래 에러가 발생한다. Unsafe code may only appear if compiling with /unsafe. Enable "Allow 'unsafe' code" in Player Settings to fix..

ajh322.tistory.com

 

4. 게임 가디언 VS 안티 치트 변수 암호화 기능

이제 본 게임 시작 안티 치트에서 제공하는 변수 암호화 기능을 사용하고 게임 가디언으로 뚫으려고 하면 어떻게 될지 확인해보자

 

먼저 변수 암호화 기능(obscured)에 대하여 알아보자

그냥 기존에 쓰던 데이터 타입에 Obscured를 붙여주면 된다. 그러면 알아서 암호화가 된다. 암시적 형 변환도 되기 때문에 불편함 없다.

그러면 코드가 위에처럼 int에서 ObscuredInt로 바뀐다.

그것뿐이다.

얼마나 간편한가!

 

그러면 이제 암호화를 했는데 게임 가디언으로 한번 메모리 변조를 시도해보겠다.

암호화를 하면 해커들이 못 찾을 거라고 하는데 과연...

 

오... 정말로 못 찾는다!

 

하지만 게임 가디언의 암호화된 값 검색을 하면 어떻게 될까?

 

 

검색 결과가 하나 나온다. 특이한 점은 80을 검색했는데 444,492라는 값을 찾아온다.

 

뚫린다... 조금 허무하네...

일단 그냥 검색이 막히기는 하지만 여전히 게임 가디언에 손쉽게 뚫린다.

 

여기서 안티 치트의 말도 한번 들어보자

대략 unknown value 검색에 의하여 암호화가 뚫릴 수 있다고 경고한다. 그렇기 때문에 암호화된 값을 바꿔줘야 한다는 말이다.

암호화 된 값을 바꾸는 기능은 Obscured 객체에 딸려있는 RandomizeCryptoKey 함수를 이용하면 된다.

 

4-1. 안티 치트 obscured 변수 암호화 원리

암호화 값을 바꿔주는 기능을 사용해보기 전에 obscured 변수 암호화에 대한 간단한 원리를 짚고 넘어가 보자

암호화란 평문을 특정 알고리즘에 의하여 암호화된 값으로 바꿔주는 것을 의미한다.

 

실제로 안티 치트에서 실 데이터에 대하여 암호화를 시키면 특정 알고리즘에 의하여 값이 바뀌고 메모리에는 암호화된 값이 저장된다. 그리고 필요할때만 복호화하여 원래 값으로 되돌려서 사용하고 다시 암호화 시켜서 암호화 된 값으로 저장해놓는 것이다.

 

 

444536이라는 암호화 된 값이 100이라는 실제 값을 가지고 있다.

그리고 해당 값을 가지고 있는 변수에는 암호화 된 값을 들고 있다.

 

게임 가디언에서는 아래와 같은 방법으로 암호화 된 값을 찾아낸다고 한다.

게임 가디언 개발자인데 호그와트에서 배운 마법으로 찾는다고 설명한다. 대단하다.

원리는 암호화가 보통 xor 연산으로 이루어지는데 그 방법을 뚫는 방법이 있다고 한다.

구글에 how game guardian detect encrypted value라고 검색하면 내용이 많이 나온다.

 

5. 게임 가디언 VS 안티 치트 변수 암호화 기능 강화 버전

그러면 단순 암호화로는 게임 가디언에게 쉽게 뚫린다는 것을 감안하여 암호화 값을 랜덤으로 바꿔주는 기능을 사용해보도록 한다.

이렇게 되면 1초마다 inGameGold의 암호화 값이 랜덤 하게 값을 가지게 된다.

즉 게임 가디언 입장에서 암호화 키가 되는 값이 확실하지는 않지만 특정 값이라고 가정하여 값을 찾다가 암호화 값이 완전히 바뀌어버리면 데이터를 놓치게 되는 것이다.

 

RandomizeKey를 사용할 때마다 실제로 암호화된 값이 계속해서 바뀐다.

 

그리고 게임 가디언에서 암호화 된 값 검색을 하여도 도중에 찾지 못한다고 나온다.

오... 안티 치트의 승리다.

 

하지만 메모리 주소에 대한 직접적인 변조는 막지 못한다.

아마 더 고도화된 메모리 변조 방지 기법은 직접 메모리 변조하는 것까지 막아야 한다고 생각한다.

 

5-1. 개발 도중 이상한 점(슈뢰딩거의 암호화)

상자 안에 1시간 뒤 50%의 확률로 죽을 수 있는 고양이가 있는데 고양이는 1시간 뒤 살았을까 죽었을까?

갑자기 뭔 개소리냐 싶은데 ㄹㅇ 슈뢰딩거 고양이 뺨치는 상황이 발생했다.

 

5번의 랜덤 암호화 기능을 구현하고 있는데 RandomizeKey 함수를 통하여 암호화 값을 랜덤 값으로 바꾸고 나서 암호화 값이 바뀌었는지 안 바뀌었는지 확인하기 위해 encrypt 값을 받아와서 라벨에 표출해주었다.

 

일단 먼저 GetEncrypted 함수를 통하여 hiddenValue(암호화 값) 값을 가져온다.

그러면 ApplyNewCrpytoKey 함수를 거치는데...

 

ApplyNewCryptoKey 함수의 내용은 위와 같다.

currentCryptoKey와 cryptoKey가 다르면 암호화 값을 cryptoKey로 암호화한 값을 넣어버리는 것이다.

currentCryptoKey는 randomizeKey를 하면 새로운 값으로 바뀌는데 cryptoKey는 바뀔 일이 절대 없다. 다시 말해서 if문은 항상 참이라는 것이다.

아마도 에셋 개발자가 암호화 값 확인을 할 때 헷갈리지 않도록 암호화 값을 받아오면 무조건 원래 암호화 키로 다시 암호화를 해주는 것 같다.

즉 암호화 값을 확인하고 싶어서 확인하는 순간 랜덤 암호키로 바꾼 암호화 값이 랜덤 하지 않은 단 하나의 암호키로 바꾼 암호화 값으로 초기화되는 것이다.

실제로 내가 테스트하면서 GetEncrypted를 계속해서 호출했는데 랜덤 암호화가 제대로 되지 않아서 랜덤 암호화 기능을 사용하였음에도 불구하고 게임 가디언에 뚫렸다.

관측하지 않은 상태에서는 암호화가 제대로 되고 있지만 관측하려는 순간 암호화가 풀려버리는 그런 것이다. 중요하지는 않지만 나중에 테스트한답시고 나처럼 허튼짓 하지 않기를 바란다.

 

6. 게임 가디언 VS 메모리 변조 디텍터

안티 치트에서 제공하는 기능 중에 메모리 변조를 시도를 탐지하는 기능이 있다고 한다.

 

원리는 암호화되지 않은 변수 값을 일부러 노출시키고 유저가 그 값을 바꾸면(해당 값을 바꿔도 실제 값은 바뀌지 않음) 메모리 변조를 시도했다고 판단하는 것이다.

가짜 덫을 만들어 놓는 것이다.

 

게임 오브젝트에 Obscured Cheating Detector를 만들어두고 Detection Event에 함수를 달아놓는다.

게임 매니저에 GotchaBitch 라는 함수를 달아놓았다.

 

이 함수를 발동시키면 텍스트를 GotchBitch!로 바꾸게 된다.

 

한번 이 기능을 넣어보고 게임 가디언으로 메모리 변조를 시도해보겠다.

 

암호화하지 않고 검색을 하면 가짜 값을 찾을 줄 알았는데 못 찾는다.

 

Randomize를 돌리지 않고 Obscured만 사용한 뒤, 암호화 검색을 하면 가짜 값이 나온다. 그래서 가운데 보면 텍스트가 바뀐 것을 알 수 있다. 근데 진짜 값도 탐지가 가능해서 해킹도 되고 해킹 감지도 된다. 좋지 않은 상황이다.

 

암호화된 상태에서 Randomize까지 작동시키면 아무것도 못 찾는다. 차라리 이게 나은 것 같다.

 

7. 결론

 

기본 Int

ObscuredInt

ObscuredInt + RandomizeKey

변조 가능

O

O

X

디텍터 반응

 

O

X

각 상황별로 게임 가디언으로 해킹을 시도했을 때 결과는 위와 같다.

 

 

메모리 변조와 관련된 게시물

게임 가디언 설치, 사용 방법

게임 가디언 사용 방법 - 실제 게임 해킹

유니티 메모리 변조 방지 - 안티 치트

반응형