oddpair
← 모든 글
기술 노트·공병욱

방치형·시뮬 게임의 시간 어뷰징 방어 — 18년차가 정리한 6가지 레이어

디바이스 시간 변경 한 번에 오프라인 보상이 무너지는 방치형·시뮬 게임을 위한 시간 위변조 방어 가이드. 5가지 공격 벡터, 6가지 방어 레이어, 외주 의뢰자 검수 체크리스트.

방치형 게임에서 가장 빠르게 매출이 무너지는 지점은 가챠 확률도, 광고 단가도 아닙니다. 시간 어뷰징입니다.

유저 한 명이 디바이스 시계를 12시간 앞으로 돌리고 게임을 켜면, 12시간치 오프라인 보상이 그대로 들어옵니다. 이 방법이 커뮤니티에 한 줄 올라가면 그날부터 매출은 0에 수렴합니다. 정상적으로 결제할 이유가 사라지기 때문입니다.

이 글은 방치형·시뮬 게임을 출시·운영하며 표준화한 6가지 방어 레이어를 정리합니다. 방치형 코어 시스템 전반의 설계는 방치형 게임의 코어 시스템 5가지를 먼저 보시면 맥락이 잡힙니다.

시간 어뷰징의 공격 벡터 5가지

방어를 설계하기 전에 어떻게 뚫는지 먼저 알아야 합니다.

  1. 디바이스 시간 변경 — 가장 흔한 방법. 설정에서 자동 시간 끄고 미래로 점프. 앱을 다시 켜면 그만큼 오프라인 시간이 흘렀다고 인식됩니다.
  2. 비행기 모드 + 시간 변경 + 재접속 — 네트워크가 끊긴 상태에서 시간 조작 후 잠깐 접속, 보상 클레임, 다시 시간 원복. NTP 동기화를 피하기 위함입니다.
  3. 에뮬레이터·가상머신 시간 가속 — 일부 안드로이드 에뮬레이터는 OS 시간을 임의 배속으로 흘릴 수 있습니다. 클라우드 폰까지 가면 자동화도 됩니다.
  4. 메모리 변조 — GameGuardian, Cheat Engine으로 클라이언트 내부의 lastLoginTime, offlineSeconds 같은 변수를 직접 수정.
  5. 패킷 변조 — HTTP/WebSocket으로 서버에 보내는 요청의 시간 필드를 가로채서 위조. Fiddler, Charles, Frida 같은 도구가 흔히 쓰입니다.

이 5가지 중 메모리·패킷 변조는 막기 어렵지만, 나머지 3가지는 서버 구조만 제대로 잡으면 거의 다 막힙니다. 즉 방어는 "클라이언트를 신뢰하지 않는 구조"를 만드는 게 핵심입니다.

방어 레이어 6가지

L1. 시간의 기준은 서버 (Single Source of Truth)

원칙 — 모든 보상 계산에 쓰이는 시간은 서버의 UTC 타임스탬프 한 곳에서만 나옵니다. 클라이언트가 "지금 몇 시인지" 직접 결정해서는 안 됩니다.

흔한 실수 — 클라가 NTP 서버에서 시간을 받아 "정확한 시간"을 만들어 쓰는 패턴. NTP 응답도 중간에서 변조 가능하고, 무엇보다 보상 계산을 클라가 하게 됩니다.

실전 — 매 API 응답에 server_time 필드를 박아 클라가 UI 표시용으로만 동기화. 보상·재화 계산은 100% 서버에서.

L2. 클라가 보낸 시간 값은 절대 신뢰 X

원칙 — 클라이언트가 "내 마지막 접속 시간은 X였습니다"라고 보내는 구조 자체가 어뷰징 입구입니다.

흔한 실수claim_offline_reward(last_login_time: ...) 같은 API. 클라가 보낸 last_login_time을 서버가 그대로 받아 보상 계산에 쓰면, 패킷 변조 한 번에 무한 보상이 됩니다.

실전 — 클라는 "보상 청구" 의도만 보냅니다. 시간 계산에 필요한 모든 값은 서버 DB에서 조회합니다.

// ❌ 안티패턴 — 클라가 시간 계산
var offlineSeconds = (DateTime.UtcNow - lastLogin).TotalSeconds;
var reward = offlineSeconds * coinPerSecond;
api.SendReward(reward);

// ✅ 올바른 패턴 — 클라는 청구만, 서버가 계산
api.ClaimOfflineReward();
// 서버: now - users.last_login_at → 보상 계산 → 응답

L3. 게임 내 타이머는 monotonic clock

원칙 — 스킬 쿨다운, 미션 타이머, 이벤트 카운트다운 등 게임 내부에서 "N초 지났는지" 측정할 때는 시스템 시간이 아니라 monotonic clock을 씁니다. 시스템 시간은 유저가 바꿀 수 있지만, monotonic clock은 앱 실행 후 단조 증가하는 값이라 변조가 어렵습니다.

흔한 실수 — Unity에서 DateTime.Now로 스킬 쿨다운 계산. 유저가 시계만 돌리면 모든 쿨다운이 풀립니다.

실전Time.realtimeSinceStartup, Stopwatch, Android SystemClock.elapsedRealtime(), iOS mach_absolute_time 계열을 사용. 단, 앱 종료 후에도 유지되어야 하는 값은 결국 서버에 의존해야 합니다.

