소개
이 문서에서는 RADIUS 인증자 헤더 및 메시지 인증자 특성, 이 특성이 사용되는 방법, 검증 실패 예상 시점에 대해 설명합니다.
인증자 헤더
RFC 2865에 따라 인증자 헤더의 길이는 16바이트입니다. Access-Request에서 사용되는 경우 이를 Request Authenticator라고 합니다. 어떤 종류의 응답에서도 사용될 경우 이를 응답 인증자라고 합니다. 다음과 같은 용도로 사용됩니다.
응답 인증
서버가 올바른 Response Authenticator로 응답하면, 클라이언트는 해당 응답이 유효한 요청과 관련된 것인지 여부를 계산할 수 있습니다.
클라이언트가 임의의 인증자 헤더와 함께 요청을 전송합니다. 그런 다음 응답을 전송하는 서버는 공유 암호와 함께 요청 패킷을 사용하여 응답 인증자를 계산합니다.
ResponseAuth = MD5(Code + ID + Length + RequestAuth + Attributes + Secret)
응답을 받은 클라이언트는 동일한 작업을 수행합니다. 결과가 같으면 패킷이 정확합니다.
참고: 비밀 값을 알고 있는 공격자는 요청을 스니핑할 수 없는 한 응답을 스푸핑할 수 없습니다.
검증 실패가 예상되는 경우:
스위치가 더 이상 요청을 캐시하지 않는 경우(예: 시간 초과) 검증 실패가 발생합니다. 공유 암호가 유효하지 않은 경우에도 이를 경험할 수 있습니다(예 - Access-Reject에도 이 헤더가 포함됨). 이 방법으로 NAD(Network Access Device)는 공유 비밀 불일치를 탐지할 수 있습니다. 일반적으로 AAA(Authentication, Authorization, and Accounting) 클라이언트/서버에서 공유 키 불일치로 보고되지만 세부 정보는 표시되지 않습니다.
비밀번호 숨기기
인증자 헤더는 일반 텍스트로 User-Password 특성을 전송하지 않도록 하기 위해 사용됩니다. 먼저 메시지 다이제스트 5(MD5 - 암호, 인증자)가 계산됩니다. 그런 다음 비밀번호의 청크로 여러 XOR 연산이 실행됩니다. MD5는 더 이상 강력한 단방향 알고리즘으로 인식되지 않으므로 이 방법은 오프라인 공격(레인보우 테이블)에 취약합니다.
다음은 사용자 비밀번호를 계산하는 Python 스크립트입니다.
def Encrypt_Pass(password, authenticator, secret):
m = md5()
m.update(secret+authenticator)
return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(password.ljust
(16,'\0')[:16], m.digest()[:16]))
재전송
RADIUS Access-Request의 특성 중 하나(예: RADIUS ID, User-Name 등)가 변경된 경우 새 인증자 필드를 생성하고 이에 종속된 다른 모든 필드를 재계산해야 합니다. 재전송이면 아무것도 변경되지 않습니다.
어카운팅
인증자 헤더의 의미는 Access-Request와 Accounting-Request에 대해 다릅니다.
액세스 요청의 경우 인증자가 무작위로 생성되고 ResponseAuthenticator가 올바르게 계산된 응답을 수신해야 합니다. 그러면 해당 응답이 특정 요청과 관련이 있음을 알 수 있습니다.
어카운팅 요청의 경우 인증자가 무작위가 아니지만 계산됩니다(RFC 2866에 따라).
RequestAuth = MD5(Code + ID + Length + 16 zero octets + Attributes + Secret)
이렇게 하면 서버는 즉시 어카운팅 메시지를 확인하고 다시 계산된 값이 인증자 값과 일치하지 않을 경우 패킷을 삭제할 수 있습니다. ISE(Identity Services Engine)는 다음을 반환합니다.
11038 RADIUS Accounting-Request header contains invalid Authenticator field
일반적인 이유는 잘못된 공유 비밀 키입니다.
메시지 인증자 특성
Message-Authenticator 특성은 RFC 3579에 정의된 RADIUS 특성입니다. 유사한 용도로 사용됩니다. 서명하고 유효성을 검사합니다. 그러나 이번에는 응답을 검증하는 데 사용되지 않고 요청을 검증하는 데 사용됩니다.
Access-Request(Access-Challenge로 응답하는 서버일 수도 있음)를 전송하는 클라이언트는 자체 패킷에서 HMAC(Hash-Based Message Authentication Code)-MD5를 계산한 다음 Message-Authenticator 특성을 서명으로 추가합니다. 그런 다음 서버가 동일한 작업을 수행하는지 확인할 수 있습니다.
공식은 인증자 헤더와 유사합니다.
Message-Authenticator = HMAC-MD5 (Type, Identifier, Length, Request Authenticator,
Attributes)
HMAC-MD5 함수는 다음 두 가지 인수를 사용합니다.
- 0으로 채워진 16바이트 Message-Authenticator 필드를 포함하는 패킷의 페이로드
- 공유 암호
메시지 인증자를 사용하는 경우:
EAP(Extensible Authentication Protocol) 메시지(RFC 3579)를 포함하는 모든 패킷에 메시지 인증자를 사용해야 합니다. 여기에는 Access-Request를 전송하는 클라이언트와 Access-Challenge로 응답하는 서버가 모두 포함됩니다. 다른 쪽은 검증에 실패할 경우 패킷을 자동으로 삭제합니다.
검증 실패가 예상되는 경우:
공유 암호가 올바르지 않으면 유효성 검사에 실패합니다. 그러면 AAA 서버가 요청의 유효성을 검사할 수 없습니다.
ISE는 다음을 보고합니다.
11036 The Message-Authenticator Radius Attribute is invalid.
이는 일반적으로 EAP 메시지가 연결 될 때 나중 단계에서 발생 합니다. 802.1x 세션의 첫 번째 RADIUS 패킷은 EAP 메시지를 포함하지 않습니다. 메시지 인증자 필드가 없으며 요청을 확인할 수 없지만, 그 단계에서는 클라이언트가 인증자 필드를 사용하여 응답을 검증할 수 있습니다.
메시지 인증자 특성 유효성 검사
다음은 값이 올바르게 계산되었는지 확인하기 위해 값을 수동으로 계산하는 방법을 보여 주는 예입니다.
패킷 번호 30(Access-Request)이 선택되었습니다. EAP 세션의 중간에 있으며, 패킷에 Message-Authenticator 필드가 포함됩니다. 목표는 메시지 인증자가 올바른지 확인하는 것입니다.
- Radius Protocol을 마우스 오른쪽 버튼으로 클릭하고 Export selected packet bytes(선택한 패킷 바이트 내보내기)를 선택합니다.
- 해당 RADIUS 페이로드를 파일(이진 데이터)에 기록합니다.
- Message-Authenticator 필드를 계산하려면 0을 입력하고 HMAC-MD5를 계산해야 합니다.
예를 들어, 16진수 모드로 전환하고 "5012" 다음부터 16바이트를 0으로 시작하는 ":%!xxd"를 입력한 후 vim과 같은 16진수/이진 편집기를 사용하는 경우(50hex는 메시지 인증자 유형인 12월에 80이고, 12는 AVP(특성 값 쌍) 헤더를 포함하는 18인 크기입니다):
vim 및 기타 텍스트 편집기는 저장 시 파일 끝에 추가 LineFeed 문자('0a', 16진수)를 추가할 수 있습니다. 텍스트 편집기(vim -b 파일)의 이진 모드를 사용하여 LineFeed 문자가 표시되지 않도록 해야 합니다.
수정 후 페이로드가 준비됩니다. 16진수/이진 모드(유형: ":%!xxd -r")을(를) 입력하고 파일(":wq")을 저장합니다. 'hexdump -C file'을 사용하여 추가 LineFeed 문자가 추가되지 않았는지 다시 확인할 수 있습니다.
- HMAC-MD5를 계산하려면 OpenSSL을 사용합니다.
pluton # cat packet30-clear-msgauth.bin | openssl dgst -md5 -hmac 'cisco'
(stdin)= 01418d3b1865556918269d3cf73608b0
HMAD-MD5 함수는 두 개의 인수를 사용합니다. 표준 입력(stdin)의 첫 번째 메시지는 메시지 자체이며, 두 번째 메시지는 공유 암호(이 예에서는 Cisco)입니다. 결과는 RADIUS Access-Request 패킷에 연결된 Message-Authenticator와 정확히 같은 값입니다.
Python 스크립트를 사용하여 다음과 같이 계산할 수 있습니다.
파이썬 2:
pluton # cat hmac.py
#!/usr/bin/env python
import base64
import hmac
import hashlib
f = open('packet30-clear-msgauth.bin', 'rb')
try:
body = f.read()
finally:
f.close()
digest = hmac.new('cisco', body, hashlib.md5)
d=digest.hexdigest()
print d
pluton # python hmac.py
01418d3b1865556918269d3cf73608b0
Python 3:
import hmac
import hashlib
with open('packet30-clear-msgauth.bin', 'rb') as f:
body = f.read()
digest = hmac.new(b'cisco', body, hashlib.md5)
print(digest.hexdigest())
앞의 예에서는 Access-Request에서 Message-Authenticator 필드를 계산하는 방법을 보여 줍니다. Access-Challenge, Access-Accept 및 Access-Reject의 경우 로직은 정확히 동일하지만, 이전 Access-Request 패킷에서 제공된 Request Authenticator를 사용해야 한다는 점을 기억해야 합니다.
관련 정보