Skip to content
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

next/92/60x/20230718/v1 #9249

Merged
merged 6 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
# Format:
#
# name {repo} {branch|tag}
libhtp https://github.com/OISF/libhtp 0.5.44
libhtp https://github.com/OISF/libhtp 0.5.45
suricata-update https://github.com/OISF/suricata-update 1.2.8
1 change: 1 addition & 0 deletions rules/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ modbus-events.rules \
mqtt-events.rules \
nfs-events.rules \
ntp-events.rules \
rfb-events.rules \
smb-events.rules \
smtp-events.rules \
ssh-events.rules \
Expand Down
10 changes: 10 additions & 0 deletions rules/rfb-events.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# RFB app-layer event rules.
#
# These SIDs fall in the 2233000+ range. See:
# http://doc.emergingthreats.net/bin/view/Main/SidAllocation and
# https://redmine.openinfosecfoundation.org/projects/suricata/wiki/AppLayer

alert rfb any any -> any any (msg:"SURICATA RFB Malformed or unknown message"; app-layer-event:rfb.malformed_message; classtype:protocol-command-decode; sid:2233000; rev:1;)
alert rfb any any -> any any (msg:"SURICATA RFB Unimplemented security type"; app-layer-event:rfb.unimplemented_security_type; classtype:protocol-command-decode; sid:2233001; rev:1;)
alert rfb any any -> any any (msg:"SURICATA RFB Unknown security result"; app-layer-event:rfb.unknown_security_result; classtype:protocol-command-decode; sid:2233002; rev:1;)
alert rfb any any -> any any (msg:"SURICATA RFB Unexpected State in Parser"; app-layer-event:rfb.confused_state; classtype:protocol-command-decode; sid:2233003; rev:1;)
14 changes: 4 additions & 10 deletions rust/src/rfb/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ use std::ptr;

