SK텔레콤 유심 해킹: 4년 숨은 백도어와 평문 인증키

아프로·2026년 11월 1일

SK텔레콤 유심 해킹 표지

2,324만 명. SK텔레콤 가입자의 유심 인증정보가 서버 밖으로 나간 규모입니다. 악성코드는 2021년 8월부터 약 4년 동안 내부 서버에 숨어 있었습니다. 회사는 그사이 2022년 2월에 감염 서버를 한 번 발견했지만 신고하지 않았습니다. 이 글은 민관합동조사단과 개인정보보호위원회(이하 개인정보위)가 밝힌 원인을 따라가고, 같은 실수가 일반 웹 서비스에서는 어떤 모양인지 살펴봅니다.

사고 원인: 알고도 덮음 + 평문 시크릿. 시크릿은 비밀번호·API 키·서명키·인증키처럼 코드와 로그 밖에 숨겨야 하는 값입니다.

한눈에 보기

항목내용
최초 침투2021-08-06 (2022-02에 감염 서버를 발견하고도 미신고)
탐지·신고2025-04-18 이상 트래픽 탐지 → 04-20 한국인터넷진흥원(KISA) 신고(24시간 초과) → 04-22 개인정보위 신고
피해23,244,649명. 유심 정보 25종 9.82GB(전화번호, IMSI, 인증키 Ki·OPc)
감염 규모서버 28대, 악성코드 33종(그중 BPFDoor 27종)
서비스 영향전 고객 무상 유심 교체, 신규 영업 50일 중단, 해지 고객 위약금 면제
제재개인정보위 과징금 1,347억 9,100만 원 + 과태료 960만 원 + 시정명령(2025-08-27)
현재 상태2026-01 과징금 취소 행정소송 제기, 1심 진행 중. 약 9천 명이 손해배상 소송
회사 대책총 1.2조 원(정보보호 5년 7,000억 원, 고객 보상 5,000억 원)

IMSI는 가입자를 구별하는 식별번호이고, Ki·OPc는 유심이 통신망에 자신을 증명할 때 쓰는 인증키 값입니다. 이 값들이 함께 나갔다는 점이 이 사고의 무게입니다.

무슨 일이 있었나

  • 2021년 8월 6일: 공격자가 내부 서버에 처음 들어왔습니다.
  • 2022년 2월: 회사가 감염 서버를 발견했습니다. 신고하지 않았습니다.
  • 2025년 4월 18일: 이상 트래픽이 탐지됐습니다. 첫 침투 뒤 약 4년이 지난 시점입니다.
  • 2025년 4월 20일: 한국인터넷진흥원에 신고했습니다. 신고 기한인 24시간을 넘긴 뒤였고, 개인정보위 신고는 4월 22일에 했습니다.
  • 2025년 8월 27일: 개인정보위가 과징금과 과태료, 시정명령을 내렸습니다.
  • 2026년 1월: 회사가 처분에 불복해 과징금 취소 행정소송을 냈습니다.

돌아보면 갈림길은 2022년이었습니다. 감염을 알고도 덮은 결정이 이후 3년의 잠복으로 이어졌습니다.

어떻게 들어왔나

인터넷망 쪽 서버에서 감염 서버, 평문 계정정보, HSS 관리서버를 거쳐 유심 인증키까지 이어진 경로와 막을 수 있었던 곳을 표시한 흐름도

경로는 원리 수준까지만 적습니다. 공격 절차와 명령은 다루지 않습니다.

  1. 출발점은 인터넷망 쪽 서버입니다. 인터넷망과 내부 코어망이 분리돼 있지 않았습니다.
  2. 감염 서버에는 BPFDoor가 있었습니다. BPFDoor는 포트를 열지 않고 특정 패킷이 올 때까지 기다리는 백도어입니다. 열린 포트가 없으니 포트 스캔으로는 찾을 수 없습니다.
  3. 다른 서버에 평문 계정정보가 있었습니다. HSS 관리서버의 계정정보가 평문으로 저장돼 있었고, 공격자는 이 계정정보로 이동했습니다.
  4. HSS의 인증키는 암호화돼 있지 않았습니다. HSS(Home Subscriber Server)는 가입자 인증 정보를 다루는 서버입니다. 그 안의 유심 인증키 Ki가 평문 그대로였습니다.

그림의 그린 표시는 아래 "막을 수 있었던 네 지점"과 "점검 5줄"에서 다시 다룹니다.

왜 뚫렸나

