[네트워크] Snort와 Suricata에 대하여, 그리고 Snort Rule 필수 사용법

SnortSuricata는 둘 다 인기 있는 오픈 소스 네트워크 IPS 및 IDS입니다. 이들은 네트워크에서 발생하는 악성 활동을 탐지하고 방어하는 데 사용됩니다. Lua 스크립팅 언어를 지원하며 사용자 정의 규칙 및 기능을 추가하고 복잡한 로직을 구현할 수 있습니다. 현재 두 기술 간에는 큰 차이가 없습니다. 규칙 세트, 새 릴리스 등과 관련하여 약간의 차이가 있지만, 이는 사소한 것입니다. 각각의 일반적인 특징은 다음과 같습니다.

  • Snort:
    1. 개발된 년도: 1998년
    2. 개발자:
      Martin Roesch(마틴 로시)가 개발했으며, 2001년 마틴 로시가 Sourcefire라는 회사를 설립하여 Snort를 상업적으로 지원했습니다. Sourcefire는 2013년 Cisco에 인수되었습니다.
    3. 기능:
      – Snort는 패킷의 특정 규칙 또는 패턴을 감지하여 네트워크에서 악성 활동을 식별합니다.
      – 유연한 규칙 기반 시스템을 사용하여 사용자가 필요에 따라 규칙을 구성할 수 있습니다.
      – 전처리 플러그인과 데이터베이스 플러그인 등과 같이 플러그인 형태로 기능을 추가할 수 있습니다.
      Snort Process
    4. Snort는 다음과 같은 세 가지 주요 운영 모드를 제공
      1. Sniffer 모드(snort -v): 기능: 네트워크 인터페이스를 통해 들어오는 패킷을 단순히 캡처하여 화면에 출력합니다.
      2. Packet Logger 모드(snort -dev -l /log_directory): 네트워크 인터페이스를 통해 들어오는 패킷을 파일에 기록합니다.
      3. Network IDS 모드(snort -c /etc/snort/snort.conf): Snort의 가장 강력한 모드로, 네트워크 트래픽을 실시간으로 분석하고, 정의된 규칙에 따라 침입 시도를 탐지합니다. 탐지된 이벤트는 로그 파일에 기록되거나 알림으로 전송될 수 있습니다.
  • Suricata:
    1. 개발된 년도: 2008년
    2. 개발자:
      오픈 소스 커뮤니티에 의해 개발되었으며, OISF(Open Information Security Foundation)라는 비영리 단체에 의해 유지보수됩니다.
    3. 기능:
      – Suricata는 Snort와 유사한 기능을 제공하지만 기존 Snort의 장점을 모두 수용하고, 단점을 보완하여 개발하였습니다.
      – 멀티코어 및 멀티스레드 시스템에서 더욱 효율적으로 동작하도록 설계되었습니다. 이러한 특성으로 인해 Suricata는 대량의 네트워크 트래픽을 처리하는 데 더 적합합니다.
      – 또한 Snort와 호환되는 규칙을 사용할 수 있습니다. GPU가속을 지원하고, Port에 관계없이 동적 프로토콜 보호 기능이 있습니다.

Suricata는 Snort보다 더 최신 기술을 적용하고 있으며 높은 성능과 확장성을 제공합니다. 아래에서 정보보안기사에 자주 출제되는 Snort rule 작성 가이드에 대해 알아보겠습니다. Snort 룰은 크게 문자열 패턴 검사와 패킷 발생량 검사, 이렇게 두 가지로 나눌 수 있는데, 일반적으로 패턴 검사는 기밀성과 무결성 침해 행위를, 발생량 검사는 가용성 침해 행위를 탐지할 때 사용합니다.


Snort rule 작성 가이드

Snoret Rule Writing Guide

출처: https://cyvatar.ai/write-configure-snort-rules/

