재전송 공격
이미 오간 정상 메시지를 붙잡아 두었다가 그대로 다시 보내는 공격입니다. 내용을 풀어 보거나 고칠 필요가 없습니다. 처음에 통했던 것이 두 번째에도 통하면 그것으로 성립합니다.
상세
공연장 입구에서 남이 이미 통과할 때 쓴 표를 주워 그대로 다시 내미는 일과 같습니다. 표를 위조할 줄 몰라도 됩니다.
NIST(National Institute of Standards and Technology, 미국 국립표준기술연구소) 용어집은 이 이름 아래 정의 셋을 나란히 싣습니다. CNSSI 4009-2015 는 전송된 인증 정보나 접근 제어 정보를 붙잡아 두었다가 나중에 다시 보내, 허가되지 않은 효과를 내거나 허가되지 않은 접근을 얻으려는 공격이라고 적습니다. NIST SP 800-53 Rev. 5 와 SP 800-63-4 는 자리를 좁혀 적습니다. 정당한 주장자와 검증자 사이에서 앞서 붙잡아 둔 메시지를 다시 보내, 검증자에게 그 주장자인 것처럼 또는 그 반대로 행세할 수 있게 되는 공격입니다.
RFC(Request for Comments) 4949 는 인터넷 보안 용어집입니다. 유효한 데이터 전송이 악의로 또는 부정하게 되풀이되는 공격이라고 정의합니다. 되풀이하는 쪽은 원래 보낸 쪽일 수도 있고, 데이터를 가로채 다시 보내는 제3자일 수도 있다고 적습니다. 그리고 가장 공격의 일부일 수 있다고 덧붙입니다.
세 정의가 겹치는 자리는 하나입니다. 되풀이되는 것이 유효한 전송 그 자체라는 것입니다. 공격하는 쪽은 메시지를 열어 볼 필요도, 한 바이트를 고칠 필요도 없습니다. 붙잡아 두는 것은 원본이 아니라 사본입니다. 정당한 상대 쪽에서는 없어지거나 실패하는 것이 없습니다. 그래서 서명이나 암호화만으로는 자리가 채워지지 않습니다. 받은 쪽이 이 메시지가 지금 것인지 가려낼 재료가 따로 붙어야 합니다.
sequenceDiagram
participant S as 보내는 쪽
participant E as 엿듣는 쪽
participant R as 받는 쪽
S->>R: 정상 메시지
Note over E: 오가는 것을 그대로 붙잡아 둔다
E->>R: 붙잡아 둔 그 메시지를 그대로
Note over R: 가려낼 재료가 없으면 또 통과한다
배경
떨어져 있는 두 쪽이 메시지를 주고받습니다. 받은 쪽에게는 두 가지 물음이 따로 있습니다. 이 메시지가 정당한 상대의 것이 맞나가 하나이고, 이 메시지가 지금 것이 맞나가 다른 하나입니다. 앞의 물음에 답해도 뒤의 물음은 남습니다.
RFC 4949 는 뒤의 물음에 걸린 성질에 따로 이름을 두었습니다. liveness 는 받은 쪽에게 그 데이터가 원 송신자가 방금 전송하고 있는 것이라는 보장을 주는 성질입니다. 정의는 그 뜻을 곧바로 풀어 적습니다. 원 송신자든 제3자든 앞선 전송에서 재전송하고 있는 것이 아니라는 보장입니다. fresh 는 최근에 생성된 것을 가리키고, 프로토콜의 앞선 상호작용에서 재전송된 것이 아닌 것이라고 못 박습니다. 처음 받아 처리되는 데이터를 두고 쓰는 말입니다.
그래서 이 신선도를 가릴 재료가 주고받는 데이터 안으로 들어가게 됩니다. RFC 4949 는 논스를 그 재료로 정의합니다. 프로토콜이 주고받는 데이터에 실리는 임의값 또는 반복되지 않는 값이고, 보통 liveness 를 보장해 재전송 공격을 탐지하고 막으려는 목적이라고 적습니다. 재전송 공격이라는 이름은 이 재료가 없거나 헐거운 자리를 노려 유효한 전송을 되풀이하는 일에 붙었습니다. RFC 4949 는 이 항목 옆에 능동적 도청, fresh, liveness, 논스를 나란히 가리켜 둡니다.
예시
TLS 1.3 의 0-RTT
TLS(Transport Layer Security) 1.3 을 정한 RFC 8446 은 8절을 통째로 이 문제에 씁니다. 절 제목이 0-RTT and Anti-Replay 입니다. 첫 문단은 TLS 가 0-RTT(zero round-trip time) 데이터에 대해 본래적인 재전송 보호를 제공하지 않는다고 적습니다. 그리고 걱정할 위협 둘을 듭니다. 하나는 0-RTT 데이터 한 묶음을 그대로 복제해 재전송 공격을 거는 네트워크 공격자입니다. 다른 하나는 클라이언트의 재시도 동작을 이용해 서버가 같은 애플리케이션 메시지를 여러 벌 받게 만드는 네트워크 공격자입니다.
첫 번째 부류는 0-RTT 데이터가 많아야 한 번 받아들여지도록 상태를 공유하면 막을 수 있다고 적습니다. 서버는 8절이 설명하는 방법 중 하나로, 또는 그에 준하는 수단으로 그 정도의 재전송 안전성을 제공해야 합니다(SHOULD). 다만 정상 동작에서 클라이언트는 서버가 그중 무엇을 실제로 구현했는지 알 수 없습니다. 그래서 클라이언트는 재전송돼도 안전하다고 스스로 판단한 조기 데이터만 보내야 합니다(MUST).
8절이 드는 방법은 셋입니다. 8.1 은 세션 티켓을 한 번만 쓰게 하는 것입니다. 서버가 유효한 티켓
전부를 데이터베이스로 들고 있다가 쓰인 티켓을 지우는 식입니다. 모르는 티켓이 오면 전체
핸드셰이크로 되돌아갑니다. 8.2 는 ClientHello 에서 뽑은 고유값을 기록해 두고 중복을 거절하는
것입니다. 대개 random 값이나 PSK(Pre-Shared Key, 사전 공유 키) binder 를 씁니다. 전부 기록하면
상태가 끝없이 늘어나므로, 주어진 시간 창 안의 ClientHello 만 기록하고 obfuscated_ticket_age 로
티켓이 그 창 밖에서 재사용되지 않게 합니다. 8.3 은 신선도 검사입니다. ClientHello 가 클라이언트가 그것을 보낸 시각을 담고 있어서,
최근에 보낸 것으로 보이는 ClientHello 에만 0-RTT 를 받아들이고 나머지는 1-RTT 핸드셰이크로
되돌립니다. 서버가 들고 있어야 하는 값은 티켓을 만든 시각에 왕복 시간 추정치를 더한 것입니다.
adjusted_creation_time = creation_time + estimated_RTT
이 값을 티켓 안에 넣어 두면 티켓마다 상태를 들고 있지 않아도 됩니다. 서버는 클라이언트가 보낸
obfuscated_ticket_age 에서 그 티켓의 ticket_age_add 값을 빼서, 클라이언트가 보는 티켓 나이를
알아냅니다.
Kerberos V5 의 재전송 캐시
RFC 4120 은 KRB_AP_REQ 메시지를 받은 쪽의 처리를 3.2.3 절에 적습니다. 인증은 서버의 현재 시각과 인증자와 티켓에 기댑니다. 시계는 느슨하게라도 맞춰져 있어야 합니다(MUST). 애플리케이션 서버가 재전송을 막을 자기 나름의 적절한 수단을 두지 않는 한, 서버는 허용된 시계 오차 안에서 제시된 인증자를 기억하는 재전송 캐시를 써야 합니다(MUST). 인증 뒤 서버가 시작하는 도전-응답 절차나 서버가 만든 암호화 부분키를 쓰는 것이 그 자기 나름의 수단에 드는 예입니다.
재전송 캐시는 최근에 본 인증자에서 적어도 서버 이름과 클라이언트 이름, time, microsecond
필드를 저장합니다. 일치하는 튜플이 있으면 KRB_AP_ERR_REPEAT 오류가 돌아갑니다. 거절이 걸리는 범위는
같은 주체가 같은 서버로 보낸 인증자로 제한됩니다. 서버가 허용 시계 오차 안에서 제시된 인증자의
기록을 잃으면, 그 시계 오차 구간이 지날 때까지 모든 요청을 거절해야 합니다(MUST).
IPsec ESP 의 재전송 방지 창
RFC 4303 은 ESP(Encapsulating Security Payload, 캡슐화 보안 페이로드)의 시퀀스 번호 검사를 3.4.3 절에 적습니다. 모든 ESP 구현은 재전송 방지 서비스를 지원해야 하고(MUST), 그것을 켜고 끄는 것은 수신자가 SA(Security Association, 보안 연관) 단위로 정할 수 있습니다. 다만 같은 SA 에 ESP 무결성 서비스가 켜져 있지 않으면 이 서비스를 켜서는 안 됩니다(MUST NOT). 시퀀스 번호 필드가 무결성 보호를 못 받기 때문입니다.
수신자가 이 서비스를 켰으면, SA 가 맺힐 때 수신 패킷 카운터를 0으로 초기화해야 합니다(MUST). 그리고 받는 패킷마다 그 SA 가 살아 있는 동안 받은 다른 패킷의 시퀀스 번호와 겹치지 않는지 확인해야 합니다(MUST). 창 크기는 32비트 시퀀스 번호를 쓸 때 최소 32 패킷을 지원해야 하고(MUST), 64 가 선호되어 기본값으로 쓰이는 것이 권장됩니다(SHOULD). 수신자는 최소치보다 큰 다른 창 크기를 고를 수 있습니다(MAY).
경계
TLS 1.3 의 조기 데이터가 서버에 두 번 도착하는 것도 재전송 공격인가. 재전송 공격입니다.
RFC 8446 이 8절에서 첫 번째 위협으로 든 것이 바로 0-RTT 데이터 한 묶음을 그대로 복제하는 네트워크 공격자입니다. 부록 E.5 의 제목도 Replay Attacks on 0-RTT 입니다. 그 부록은 재전송 가능한 0-RTT 데이터가 TLS 를 쓰는 애플리케이션에 여러 보안 위협을 준다고 적습니다. 다만 그 애플리케이션이 재전송 아래에서 안전하도록 특별히 설계된 경우는 뺍니다. 최소한 멱등이어야 하고, 많은 경우에는 응답 시간을 일정하게 유지하는 것 같은 더 강한 조건도 필요하다고 덧붙입니다. 드는 위협은 물건을 사거나 돈을 옮기는 것처럼 부작용을 낳는 동작이 중복되는 것, 공격자가 0-RTT 메시지를 저장해 두었다가 다시 보내 다른 메시지와의 순서를 뒤바꾸는 것입니다. 삭제를 생성 뒤로 옮기는 식입니다.
메시지를 고쳐 넣는 순간은 이 표제어가 아닙니다. NIST 용어집은 중간자 공격을 오가는 데이터를 가로채 선택적으로 고치는 능동적 도청 공격으로 정의하지만, 고친다는 말은 재전송 공격 쪽 정의에 없습니다.
판정에 따라오는 단서가 하나 있습니다. 부록 E.5 는 0-RTT 데이터 복제를 쓰는 공격으로부터 스스로를 지킬 책임이 궁극적으로 서버에 있다고 적습니다. 8절이 설명한 수단들은 TLS 계층에서 재전송을 막으려는 것이고, 클라이언트 데이터의 사본을 여러 벌 받는 것에 대한 완전한 보호를 주지는 않습니다.
관련 항목
재전송을 가려내는 재료
논스 · 타임스탬프 · 시퀀스 번호 · 신선도 · 일회용 티켓 · 재전송 캐시 · 도전-응답 · 일회용 비밀번호 · 시간과 시계 · 데이터베이스
재전송이 걸리는 통신 계층과 프로토콜
네트워크 · TLS · Kerberos · IPsec · HTTP
재전송 공격이 다루는 대상과 수법
메시지 · 인증 · 접근 제어 · 0-RTT · 조기 데이터 · 세션 · 세션 토큰 · 쿠키 · 인증과 인가 · 복제
재전송 공격에 관여하는 역할과 참여자
검증자 · 주장자 · 인증자
재전송 공격과 헷갈리는 이웃
중간자 공격 · 능동적 도청 · 세션 하이재킹 · 가장 공격
재전송 방어에 얽히는 성질과 수단
다른 이름: replay attack · 리플레이 공격 · 재생 공격