* 공격 수단 축소
IDS에 의해 감시되는 스푸핑된 공격은 긍정 오류를 생성하지 못하며, 기본 버리기 패킷 필터 때문에 세션이 숫립될 수 없으므로 수립된 TCP 세션을 통해 실제 공격을 전달하려는 시도도 실패한다. 그러므로 포트 노킹과 SPA는 네트워크 서비스에 대해 공격을 가할 수 있는 수단을 감소시킨다. iptables 가 제공하는 기능을 통해 효과적인 포트 노킹과 PSA 시스템을 쉽게 구현할 수 있다. SSHD와 같은 서비스에 이렇게 추가적인 보안 계층을 추가함으로써 시스템이 침투되지 않고 안전한 상태로 유지되게 할 수 있다.
* 제로 데이 공격 문제
Bugtraq, 풀-디스클로저, Vuln-dev 메일링 리스트는 매우 활발하며, 최신 공격 기술에 대해 아주 훌륭한 기술 정보와 논의를 제공한다. 회사 전체(예를 들어 iDefense, http://idefense.com 참조)가 취약점 추적에 기반한 사업 모형을 가지고 사용자를 위한 취약점 조기 경고 시스템을 제공하기도 한다. iDefense 는 새로운 취약점을 발견한 사람에게 돈을 지불하고 자신이 취약점을 먼저 공개할 권리를 사기도 한다.
상용으로 개발되는 대부분의 소프트웨어는 보안이 아니라 이익을 극대화하려는 고객을 위해 개발된다. 그러나 피싱(phishing), 스파이웨어, 신원 도난, 마이크로소프트 시스템을 목표로 하는 특히 치명적인 웜(코드 레드와 SQL 슬래머 등)과 같이 보안 문제의 분류가 세분화됨에 따라 회사들이 보안을 강조하기 시작했다.
그렇다면 한가지 의문점이 든다. 왜 이렇게 보안 취약점이 많은가?
– 소프트웨어는 항상 구현에 따라 달라지며 소프트웨어가 안전하다는 것을 엄밀히 증명해주는 방법은 존재하지 않는다. 구현상 버그로 인해 이론적으로 안전한 소프트웨어 설계가 보안 문제에 노출될 수 있다.
– OpenSSH 프로젝트(http://www.openssh.org 참조)를 살펴보자. OpenSSH는 세계에서 가장 예리하며 보안을 고려하는 개발자들이 작성하지만 이런 OpenSSH 조차 취약점을 가져왔다. 이는 버그가 없는 소프트웨어를 작성하는 것이 정말로 힘들며 최고의 보안 개발자들도 실수한다는 사실을 말해준다.
** 제로데이 공격 발견
제로 데이 공격(zero-day attack)은 소프트웨어에서 누군가가 이전에 발견되지 않은 보안 취약점을 발견한 후 이에 대한 공격을 작성할 때 발생한다. 얼마 동안은 이 사람만 이 취약점을 알고 있게 되는데, 이때 그는 선택의 기로에 놓인다. 공격을 사용하지 않고 취약점을 수정할 수 있게 소프트웨어 회사에게 알리는 길과 개인적인 이득을 위해 공격을 사용하고 누구에게도 알리지 않는 길이 있다. 후자는 분명 소프트웨어 사용자에게 가장 큰 위협이며, 제로 데이 공격은 선의의 해커와 악의의 해커 모두에 의해 점점 더 많이 발견되고 있다.
** 서명 기반 탐지의 영향
스노트 규칙집합의 일부 서명은 공격자가 특권을 얻은 후 시스템을 수상한 방식으로 사용하려는 시도를 일반적으로 탐지하게 설계됐다. 이는 때때로 스노트가 공격 자체를 탐지할 필요 없이 제로 데이 공격의 영향(즉, 공격자가 권한을 얻은 후 실제로 침투된 시스템을 사용하려고 할 때)을 탐지하게 해준다.
제로 데이 취약점 문제로 인해 네트워크 이상 탐지 시스템(Network Anomaly Detection System)을 개발하는 새로운 분류의 보안 회사가 등장했다. 네트워크 탐지 시스템은 컴퓨터 네트워크 내의 이상 행위를 탐지하게 설계된 제품이다. 이런 시스템의 목표는 공격자가 침투에 성공한 후 네트워크 내에서 시스템을 사용하는 방식을 탐지하는 것이다.
하지만 문제는 일상적인 동작과 비일상적인 동작을 구별하기에는 너무 큰 이종성이 네트워크에 존재한다는 것이다. 상용 회사와 하계 모두에서 알려지지 않은 취약점에 대한 공격의 영향을 어떻게 줄일지 활발히 연구하고 있지만 아직 일반적인 해결책은 없다.
* 포트 노킹
2003년 마틴 크리지빈스키는 시스어드민(Sysadmin)에 실은 글에서 포트 노킹(port knocking)이라는 훌륭한 개념을 보안 커뮤니티에 소개했다. 포트 노킹은 서비스(예를 들어 SSHD)가 기본 버리기 전략으로 설정된 패킷 필터에 의해 보호되게 해주는 닫힌 포트를 통한 인증 데이터의 통신이다. 기본 버리기 패킷 필터를 통해 보호되는 서비스에 연결하고자 하는 클라이언트는 우선 유효한 포트 노크 나열(port knock sequence)을 소유하고 있다는 것을 증명해야 한다. 클라이언트가 (예를 들어 적절한 순서로 포트 나열을 구성하는 포트에 연결함으로써) 올바른 노크 나열을 생성하면 패킷 필터는 보호되는 서비스에 연결하기 위해 포트 나열을 전송한 IP 주소를 잠시 허용하게 일시적으로 재설정 된다.
포트 노킹은 빠르게 전파됐으며, 보안 분야에서 알려진 포트 노킹 구현 기법만 거의 30개에 이른다. 각 구현은 포트 노킹의 개념을 약간씩 다르게 제공하는데, 예를 들어 cd00r과 포트 키(port key)는 포트 노크 나열을 전송하기 위해 TCP SYN 패킷을 사용하는 반면 텀블러(Tumbler)는 해싱된 인증 데이터를 전송하기 위해 패킷 페이로드를 사용한다.
** Nmap과 목표 식별 단계 무력화하기
포트 노킹 나열은 수동적인 방법(예를 들어 방화벽 로그 파일을 감시하거나 libpcap 과 같은 패킷 캡처 도구를 이용해서 인터페이스를 스니핑하는 방법)으로 네트워크를 감시할 수 있는 포트 노킹 서버가 감시한다. 포트 노킹 시스템을 사용하면 궁극적으로 네트워크를 오가는 트래픽을 감시할 수 없는 사람에게는 서비스가 보이지 않게 된다. Nmap 조차 기본 버리기 패킷 필터로 보호되는 서비스는 볼 수 없다. 공격자가 제로 데이 공격을 가지고 있더라도 달라지는 것은 없다.
** 공유 포트 노킹 나열
공유 포트 노킹 나열은 포트 노킹 클라이언트와 서버 가동의 한 정렬된 포트 집합이다. 네트워크에서 이 나열이 보이면 기본 버리기 패킷 필터는 나열을 전송한 것으로 보이는 IP 주소가 특정 포트에 접근할 수 있게 재설정된다. 예를 들어 TCP 포트 22번에서 실행 중인 SSHD에 접속하려면 클라이언트는 우선 SYN 패킷을 TCP 포트 5005, 5008, 1002, 1050 으로 전송해야 할 수 있다. 이런 노크 나열이 닫힌 포트로의 패킷을 기록하게 설정된 iptables 방화벽에 전송되면 로그에 접속을 시도한 포트의 로그가 나타날 것이다.
일단 포트 노킹 서버가 /var/log/messages 파일에서 포트 노크 나열을 발견하면 iptables는 SSHD와 같은 서비스로의 접근을 일시적으로 허용하게 재설정된다.
포트 노킹 나열은 TCP 외에 다른 인터넷 프로토콜을 수반할 수도 있다. UDP, ICMP, 또는 세 프로토콜이 동시에 나열을 구성할 수도 있다. 예를 들어 포트 노크 나열은 TCP/10001, UDP/2300, ICMP 에코 요청, TCP/6005, UDP/3000 과 같을 수 있다.
ICMP에는 “포트”라는 개념이 없기 때문에 포트 노킹 나열에 ICMP 패킷을 포함하는 것은 포트 노킹의 정의에서 약간 벗어난다. 그러나 포트 노킹은 사실 정보를 패킷 헤더 내에 인코딩하는 것에 대한 기술이므로 ICMP 패킷을 포함하는 것이 포트 노킹의 정의를 크게 위방하는 것은 아니다. ICMP를 나열에 사용하지 못할 이유는 전혀 없다.
사실 TCP나 UDP 헤더에서 포트 항목을 제외한 다른 항목도 포트 노킹 나열 내에 추가적인 정보를 인코딩하는 데 사용될 수 있다. 예를 들어 UDP 헤더의 16비트 크기의 체크섬 항목은 포트 노킹 클라이언트에 의해 직접 미리 결정된 값으로 설정 될 수 있으며, 포트 노킹 서버는 체크섬이 미리 정한 값과 매칭되는 경우 UDP 패킷을 포트 노킹 나열의 일부로서 수용하게 구현될 수 있다.
** 포트 노킹의 구조적 한계
포트 노킹이 발견되지 않은 보안 버그를 가질 수 있는 네트워크 서비스에 대해 추가적인 보호 계층을 제공할 수 있지만 포트 노킹은 그 구조적 특징으로 인해 회사 수준의 배치를 하기에는 적합하지 않다. 이런 한계는 애플리케이션 계층 페이로드를 사용하지않고 패킷 헤더를 데이터 전송 기법으로 사용하는 데서 기인한다.
– 나열 재전송 문제.
보안 위협이 매우 큰 요즘에는 모든 트래픽이 네트워크를 통해 전송될 때 미지의 제 3자에 의해 감시당한다고 가정해야 한다. 이런 관점에서 볼 때 민감한 정보(예를 들어 신용카드 번호)는 암호화된 형태로 전송돼야 한다.
포트 노킹의 경우 어떤 패킷도 애플리케이션 계층 데이터를 가지지 않으므로 포트 노킹 나열을 가로챌 이유는 거의 없는 것처럼 보인다.
그러나 포트 노킹의 목적은 수신측이 패킷 필터를 일시적으로 재설정해서 노트 나열을 통해 자신을 증명한 IP 주소에게 접근 권한을 부여하기 위해 필요한 정보를 네트워크로 전송하는 것이다. 포트 노킹 나열이 네트워크를 통해 전송될 때 공격자가 이를 가로챌 수 있다면 공격자는 나중에 동일한 목표에 동일한 노크 나열을 쉽게 전송할 수 있다. 공격자가 적법한 포트 노킹 클라이언트와 동일한 접근 권한을 얻기 위해 목표에게 노크 나열을 재전송하기 때문에 이를 재전송 공격(Reply attack)이라고 한다. 포트 노킹이 단순히 패킷 해더만을 사용하기 때문에 포트 노크 나열에 재전송 공격을 막을 정도로 충분한 가변성을 추가하기는 힘들다.
일부 포트 노킹 구현은 재전송 공격을 막기 위해 해쉬 함수의 연속적인 반복(RFC 1760 에서 정의하는 S/Key 인증과 유사함)을 사용하지만 이 방법을 사용하려면 클라이언트와 서버가 모두 일종의 상태 정보를 저장해야 한다. 또는 단순하게 일단 접근 권한이 부여되면 공유 포트 노크 나열이나 평문화 암호를 변경할 수도 있지만 이는 많은 사용자가 이용하는 서비스에는 쓰일 수 없다.
– 최소 데이터 전송 속도
TCP와 UDP 헤더의 포트 항목은 16비트기 때문에 포트 노킹 구현이 노크 나열의 각 패킷에서 목적지 포트 번호만 사용한다고 가정하면 패킷당 2 바이트의 정보만을 전송할 수 있다. 또 포트 노킹에는 TCP와 같이 패킷을 순서대로 전달하거나 패킷을 재전송하는 기법이 없기 때문에(포트 노킹은 철저히 단방향이다) 연속적인 패킷 사이에 시간 지연을 추가하지 않고는 전체 포트 노킹 나열을 네트워크로 전송할 수 없다. 패킷이 여러 라우팅 경로로 도착할 수 있기 때문에(즉, 어떤 패킷은 다른 패킷보다 느릴 수도 있다) 올바른 포트 노킹 나열의 정렬을 유지하기 위해서는 시간 지연이 필요하다.
모든 네트워크에 잘 적용되는 최적의 시간 지연은 없지만(그리고 실제로 포트 노킹 나열의 일부가 손실되면 전체 나열을 재전송해야 하지만) 0.5 초 정도의 시간 지연이 필요하다.
그러므로 128비트 블록 크기(Rijndael 알고리즘의 최소 블록 크기)를 가지는 대칭 키 알고리즘으로 암호화된 포트 노킹 나열의 경우 최소한 8개의 패킷이 필요하다(128 비트 / 패킷당 16 비트 = 8패킷). 패킷 사이마다 0.5 초의 지연을 추가하는 것은 나열은 전송하는 데만 4초가 필요하며 데이터를 더 전송해야 하는 경우네는 두 패킷마다 1초씩 추가된다는 의미이다. 수 바이트 이상의 데이터를 전송하는 포트 노킹 나열을 구성하는 것을 현실적으로 불가능하게 하는 것이 바로 긴 전송 시간이다.
포트 노킹의 데이터 전송 기능이 극히 제한적이기 때문에 포트 노킹 나열을 암호화하기 위해 비대칭 암호화 알고리즘을 사용하는 것은 적절하지 않다. GnuPG와 2048 비트 키를 사용하는 Elgamal로 10 바이트의 정보만을 암호화해도 수백 바이트의 암호화된 정보가 생성된다.
– 노크 나열과 포트 스캔
포트 스캔은 짧은 시간 동안 다수의 목표 시스템 포트에 연결한다. 포트 스캔과 노크 나열의 목적은 전혀 다름에도 불구하고 네트워크상에서 보면 포트 노크 나열도 포트 스캔의 정의에 정확히 일치한다. 문제는 포트 스캔을 탐지하는 침입 탐지 시스템이 두 활동을 구별하지 못해서 둘 모두에 대해 경고를 생성한다는 점이다. 이런 경고 때문에 원격 서비스에 인증하기 위해 포트 노킹을 사용하는 사람에게 불필요한 주의를 기울여야 할 수 있다.
– 스푸핑된 패킷을 이용한 노크 나열 파괴
포트 노킹은 (암호화된 애플리케이션 계층 데이터를 사용하지 않고) 패킷 헤더의 정보만을 인코딩하기 때문에 공격자는 패킷이 적법한 노크 나열의 일부인 것처럼 쉽게 꾸밀 수 있다. 패킷이 네트워크에 있는 도중에 중복 패킷을 포트 노킹 나열로 스푸핑하면 노크 서버는 이 추가적인 패킷이 포트 노킹 클라이언트가 전송한 실제 나열의 일부가 아니라는 것을 알 수 없다. 결과적으로 서버는 클라이언트가 유효한 노크 나열을 알지 못한다고 판단한다. 공격자는 서버가 적법한 포트 노킹 클라이언트에게 권한을 부여하지 못하게 할 수 있기 때문에 이는 노크 서버에 대한 서비스 거부(Dos) 공격이다. DoS 공격이 복잡한 작업일 수도 있지만(예를 들어 좀비 머신으로 구성된 네트워크에서 단일 IP 주소로의 트래픽 플러딩을 관리해야 한다) 때로는 수행하기 매우 간단할 수도 있다. 예를 들어 서버에 대한 DoS에는 하나의 패킷만이 필요하며 이런 공격은 너무도 수행하기 쉬우며 어느 곳으로부터도 스푸핑될 수 있다!
* 단일 패킷 권한 부여
단일 패킷 권한 부여(SPA, Single Packet Authorization)는 포트 노킹 구현과 유사한 방식으로 기본 버리기 패킷 필터와 수동적으로 감시하는 패킷 스니퍼를 결합한다. 그러나 패킷 헤더 항목을 이용해서 인증 데이터를 전송하는 대신 SPA는 인증 정보의 소유를 증명하기 위해 페이로드 데이터를 활용한다. 이는 대부분 네트워크의 MTU 크기가 수백 바이트 단위(예를 들어 이더넷 MTU 는 이더넷 헤더를 포함해서 1514 바이트다)기 때문에 가능하며 클라이언트는 단 하나의 패킷으로 SPA 서버에 자신의 식별 정보를 전송할 수 있다.
** 포트 노킹 한계점 해결.
포트 노킹 프로토콜이 가지는 문제를 요약하면 다음과 같다.
– 포트 노킹 나열을 감시할 수 있는 공격자의 재전송 공격을 막기 힘들다.
– 효과적인 데이터 전송 방법의 부재로 인해 전송할 수 있는 정보 유형과 나열 데이터를 암호화하는 데 사용할 수 있는 암호화 알고리즘이 제한된다.
– 포트 노크 나열이 네트워크를 통해 전송될 때 중간 IDS가 경고를 생성할 수 있다.
– 해킷 헤더의 중복과 스푸핑은 어렵지 않기 때문에 나열 파괴 공격이 매우 쉽다.
SPA 에서는 페이로드 데이터를 사용해서 이런 문제를 해결한다.
– SPA는 모든 SPA 패킷에 무작위 데이터를 포함시키는 방법으로 재전송 문제를 해결한다. SPA 패킷은 잘 정의된 평문 패킷 형식에 따라 구성된다. 이 형식에는 무작위 데이터를 위한 부분이 있으며, 패킷은 구성된 후 암호화된다. 무작위 데이터를 포함하는 것은 어떤 SPA 패킷도(SPA 서버에 동일한 접근을 요청하는 패킷끼리도) 겹치지 않게 보장해준다. 어떤 SPA 패킷도 동일한 MD5 의 합을 가지지 않는다는 것을 알기 때문에 성공적으로 편문화된 SPA 패킷의 MD5 합을 서버 측에 저장암으로써 동일한 접근 요청은 반복적으로 전송할 수 없다. 그러므로 새로운 SPA 패킷과 이전에 감시된 패킷의 MD5 합을 비교함으로써 재전송 공격을 쉽게 무력화시킬 수 있다.
– SPA는 TCP가 애플리케이션 데이터를 캡슐화하는 것과 유사한 방식으로 IP 패킷의 페이로드 부분을 사용해서 데이터 전송 문제를 해결한다. 패킷 페이로드를 사용하면 비대칭 알고리즘을 사용하기 쉬워지는데, 이는 패킷 페이로드가 (패킷 헤더만을 사용하는) 그 어떤 포트 노킹 구현보다도 많은 양의 데이터를 전송할 수 있기 때문이다. SPA를 통한 명령 채널(즉, 암호화된 SPA 페이로드에 완전한 명령을 담아 전송하는 것)도 생성할 수 있다.
– SPA는 인증 정보를 전송하기 위해 단 하나의 패킷만을 사용하기 때문에 SPA 네트워크 통신은 절대 포트 스캔처럼 보이지 않는다. 그러므로 IDS는 포트 범위에 대한 탐사들을 보지 않게 된다. SPA 페이로드는 암호화되기 때문에 IDS는 SPA 메시지의 내용도 디코딩할 수 없다. SPA 패킷은 스니핑하는 측에게 해설 불가능한 페이로드 데이터 덩어리로 보인다.
– SPA를 사용하면 공격자는 SPA 클라이언트 시스템으로부터 SPA 서버로 패킷을 스푸핑하는 방법으로 SPA 프로토콜을 쉽게 깰 수 없기 때문에 스푸핑 공격을 무력화할 수 있다(물론 네트워크 패킷 데이터를 조사하는 모든 시스템은 쓰레기 패킷 데이터로 플러딩 당할 경우 DoS 에 취약하기 쉽지만 이는 SPA 프로토콜 자체의 약점은 아니다).
** SPA의 구조적 한계
– NAT 주소를 통한 피기 백킹(Piggy-Backing) 접근
패킷 필터는 일반적으로 전송 계층이나 그 이하 계층에서 트래픽을 필터링하는 데는 우수하지만 애플리케이션 계층을 해설하는 데는 그다지 좋지 못하다. 결과적으로 SPA가 (유효한 SPA 패킷을 수신한 후) 들어오는 연결을 수용하기 위해 적용하는 필터링 기준은 현실적으로 출발지 IP 주소, 요청된 인터넷 프로토콜, 포트 번호만 포함할 수 있다. 즉, SPA 패킷이 SPA 서버에게 TCP 포트 22를 30초 동안 특정 IP 주소에 대해 열게” 지시할 때 SPA 서버는 30초 동안 출발지 IP 주소에서 TCP 포트 22로 연결하는 모든 패킷을 수용하게 패킷 필터를 설정한다. SPA 패킷 내의 IP 주소가 외부 NAT 주소라면(이는 SPA 클라이언트가 NAT 장치 뒤에 있을 때 필요하다)적법한 클라이언트와 동일한 내부 네트워크상의 누구라도 허용된 시간 동안 동일한 접근 권한을 가지게 된다.
– HTTP와 단기 세션
SPA 데몬이 TCP 연결의 수립을 허용하기 위해 패킷 필터 규칙집합에 임시 규칙을 추가할 때 적법한 클라이언트 측에는 보통 TCP 쓰리웨이 핸드쉐이크를 완료하기에 충분한 시간이 있다. 그러나 SSH 세션은 보통 TCP 연결을 수립된 상태로 만드는데 필요한 시간보다 훨씬 더 길게 지속된다.
규칙이 규칙 집합에서 삭제될 때 어떤 일이 일어나는가? 수립된 연결에 속하는 패킷이 기본 버리기 규칙에 의해 버려지기 전에 이를 수용하기 위해 (넷필터 등이 제공하는)연결 추적 기법을 사용하는 경우 연결은 세션이 수립되게 해준 초기 규칙이 삭제 됐음에도 불구하고 열린 상태로 남을 수 있다.
수립된 TCP 연결을 열린 상태로 유지하기 위한 연결추적 기법은 길게 유지되는 TCP 세션에 대해 훌륭한 해결책을 제공한다. 하지만 웹을 통해 HTTP 데이터를 전송하거나 메일 서버 간에 SMTP 데이터를 전송하는 것과 같은 단기 연결의 경우는 어떤가? 사용자가 보고자 하는 모든 웹 링크마다 새로운 SPA 패킷을 생성하는 것은 불편할 것이다. 모든 링크가 별도의 TCP 연결을 통해 전송된다는 사실은 이 문제를 더 악화시킨다. 일반적으로 SPA는 이런 서비스를 보호하는 데 적합하지 않다.
해결책의 하나로 가령 한 시간 동안 새로운 SPA 패킷이 필요 없게 단순히 클라이언트 IP 주소의 시간 만료를 확장하는 방법이 있다. 이런 확장이 SPA 유효성을 어느 정도 감소시키긴 하지만 웹서버가 중요한 애플리케이션을 실행 중이고 보안이 가장 중요한 고려사항일 때는 이런 해결책이 타당할 수 있다.