민관합동조사단과 개인정보위가 밝힌 원인은 여섯 가지입니다.

  • 평문 계정정보. HSS 관리서버 계정정보를 다른 서버에 평문으로 저장했고, 공격자가 이를 이용해 이동했습니다.
  • 암호화하지 않은 인증키. 유심 인증키 Ki를 암호화하지 않았습니다. 같은 인증키를 KT와 LG유플러스는 암호화하고 있었습니다.
  • 9년 된 커널 취약점. 2016년에 알려진 DirtyCow(더티카우, 리눅스 커널 취약점)가 있는 OS를 2025년까지 패치하지 않았습니다.
  • 망 미분리. 인터넷망과 내부·코어망이 분리되지 않았습니다.
  • 관리 범위 밖 자산. CISO(정보보호최고책임자)가 IT 영역만 담당해 네트워크 자산(43%)이 보안 관리에서 빠졌습니다. 침입탐지 시스템의 이상 로그도 확인하지 않았습니다.
  • 조사 중 자료 훼손. 자료보전 명령 뒤 서버 2대를 포렌식이 불가능한 상태로 제출했습니다.

여섯 항목 가운데 새로운 공격 기법은 없습니다. 평문 시크릿, 오래된 패치, 관리 목록에서 빠진 자산은 규모와 상관없이 어느 서비스에서나 생길 수 있는 실패입니다.

개발자 시점: 내 서비스였다면

사고 회사의 코드가 아니라 같은 실수를 보여 주는 일반 예시입니다. 값은 모두 가짜입니다.

위험한 모양

# config.yml
db:
  host: db.example.com
  user: alice
  password: FAKE-PlainPass-0000

# save_key.py
row = {
  "sub_id": "alice",
  "auth_key": key_hex,  # 평문 그대로
}
db.insert("sim_keys", row)

위쪽 설정 파일에는 DB 비밀번호가 평문으로 적혀 있습니다. 이 파일이 있는 서버 하나가 열리면 그 계정으로 DB까지 갈 수 있습니다. 사고에서 다른 서버에 평문으로 남아 있던 HSS 관리 계정정보와 같은 모양입니다.

아래쪽 코드는 인증키를 칼럼에 그대로 넣습니다. DB가 통째로 읽히면 키도 그대로 쓰입니다.

고친 모양

# config.yml
db:
  host: db.example.com
  user: alice
  password_ref: FAKE-secret/db-app

# save_key.py
dk = kms.data_key("FAKE-kms-key-01")
row = {
  "sub_id": "alice",
  "auth_key": seal(dk.plain, key_hex),
  "dk_wrapped": dk.wrapped,
}
  • 값 대신 참조 이름. 설정에는 비밀번호 대신 시크릿 매니저의 참조 이름만 둡니다. 실제 값은 권한을 가진 서버만 실행할 때 받아 옵니다. 설정 파일이 새도 비밀번호는 함께 새지 않습니다.
  • 봉투 암호화. 민감한 칼럼은 봉투 암호화(envelope encryption, 데이터 키로 값을 암호화하고 그 데이터 키를 KMS의 마스터 키로 다시 감싸는 방식)로 저장합니다. DB에는 암호문과 감싼 데이터 키(dk_wrapped)만 남습니다.
  • 풀려면 KMS 권한이 필요합니다. DB가 유출돼도 KMS 권한 없이는 값을 풀 수 없습니다. 인증키처럼 중요한 값은 HSM(하드웨어 보안 모듈)에 두는 방법도 있습니다.

seal()과 kms.data_key()는 설명용 이름입니다. 실제로는 사용하는 클라우드의 KMS SDK나 암호화 라이브러리가 같은 역할을 합니다.

막을 수 있었던 네 지점

조사 결과를 거꾸로 읽으면 막을 기회가 네 번 있었습니다.

  1. 2022년에 신고하고 전수 조사했다면. 감염 서버를 발견한 그때 신고하고 전체를 조사했다면 3년을 더 숨어 있지는 못했습니다.
  2. 인증키를 암호화하고 계정정보를 평문으로 두지 않았다면. 침투를 당해도 핵심 자산은 지킬 수 있었습니다.
  3. 9년 된 커널 취약점을 패치하고 백신을 설치했다면. 서버 사이를 옮겨 다니는 수평 이동이 훨씬 어려웠습니다.
  4. HSS 로그를 전부 보고 웹셸을 점검 항목에 넣었다면. 과거 점검에서 HSS 로그를 6개 중 1개만 봤습니다. 웹셸(서버에 심어 원격으로 명령을 받는 악성 파일)을 점검 항목에 넣었다면 더 일찍 찾았을 것입니다.

로그도 문제였습니다. 남아 있지 않은 기간이 있어 유출 범위를 끝내 확정하지 못했습니다. 방화벽 로그는 6개월 이상 보관해야 사고 뒤에 범위를 가릴 수 있습니다.

