Snort Rule Manual

[+] Snort Rule

[+] Summary

구조

Snort 룰은 크게 Header와 Option으로 나눌 수 있다. 여러 블로그들을 찾아봤지만 뭐니뭐니해도 오피셜이 최고니깐 공식 홈페이지에서 가이드를 확인해봤다.

ex) alert tcp any any -> 192.168.1.0/24 111 (content:"|00 01 86 a5|"; msg:"mountd access";)

[+] Header

헤더에는 다음과 같은 정보를 작성한다.

  1. Rule Actions
  2. Protocols
  3. IP Addresses
  4. Port Numbers
  5. The Direction Operator
  6. Activate/Dynamic Rules

Rule Actions

스노트에는 기본적으로 3가지 동작이 존재한다. alert, log, pass 가 기본동작이다. 만약에 스노트가 인라인 모드에서 동작 중이라면 drop, reject, sdrop과 같은 동작도 가능하다(IPS기능).

  • alert

    룰에 일치하는 경우 경고를 발생 시키고 로그로 기록한다.

  • log

    로그로 기록한다.

  • pass

    패킷을 무시한다.

  • drop

    패킷을 차단하고 로그로 남긴다.

  • reject

    패킷을 차단하고 로그로 남긴다, 그리고 tcp 패킷의 경우 rst 패킷을 응답하고 udp 패킷의 경우 icmp unreachable 패킷으로 응답한다.

  • sdrop

    패킷을 차단하고 로그를 남기지 않는다.

Protocols

TCP, UDP, ICMP, IP 프로토콜이 사용 가능하다. 앞으로 더 많은 프로토콜을 지원 예정이라고 하지만 이 가이드가 꽤 되어보여서… 모르겠다. 어쨋든 주요 프로토콜은 지원

IP Addresses

IP 주소와 포트정보에 대한 필드이다. 호스트 네임을 찾는 메커니즘이 존재하지 않기 때문에 직접적인 IP 주소와 CIDR표기법을 사용할 수 있다. any의 경우 임의의 모든 것을 의미한다.

  • example
    1. alert tcp !192.168.1.0/24 any -> 192.168.1.0/24 111 (content:” 00 01 86 a5 ”; msg:”external mountd access”;)
    2. alert tcp ![192.168.1.0/24,10.1.1.0/24] any -> [192.168.1.0/24,10.1.1.0/24] 111 (content:” 00 01 86 a5 ”; msg:”external mountd access”;)

1번 예제의 경우 논리부정연산자(‘!‘)를 이용한 표기법이고, 2번 예제는 여러 IP주소에 대한 표기 방법([])에 대한 예제이다. 콤마(‘,‘)로 구분한다.

Port Numbers

특정 포트의 범위나 단일 포트를 표현할 수 있다.

  • example
    1. 1:1024 = 1 ~ 1024 port
    2. :1024 = 1024 port 이하
    3. 1024: = 1024 port 이상
    4. !1:1024 = 1 ~ 1024 port를 제외한 나머지 port

The Direction Operator

방향 연산자를 표현한다. 즉, 규칙이 적용되는 트래픽의 방향을 나타낸다. -> 의 경우 outgoing 패킷을 의미, <- 의 존재하지 않는다. 또한 <> 으로 양방향을 의미하도록 할 수 있다.

Activate/Dynamic Rule

이건 패쓰.!

[+] Rule Options

룰에 대한 옵션이 스노트 룰의 핵심이다. 모든 규칙은 세미콜론(‘;‘)으로 구분하며 옵션 키워드는 콜론(‘:‘)으로 표현한다. 총 4개 general, payload, non-payload, post-detection 으로 구분된다

  • general

    룰에 대한 정보를 포함하는 옵션

  • payload

    패킷 내 페이로드 내부의 데이터를 찾고 상호작용을 할 수 있는 옵션

  • non-payload

    페이로드가 없는 데이터에서 사용

  • Post-detection

    사후탐지에 대한 옵션, 룰 실행 후의 규칙

[+] General

msg

: alert 엔진을 통해 전달하는 메시지를 설정할 수 있다.

  • example

    msg:"<message text>";

reference

: CVE, nessus, mcafee 등 다른 외부 참조를 통해 규칙을 참조할 수 있다.

  • example

    reference:<id system>, <id>; [reference:<id system>, <id>;]

gid

: gid란 generator id 를 의미한다. 일반적인 규칙을 사용할 때 사용하지 않는 것이 좋다고 나와있다. 어떤 규칙이 실행될 때 스노트의 어떤 부분이 이벤트를 생성하는지 식별하는데 사용된다고 한다.

  • example

    gid:<generator id>;

sid

: Snort ID의 약자로 룰을 식별하기 위해 사용된다. 해당 옵션은 rev 키워드와 함께 사용되야 된다. pdf로 된 가이드 기준으로 sid 범위를 작성해 놓는다.

  • 100 이하의 sid 의 경우 예약된 sid

  • 100 ~ 999,999 까지는 기본 포함된 스노트 룰 sid

  • 1,000,000 이상의 sid는 유저가 작성가능한 로컬 룰

  • example

    sid:<snort rules id>;