Rule Header
  1. Action
    패킷이 매칭되었을 때 처리하는 방법을 지정하며, 5개의 Basic action과 3개의 Active response가 있습니다.
    • Basic Action
      alert-> 현재 패킷에 대한 alert 생성
      block-> 현재 패킷과 이 흐름의 모든 후속 패킷을 차단
      drop-> alert가 생성되자마자 현재 패킷을 삭제
      log-> 현재 패킷을 기록
      pass-> 현재 패킷을 통과된 것으로 표시
    • Active response
      react-> 클라이언트에 응답을 보내고 세션을 종료
      reject-> TCP reset이나 ICMP unreachable를 가지고 세션를 종료(2024년3월19일 정보보안기사 필기 시험 문제)
      rewrite-> 규칙의 “replace” 옵션을 기반으로 패킷 내용 덮어쓰기를 활성화
  2. Protocol
    4개의 프로토콜(ip, icmp, tcp, udp)과 3개의 서비스(ssl, http, smtp)를 지원합니다.
  3. Source Address
    패킷의 출발지 주소 정보를 정의합니다.
    • 키워드 any는 모든 IP 주소를 의미합니다.
    • IP주소나 CIDR 블록(예: 192.168.0.5, 192.168.1.0/24)
    • 네트워크 주소 또는 네트워크 주소 집합을 지정하는 Snort 구성에 정의된 변수(예: $EXTERNAL_NET, $HOME_NET 등)
    • 대괄호로 묶고 쉼표로 구분된 IP 주소(예: [192.168.1.0/24,10.1.1.0/24])
    • Address 앞에 “!”를 입력하면 제외할 주소를 지정
  4. Source Port
    패킷의 출발지 포트 정보를 정의합니다.
    • 키워드 any는 모든 포트를 의미합니다.
    • 정적 포트(예: 80, 445, 21)
    • 포트 또는 포트 집합을 지정하는 Snort 구성에 정의된 변수(예: $HTTP_PORTS)
    • 범위 연산자로 표시된 포트 범위(1:100, 500:, :1024)
    • 대괄호로 묶이고 쉼표로 구분된 정적 포트, 포트 변수 및/또는 포트 범위 목록(예: [1:1024,4444,5555,$HTTP_PORTS])
    • “service” rule option을 사용하면 해당 서비스에 해당하는 well-known port 트래픽에 대해 매칭 작업을 진행(예: service:http;)
  5. Direction
    헤더의 방향 연산자는 규칙이 적용되어야 하는 트래픽의 방향을 나타냅니다. 유효한 방향 연산자는 두 가지가 있습니다.
    • -> : 가장 일반적이며, 왼쪽의 IP 주소와 포트 번호는 Source를 나타내고 오른쪽의 IP 주소와 포트 번호는 Destination
    • <> : 양방향 연산자이며 Snort에게 두 개의 IP 주소와 포트 쌍을 소스 또는 대상으로 간주하도록 지시
  6. Destination Address : Source Address와 동일
  7. Destination Port : Source Port와 동일
Rule Option