같은 사고를 막는 점검 5줄

  1. 설정 파일·코드에 평문 비밀번호가 없습니다. 서버 계정정보는 시크릿 관리 도구에 두고 참조 이름만 씁니다.
  2. 핵심 시크릿과 민감 칼럼은 KMS 봉투 암호화나 HSM으로 보호합니다. DB가 새도 값은 읽히지 않게 합니다.
  3. 커널·패키지 패치 날짜를 자산 목록과 대조합니다. 보안 담당 범위에 네트워크 자산까지 넣어, 목록에서 빠진 영역을 없앱니다.
  4. 망을 나누고 리눅스 서버에도 EDR과 이상 패킷 탐지를 둡니다. 코어망 접근은 지정된 경로로만 허용하고, 방화벽 로그는 6개월 이상 남깁니다.
  5. 침해를 발견하면 24시간 안에 신고하는 절차를 미리 적어 둡니다. 누가 판단하고 누가 신고하는지까지 정해 둡니다.

EDR(Endpoint Detection and Response)은 서버·PC에서 이상 행위를 찾아 알리는 도구입니다.

제재와 비용

  • 개인정보위 처분(2025-08-27): 과징금 1,347억 9,100만 원, 과태료 960만 원, 시정명령. 당시로서는 역대 최대 과징금이었습니다. 반년 뒤 쿠팡(03편)에 부과된 6,247억 원은 이 금액의 4.6배입니다.
  • 소송(2026년 10월 말 기준): 회사는 처분에 불복해 2026년 1월 과징금 취소 행정소송을 냈고, 1심이 진행 중입니다. 약 9천 명이 낸 손해배상 소송도 있습니다.
  • 서비스 영향: 모든 고객의 유심을 무상으로 바꿔 줬고, 신규 영업을 50일 동안 멈췄습니다. 해지 고객의 위약금도 면제했습니다.
  • 회사 대책: 총 1.2조 원 규모입니다. 정보보호에 5년간 7,000억 원, 고객 보상에 5,000억 원입니다.

위 제재는 개인정보위 처분 기준이며, 회사는 불복해 소송 중입니다. 결과에 따라 바뀔 수 있고, 이 글은 법률 자문이 아닙니다.

정리

  • 피해를 키운 건 침투 그 자체가 아니라 알고도 덮은 것과 핵심 시크릿을 평문으로 둔 것이었습니다.
  • 뚫릴 수 있다고 가정하고, 뚫려도 중요한 값은 읽히지 않게 설계해야 합니다.
  • 내 서비스에서는 설정 파일의 평문 비밀번호, 암호화하지 않은 민감 칼럼, 자산 목록과 패치 날짜, 24시간 신고 절차부터 확인합니다.

더 깊게

인프런 강의 「백엔드 개발자를 위한 서버 보안 실무」에서 이어지는 수업입니다.

  • 0-2 2025~2026 유출 사고로 보는 공격 경로: SKT 유심 해킹과 쿠팡
  • 5-2 저장 데이터 암호화와 KMS 키 관리: 봉투 암호화를 직접 해 봅니다.
  • 5-3 시크릿 관리: .env 유출, 저장소 스캔, 키 회전
  • 1-3 패치는 속도전이다: 보안 업데이트 자동화
  • 6-8 위협 헌팅 입문: 공격자가 남긴 지속성 흔적 찾기
  • 6-10 사고 이후: 유출 신고 의무와 재발 방지

관련 velog 글: ca-chains 22편 운영 체크리스트: TLS 하드닝, 키 관리, 만료로 터지는 인증서들

보안을 더 알고 싶다면

오늘 본 사고의 원인은 대부분 서버와 코드의 기본기에서 막을 수 있는 것들이었습니다. 직접 손으로 막아 보고 싶다면 이런 강의도 있습니다.

백엔드 개발자를 위한 서버 보안 실무: 해킹 방어부터 정보유출 방지까지

  • 서버를 공격하는 흐름을 로그로 보고, 내 서버와 Spring·Express 코드에서 직접 막아 봅니다.
  • SSH 하드닝, 인젝션, 인증·인가, 시크릿과 개인정보 보호, 침해사고 첫 한 시간까지 8개 섹션 54개 수업입니다.
  • 이 글과 이어지는 수업: 5-2 저장 데이터 암호화와 KMS 키 관리, 5-3 시크릿 관리: .env 유출, 저장소 스캔, 키 회전, 6-10 사고 이후: 유출 신고 의무와 재발 방지

출처와 확인 날짜

수치는 2026년 10월 말 기준 공개 보도·발표입니다. 진행 중인 사건은 바뀔 수 있고, 이 글은 법률 자문이 아닙니다.


다음 글 KT 무단 소액결제: 잃어버린 기지국 하나가 인증을 무너뜨렸다
시리즈 전체 목록 해킹 사고 해부 전체 목록

profile
고인물 개발자(OG)

0개의 댓글