rev

: rev 키워드의 경우 해당 룰의 버전 정보 ? 를 표현할 수 있는 영역이다.

  • example

    rev:<revision integer>;

classtype

: 특정 공격에 대한 분류를 하는데 사용된다. Snort에서 제공되는 특정 공격들에 대한 분류를 이용한다.

  • example

    classtype:<class name>;

    Classtype Description Priority
    attempted-admin Attempted Administrator Privilege Gain high
    attempted-user Attempted User Privilege Gain high
    inappropriate-content Inappropriate Content was Detected high
    policy-violation Potential Corporate Privacy Violation high
    shellcode-detect Executable code was detected high
    successful-admin Successful Administrator Privilege Gain high
    successful-user Successful User Privilege Gain high
    trojan-activity A Network Trojan was detected high
    unsuccessful-user Unsuccessful User Privilege Gain high
    web-application-attack Web Application Attack high
    attempted-dos Attempted Denial of Service medium
    attempted-recon Attempted Information Leak medium
    bad-unknown Potentially Bad Traffic medium
    default-login-attempt Attempt to login by a default username and password medium
    denial-of-service Detection of a Denial of Service Attack medium
    misc-attack Misc Attack medium
    non-standard-protocol Detection of a non-standard protocol or event medium
    rpc-portmap-decode Decode of an RPC Query medium
    successful-dos Denial of Service medium
    successful-recon-largescale Large Scale Information Leak medium
    successful-recon-limited Information Leak medium
    suspicious-filename-detect A suspicious filename was detected medium
    suspicious-login An attempted login using a suspicious username was detected medium
    system-call-detect A system call was detected medium
    unusual-client-port-connection A client was using an unusual port medium
    web-application-activity Access to a potentially vulnerable web application medium
    icmp-event Generic ICMP event low
    misc-activity Misc activity low
    network-scan Detection of a Network Scan low
    not-suspicious Not Suspicious Traffic low
    protocol-command-decode Generic Protocol Command Decode low
    string-detect A suspicious string was detected low
    unknown Unknown Traffic low
    tcp-connection A TCP connection was detected very low

priority

: 우선순위를 지정할 수 있다.

  • example

    priority:<priority integer>;

[+] Payload

content

: 페이로드 내 존재하는 특정 문자열이나 헥스 값 등을 판별하여 룰에 영향을 줄 수 있다. 사실상 가장 많이 쓰일 것 같다. 헥스 값의 경우 ‘|’ 으로 감싸주어 사용 가능하다.

  • example

    content :[!]"<content string>";

    alert tcp any any -> any 80 (content:!"GET") (외부로 나가는 모든 80 포트에 GET이 포함되지 않은 경우 경고)

protected_content

: 룰에 접근 가능한 다른 사용자로부터 콘텐트의 내용을 숨길 수 있다. md5, sha256&512 해시 알고리즘을 이용한다.

  • example

    protected_content:[!]"<content hash>", length:orig_len[, hash:md5|sha256|sha512];

    alert tcp any any <> any 80 (msg:"SHA256 Alert"; protected_content:"56D6F32151AD8474F40D7B939C2161EE2BBF10023F4AF1DBB3E13260EBDC6342"; hash:sha256; offset:0; length:4;)

    해당 해시 값을 검색하면 ‘HTTP’ 문자열이 나온다. length 필드의 4는 해시함수를 거치기 전 원래 콘텐트의 길이 값을 의미한다.

hash

: 위의 protected_content에서 함께 사용하는 옵션이다. 해당 해시 값이 어떤 해시 알고리즘을 사용했는지 나타낸다.

length

: 역시 protected_content에서 함께 사용하는 옵션이다. 해시화하기 전 원래의 문자열에 대한 길이를 나타낸다.

nocase

: 대소문자 구분을 하지 않는다는 의미를 가진다.

  • example

    alert tcp any any -> any 21 (msg:"FTP ROOT"; content:"USER root"; nocase;)

    tcp 프로토콜을 이용하여 ftp 21(control channel)로 접근하는 모든 패킷에서 USER root 라는 문자열을 포함되어 있는 경우 ‘FTP ROOT’라는 메시지를 출력한다. USER root 문자열의 경우 대소문자를 구분하지 않는다.

rawbytes

: 키워드명처럼 raw 데이터를 검출한다.

  • example

    alert tcp any any -> any 21 (msg:"Telnet NOP"; content:"|FF F1|"; rawbytes;)

    메뉴얼 상에 오타인가? 21포트인데 Telnet..? 음 아무튼 해당 21 포트로 접근하는 패킷에서 로우데이터에 0xFF 0xF1가 포함된 경우 Telnet NOP 이라는 메시지를 출력한다.

depth

: 지정된 패턴을 검색 시 패킷의 길이를 지정할 수 있다. depth가 5인 경우 페이로드의 처음 5바이트 내에서 지정된 패턴을 찾는다. offset 키워드와 함께 사용 가능하다.

offset

