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

Rust add snmp 02 #3879

Closed
wants to merge 12 commits into from
Closed
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
1 change: 1 addition & 0 deletions doc/userguide/rules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Suricata Rules
enip-keyword
ftp-keywords
kerberos-keywords
snmp-keywords
app-layer
xbits
thresholding
Expand Down
75 changes: 75 additions & 0 deletions doc/userguide/rules/snmp-keywords.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
SNMP keywords
=============

snmp_version
chifflier marked this conversation as resolved.
Show resolved Hide resolved
------------

SNMP protocol version (integer). Expected values are 1, 2 (for version 2c) or 3.

Syntax::

snmp_version:[op]<number>

The version can be matched exactly, or compared using the _op_ setting::

snmp_version:3 # exactly 3
snmp_version:<3 # smaller than 3
snmp_version:>=2 # greater or equal than 2

Signature example::

alert snmp any any -> any any (msg:"old SNMP version (<3)"; snmp_version:<3; sid:1; rev:1;)

snmp_community
--------------

SNMP community strings are like passwords for SNMP messages in version 1 and 2c.
In version 3, the community string is likely to be encrypted. This keyword will not
match if the value is not accessible.

The default value for the read-only community string is often "public", and
"private" for the read-write community string.

Comparison is case-sensitive.

Syntax::

snmp_community; content:"private";

Signature example::

alert snmp any any -> any any (msg:"SNMP community private"; snmp_community; content:"private"; sid:2; rev:1;)

``snmp_community`` is a 'sticky buffer'.

``snmp_community`` can be used as ``fast_pattern``.

snmp_pdu_type
-------------

SNMP PDU type (integer).

Common values are:

- 0: GetRequest
- 1: GetNextRequest
- 2: Response
- 3: SetRequest
- 4: TrapV1 (obsolete, was the old Trap-PDU in SNMPv1)
- 5: GetBulkRequest
- 6: InformRequest
- 7: TrapV2
- 8: Report

This keyword will not match if the value is not accessible within (for ex, an encrypted
SNMP v3 message).


Syntax::

snmp_pdu_type:<number>

Signature example::

alert snmp any any -> any any (msg:"SNMP response"; snmp_pdu_type:2; sid:3; rev:1;)

1 change: 1 addition & 0 deletions rust/Cargo.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ kerberos-parser = "0.2"

ntp-parser = "0.3"
ipsec-parser = "0.4"
snmp-parser = "0.3.0"
2 changes: 2 additions & 0 deletions rust/gen-c-headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
"TFTPState": "TFTPState",
"SMBState": "SMBState",
"SMBTransaction": "SMBTransaction",
"SNMPState": "SNMPState",
"SNMPTransaction": "SNMPTransaction",
"IKEV2State": "IKEV2State",
"IKEV2Transaction": "IKEV2Transaction",
"KRB5State": "KRB5State",
Expand Down
1 change: 1 addition & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub mod smb;
pub mod krb;

pub mod ikev2;
pub mod snmp;

pub mod ntp;
pub mod tftp;
Expand Down
9 changes: 9 additions & 0 deletions rust/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

use core::{DetectEngineState,Flow,AppLayerEventType,AppLayerDecoderEvents,AppProto};
use filecontainer::FileContainer;
use applayer;

use libc::{c_void,c_char,c_int};
use applayer::{AppLayerGetTxIterTuple};
Expand Down Expand Up @@ -169,8 +170,16 @@ pub const APP_LAYER_PARSER_NO_REASSEMBLY : u8 = 0b10;
pub const APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD : u8 = 0b100;
pub const APP_LAYER_PARSER_BYPASS_READY : u8 = 0b1000;

pub type AppLayerGetTxIteratorFn = extern "C" fn (ipproto: u8,
alproto: AppProto,
alstate: *mut c_void,
min_tx_id: u64,
max_tx_id: u64,
istate: &mut u64) -> applayer::AppLayerGetTxIterTuple;

extern {
pub fn AppLayerParserStateSetFlag(state: *mut c_void, flag: u8);
pub fn AppLayerParserStateIssetFlag(state: *mut c_void, flag: u8) -> c_int;
pub fn AppLayerParserConfParserEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int;
pub fn AppLayerParserRegisterGetTxIterator(ipproto: u8, alproto: AppProto, fun: AppLayerGetTxIteratorFn);
}
63 changes: 63 additions & 0 deletions rust/src/snmp/detect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* Copyright (C) 2017-2018 Open Information Security Foundation
chifflier marked this conversation as resolved.
Show resolved Hide resolved
*
* 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.
*/

// written by Pierre Chifflier <[email protected]>

use libc;
use snmp::snmp::SNMPTransaction;

#[no_mangle]
pub extern "C" fn rs_snmp_tx_get_version(tx: &mut SNMPTransaction,
version: *mut libc::uint32_t)
{
debug_assert!(tx.version != 0, "SNMP version is 0");
unsafe {
*version = tx.version as libc::uint32_t;
}
}

#[no_mangle]
pub extern "C" fn rs_snmp_tx_get_community(tx: &mut SNMPTransaction,
buf: *mut *const libc::uint8_t,
len: *mut libc::uint32_t)
{
match tx.community {
Some(ref c) => {
unsafe {
*buf = (&c).as_ptr();
*len = c.len() as libc::uint32_t;
}
},
None => ()
}
}

#[no_mangle]
pub extern "C" fn rs_snmp_tx_get_pdu_type(tx: &mut SNMPTransaction,
pdu_type: *mut libc::uint32_t)
{
unsafe {
match tx.info {
Some(ref info) => {
*pdu_type = info.pdu_type.0 as libc::uint32_t;
},
None => {
*pdu_type = 0xffffffff;
}
}
}
}
68 changes: 68 additions & 0 deletions rust/src/snmp/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* Copyright (C) 2018 Open Information Security Foundation
chifflier marked this conversation as resolved.
Show resolved Hide resolved
*
* 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.
*/

// written by Pierre Chifflier <[email protected]>

use json::*;
use snmp::snmp::{SNMPState,SNMPTransaction};
use snmp::snmp_parser::NetworkAddress;

#[no_mangle]
pub extern "C" fn rs_snmp_log_json_response(state: &mut SNMPState, tx: &mut SNMPTransaction) -> *mut JsonT
{
let js = Json::object();
js.set_integer("version", state.version as u64);
if tx.encrypted {
js.set_string("pdu_type", "encrypted");
} else {
match tx.info {
Some(ref info) => {
js.set_string("pdu_type", &format!("{:?}", info.pdu_type));
if info.err.0 != 0 {
js.set_string("error", &format!("{:?}", info.err));
}
match info.trap_type {
Some((trap_type, ref oid, address)) => {
js.set_string("trap_type", &format!("{:?}", trap_type));
js.set_string("trap_oid", &oid.to_string());
match address {
NetworkAddress::IPv4(ip) => js.set_string("trap_address", &ip.to_string())
}
},
_ => ()
}
if info.vars.len() > 0 {
let jsa = Json::array();
for var in info.vars.iter() {
jsa.array_append_string(&var.to_string());
}
js.set("vars", jsa);
}
},
_ => ()
}
match tx.community {
Some(ref c) => js.set_string("community", c),
_ => ()
}
match tx.usm {
Some(ref s) => js.set_string("usm", s),
_ => ()
}
}
js.unwrap()
}
24 changes: 24 additions & 0 deletions rust/src/snmp/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Copyright (C) 2017-2018 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.
*/

// written by Pierre Chifflier <[email protected]>

extern crate snmp_parser;

pub mod snmp;
pub mod log;
pub mod detect;
Loading