-
Notifications
You must be signed in to change notification settings - Fork 1.7k
detect/sip: add sticky buffers to match headers v3 #11004
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d959bc5
cc50584
6474430
0b4f35f
7340116
6720c69
4d414cf
f9553bc
e4cc816
b2b5c8a
a0a400c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,12 @@ sip.stat_code Response | |
| sip.stat_msg Response | ||
| sip.response_line Response | ||
| sip.protocol Both | ||
| sip.from Both | ||
| sip.to Both | ||
| sip.via Both | ||
| sip.user_agent Both | ||
| sip.content_type Both | ||
| sip.content_length Both | ||
| ============================== ================== | ||
|
|
||
| sip.method | ||
|
|
@@ -177,3 +183,129 @@ Example | |
| :: | ||
|
|
||
| sip.protocol; content:"SIP/2.0" | ||
|
|
||
| sip.from | ||
| -------- | ||
|
|
||
| This keyword matches on the From field that can be present in SIP headers. | ||
|
|
||
| Syntax | ||
| ~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.from; content:<from> | ||
|
|
||
| Where <from> is the value of the From header. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jufajardini we should precise this is a sticky buffer, right ? |
||
|
|
||
| Example | ||
| ~~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.from; content:"user" | ||
|
|
||
| sip.to | ||
| ------ | ||
|
|
||
| This keyword matches on the To field that can be present in SIP headers. | ||
|
|
||
| Syntax | ||
| ~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.to; content:<to> | ||
|
|
||
| Where <to> is the value of the To header. | ||
|
|
||
| Example | ||
| ~~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.to; content:"user" | ||
|
|
||
| sip.via | ||
| -------- | ||
|
|
||
| This keyword matches on the Via field that can be present in SIP headers. | ||
|
|
||
| Syntax | ||
| ~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.via; content:<via> | ||
|
|
||
| Where <via> is the value of the Via header. | ||
|
|
||
| Example | ||
| ~~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.via; content:"SIP/2.0/UDP" | ||
|
|
||
| sip.user_agent | ||
| -------------- | ||
|
|
||
| This keyword matches on the User-Agent field that can be present in SIP headers. | ||
|
|
||
| Syntax | ||
| ~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.user_agent; content:<user_agent> | ||
|
|
||
| Where <user_agent> is the value of the User-Agent header. | ||
|
|
||
| Example | ||
| ~~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.user_agent; content:"Asterisk" | ||
|
|
||
| sip.content_type | ||
| ---------------- | ||
|
|
||
| This keyword matches on the Content-Type field that can be present in SIP headers. | ||
|
|
||
| Syntax | ||
| ~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.content_type; content:<content_type> | ||
|
|
||
| Where <content_type> is the value of the Content-Type header. | ||
|
|
||
| Example | ||
| ~~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.content_type; content:"application/sdp" | ||
|
|
||
| sip.content_length | ||
| ------------------ | ||
|
|
||
| This keyword matches on the Content-Length field that can be present in SIP headers. | ||
|
|
||
| Syntax | ||
| ~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.content_length; content:<content_length> | ||
|
|
||
| Where <content_length> is the value of the Content-Length header. | ||
|
|
||
| Example | ||
| ~~~~~~~ | ||
|
|
||
| :: | ||
|
|
||
| sip.content_length; content:"200" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,6 +55,14 @@ Major changes | |
| - SDP parser and logger have been introduced. | ||
| Due to SDP being encapsulated within other protocols, such as SIP, they cannot be directly enabled or disabled. | ||
| Instead, both the SDP parser and logger depend on being invoked by another parser (or logger). | ||
| - The following sticky buffers for matching SIP headers have been implemented: | ||
| - sip.via | ||
| - sip.from | ||
| - sip.to | ||
| - sip.content_type | ||
| - sip.content_length | ||
|
|
||
| Note: Headers expressed in compact form will still be matched. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the Note line is too much details for this file |
||
|
|
||
| Upgrading 6.0 to 7.0 | ||
| -------------------- | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| /* Copyright (C) 2019 Open Information Security Foundation | ||
| /* Copyright (C) 2024 Open Information Security Foundation | ||
| * | ||
| * You can copy, redistribute or modify this Program under the terms of | ||
| * the GNU General Public License version 2 as published by the Free | ||
|
|
@@ -19,8 +19,26 @@ | |
|
|
||
| use crate::core::Direction; | ||
| use crate::sip::sip::SIPTransaction; | ||
| use std::ffi::CStr; | ||
| use std::ptr; | ||
|
|
||
| fn header_compact_name(h: &str) -> Option<String> { | ||
| let compact = match h { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you add a comment to the RFC specifying these ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, would not it be simpler the other way, to associate |
||
| "Call-ID" => "i", | ||
| "Contact" => "m", | ||
| "Content-Encoding" => "e", | ||
| "Content-Length" => "l", | ||
| "Content-Type" => "c", | ||
| "From" => "f", | ||
| "Subject" => "s", | ||
| "Supported" => "k", | ||
| "To" => "t", | ||
| "Via" => "v", | ||
| _ => return None, | ||
| }; | ||
| Some(compact.to_string()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need the allocation ? |
||
| } | ||
|
|
||
| #[no_mangle] | ||
| pub unsafe extern "C" fn rs_sip_tx_get_method( | ||
| tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32, | ||
|
|
@@ -165,3 +183,36 @@ pub unsafe extern "C" fn rs_sip_tx_get_response_line( | |
|
|
||
| return 0; | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| pub unsafe extern "C" fn rs_sip_tx_get_header_value( | ||
| tx: &mut SIPTransaction, direction: u8, strname: *const std::os::raw::c_char, | ||
| buffer: *mut *const u8, buffer_len: *mut u32, | ||
| ) -> u8 { | ||
| let hname: &CStr = CStr::from_ptr(strname); | ||
| if let Ok(s) = hname.to_str() { | ||
| let s2 = header_compact_name(s); | ||
| let headers = match direction.into() { | ||
| Direction::ToServer => tx.request.as_ref().map(|r| &r.headers), | ||
| Direction::ToClient => tx.response.as_ref().map(|r| &r.headers), | ||
| }; | ||
| if let Some(headers) = headers { | ||
| let header_value = headers | ||
| .get(s) | ||
| .or_else(|| s2.as_ref().and_then(|s2| headers.get(s2))); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That means if I have the header in long and short form, I only get the long form, right ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, right. |
||
|
|
||
| if let Some(value) = header_value { | ||
| if !value.is_empty() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this test ? cf #11070 and https://redmine.openinfosecfoundation.org/issues/2224 |
||
| *buffer = value.as_ptr(); | ||
| *buffer_len = value.len() as u32; | ||
| return 1; | ||
| } | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| *buffer = ptr::null(); | ||
| *buffer_len = 0; | ||
|
|
||
| return 0; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| /* Copyright (C) 2024 Open Information Security Foundation | ||
| * | ||
| * You can copy, redistribute or modify this Program under the terms of | ||
| * the GNU General Public License version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * version 2 along with this program; if not, write to the Free Software | ||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| * 02110-1301, USA. | ||
| */ | ||
|
|
||
| /** | ||
| * \file | ||
| * | ||
| * \author Giuseppe Longo <giuseppe@glongo.it> | ||
| * | ||
| * Implements the sip.content_length sticky buffer | ||
| */ | ||
|
|
||
| #define KEYWORD_NAME "sip.content_length" | ||
| #define KEYWORD_DOC "sip-keywords.html#sip-content-length" | ||
| #define BUFFER_NAME "sip.content_length" | ||
| #define BUFFER_DESC "sip content-length header" | ||
| #define HEADER_NAME "Content-Length" | ||
| #define KEYWORD_ID DETECT_AL_SIP_HEADER_CONTENT_LENGTH | ||
| #define KEYWORD_TOSERVER 1 | ||
| #define KEYWORD_TOCLIENT 1 | ||
|
|
||
| #include "detect-sip-headers-stub.h" | ||
| #include "detect-sip-content-length.h" | ||
|
|
||
| void RegisterSipHeadersContentLength(void) | ||
| { | ||
| DetectSipHeadersRegisterStub(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| /* Copyright (C) 2024 Open Information Security Foundation | ||
| * | ||
| * You can copy, redistribute or modify this Program under the terms of | ||
| * the GNU General Public License version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * version 2 along with this program; if not, write to the Free Software | ||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| * 02110-1301, USA. | ||
| */ | ||
|
|
||
| #ifndef __DETECT_SIP_CONTENT_LENGTH_H__ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Old guard style |
||
| #define __DETECT_SIP_CONTENT_LENGTH_H__ | ||
|
|
||
| void RegisterSipHeadersContentLength(void); | ||
|
|
||
| #endif /* __DETECT_SIP_CONTENT_LENGTH_H__ */ | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if there are multiple
Fromheaders ?Should it be a multi buffer ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should.