무료 IPS 도구이다.
apt
로 설치할 수 있다.
apt install snort
룰을 실습하기 위함이므로 기존의 룰은 주석처리한다.
/etc/snort/snort.conf
에서 578~696라인이다.
이러면 local.rule
만 남게 된다.
다음의 형식을 취하게 된다.
다음의 기본 룰에서
alert icmp any any -> 192.168.0.5 any (sid:1000001;)
alert icmp any any -> 192.168.0.5 any
을 RTN(Rule Tree Node)이라 하고,
(sid:1000001;)
부분을 OTN(Option Tree Node) 이라고 한다.
위에서 본 sid는 시스템 ID를 의미한다. 룰 설정에서 필수적인 정보이다.
범위
sid <= 99 : 시스템 내부에서 사용
sid <= 100~1000000 : 외부에서 제작해 배포하는 탐지 규칙에서 사용
sid > 1000001 이상 : 사용자가local.rules
탐지 규칙을 설정할 때 임의로 사용
snort -A console -q -u snort -c /etc/snort/snort.conf
-A
는 콘솔로 경고를 출력하겠다는 것이고 -c
로 설정파일 위치를 지정해주었다.
테스틀 룰을 작성해본다.
기본적인 룰이다.
alert icmp any any -> 192.168.0.5 any (sid:1000001;)
192.168.0.5는 snort를 실행중인 우분투를 가리킨다.
호스트 PC(192.168.0.11)에서 우분투로 ping을 실행해본다.
해당 패킷에 대한 로그가 출력되고 있다.
네트워크 주소를 이용해 탐지할 수도 있다.
사설 ip 주소대역을 탐지하는 룰이다.
alert icmp 172.16.0.0/16 any -> 192.168.0.5 any (sid:1000001;)
alert icmp 10.0.0.0/8 any -> 192.168.0.5 any (sid:1000002;)
그리고 hping3
도구를 이용해 칼리 리눅스의 ip를 룰에서 설정한 ip 대역으로 변경하여 ping을 전송하면
탐지가 된다.
ping of death는 icmp의 페이로드가 크게 설정된 패킷을 전송하여 서버에 과부하를 일으키는 공격이다.
alert icmp any any -> 192.168.0.5 any (msg:"Detect Ping of Death Attack";threshold:type both,track by_src,count 10,seconds 2;sid:1000001;)
중요한 것은 count 10,seconds 2
인데 2초 동안 10개 이상의 패킷이 수신됐는지 판단하는 것이다.
적용한 후 kali에서 공격을 실행하면
스캔 탐지는 FLAG를 확인하여 이뤄진다.
alert tcp any any -> 192.168.0.5 22 (flags:F;sid:1000001;)
alert tcp any any -> 192.168.0.5 22 (flags:UPF;sid:1000002;)
alert tcp any any -> 192.168.0.5 22 (flags:!UAPRSF;sid:1000003;)
위에서부터 FIN
/XMAS
/NULL
스캔에 대한 룰이다.
적용하면 다음처럼 스캔했을 때 우분투에서 탐지되는 것을 확인할 수 있다.
실제 취약점을 탐지해본다.
사용할 취약점은 CVE-2015-4852로 아파치의 commons-collections 라이브러리에서 발생했던 것으로 페이로드 전송시 라이브러리 안 InvokerTransformer()
함수에 의해 RCE가 가능하다.
자세한 건 몰라도 된다. 제로데이라 가정하고, 룰을 추가하는게 목표이므로
scapy를 이용하여 페이로드를 전송해야 한다.
import sys
from scapy.all import *
ip = IP()
ip.dst = '192.168.0.5'
ip.src = '192.168.0.11'
tcp = TCP()
tcp.sport = 45612
tcp.dport = 8888
payload = """POST / HTTP/1.0
HOST: 127.0.0.1:8880
Content-Type: text/xml; charset=utf-8
Content-Length: 2646
SOAPAction: "urn:AdminService"
<?xml version=1.0' encoding='UTF-8'?><SOAP-ENV:Envelop xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header xmlns:ns0="admin" ns0:WASRemoteRuntimeVersion="8.5.5.1"ns0:JMXMessageVersion="1.2.0" ns0:SecurityEnabled="true" ns0:JMXVersion="1.2.0"><LoginMethod>Basic Auth</LoginMethod></SOAP-ENV:Header><SOAP-ENV:Body><ns1:getAttribute xmlns:ns1="urn:AdminService"SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><objectname xsi:type="ns1:javax.management.ObjectName">rO0ABXNyADJzdW4uc"""
send(ip/tcp/payload)
먼저, 탐지를 위해 완성한 룰이다.
alert tcp any any -> any 8888 (msg:"Apache commons collection library WebSphere Attack";content:"POST "; offset:0; depth:5; content:"SOAPAction|3A| |22|urn|3A|AdminService|22|"; distance:0;within:140; content:".ObjectName|22|>rO0AB";sid:3000002; )
간단히 이해해보자.
|3A|
는 바이너리 값을 입력할 때 사용하는 방식으로 파이썬의 '\x3a'와 같다.
content:"POST ";
는 IDS의 부하를 줄이기 위해 5바이트만 확인하여POST
가 아닐 경우는 뒤의 검사를 진행하지 않도록 만드는 것이다.
content:"SOAPAction|3A| |22|urn|3A|AdminService|22|"; distance:0;within:140; content:".ObjectName|22|>rO0AB"
는 공격을 탐지하기 위한 추가적인 조건이다.
위의 룰을 적용한 상태로 앞서 작성한 파이썬 코드를 실행하여 패킷을 전송했을 때, 다음과 같이 룰에 일치하여 패킷이 탐지된 것을 확인할 수 있다.