-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
app-layer: websockets protocol support
Ticket: 2695 Introduces a device EnumStringU8 to ease the use of enumerations in protocols : logging the string out of the u8, and for detection, parsing the u8 out of the string
- Loading branch information
1 parent
7d95c4c
commit 1549f0b
Showing
27 changed files
with
1,244 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
WebSocket Keywords | ||
================== | ||
|
||
websocket.payload | ||
----------------- | ||
|
||
A sticky buffer on the unmasked payload, | ||
limited by suricata.yaml config value ``websocket.max-payload-size``. | ||
|
||
Examples:: | ||
|
||
websocket.payload; pcre:"/^123[0-9]*/"; | ||
websocket.payload content:"swordfish"; | ||
|
||
``websocket.payload`` is a 'sticky buffer' and can be used as ``fast_pattern``. | ||
|
||
websocket.fin | ||
------------- | ||
|
||
A boolean to tell if the payload is complete. | ||
|
||
Examples:: | ||
|
||
websocket.fin:true; | ||
websocket.fin:false; | ||
|
||
websocket.mask | ||
-------------- | ||
|
||
Matches on the websocket mask if any. | ||
It uses a 32-bit unsigned integer as value (big-endian). | ||
|
||
Examples:: | ||
|
||
websocket.mask:123456; | ||
websocket.mask:>0; | ||
|
||
websocket.opcode | ||
---------------- | ||
|
||
Matches on the websocket opcode. | ||
It uses a 8-bit unsigned integer as value. | ||
Only 16 values are relevant. | ||
It can also be specified by text from the enumeration | ||
|
||
Examples:: | ||
|
||
websocket.opcode:1; | ||
websocket.opcode:>8; | ||
websocket.opcode:ping; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* Copyright (C) 2023 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. | ||
*/ | ||
|
||
extern crate proc_macro; | ||
use super::applayerevent::transform_name; | ||
use proc_macro::TokenStream; | ||
use quote::quote; | ||
use syn::{self, parse_macro_input, DeriveInput}; | ||
|
||
pub fn derive_enum_string_u8(input: TokenStream) -> TokenStream { | ||
let input = parse_macro_input!(input as DeriveInput); | ||
let name = transform_name(&input.ident.to_string()); | ||
let mut values = Vec::new(); | ||
let mut names = Vec::new(); | ||
|
||
if let syn::Data::Enum(ref data) = input.data { | ||
for (_, v) in (&data.variants).into_iter().enumerate() { | ||
let fname = transform_name(&v.ident.to_string()); | ||
names.push(fname); | ||
if let Some((_, val)) = &v.discriminant { | ||
if let syn::Expr::Lit(l) = val { | ||
if let syn::Lit::Int(li) = &l.lit { | ||
if let Ok(value) = li.base10_parse::<u8>() { | ||
values.push(value); | ||
} else { | ||
panic!("EnumString requires explicit u8"); | ||
} | ||
} else { | ||
panic!("EnumString requires explicit literal integer"); | ||
} | ||
} else { | ||
panic!("EnumString requires explicit literal"); | ||
} | ||
} else { | ||
panic!("EnumString requires explicit values"); | ||
} | ||
} | ||
} else { | ||
panic!("EnumString can only be derived for enums"); | ||
} | ||
|
||
let stringer = syn::Ident::new(&(name.clone() + "_string"), proc_macro2::Span::call_site()); | ||
let parser = syn::Ident::new(&(name + "_parse"), proc_macro2::Span::call_site()); | ||
|
||
let expanded = quote! { | ||
fn #stringer(v: u8) -> Option<&'static str> { | ||
match v { | ||
#( #values => Some(#names) ,)* | ||
_ => None, | ||
} | ||
} | ||
|
||
pub(crate) fn #parser(v: &str) -> Option<u8> { | ||
match v { | ||
#( #names => Some(#values) ,)* | ||
_ => None, | ||
} | ||
} | ||
}; | ||
|
||
proc_macro::TokenStream::from(expanded) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* Copyright (C) 2023 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. | ||
*/ | ||
|
||
use super::logger::web_socket_opcode_parse; | ||
use super::websocket::WebSocketTransaction; | ||
use crate::detect::uint::{detect_parse_uint, DetectUintData, DetectUintMode}; | ||
use std::ffi::CStr; | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn SCWebSocketGetOpcode(tx: &mut WebSocketTransaction) -> u8 { | ||
return tx.pdu.opcode; | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn SCWebSocketGetFin(tx: &mut WebSocketTransaction) -> bool { | ||
return tx.pdu.fin; | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn SCWebSocketGetPayload( | ||
tx: &WebSocketTransaction, buffer: *mut *const u8, buffer_len: *mut u32, | ||
) -> bool { | ||
*buffer = tx.pdu.payload.as_ptr(); | ||
*buffer_len = tx.pdu.payload.len() as u32; | ||
return true; | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn SCWebSocketGetMask( | ||
tx: &mut WebSocketTransaction, value: *mut u32, | ||
) -> bool { | ||
if let Some(xorkey) = tx.pdu.mask { | ||
*value = xorkey; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn SCWebSocketParseOpcode( | ||
ustr: *const std::os::raw::c_char, | ||
) -> *mut DetectUintData<u8> { | ||
let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe | ||
if let Ok(s) = ft_name.to_str() { | ||
if let Ok((_, ctx)) = detect_parse_uint::<u8>(s) { | ||
let boxed = Box::new(ctx); | ||
return Box::into_raw(boxed) as *mut _; | ||
} | ||
if let Some(arg1) = web_socket_opcode_parse(s) { | ||
let ctx = DetectUintData::<u8> { | ||
arg1, | ||
arg2: 0, | ||
mode: DetectUintMode::DetectUintModeEqual, | ||
}; | ||
let boxed = Box::new(ctx); | ||
return Box::into_raw(boxed) as *mut _; | ||
} | ||
} | ||
return std::ptr::null_mut(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* Copyright (C) 2023 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. | ||
*/ | ||
|
||
use super::websocket::WebSocketTransaction; | ||
use crate::jsonbuilder::{JsonBuilder, JsonError}; | ||
use std; | ||
use suricata_derive::EnumStringU8; | ||
|
||
#[derive(EnumStringU8)] | ||
pub enum WebSocketOpcode { | ||
Continuation = 0, | ||
Text = 1, | ||
Binary = 2, | ||
Ping = 8, | ||
Pong = 9, | ||
} | ||
|
||
fn log_websocket(tx: &WebSocketTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> { | ||
js.open_object("websocket")?; | ||
js.set_bool("fin", tx.pdu.fin)?; | ||
if let Some(xorkey) = tx.pdu.mask { | ||
js.set_uint("mask", xorkey.into())?; | ||
} | ||
if let Some(val) = web_socket_opcode_string(tx.pdu.opcode) { | ||
js.set_string("opcode", val)?; | ||
} else { | ||
js.set_string("opcode", &format!("unknown-{}", tx.pdu.opcode))?; | ||
} | ||
js.close()?; | ||
Ok(()) | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn rs_websocket_logger_log( | ||
tx: *mut std::os::raw::c_void, js: &mut JsonBuilder, | ||
) -> bool { | ||
let tx = cast_pointer!(tx, WebSocketTransaction); | ||
log_websocket(tx, js).is_ok() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* Copyright (C) 2023 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. | ||
*/ | ||
|
||
//! Application layer websocket parser and logger module. | ||
|
||
pub mod detect; | ||
pub mod logger; | ||
mod parser; | ||
pub mod websocket; |
Oops, something went wrong.