#[no_mangle]
pub unsafe extern "C" fn rs_rfb_tx_get_name(
tx: &mut RFBTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut RFBTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.tc_server_init {
let p = &r.name;
Expand All @@ -42,10 +40,7 @@ pub unsafe extern "C" fn rs_rfb_tx_get_name(
}

#[no_mangle]
pub unsafe extern "C" fn rs_rfb_tx_get_sectype(
tx: &mut RFBTransaction,
sectype: *mut u32,
) -> u8 {
pub unsafe extern "C" fn rs_rfb_tx_get_sectype(tx: &mut RFBTransaction, sectype: *mut u32) -> u8 {
if let Some(ref r) = tx.chosen_security_type {
*sectype = *r;
return 1;
Expand All @@ -58,13 +53,12 @@ pub unsafe extern "C" fn rs_rfb_tx_get_sectype(

#[no_mangle]
pub unsafe extern "C" fn rs_rfb_tx_get_secresult(
tx: &mut RFBTransaction,
secresult: *mut u32,
tx: &mut RFBTransaction, secresult: *mut u32,
) -> u8 {
if let Some(ref r) = tx.tc_security_result {
*secresult = r.status;
return 1;
}

return 0;
}
}
38 changes: 26 additions & 12 deletions rust/src/rfb/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

// Author: Frank Honza <frank.honza@dcso.de>

use std;
use std::fmt::Write;
use super::rfb::{RFBState, RFBTransaction};
use crate::jsonbuilder::{JsonBuilder, JsonError};
use std;
use std::fmt::Write;

fn log_rfb(tx: &RFBTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.open_object("rfb")?;
Expand Down Expand Up @@ -63,15 +63,17 @@ fn log_rfb(tx: &RFBTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
}
js.close()?;
}
_ => ()
_ => (),
}
if let Some(security_result) = &tx.tc_security_result {
let _ = match security_result.status {
0 => js.set_string("security_result", "OK")?,
1 => js.set_string("security-result", "FAIL")?,
2 => js.set_string("security_result", "TOOMANY")?,
_ => js.set_string("security_result",
&format!("UNKNOWN ({})", security_result.status))?,
_ => js.set_string(
"security_result",
&format!("UNKNOWN ({})", security_result.status),
)?,
};
}
js.close()?; // Close authentication.
Expand All @@ -91,15 +93,27 @@ fn log_rfb(tx: &RFBTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.set_string_from_bytes("name", &tc_server_init.name)?;

js.open_object("pixel_format")?;
js.set_uint("bits_per_pixel", tc_server_init.pixel_format.bits_per_pixel as u64)?;
js.set_uint(
"bits_per_pixel",
tc_server_init.pixel_format.bits_per_pixel as u64,
)?;
js.set_uint("depth", tc_server_init.pixel_format.depth as u64)?;
js.set_bool("big_endian", tc_server_init.pixel_format.big_endian_flag != 0)?;
js.set_bool("true_color", tc_server_init.pixel_format.true_colour_flag != 0)?;
js.set_bool(
"big_endian",
tc_server_init.pixel_format.big_endian_flag != 0,
)?;
js.set_bool(
"true_color",
tc_server_init.pixel_format.true_colour_flag != 0,
)?;
js.set_uint("red_max", tc_server_init.pixel_format.red_max as u64)?;
js.set_uint("green_max", tc_server_init.pixel_format.green_max as u64)?;
js.set_uint("blue_max", tc_server_init.pixel_format.blue_max as u64)?;
js.set_uint("red_shift", tc_server_init.pixel_format.red_shift as u64)?;
js.set_uint("green_shift", tc_server_init.pixel_format.green_shift as u64)?;
js.set_uint(
"green_shift",
tc_server_init.pixel_format.green_shift as u64,
)?;
js.set_uint("blue_shift", tc_server_init.pixel_format.blue_shift as u64)?;
js.close()?;

Expand All @@ -112,9 +126,9 @@ fn log_rfb(tx: &RFBTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
}

#[no_mangle]
pub extern "C" fn rs_rfb_logger_log(_state: &mut RFBState,
tx: *mut std::os::raw::c_void,
js: &mut JsonBuilder) -> bool {
pub extern "C" fn rs_rfb_logger_log(
_state: &mut RFBState, tx: *mut std::os::raw::c_void, js: &mut JsonBuilder,
) -> bool {
let tx = cast_pointer!(tx, RFBTransaction);
log_rfb(tx, js).is_ok()
}
2 changes: 1 addition & 1 deletion rust/src/rfb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
pub mod detect;
pub mod logger;
pub mod parser;
pub mod rfb;
pub mod rfb;
54 changes: 24 additions & 30 deletions rust/src/rfb/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@

// Author: Frank Honza <frank.honza@dcso.de>

use std::fmt;
use nom::*;
use nom::number::streaming::*;
use nom::*;
use std::fmt;

#[derive(Debug, PartialEq)]
pub enum RFBGlobalState {
TCServerProtocolVersion,
TCSupportedSecurityTypes,
Expand All @@ -33,7 +34,7 @@ pub enum RFBGlobalState {
TSVncResponse,
TCSecurityResult,
TSClientInit,
Message
Skip,
}

impl fmt::Display for RFBGlobalState {
Expand All @@ -50,43 +51,43 @@ impl fmt::Display for RFBGlobalState {
RFBGlobalState::TCSecurityResult => write!(f, "TCSecurityResult"),
RFBGlobalState::TCServerSecurityType => write!(f, "TCServerSecurityType"),
RFBGlobalState::TSClientInit => write!(f, "TSClientInit"),
RFBGlobalState::Message => write!(f, "Message")
RFBGlobalState::Skip => write!(f, "Skip"),
}
}
}

pub struct ProtocolVersion {
pub major: String,
pub minor: String
pub minor: String,
}

pub struct SupportedSecurityTypes {
pub number_of_types: u8,
pub types: Vec<u8>
pub types: Vec<u8>,
}

pub struct SecurityTypeSelection {
pub security_type: u8
pub security_type: u8,
}

pub struct ServerSecurityType {
pub security_type: u32
pub security_type: u32,
}

pub struct SecurityResult {
pub status: u32
pub status: u32,
}

pub struct FailureReason {
pub reason_string: String
pub reason_string: String,
}

pub struct VncAuth {
pub secret: Vec<u8>
pub secret: Vec<u8>,
}

pub struct ClientInit {
pub shared: u8
pub shared: u8,
}

pub struct PixelFormat {
Expand All @@ -107,17 +108,16 @@ pub struct ServerInit {
pub height: u16,
pub pixel_format: PixelFormat,
pub name_length: u32,
pub name: Vec<u8>
pub name: Vec<u8>,
}

named!(pub parse_protocol_version<ProtocolVersion>,
do_parse!(
_rfb_string: take_str!(3)
>> be_u8
_rfb_string: tag!("RFB ")
>> major: take_str!(3)
>> be_u8
>> _sep1: tag!(".")
>> minor: take_str!(3)
>> be_u8
>> _sep2: tag!("\n")
>> (
ProtocolVersion{
major: major.to_string(),
Expand Down Expand Up @@ -258,8 +258,8 @@ named!(pub parse_server_init<ServerInit>,

#[cfg(test)]
mod tests {
use nom::*;
use super::*;
use nom::*;

/// Simple test of some valid data.
#[test]
Expand All @@ -278,8 +278,7 @@ mod tests {
Err(Err::Incomplete(_)) => {
panic!("Result should not have been incomplete.");
}
Err(Err::Error(err)) |
Err(Err::Failure(err)) => {
Err(Err::Error(err)) | Err(Err::Failure(err)) => {
panic!("Result should not be an error: {:?}.", err);
}
}
Expand All @@ -288,13 +287,10 @@ mod tests {
#[test]
fn test_parse_server_init() {
let buf = [
0x05, 0x00, 0x03, 0x20, 0x20, 0x18, 0x00, 0x01,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x10, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
0x61, 0x6e, 0x65, 0x61, 0x67, 0x6c, 0x65, 0x73,
0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
0x73, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e
0x05, 0x00, 0x03, 0x20, 0x20, 0x18, 0x00, 0x01, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x61, 0x6e, 0x65, 0x61,
0x67, 0x6c, 0x65, 0x73, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
];

let result = parse_server_init(&buf);
Expand All @@ -311,11 +307,9 @@ mod tests {
Err(Err::Incomplete(_)) => {
panic!("Result should not have been incomplete.");
}
Err(Err::Error(err)) |
Err(Err::Failure(err)) => {
Err(Err::Error(err)) | Err(Err::Failure(err)) => {
panic!("Result should not be an error: {:?}.", err);
}
}
}

}
Loading
Loading