
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년의 잠복으로 이어졌습니다.
어떻게 들어왔나

경로는 원리 수준까지만 적습니다. 공격 절차와 명령은 다루지 않습니다.
- 출발점은 인터넷망 쪽 서버입니다. 인터넷망과 내부 코어망이 분리돼 있지 않았습니다.
- 감염 서버에는 BPFDoor가 있었습니다. BPFDoor는 포트를 열지 않고 특정 패킷이 올 때까지 기다리는 백도어입니다. 열린 포트가 없으니 포트 스캔으로는 찾을 수 없습니다.
- 다른 서버에 평문 계정정보가 있었습니다. HSS 관리서버의 계정정보가 평문으로 저장돼 있었고, 공격자는 이 계정정보로 이동했습니다.
- 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나 암호화 라이브러리가 같은 역할을 합니다.
막을 수 있었던 네 지점
조사 결과를 거꾸로 읽으면 막을 기회가 네 번 있었습니다.
- 2022년에 신고하고 전수 조사했다면. 감염 서버를 발견한 그때 신고하고 전체를 조사했다면 3년을 더 숨어 있지는 못했습니다.
- 인증키를 암호화하고 계정정보를 평문으로 두지 않았다면. 침투를 당해도 핵심 자산은 지킬 수 있었습니다.
- 9년 된 커널 취약점을 패치하고 백신을 설치했다면. 서버 사이를 옮겨 다니는 수평 이동이 훨씬 어려웠습니다.
- HSS 로그를 전부 보고 웹셸을 점검 항목에 넣었다면. 과거 점검에서 HSS 로그를 6개 중 1개만 봤습니다. 웹셸(서버에 심어 원격으로 명령을 받는 악성 파일)을 점검 항목에 넣었다면 더 일찍 찾았을 것입니다.
로그도 문제였습니다. 남아 있지 않은 기간이 있어 유출 범위를 끝내 확정하지 못했습니다. 방화벽 로그는 6개월 이상 보관해야 사고 뒤에 범위를 가릴 수 있습니다.
같은 사고를 막는 점검 5줄
- 설정 파일·코드에 평문 비밀번호가 없습니다. 서버 계정정보는 시크릿 관리 도구에 두고 참조 이름만 씁니다.
- 핵심 시크릿과 민감 칼럼은 KMS 봉투 암호화나 HSM으로 보호합니다. DB가 새도 값은 읽히지 않게 합니다.
- 커널·패키지 패치 날짜를 자산 목록과 대조합니다. 보안 담당 범위에 네트워크 자산까지 넣어, 목록에서 빠진 영역을 없앱니다.
- 망을 나누고 리눅스 서버에도 EDR과 이상 패킷 탐지를 둡니다. 코어망 접근은 지정된 경로로만 허용하고, 방화벽 로그는 6개월 이상 남깁니다.
- 침해를 발견하면 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 무단 소액결제: 잃어버린 기지국 하나가 인증을 무너뜨렸다
시리즈 전체 목록 해킹 사고 해부 전체 목록