* 들어가며..
스노트 규칙을 항상 깔끔하게 변활할 수는 없으며, 스노트 규칙 언어는 매우 복잡하기 때문에 fwsnort는 스노트 버전 2.3.3 에 포함된 규칙의 약 60% 정도를 변환할 수 있다.
fwsnort가 전체 스노트 서명 집합을 iptables 규칙으로 변활할 수는 없지만 fwsnort 는 항상 네트워크 트래픽에 인라인으로 배치된다. 스노트는 주로 수동적 전략으로 배치되며 네트워크 트래픽에서 수상한 활동을 감시하는 데 쓰인다. 즉, 스노트는 인라인 기능을 지원함에도 불구하고 대개 인라인으로 배치되지 않는다. fwsnort가 생성한 모든 정책은 수동적 패킷 조사에 국한되지 않는다. fwsnort가 생성한 모든 정책은 수동적 패킷 조사에 국한되지 않는다. fwsnort 정책은 iptables DROP 타켓을 통해 악의적인 패킷을 버리게 설정할 수 있다.
스노트 규칙 언어의 융통성과 완결성은 스노트가 네트워크 기반 공격의 설명적 표현을 검색할 수 있게 해주며, 공격이 네트워크를 통해 전송될 때 이에 응답할 수 있게 해준다. 이것이 스노트를 최고의 네트워크 침입 탐지와 방지 도구의 하나로 굳게 자리매김해준 기능이다.
그러나 좋은 침입 방지 시스템(IPS)이 효과적인 방화벽의 완벽한 대체 수단이 되는 것은 절대 아니다. 방화벽과 침입 방지 시스템은 일반적으로 서로 반대 관점에서 보안 강화에 접근한다. 방화벽은 보안 정책에 기반해서 허용 가능한 트래픽을 정의하고 정책을 따르지 않는 트래픽을 차단(그리고 기록)한다. 반면 침입 방지 시스템은 허용할 수 없는 네트워크 트래픽을 정의하고 이런 활동만 차단(또는 응답)한다.
이와 동시에 방화벽과 IPS 구현의 경계는 이 둘이 융합하면서 점차 불분명해지기 시작했다. 방화벽은 좀 더 많은 애플리케이션 계층 처리 기능(오랫동안 침입 탐지 시스템만의 기능이었다)을 가지게 됐고 침입 방지 시스템은 애플리케이션 계층 처리와 독립적인 기본적인 필터링 기능을 제공하게 되었다.
* fwsnort를 사용해야 하는 이유
fwsnort 프로젝트는 리눅스 시스템과 통신하게 허용되는 패킷의 유형을 제어하는 리눅스 커널의 기능을 향상시키는 데 초점을 두고 있다. 스노트 서명 언어의 강력함에 리눅스 커널의 속도와 iptables 명령의 간결성을 결합함으로써 fwsnort는 기존 IPD/IPS 인프라스트럭처의 보안 전략을 보완할 수 있다. fwsnort 는 단순히 iptables 명령을 실행(주로 말단 호스트에서 실행)하는 쉘 스크립트를 작성하기 때문에 fwsnort를 다른 IDS/IPS와 함께 배치하는 것은 매우 쉽다. 더욱이 iptables는 네트워크 트래픽에 항상 인라인이기 때문에 안정성과 속도 측면에서 엄격하게 테스트됐다.
** 철저한 방어
긍정 오류를 생성하게 하는 방법으로 IDS 경고 기능을 전복하려는 시도에서 IDS 내에 존재하는 취약점을 이용해서 코드를 실행하려는 시도에 이르기까지 침입 탐지 시스템 자체가 공격 목표가 되는 경우도 많다.
철저한 방어의 원리는 전형적인 컴퓨터 시스템(서버와 데스크톱)뿐만 아니라 방화벽이나 침입 탐지 시스템과 같은 보안 인프라스트럭처에도 적용된다. 그러므로 기존의 침입 탐지/방지 시스템을 추가적인 방법으로 보충할 여지가 있다.
** 목표 기반 침입 탐지와 네트워크 계층 비단편화
IDS 에 탐지 동작과 말단 호스트의 특징을 결합할 수 있게 해주는 기능을 추가하는 것을 목표 기반 침입 탐지(target-based intrusion detection)이라고 한다.
예를 들어 윈도우 시스템에 대해 단편화된 공격이 전송되는데, 스노트는 리눅스 IP 스택이 사용하는 알고리즘으로 공격을 비단편화한다면 공격을 놓치거나 잘못 보고할 수 있다.
fwsnort 의 경우(공격자가 목표로 삼은 동일한 시스템에 로컬하게 배치될 때는 특히) 단편화 문제에 대해 신경 쓸 필요가 없다. fwsnort 에 적용된 단편화 알고리즘은 실제 공격 대상 IP 스택의 알고리즘이기 때문이다. fwsnort를 사용하면 네트워크 단편화는 (패킷을 올바른 연결로 분류하기 위해 트래픽을 비단편화해야 하는) 넷필터 연결추적 하위시스템을 fwsnort 정책과 함께 사용하는 방법으로 수행된다. fwsnort가 수행하는 애플리케이션 계층 조사는 리눅스 IP 스택이 이미 트래픽을 단편화한 후에 일어난다.
– fwsnort와 iptables를 이용하면 단편화된 공격에 대해서는 덜 걱정해도 되지만 목표 기반 침입 탐지의 장점이 네트워크 단편화 문제 때문에 제한되는 것은 아니며 단편화 문제는 IDS 커뮤니티에서 활발한 연구 개발이 진행 중인 분야다. 예를 들어 IDS는 잠재적인 긍정 오류를 판별하거나 보고된 공격의 심각성을 좀 더 정확히 판단하기 위해 OS와 애플리케이션 정보를 사용할 수 있다. 예를 들어 마이크로소프트 IIS 웹서버의 버퍼 오버플로우를 이용하는 공격은 아파치 웹서버로 전송되면 목표에 절대 침투할 수 없다. IDS가 이공격을 탐지하는 경우 이벤트의 심각성은 공격이 실제 IIS 서버로 전달됐을 때보다 상당히 낮아야 한다.
** 적은 자원 사용
사용량이 많은 시스템은 침입 탐지를 위해 사용자 프로세스(예를 들어 스노트)를 추가로 실행하기에는 자원이 부족할 수 있다. fwsnort의 경우 패킷 조사가 리눅스 커널 내부에서 직접 일어나며, 이는 주로 시스템 자원을 조금만 사용한다. (일반적인 IPS와 달리) 커널 공간에서 사용자 공간 프로세스로 메모리를 복사할 필요가 없다. 자원 제약 때문에 IDS/IPS 를 설치하기 힘든 시스템이라면 fwsnort 가 적절한 대안이다.
** 인라인 응답
fwsnort가 생성하는 iptables 서명 정책은 항상 네트워크 트래픽에 인라인이기 때문에 특히 악의적인 특정 공격에 조치를 취할 때에는 iptables 이 이상적일 수 있다.
서버의 가동 시간이 서비스 수준 계약서 (SLA, Service Level Agreement)를 따라야 하는 경우에는 서버를 중단하고 패치하기 전에 대기 시간이 있을 수 있다. 물론 이는 취약점을 수정할 패치가 존재한다고 가정한다(그러나 패치가 항상 존재하는 것은 아니다). 패치를 적용하기 위해 서비스 중단 시간을 잡을 수 있기 전까지는 사용자가 서버 소프트웨어를 이용할 수 있어야 한다면 인라인 방지 기법이 취약점에 대한 공격으로부터 서버를 적절히 보호할 수 있다(또 fwsnort 정책은 경량이기 때문에 대개는 인라인 모드로 실행중인 스노트와 같은 다른 방지 기법과 함께 배치될 수 있다).
– fwsnort는 단순히 iptables를 실행하기 위한 쉘 스크립트를 작성하기 때문에 SSH를 통해 한번에 여러 원격 시스템에 명령어를 실행할 수 있는 제노스(Zenoss, http://www.zenos.org)와 같은 것을 갖춘 시스템에 쉽게 배치할 수 있다. Zenoss 는 시스템 인프라스터럭처의 모든 리눅스 시스템에 fwsnort 를 쉽게 배치할 수 있게 해준다.
* fwsnort의 스노트 규칙 해석
스노트가 제공하는 기능에 비해 iptables가 제공하는 기능이 가지는 한계 때문에 모든 스노트 규칙이 변환될 수 있는 건 아니다. 뒤에서 설명하겠지만 스노트가 제공하는 기능에 비해 iptables가 제공하는 기능이 가지는 한계 때문에 모든 스노트 규칙이 변환될 수 있는 건 아니다.
네트워크 기반 공격은 굉장히 큰 가변성을 가진다. 엄청난 속도로 모든 종류의 소프트웨어에 대해 새로 발표되는 취약점뿐만 아니라 불명확한 방식으로 이런 취약점을 사용하는 TCP/IP 와 애플리케이션 API도 공격 전달을 가능하게 한다. 패킷 단편화, TCP 세션 결합(TCP session spicing), 다양한 애플리케이션 인코딩, 그리고 이와 유사한 것 때문에 단순히 트래픽이 네트워크를 통해 아무 문제없이 전송될 때 이를 감시하는 수동적 감시 시스템이 공격을 탐지하기는 더욱 어렵다.
** 스노트 규칙 헤더 변환
스노트 규칙은 규칙 헤더와 규칙 옵션이라는 두 개의 주요 부분으로 나뉜다. 규칙 헤더는 네트워크와 전송 계층의 매칭 기준을 엄격히 정의한다. 애플리케이션 계층 매칭 기준은 스노트 규칙 헤더에 존재할 수 없다.
– 스노트 규칙 헤더
예를 들어 스노트가 임의의 출발지 IP 주소에서 192.168.10.0/24 서브넷에 존재하는 임의의 IP 주소의 포트 53으로 전송되는 모든 TCP 트래픽과 매칭시키게 지시하는 스노트 규칙 헤더는 다음과 같다.
alret tcp any any -> 192.168.10.0/24 53
서명 관점에서 이 헤더는 다음과 같이 iptables 명령과 비슷하다.
# iptables -A FORWARD -p tcp -d 192.168.10.0/24 –dport 53 -j LOG
우선 스노트는 규칙 헤더에서 직접 IP, ARP, UDP, ICMP, TCP 를 지원한다(다른 프로토콜은 뒤에서 보이지 않게 지원한다). 다음으로 스노트 규칙은 스노트 규칙 헤더의 주소 부분을 통해 네트워크나 개별 IP 주소에 적용될 수 있다. 네트워크는 CIDR 표기법(예를 들어 192.168.10.0/24)이나 표준 도트 4자리 표기법(예를 들어 192.168.10.0/255.255.255.0)으로 명시할 수 있다.
끝으로 전송 계층 출발지와 목적지 포트 번호가 정의 된다. 포트 범위는 콜론(:)으로 명시할 수 있으며(예를 들어 :2123 은 포트 21에서 23까지를 의미한다), 포트 번호 역시 느낌표(!)로 부정할 수 있다(예를 들어 !80은 포트 80을 제외한 모든 포트에 적용된다).
– 스노트 헤더 와일드 카드와 변수 결정
스노트 규칙 헤더의 모든 매칭 기준(프로토콜은 제외)은 스노트가 특정 IP 주소나 포트 번호로 조사를 제한하지 않게 하기 위해 와일드카드로 설정할 수 있다. 또 스노트는 snort.conf 설정 파일에 값(예를 들어 IP 주소나 포트 번호의 목록)이 명시된 변수의 정의도 지원한다.예를 들어 스노트의 많은 웹 기반 규칙이 다음과 같은 헤더를 포함한다.
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS
– 규칙 동작과 iptables 에뮬레이션
규칙 동작은 alert, log, pass, activate, dynamic 중 하나가 될 수 있으며, 대부분의 스노트 규칙은 alert 를 기본 동작으로 가진다. alert 동작이 가장 중요하다(alert 는 스노트가 이벤트를 생성하고 이 경고를 일으킨 패킷을 기록하게 한다). 나머지 동작은 어떤 조치도 없이 패킷을 통과시키거나(pass) 패킷을 기록하거나(log) 특정 규칙이 매칭될 때까지 비활성 상태에 있다가 매칭 시점에 활성화돼서 패킷을 기록하게 일부 규칙을 설정하는 (activate 와 dynamic) 부가적인 기능을 제공한다.
지금까지 살펴본 바로는 스노트 규칙 헤더에서 activate과 dynamic 동작을 제외한 모든 것이 iptables 와 fwsnort 에서도 유사한 기능에 의해 지원된다.
-s IP 나 -d IP 인자를 사용하면 각기 출발지와 목적지 IP 주소나 네트워크를 iptables에 명시할 수 있으며 둘 모두 CIDR와 도트 4자리 표기법을 지원한다. 출발지와 목적지 포트 번호는 –sport port 와 –dport port 옵션을 사용해서 줄 수 있으며, 스노트와 마찬가지로 포트 범위는 콜론(:)으로 명시한다. 프로토콜은 -p protocol 로 명시할 수 있다.
예를 들어 TCP 트래픽에 적용되는 iptables 규칙을 만들고자 한다면 iptables 명령에 -p tcp 인자를 사용한다. 규칙을 목적지 포트 53으로 제한하고 싶다면 –dport 53 을 사용한다. 규칙의 목적지 주소를 192.168.10.0/24 서브넷의 모든 IP 주소로 적용하려면 -d 192.168.10.0/24 를 사용한다.
– 스노트 동작과 경고
스노트는 경고를 생성하고 패킷 데이터를 기록하는 몇 가지 훌륭한 옵션을 제공한다. fwsnort를 이용하면 다음과 같은 스노트 동작을 에뮬레이션하기 위해 이런 기능을 결합할 수 있다.
— 경고 : 주요 스노트 규칙 동작이며, fwsnort 내에서 경고는 로그 메시지 나머지 부분의 로그 접두어와 패킷 헤더 정보 내에 있는 스노트 서명 msg 항목을 기록하기 위해 iptables LOG 타겟을 사용하는 것과 같다. iptables 로는 애플리케이션 계층 데이터를 기록할 수 없지만 (ulogd PCAP 작성기와 함께 ULOG 타겟을 사용하면 가능하다) 적어도 msg 항목을 통해 공격은 기록된다.
— 기록 : fwsnort 내에서 이 동작은 좀 더 포괄적인 패킷 로깅을 위해 ulogd PCAP 작성기를 사용하는 할 때의 iptables ULOG 타겟과 동일하다.
— 통과 : 이 동작은 스노트 규칙 집합에서 때때로 패킷을 무시하기 위해 쓰이며, fwsnort 내에서는 iptables ACCEPT 타겟과 동일하다. ACCEPT 타겟은 매칭되는 트래픽이 iptables 의 어떠한 수정이나 추가적인 동작 없이 통과하게 해준다.
** 스노트 규칙 옵션 변환: iptables 패킷 로깅
스노트의 복잡한 패킷 처리는 주로 규칙 옵션(TCP 스트림 재조립이나 포트 스캔 탐지와 같은 특정 문제를 해결하는 전담 전처리기가 수행하는 작업은 예외)에 의해 구현된다.
fwsnort는 iptables에 동등한 매칭/필터링 옵션이 없는 다음 목록과 같은 옵션을 포함하는 스노트 규칙은 변환하지 않는다.
ack : TCP 헤더의 32비트 승인 번호와 매칭시킨다.
icmp_id : 일부 ICMP 패킷에 존재하는 ID 값과 매칭시킨다.
icmp_seq : 일부 ICMP 패킷에 존재하는 순서 번호 값과 매칭시킨다.
id : IP 헤더의 16비트 IP ID 항목과 매칭시킨다.
sameip : 동일한 출발지와 목적지 IP 주소를 검색한다.
seq : TCP 헤더의 32 비트 순서 번호와 일치시킨다.
window : TCP 헤더의 16 비트 윈도우 값과 일치시킨다.
그러나 위 목록의 모든 패킷 헤더 정보는 psad와 같은 애플리케이션이 쉽게 분석할 수 있게 iptables 로그에 포함된다.
** 스노트 옵션과 iptables 패킷 필터링
지금까지는 iptables 의 로깅 기능만 이용하는 스노트 규칙 옵션을 논했다. 이제 iptables가 명시적인 매칭과 필터링을 지원하는 스노트 규칙 옵션을 살펴보자. 이런 옵션을 사용하는 스노트 규칙은 동등한 iptables 규칙으로 변환 가능하며, 표준 iptables 타겟 보두가(LOG, DROP, REJECT 등) 패킷을 매칭하는 데 적용될 수 있다. 이런 분류에 속하는 스노트 규칙 옵션은 다음과 같다.
content, flags, dsize, uricontent, itype, ip_proto, offset, icode, flow, depth, ttl, replace, distance, tos, resp, within, ipopts
– content
스노트 규칙 언어의 content 옵션에는 인자가 바이트의 나열 형태, 예를 들어 /bin/sh 여야 하며 스노트는 보이어-무어 문자열 검색 알고리즘을 사용해서 애플리케이션 계층 데이터에서 이런 바이트 나열을 검색한다. iptables 매칭 확장은 커널에 구현된 동일한 알고리즘(사용자가 선택)을 사용해서 패킷이 네트워킹 스택으로 들어올 때 패킷의 애플리케이션 페이로드에 있는 바이트 나열을 검색한다.
– uricontent
uicontent 스노트 옵션은 스노트가 HTTP를 통해 전송되는 URL 인코딩된 애플리케이션 데이터를 처리하게 해준다. 이 옵션은 스노트 규칙 언어에 직접 통합돼 있으며(전처리기에 구현되는 것과 다르다) 이는 웹 애플리케이션 통신의 중요성이 커지면서 이들을 대상으로 하는 공격을 탐지할 필요성도 커졌기 때문이다. URL 인코딩된 데이터를 지원하는 웹서버에 대한 공격은 인코딩 방식의 제약 조건 하에서 어떤 형태도 취할 수 있으며, 그 결과 공격은 네트워크상에서 데이터를 정규화하는 방법 없이는 디코딩하기 어려운 수준의 가변성을 가지게 됐다. 엄격히 말해서 iptables의 문자열 매칭 확장은 URL 인코딩된 데이터를 직접 디코딩할 수 없기 때문에 iptables에 uricontent 스노트 옵션에 대한 직접적인 변환은 없다.
정규식과 iptables
iptables에 (역 참조나 반복과 같은 기능이 제거된) 제한된 형태의 정규식 지원을 추가하는 것은 전부터 iptables 프로젝트 관리자에게 제안되고 있다. 그러나 커널에 (펄, 파이선, GNU Emacs, vi, grep 등과 같이 많은 언어, 유틸리티, 편집기에서 사용되는 것과 비슷한) 비결정적 유한 오토마타, 즉 NFA(nondeterministic finite automaton)과 같은 일반화된 정규식 엔진을 구현하는 것은 위험하다. 때로는 데이터에 대한 특정 정규식의 실행 시간이 수천 년이 될 수도 있는 악의적 데이터를 생성하는 것도 가능하다. 단순히 시스템 인터페이스를 통과하는 악의적으로 구성된 패킷에 의해 시스템이 쉽게 다운되길 원하는 사람은 아무도 없다.
– offset
offset 스노트 옵션은 스노트가 패킷의 페이로드 데이터 시작 부분으로부터 특정 바이트만큼 떨어진 곳에서 애플리케이션 내용 매칭 동작을 시작하게 한다. 이는 스노트 규칙의 모든 내용 매칭에 적용되는 절대 값으로 여러 내용 매칭 간의 상대적인 바이트 수에 종속적이지 않다(distance 스노트 옵션이 이를 위해 사용된다). iptables에서 offset 옵션은 페이로드 데이터에서 패턴을 검색할 때 문자열 매칭 확장에 –from 명령 행 인자를 사용함으로써 지원된다(이 인자는 커널 버전 2.6.14 와 그 이후 버전에서만 지원된다).
– depth
depth 스노트 옵션은 패킷 페이로드 데이터 내용을 매칭하려는 모든 시도가 페이로드 시작 지점에서 특정 바이트 수를 넘지 않게 한다.
– distance
스노트는 패턴 매칭 사이에 건너뛸 바이트 수를 명시하기 위해 distance 옵션을 사용한다.
– within
within 옵션은 스노트가 처음 매칭 다음의 패턴 매칭이 특정 바이트 수 이내에서 일어나게 요구하게 한다.
– flags
flags 스노트 옵션은 TCP 헤더의 제어 비트에 검색 기준을 적용한다. 제어 비트는 TCP 연결의 상태에 따라 달라지며 iptables는 –tcp-flags 인자를 통해 특정 조합을 매칭할 수 있다.
– itype과 icode
itype과 icode 옵션은 각기 ICMP 헤더의 8비트 ICMP 유형과 코드 항목의 특정 숫자 값과 매칭된다.
– ttl
스노트는 ttl 옵션을 이용해서 IP 헤더의 패킷 유지 시간(TTL, Time-to-Live)값과 매칭할 수 있다.
– tos
tos 옵션은 스노트가 IP 헤더의 서비스 유형(TOS, Type Of Service) 비트를 조사하게하며, 이 옵션은 숫자 값과 부정 기호 !를ㄹ 붙인 숫자값만 받아들일 수 있기 때문에 스노트 규칙에서 상대적으로 간단하다.
– ipopts
ipopts 스노트 옵션은 검색 기준이 IP 헤더의 옵션 부분에도 적용되게 해준다. IP 옵션은 적법한 IP 트래픽에서 거의 사용되지 않지만 소스 라우팅 IP 옵션(공격자가 다른 방법으로는 도달할 수 없는 네트워크를 통해 패킷을 라우팅하려는 시도에 사용할 수 있는 옵션)을 사용하려는 시도를 탐지하는 것은 중요하다.
– dsize
dsize 스노트 옵션은 패킷 페이로드 데이터의 크기에 조건을 건다. dsize 옵션은 양의 정수를 취하며 규칙이 매칭되기 위해 피킷의 애플리케이션 부분에 존재해야할 바이트 수를 나타내는 < 와 > 연산자를 사용할 수도 있다.
fwsnort 에서는 /etc/fwsnort/fwsnort.conf 의 AVG_IP_HEADER_LEN 와 AVG_TCP_HEADER_LEN 키워드를 통해 IP와 TCP 헤더의 평균 헤더 길이를 설정할 수 있다.
– ip_proto
ip_proto 스노트 옵션은 스노트 규칙이 IP 헤더의 프로토콜 항목으로 가능한 값 256개 중 임의의 것으로 제한할 수 있게 해준다. 이 값들은 /etc/protocols 파일에 정의되 있다.
– flow
flow 스노트 옵션은 스노트 규칙 언어에서 좀 더 중요한 기능 중 하나로 스트림 전처리기와 함께 사용된다. 흐름 옵션은 스노트 규칙이 재조립된 TCP 스트림에 대해 상태와 방향 기준을 적용할 수 있게 해준다.
– replace
replace 스노트 옵션은 스노트가 인라인 모드로 실행 중이고 패킷 데이터 경로에 인라인으로 배치됐을 때만 적용될 수 있다. 이 모드에서 스노트는 보호된 니테으쿼ㅡ 안팎으로 스노트의 탐지 엔진이 패킷을 조사한 후에만 이를 전달하는 기능을 갖춘 진정한 침입 방지 시스템이 된다. replace 옵션은 애플리케이션 계층 데이터에 대해 동작하며 content 옵션에 의해 탐지된 바이트 나열이 동일한 길이의 다른 나열로 대체되게 해준다.
– resp
flexresponse 와 flexresponse2 스노트 탐지 플러그인이 제공하는 resp 옵션은 스노트가 서명 매칭을 종료시키기 위해 TCP RST/ACK 패킷을 전송하는 것과 ICMP 네트워크, 호스트, 포트 도달 불가 패킷을 생성하는 것이 있다. iptables REJECT 타켓은 TCP 연결에 대해서 인자 -j REJECT –reject-with tcp-reset, UDP 패킷에 대해 인자 -j REJECT –reject-with icmp-*-unreachable(*는 net, host, port 중 하나)을 통해 이런 기능을 제공한다.