우리가 시그니처를 만들 때 중요한 건 결국 “이 트래픽 안에 공격이 있는지”를 찾아내는 거지?
그러면 그 트래픽 속에서 “어떤 단어(또는 패턴)”가 있는지 확인해야 해.
이걸 해주는 게 바로 content와 pcre야.
🧠 content vs pcre: 개념적으로 이해하기
✅ content는 "정확히 이 단어 있는지?"
= 단어 찾기 (정확히 일치)
- 마치 Ctrl+F로 'password' 찾기 같은 거야.
- 네트워크 패킷 안에서 특정한 단어(문자열)가 그대로 포함되어 있는지만 검사해.
📌 예시:
이 트래픽 안에 "GET /admin"이 있는지 찾아줘!
→ content:"GET /admin";
✏️ 딱 떨어지는 키워드가 있는지, 그걸 빠르게 찾고 싶을 때
✅ pcre는 "어떤 패턴이 있는지?"
= 규칙을 찾아내는 탐정처럼
- pcre는 **정규표현식(Regex)**을 사용하는 고급 도구야.
- 단어가 모양을 바꿔서 우회해도, 그 패턴을 인식해서 찾아낼 수 있어.
📌 예시:
<script>alert(1)</script>
→ 공격자는 이렇게 우회할 수 있어:
<scr<script>ipt>alert(1)</scr</script>ipt>
→ 이럴 땐 content는 못 잡지만, pcre는 **"script라는 말이 우회돼도 비슷한 모양이면 잡아!"**라고 탐지 가능해.
🔁 관계 정리: content와 pcre는 역할이 다르다!
구분 비유 개념
content | "정확히 이 단어 찾아줘!" | 문자열 매칭 |
pcre | "이런 모양의 패턴을 찾아줘!" | 규칙 기반 탐지 |
관계 | 함께 쓰면 더 강력 | content로 먼저 좁히고, pcre로 정밀 검사 |
🧠 더 쉽게 비유해보면…
📘 책에서 특정 문장을 찾는다고 생각해보자.
- 🔍 content는:
- “이 책에서 정확히 ‘나는 고양이가 되고 싶다’라는 문장을 찾아줘”
- 🕵️♀️ pcre는:
- “고양이에 관한 문장인데, 중간에 단어 순서가 조금 바뀌거나 띄어쓰기가 달라도 다 찾아줘”
→ 패턴과 유사성을 인식해서 찾아주는 거지.
🧠 언제 어떤 걸 쓰면 좋을까?
상황 쓰는 것
딱 맞는 문장이 있을 때 | ✅ content |
공격자가 글자를 섞거나 인코딩해서 우회할 때 | ✅ pcre |
성능(속도)이 중요할 때 | content 우선 |
탐지 정확도가 중요할 때 | content + pcre 조합 |
📌 마무리 요약
- content: 정확한 단어 찾기. 빠르고 간단.
- pcre: 규칙/패턴으로 찾기. 느리지만 유연하고 강력.
- 둘 다 "Payload 안의 공격 흔적을 찾는 방법"이지만 방식이 다름.
시그니처를 제대로 만들기 위해서는 이 둘이 룰 내부에서 어떤 역할을 하며 어떻게 함께 쓰이는지를 정확히 이해하는 게 핵심이야.
🔗 content, pcre, Snort 시그니처의 관계
✅ 1. Snort 시그니처 구조 개요
alert tcp any any -> any 80 (
msg:"Example Rule";
flow:to_server,established;
content:"/admin"; http_uri;
pcre:"/\/admin(\/|$)/";
sid:1000001; rev:1;
)
- 헤더 (Header): 탐지할 조건 (프로토콜, 포트, 방향)
- 옵션 (Options): 구체적인 탐지 조건
여기서 content, pcre 등이 포함됨
→ content와 pcre는 둘 다 **Payload(데이터)**를 분석하는 역할을 하지만, 탐지 방식이 달라
✅ 2. content와 pcre의 관계 (핵심 요약)
항목 설명
공통점 | 둘 다 Payload 안의 문자열 또는 패턴을 기반으로 탐지 |
차이점 | content는 고정 문자열 탐지, pcre는 정규표현식 기반 패턴 탐지 |
실행 순서 | Snort는 내부적으로 content를 먼저 평가해서 가능한 패킷만 pcre로 전달함 |
성능 측면 | content는 빠르고 가벼움 → 가능한 한 content로 먼저 필터링하는 게 좋음 |
조합 사용 | content로 narrowing → pcre로 우회 탐지 또는 세부 조건 확인 |
✅ 3. 조합 전략: content + pcre
📌 예시: /cgi-bin/admin.cgi;cat /etc/passwd 같은 우회 공격 탐지
alert tcp any any -> any 80 (
msg:"Command Injection Attempt";
flow:to_server,established;
content:"/cgi-bin/"; http_uri;
pcre:"/;.*(cat|ls|wget)/"; http_uri;
sid:1001001; rev:1;
)
- content:"/cgi-bin/": 해당 URI가 포함된 트래픽만 대상으로 삼음 (빠른 필터링)
- pcre:"/;.*(cat|ls|wget)/": 그 뒤에 우회된 쉘 명령이 있는지 확인
➕ 왜 이게 좋은가?
- pcre만 쓰면 모든 트래픽을 정규표현식으로 비교해야 해서 무겁고 느림
- content로 먼저 줄여주면 탐지 효율도 좋고 false positive도 줄어듦
✅ 4. content 없이 pcre만 써도 되나?
가능은 하지만 비추천이야.
pcre:"/alert\(1\)/";
- 문제점:
- 성능 저하
- false positive 가능성 ↑
- 탐지 범위 너무 넓어질 수 있음
✅ 해결 방법: 최소한의 content로 narrowing 후 pcre 적용
content:"alert"; pcre:"/alert\(1\)/";
✅ 5. 흐름 정리
1. Snort는 먼저 Header를 보고 트래픽을 필터링하고,
2. content를 기반으로 문자열 매칭을 시도하며,
3. 조건이 맞는 경우 pcre를 추가적으로 검사해줌.
🧪 실전 체크리스트
질문 예시
단순 문자열인가? | content |
위치를 제한하고 싶은가? | offset, depth, within, distance와 함께 content |
문자열이 우회되거나 변형될 가능성이 있는가? | pcre |
성능 이슈를 줄이고 싶은가? | content + pcre 조합 전략 |
🎯 결론
목적 추천 조합
빠르고 정확한 탐지 | ✅ content 단독 |
복잡한 패턴, 공격 우회 대응 | ✅ content + pcre |
단순한 정규 매칭만 필요 | pcre 단독 (단, 성능 유의) |
원하면 content → pcre 조합으로 우회된 공격 트래픽을 실제로 탐지하는 룰 예제를 같이 만들어볼 수도 있어.
아니면 지금 너가 분석 중인 트래픽에서 어떤 룰이 적절할지 판단해줄 수도 있어.그다음 주제로 offset, depth, distance, within 위치 제한 옵션에 대해서도 들어가볼까?
“실제 공격 트래픽에서 content와 pcre가 어떻게 적용되는지” 보여줄게.
CVE 사례 기반의 실전 예시로, 공격 패턴이 어떻게 트래픽에 담기고, 그걸 Snort 시그니처에서 어떻게 탐지하는지를 설명해볼게.
🎯 실제 공격 트래픽에서 content vs pcre 적용 예시
✅ 예시 공격: CVE-2016-6277
- 취약점: Netgear R7000, R6400 라우터의 cgi-bin 경로에서 Command Injection
- 공격 요청 URI 예시:
GET /cgi-bin/;cat${IFS}/etc/passwd HTTP/1.1
🔍 이 트래픽은 어떻게 생겼을까? (Wireshark 기준)
필드 내용
Method | GET |
URI | /cgi-bin/;cat${IFS}/etc/passwd |
목적 | 쉘 명령 실행을 통해 패스워드 파일 노출 (Command Injection) |
💣 시그니처 설계
🎯 Step 1: content만으로 탐지
alert tcp any any -> any 80 (
msg:"Netgear CVE-2016-6277 Command Injection";
flow:to_server,established;
content:"/cgi-bin/"; http_uri;
content:"/etc/passwd"; http_uri;
sid:25755; rev:1;
)
🧠 설명:
- /cgi-bin/이 포함된 URI → 공격 경로
- /etc/passwd → 민감한 시스템 파일
📌 이건 명확한 두 단어가 포함된 경우이기 때문에 content만으로도 탐지 가능!
🎯 Step 2: 공격자가 우회를 시도한 경우
우회 예시:
GET /cgi-bin/;%63%61%74${IFS}/etc/passwd
- %63%61%74 = cat
- ${IFS} = 공백 문자 우회
- 전체적으로 인코딩/변형된 쉘 명령어
🔍 이럴 땐 content만으로는 탐지가 어려움 → pcre 필요
alert tcp any any -> any 80 (
msg:"Netgear CVE-2016-6277 - Obfuscated Command Injection";
flow:to_server,established;
pcre:"/\/cgi-bin\/.*?(cat|wget|ls).*?\/etc\/passwd/Ui";
sid:25756; rev:1;
)
🧠 설명:
- .*? : 중간에 다른 인코딩된 우회 문자도 허용
- (cat|wget|ls) : 여러 쉘 명령 중 하나
- /etc/passwd : 목표 파일
- U : ungreedy, i : 대소문자 무시
📌 pcre는 공격이 우회된 경우까지 포괄적으로 탐지할 수 있음
✅ 실제 공격 트래픽 분석 흐름 요약
단계 내용
① 공격자가 HTTP 요청을 보냄 | /cgi-bin/;cat${IFS}/etc/passwd |
② Wireshark/PCAP으로 URI 확인 | Request URI → /cgi-bin/... |
③ Snort에서 탐지 시도 | content로 명확한 키워드 탐지 |
④ 우회 공격 존재 | 인코딩, 변수치환 등 |
⑤ pcre로 패턴 기반 탐지 필요 | 복잡한 정규표현식으로 대응 |
🧠 결론: 실전에서의 적용 정리
상황 사용 방식
공격 트래픽이 정직(?)하게 들어올 때 | content로 빠르고 간단하게 탐지 |
공격자가 변형, 인코딩, 우회를 시도할 때 | pcre로 유연하게 대응 |
성능이 중요할 때 | content + offset, depth로 최적화 |
탐지율이 중요할 때 | content + pcre 조합 사용 |
🧪 직접 해보는 실습 추천
- curl로 아래 명령 실행해보기:
curl "http://localhost/cgi-bin/;cat${IFS}/etc/passwd"
- Snort에 content 기반 룰과 pcre 기반 룰을 각각 적용
- alert 로그에 어떤 룰이 탐지됐는지 확인
혹시 너가 가지고 있는 PCAP 파일이나 특정 공격 사례가 있다면,
그걸 기준으로 직접 content, pcre 조합해서 룰을 같이 만들어보는 실전 연습 해볼 수도 있어.
한번 해볼래? 또는 다음 주제로 넘어갈까?