“옵션key:옵션value;” 형식으로 선언되며 댜양한 옵션으로 트래픽을 필더링할 수 있습니다.

  • msg
    규칙을 설명하는 메시지를 추가하는 데 사용됩니다. 메시지는 규칙의 목적을 요약해야 하며 규칙에 의해 생성된 이벤트와 함께 출력됩니다. 이 옵션은 규칙이 일치할 트래픽 종류를 설명하는 큰따옴표로 묶인 텍스트 문자열인 단일 인수만 사용합니다. msg 옵션은 일반적으로 Snort 규칙에 있는 첫 번째 규칙입니다.
    Snort 규칙에는 몇 가지 예약된 문자(예: ” , ;)가 있으며 msg 옵션에서 사용하려면 이스케이프(\)해야 합니다.
    • 형식: msg:”message”;
    • 예제: msg:”Malicious file download attempt”;
  • sid
    sid 옵션은 특정 Snort 규칙을 고유하게 식별하는 숫자 값인 단일 인수를 사용합니다. 기술적으로 필요하지는 않지만 모든 Snort 규칙에는 경고가 생성될 경우 규칙을 신속하게 식별할 수 있는 sid 옵션이 있어야 합니다.
    sid값 0-999999는 Snort 배포에 포함된 규칙에 사용되기 때문 예약되어 있습니다. 따라서 사용자는 1000000에서 시작하는 로컬 규칙 sid 값을 사용해야 하며, 각 추가 로컬 규칙에 대해 sid 값을 1씩 늘려야 합니다.
    • 혈식: sid:signature_id;
    • 예제: sid:1000001;
  • service
    service 옵션은 Snort에게 규칙을 적용할 애플리케이션 계층 서비스를 알려주는 데 사용됩니다. service 옵션을 사용하면 Rule Header에 정의된 포트가 일치하는 한 지정된 서비스가 트래픽의 실제 서비스와 일치할 필요가 없습니다. 또한 반대도 마찬가지입니다. 서비스가 일치하는 한 포트는 일치할 필요가 없습니다. 한마디로 “OR 포트” 조건문과 같습니다.
    • 형식: service:service[,service]…;
    • 예제: alert tcp any any -> any any 8000 (msg:”HTTP traffic or dst port 8000 please”; service:http; sid:1000000;)
  • content
    패킷 데이터에 대해 기본 패턴 일치를 수행하는 데 사용되는 옵션입니다. 큰따옴표로 묶인 콘텐츠 문자열로 선언하며, 클론(:) 바로 뒤에 !를 사용하여 일치하지 않는 항목으로 선언할 수도 있습니다. 컨텐트 매치는 ASCII 문자열, 16진수 바이트 또는 이 둘의 혼합이 포함될 수 있습니다. 16진수 바이트는 파이프(|)로 묶어야 합니다. 다수의 content match 룰을 선언할 수 있으며, 선언된 순서대로 평가됩니다. 빠른 매칭을 위해 가장 유니크한 match를 맨 앞에 선언하는 게 좋습니다. “nocase;” 옵션과 함께 사용하면 대소문자를 구분하지 않고 매칭 여부를 확인합니다.
    • 형식: content:[!]”content_string”;
    • 문자열 매칭 예제: content:”USER root”;
    • 혼합 매칭 예제: content:”PK|03 04|”;
  • offset, depth, distance, within
    – offset 숫자(-65535 ~ 65535): 패킷/버퍼의 시작 부분을 기준으로 패턴 검색의 시작 위치를 지정할 수 있습니다. offset을 생략하면 “offset 0″입니다.
    – depth 숫자(content 옵션 길이 ~ 65535) : 패킷/버퍼에서 지정된 패턴(content)을 찾는 범위를 지정할 수 있습니다.
    – distance 숫자: offset과 유사하지만 페이로드/버퍼의 시작 대신 이전 content match를 기준으로 합니다.
    – within: depth와 유사하지만, distance와 같이 이전 content match를 기준으로 합니다.
    • 형식:
      offset {offset|variable_name}
      depth {depth|variable_name}
      distance {distance|variable_name}
      within {within|variable_name}
    • 예제:
      content:”|FE|SMB”, offset 4;
      content:”GET”, offset:0; content:”downloads”, offset 13;
      content:”|FE|SMB”, {offset 4;,} depth 4;
      content:”ABC”; content:”EFG”, distance 1;
      content:”ABC”; content:”EFG”, {distance 1;,} within 3;
  • dsize
    패킷의 페이로드 크기를 테스트하는 데 사용됩니다. 지정된 정수 값보다 작거나, 크거나, 같거나, 같지 않거나, 작거나 같거나, 크거나 같은 패킷 크기를 찾을 수 있습니다. 이 규칙 옵션은 또한 배타적 범위 확인을 위해 <> 범위 연산자를 사용하거나 포함 범위 확인을 위해 <=>를 사용하여 페이로드 크기가 숫자 범위 사이에 있는지 확인하는 데 사용될 수도 있습니다. 유효한 dsize 번호 범위는 0~65535입니다.
    • 형식:
      – 단일 값 비교: dsize:[<|>|=|!|<=|>=]size;
      – 범위 비교: dsize:min_size{<>|<=>}max_size;
    • 예제:
      dsize:300<>400;
      dsize:>10000;
      dsize:<10;
  • flags
    지정된 플래그 비트가 TCP 헤더에 설정되어 있는지 확인합니다. flags 옵션을 쉼표(,)로 구분하면 뒤에 오는 플래그 비트(들)을 무시하도록 지정할 수 있습니다.

    • F -> FIN (Finish)
    • S -> SYN (Synchronize sequence numbers)
    • R -> RST (Reset the connection)
    • P -> PSH (Push buffered data)
    • A -> ACK (Acknowledgement)
    • U -> URG (Urgent pointer)
    • C -> CWR (Congestion window reduced)
    • E -> ECE (ECN-Echo)
    • 0 -> No TCP flags set
    • + -> match any of the specified bits, plus any others
    • * -> match if any of the specified bits are set
    • ! -> match if the specified bits are not set
    • !UAPRSF -> NULL 스캔 탐지
    • 형식: flags:flag…[,flag…];
    • 예제:
      – SYN 플래그만 설정된 TCP 패킷을 확인: flags:S;
      – SYN 및 ACK 플래그만 설정된 TCP 패킷을 확인: flags:SA;
      – SYN 및/또는 ACK 플래그가 설정된 TCP 패킷을 확인: flags:*SA;
      – CWR 및 ECN 비트를 무시하고 SYN 및 FIN 비트가 설정되었는지 확인: flags:SF,CE;
    • TCP SYN Flooding 공격 탐지
      alert tcp any any -> $HTTP_SERVERS 80 (msg:”TCP SYN Flooding attack detected”; flags:S; threshold: type threshold, trace by_src, count 5, second 1; sid:100100;)
  • flow
    특정 패킷의 세션 속성을 확인하는 데 사용됩니다. 이 옵션으로 확인할 수 있는 네 가지 주요 속성 범주는 다음과 같습니다.
    1. 패킷의 방향, 특히 클라이언트에서 서버로 또는 서버에서 클라이언트로의 방향
    2. 패킷이 설정된 TCP 연결의 일부인지 여부
    3. 패킷이 재조립된 패킷인지 여부
    4. 패킷이 재구성된 조각 패킷인지 여부
    이러한 각 속성 범주에는 흐름 옵션에 지정할 수 있는 몇 가지 다른 인수가 있지만 각 “범주”에서 하나의 속성만 단일 옵션에 포함될 수 있습니다. 아래 표에는 가능한 모든 인수가 나열 및 설명되어 있으며, 여러 속성을 지정하려면 인수 사이에 쉼표를 추가하면 됩니다. 순서는 중요하지 않습니다.
    flow option values
    • 형식:
      flow:[{established|not_established|stateless}] \
      [,{to_client|to_server|from_client|from_server}] \
      [,{no_stream|only_stream}] \
      [,{no_frag|only_frag}];
    • 예제:
      flow:to_server,established;
      flow:to_client,established;
      flow:stateless;
  • replace
    Post-detection rule 옵션 중의 하나로, 규칙이 “실행”된 후에 발생하는 특정 트리거입니다. Rule Header의 rewrite Action과 관련되어 있습니다. 이전에 일치하는 콘텐츠를 replace 옵션에 제공된 문자열로 덮어쓰는 데 사용됩니다. 이 옵션은 다시 쓰기 규칙 작업과 함께 사용해야 하며 원시 패킷에만 작동합니다.
    • 형식: replace:”string”;
    • 예제: content:”ABCD”; replace:”EFGH”;
  • sameip
    출발지IP와 목적지IP가 동일한 Land Attack을 탐지합니다.
    alert ip any any -> $HOME_NET any (msg:”Land attack detected”; sameip; sid:100100)
  • threshold
    Snort3에서는 threshold 옵션을 지원하지 않지만, 하위 버전의 룰을 확인하기 위해 간략하게 알아보겠습니다. 동일한 특정 패킷에 대해서 설정한 시간 내에 일정 수가 발생하면 탐지합니다. 특히 무작위 공격(Brute Force Attack)을 탐지하는 데 유용합니다.
    • 형식: threshold: type [limit, threshold, both], track [by_src, by_dst], count [횟수], seconds [초];
    • 예제:

      – limit: 임계시간(초)를 기준으로 로그를 생성, time interval 마다 [횟수] 번째 이벤트를 탐지, 한 번 이벤트가 트리거되면 그 이후의 패킷을 무시

      # 60초마다 10 번째 이벤트까지 각각 기록하고, 나머지 패킷을 무시합니다.
      threshold: type limit, track by_src, count 10 , seconds 60 ;
      

      – threshold: 패킷 발생량으로 정확하게 측정, time interval 동안에 매 횟수마다 계속 탐지

      # 60초 간격 동안 모든 10번째 이벤트를 기록하므로 60초 내에 10개 미만이 발생하면 아무 것도 기록되지 않습니다.
      # 이벤트가 기록되면 type threshold에 대한 새 기간이 시작됩니다.
      threshold: type threshold, track by_dst, count 10 , seconds 60 ;
      

      – both: IP주소를 로그 발생의 기준으로 함, time interval 동안 [횟수] 만큼 트래픽이 발생될 시 한 번만 탐지하고 나머지는 무시, time interval 간격으로 계속해서 이벤트를 추적하고 추가적인 패킷을 분석

      # 최소 10개의 이벤트가 실행되는 경우 60초마다 최대 하나의 이벤트를 기록합니다.
      threshold: type both , track by_dst, count 10 , seconds 60 ;
      
    • Snort threshold

      출처: https://www.dailysecu.com/news/articleView.html?idxno=10240

더 자세한 작성 가이드를 알고 싶으시다면 Snort 3 Rule Writing Guide 사이트를 방문하시거나 Snort Users Manual 2.9.16를 다운로드하시면 됩니다.

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다