// ❌ 안티패턴
var elapsed = (DateTime.Now - skillStartTime).TotalSeconds;

// ✅ 올바른 패턴
var elapsed = Time.realtimeSinceStartup - skillStartRealtime;

L4. "마지막 접속 시간"은 서버 DB만 truth

원칙last_login_at을 로컬 PlayerPrefsSharedPreferences에 저장하면 안 됩니다. 클라 로컬 저장소는 변조 자유 구간입니다.

흔한 실수 — 서버 통신을 줄이려고 로컬에 캐시. 캐시 값을 보상 계산에 그대로 사용.

실전 — 매 접속 시 서버가 users.last_login_at을 트랜잭션 안에서 갱신, 보상 계산은 갱신 전 값과 NOW()의 차이로 처리. 클라는 결과만 받습니다.

L5. 오프라인 보상 캡 + 어뷰징 로그

원칙 — 모든 방어를 뚫렸을 때의 마지막 안전망. 캡은 보상 상한, 로그는 사후 분석용입니다.

흔한 실수 — 캡은 걸어놨지만 어뷰징 시도 자체를 모니터링하지 않아, 운영 한 달 뒤에야 매출 그래프 보고 알아차림.

실전

  • 오프라인 보상 시간 캡: 8~24시간 (게임에 따라 결정)
  • 비정상 패턴 로그
    • 짧은 시간 안에 보상 청구를 반복하는 계정
    • 디바이스가 보내온 client_timeserver_time 격차가 일정 이상
    • 캡에 정확히 걸리는 청구가 반복되는 계정
  • 임계값 초과 시: 자동 차단보다는 플래그 + 운영 검토 큐가 안전합니다. 자동 차단은 정상 유저 오판 시 사고가 큽니다.

L6. 디바이스 시간 vs 서버 시간 격차 모니터링 (선택)

원칙 — 클라가 매 요청에 자신의 디바이스 시간을 같이 보내고, 서버는 자신의 시간과 비교해 격차를 로그로 남깁니다. 보상 계산에는 쓰지 않습니다.

실전 — 격차가 큰 계정 = 시계 변조 의심. 단독 증거로는 약하지만, L5의 보상 청구 패턴과 교차 분석하면 정밀도가 올라갑니다. 시간대 차이·서머타임·시계 어긋남 같은 정상 케이스가 섞이므로 단독 차단 근거로는 쓰지 않습니다.

외주 의뢰자 검수 체크리스트 3가지

방치형·시뮬 게임을 외주로 받았다면, 코드를 다 읽지 않아도 다음 3가지만 확인하면 시간 어뷰징 위험의 80%가 드러납니다.

  1. 오프라인 보상 계산 위치 — "보상 수치를 누가 결정하는가"를 물어보세요. 답이 "서버"가 아니면 위험합니다. 결제·재화 발급도 마찬가지.
  2. DateTime.Now / System.currentTimeMillis() 의존 코드 위치 — 전체 코드에서 디바이스 시간을 직접 읽는 모든 지점을 목록으로 받아보세요. 보상·재화·쿨다운에 관여하는 곳이 하나라도 있으면 수정 대상입니다.
  3. 어뷰징 로그·캡 로직 + 운영 대시보드 — 캡이 있는지, 비정상 패턴 로그가 쌓이는지, 운영팀이 그 로그를 볼 수 있는 대시보드가 있는지. 셋 다 있어야 합니다.

외주 계약 시점에 이 3가지를 산출물 항목으로 명시해두는 게 가장 안전합니다. 검수 단계 일반론은 게임 외주 7가지 체크리스트를 참고하세요.

정리 — 한 명만 뚫리면 끝난다

방치형·시뮬 게임의 시간 어뷰징은 다른 치팅과 성격이 다릅니다. 한 명이 뚫고 그 방법이 커뮤니티에 올라오는 순간, 정상 결제 유저가 사라집니다. 출시 후 발견되는 경우 강제 업데이트와 데이터 부분 롤백 없이는 수습이 어렵고, 양쪽 다 유저 신뢰를 크게 깎는 작업입니다.

위 6가지 레이어는 새 기술이 아니라 출시 전에 반드시 박아넣어야 할 기본기입니다. 출시 후 발견하면 비용이 10배 이상으로 뜁니다. 라이브 운영 단계에서의 KPI 점검은 출시 후 매출이 안 나올 때의 첫 30일 진단 가이드에서 다뤘습니다.


관련 글

oddpair의 접근

저희는 방치형·하이브리드 RPG를 직접 출시·운영해온 경험을 바탕으로, 위 6가지 레이어를 모든 신규 프로젝트의 기본 구조로 표준화하고 있습니다. 외주 의뢰가 들어올 때도 견적 단계에서 이 6가지의 적용 여부를 먼저 확인합니다.

기획 중인 방치형·시뮬 게임이 있으시거나, 운영 중인 게임의 어뷰징 점검이 필요하시다면 30분 무료 컨설팅에서 함께 검토해드립니다. 의심 패턴이 어디서 발생할 수 있는지, 어떤 레이어가 비어 있는지 1페이지 리포트로 정리해드립니다.

이 글이 도움이 되셨나요?

oddpair는 18년 경력 시니어가 직접 게임 개발 외주를 진행합니다.
30분 무료 컨설팅에서 당신의 프로젝트를 함께 검토해드립니다.

More articles

See more posts →