: depth와 비슷하며 함께 자주 쓰인다. 말 그대로 해당 오프셋부터 패턴을 검색한다. offset이 5인 경우 offset 5부터 지정된 패턴을 검색한다.

  • example

    alert tcp any any -> any 80 (content:"cgi-bin/phf"; offset:4; depth:20;)

    80(http/tcp)로 접근하는 모든 패킷의 offset 4부터 20바이트 내 cgi-bin/phf 문자열이 존재하는지 확인한다.

distance

: 이전 패턴이 일치한 경우 매치된 바이트부터 특정 바이트 떨어진 위치에서 다음 패턴을 검사할지 지정한다. 오프셋과 매우 유사하다.

  • example

    alert tcp any any -> any any (content:"ABC"; content:"DEF"; distance:1;)

    모든 패킷 내 ABC 문자열이 포함된 패킷을 검출한다. 검출된 경우 해당 오프셋에서 1바이트 떨어진 위치부터 DEF 문자열이 포함된 패킷을 찾는다.

within

: distance와 함께 사용한다. distance부터 특정 바이트 범위 내에서 패턴을 검사할지 지정한다.

  • example

    alert tcp any any -> any any (content:"ABC"; content:"EFG"; within:10;)

    모든 패킷 내 ABC 문자열이 포함된 패킷을 검출한다. 검출된 경우 해당 오프셋에서 부터 10바이트 범위 내에서 DEF 문자열이 포함된 패킷을 찾는다.

여기까지 기본적인… 옵션들이다. 너무 많아서 상세한건 다시 메뉴얼을 보자아아

[+] Non-Payload

fragoffset

: IP Fragment 오프셋 필드의 값을 비교할 수 있다.

  • example

    fragoffset:[!]<|>]<number>;

ttl

: TTL(Time To Live) 항목이다. traceroute 명령어를 탐지하기 위한 키워드이다.

  • example

    ttl:[<,>,=,<=,>=]<number>; , ttl:[<number>]-[<number];

id

: 특정한 IP ID 필드의 값을 확인하는데 사용한다. 예로 31337은 공격자들이 도구를 이용해 많이 사용하는 IP ID 필드의 값이다.

  • example

    id:31337;

fragbits

: 단편화된 패킷이거나 IP Header 내 flags 필드에 비트가 설정되어 있는지 확인하는데 사용된다.

  • example

    M - More Fragments, D - Don’t Fragments, R - Reserved Bit

    fragbits:MD+; More Fragments bit & Don’t Fragments bit

flags

: TCP flag 비트를 확인하는데 사용한다. 기본적으로 UAPRSF(URG, ACK, PSH, RST, SYN, FIN)를 확인할 수 있고, 추가적으로 CWR, ECE 를 사용할 수 있다.

  • example

    alert tcp any any -> any any (flags:SF;)

    모든 패킷에 SYN과 FIN 패킷을 탐지한다.

seq

: TCP sequence number를 확인한다.

  • example

    seq:0;

ack

: TCP acknowledge number를 확인한다.

  • example

    ack:0;

itype

: ICMP type을 확인할 수 있다.

  • example

    itype:>30;

icode

: ICMP code를 확인할 수 있다.

  • icode:<number<=256

icmp_id

: 특정 ICMP의 식별자를 확인할 수 있다.

  • example

    icmp_id:0;

ip_proto

: IP 프로토콜 헤더 대한 검사를 수행할 수 있다.

  • example

    alert ip any any -> any any (ip_proto:igmp;)

    IGMP 트래픽을 확인한다.

sameip

: 출발지와 목적지 IP가 같은 패킷을 확인한다.

  • example

    alert ip any any -> any any (sameip;)

[+] Post-Detection

logto

: 패턴에 탐지되는 것들에 대해 로그 파일로 저장한다.

  • example

    logto:"filename";

session

: telnet, rlogin, ftp, http 와 같이 평문 통신 프로토콜로 부터 세션의 트래픽을 기록한다.

  • example

    log tcp any any <> any 23 (session:printable;)

    텔넷 서비스의 패킷을 출력 가능한 형태로 남긴다

[+] Rule Thresholds

: 임계값에 대한 설정이다. DoS, DDoS 공격에 대응하기 위한 옵션이라고 생각할 수 있다.

  • Format

    threshold: type <limit|threshold|both>, track <by_src|by_dst>, count <c>, seconds <s>;

    • type : limit

      매 s 초 동안 c 번째 이벤트까지 액션 수행

    • type : threshold

      매 s 초 동안 c 번째 이벤트 마다 액션 수행

    • type : both

      매 s 초 동안 c 번째 이벤트 시 한번의 액션을 수행

    • track by_src

      출발지 ip 기준

    • track by_dst

      도착지 ip 기준

    • count(c)/seconds(s)

      횟수 및 시간

  • example

    alert tcp $External_net any -> $Home_net any (msg:"HTTP Get Flooding"; content:"GET"; http_method; nocase; sid:1000001; threshold:type threshold, track by_dst, count 10, seconds 1;)

    HTTP Get flooding 에 대한 룰인데 음… 실제 테스트를 해봐야겠다.

[+] Refenrence

  1. Snort 2.9.12 User Manual
  2. 각종 룰