기타

Clicker Heroes

nopdata 2018. 2. 26. 02:12
LiveOverflow에서 Don't wasting your time 을 주제로 영상이 하나 올라왔다.

내용 중에 안드로이드 게임의 취약한 부분을 이용한 공격을 하는 내용이 있어서 따라해 보게 되었다.

타겟이 되는 게임은 Clicker Heroes


레벨 별로 몬스터가 등장하는데 아이템을 구매해서 더 강하게 키워나가는 방식이다.
터치로 데미지를 줄 수도 있고, 아이템 구매를 통해 시간당 데미지, DPS를 올려 잡는 방법이 있다.
조금 해봤는데 마지막 영웅의 값이 얼마일지 추측이 되지 않는 수준까지 된다. 물론 과금도 있다.

해당 게임의 경우, 백업을 할 수 있는데, 백업의 형태가 특이하다.


Export, Import 기능이 존재한다.


컴퓨터를 많이 다뤄본 사람이라면 대충 눈치 채겠지만 base64 인코딩이 되어 있다.
다음 내용은 영상을 참고하고 개인이 편한대로 작성하였다.


Export로 데이터를 2번 획득하여 두 파일의 차이점을 확인한다.



각각 두개의 데이터를 1.origin, 2.origin으로 저장하고 base64 명령을 통해 디코딩한다.



디코딩이 되면 바이너리 값으로 되어 있는데 눈으로 보기 편하게 하기 위해 hexdump로 hex값으로 볼 수 있도록 한다.

use command :
vimdiff 1.hex 2.hex

보면 앞 부분은 동일하게 나타난다. 앱에서 사용하는 식별 헤더로 보인다. 하지만 정확히 어떤 데이터인지는 확인이 불가능하다.
해서, 어떤 파일인지 알아내기 위해 file 명령도 사용해 보고(영상에서..) binwalk를 통해 추출 가능한 파일을 확인한다.


binwalk로 확인을 해 보면 24, 0x18부분에서 zlib 헤더를 확인할 수 있다.


hexdump로 확인을 해 보면 78 da부터이다.

구글링을 해 보면 다음과 같은 정보를 얻을 수 있다.

78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression

zlib의 best compression이며, zlib를 이용하여 decompress를 하면 원래의 데이터를 획득할 수 있다.
영상에서는 openssl의 zlib를 사용하였는데, 실제로 확인을 할 때는 binwalk의 -e옵션을 이용해서 바로 획득하였다.

[ decompress 일부 ]

위 사진은 zlib를 이용해서 decompress한 데이터의 일부이다. json형태를 띄고 있으며, 게임에 필요한 각 정보를 포함하고 있다.
게임을 조금 즐기고 난 후에 추출한 데이터이기 때문에 gold의 값이 상당히 높다. 하지만 마지막 영웅을 구매하려면 턱도 없는 골드...

[ deompcress 영웅 정보 ]

골드를 올려 직접 살 필요 없이, 영웅 옵션에서 값을 변경해도 된다.

import zlib, base64
data = open('mod.json','rb').read()
data = zlib.compress(data,8)
data = 'EDAF7DD1DE34E5DD9CE9F6FDDDA6BC7DB6F479CD5ADDBDB7'.decode('hex') + data
data = base64.b64encode(data).replace('\n','')
f=open('result.backup','wb')
f.write(data)
f.close()

확인을 위해 마지막 50번째 영웅의 레벨을 -1로 하고, 에픽 레벨을 100으로 설정하였다.
결과 파일을 만드는건 위 코드를 이용하였다.



수정된 데이터를 import 시키면 마지막 영웅의 에픽 레벨 100, 영웅 레벨은 -1로 설정된 것을 볼 수 있다.

예제 파일은 로컬에 저장.