← 목록으로
● 2025-11 GJTec·Qilin 랜섬웨어(코리안 리크스) 사고 분석 기반 — 금융기관 28곳 피해

MSP 공급망 공격을 그대로 재현하고,
막는 코드까지 공개합니다

관리형 서비스 제공업체(MSP) 하나의 계정이 털리면서 하위 고객사 28곳이 동시에 뚫린 코리안 리크스 사고의 구조를 재현했습니다. 공유 크리덴셜 대신 고객사별로 분리된 전용 접근권한을 쓰면 피해가 어떻게 한 곳에 갇히는지 보여줍니다. 지금은 전부 무료로 공개합니다.

라이브 데모 보기 → 코드 바로보기

누구를 위한 건가

진짜 MSP 운영자용이 아닙니다 — 멀티테넌트 SaaS나 여러 고객사를 관리하는 백엔드/인프라 개발자가 '벤더 하나가 뚫리면 왜 전부 뚫리는가'를 코드로 직접 확인하기 위한 학습 자료입니다.

28
코리안 리크스 사고로 피해를 입은 금융기관 수(곳)
2TB
유출된 데이터 총량(파일 100만 개 이상)
0원
지금 공개하는 코드의 가격 — 전부 무료

코드 — shared-credential-access.js

하나의 크리덴셜로 모든 고객사에 접근 가능한 취약한 MSP 접근 모델.

shared-credential-access.js
// 취약한 MSP 접근 모델 — "코리안 리크스" 캠페인 모델링:
// GJTec 크리덴셜 하나가 털리면서 하위 금융기관 28곳이 연쇄로
// 뚫림. 결함: 크리덴셜 하나가 MSP가 관리하는 모든 고객사에
// 상시 접근 권한을 가짐.
class SharedCredentialAccess {
  constructor(tenants) {
    this.tenants = tenants; // [{id, name}, ...]
    this.credential = { id: 'msp-admin', scope: 'all-tenants' };
  }

  // 탈취된 크리덴셜로 어떤 고객사든 접근 가능 — 격리 없음.
  accessTenant(credential, tenantId) {
    if (credential.scope !== 'all-tenants') return { status: 'denied' };
    const tenant = this.tenants.find(t => t.id === tenantId);
    return { status: 'breached', tenant };
  }

  simulateCompromise() {
    // 공격자가 크리덴셜 하나를 확보 — 모든 고객사가 노출됨.
    return this.tenants.map(t => this.accessTenant(this.credential, t.id));
  }
}

module.exports = { SharedCredentialAccess };

코드 — tenant-isolated-access.js

고객사별로 분리된 전용 크리덴셜로 피해를 한 곳에 가두는 방어 코드.

tenant-isolated-access.js
// 해결책: 크리덴셜을 고객사 1곳으로 한정하고 빠르게 만료시킨다.
// 한 고객사에 쓰인 크리덴셜이 털려도 다른 고객사는 절대 접근
// 불가 — GJTec식 MSP 피해를 한 곳에 가뒀을 방법.
class TenantIsolatedAccess {
  constructor(tenants) {
    this.tenants = tenants;
    this.credentials = new Map(
      tenants.map(t => [t.id, { tenantId: t.id, issuedAt: Date.now(), ttlMs: 15 * 60 * 1000 }])
    );
    this.blockedAttempts = [];
  }

  accessTenant(credential, tenantId) {
    if (credential.tenantId !== tenantId) {
      this.blockedAttempts.push({ credentialTenant: credential.tenantId, attemptedTenant: tenantId });
      return { status: 'denied', reason: 'scope_mismatch' };
    }
    const tenant = this.tenants.find(t => t.id === tenantId);
    return { status: 'breached', tenant }; // 표적 고객사만 노출
  }

  simulateCompromise(compromisedTenantId) {
    const stolenCredential = this.credentials.get(compromisedTenantId);
    return this.tenants.map(t => this.accessTenant(stolenCredential, t.id));
  }
}

module.exports = { TenantIsolatedAccess };

가격

무료 (지금)
심화 버전(크리덴셜 로테이션, 교차테넌트 이상탐지, 인시던트 대응 가이드 포함) 출시 예정 — 사업자등록 완료 후 자유가격($0부터)으로 공개
goalsgo7574@gmail.com
구매·결제가 아닙니다 — "심화버전 출시알림 받고 싶어요"라고 메일 한 통만 보내주시면, 출시 시 연락드립니다.
주의: 이건 학습용 축소 구현입니다. 크리덴셜 로테이션, 이상탐지, 실전 MSP 운영 체계가 없어 실제 멀티테넌트 시스템에 그대로 넣으면 안 됩니다.

의견을 남겨주세요

이 상품에 대한 피드백이나 질문이 있으면 알려주세요. 회신을 원하시면 이메일을 남겨주세요(선택).