mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-07-18 05:48:10 -07:00
lib: Use pycrate-rs NAS parser
This commit is contained in:
committed by
Cooper Quintin
parent
deeab1f1b0
commit
2e4de4a2df
Generated
+14
@@ -2220,6 +2220,19 @@ dependencies = [
|
|||||||
"syn 2.0.101",
|
"syn 2.0.101",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pycrate-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/wgreenberg/pycrate-rs#9e72e40bee9c3c09205ad871cf681628b443de7c"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"deku",
|
||||||
|
"env_logger 0.11.8",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "qoi"
|
name = "qoi"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -2378,6 +2391,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
"pcap-file-tokio",
|
"pcap-file-tokio",
|
||||||
|
"pycrate-rs",
|
||||||
"serde",
|
"serde",
|
||||||
"telcom-parser",
|
"telcom-parser",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ libc = "0.2.150"
|
|||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
nix = { version = "0.29.0", features = ["feature"] }
|
nix = { version = "0.29.0", features = ["feature"] }
|
||||||
pcap-file-tokio = "0.1.0"
|
pcap-file-tokio = "0.1.0"
|
||||||
|
pycrate-rs = { git = "https://github.com/wgreenberg/pycrate-rs" }
|
||||||
thiserror = "1.0.50"
|
thiserror = "1.0.50"
|
||||||
telcom-parser = { path = "../telcom-parser" }
|
telcom-parser = { path = "../telcom-parser" }
|
||||||
tokio = { version = "1.44.2", default-features = false }
|
tokio = { version = "1.44.2", default-features = false }
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
use std::any::Any;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use pycrate_rs::nas::emm::EMMMessage;
|
||||||
|
use pycrate_rs::nas::generated::emm::emm_identity_request::{EMMIdentityRequest, IDTypeV};
|
||||||
|
use pycrate_rs::nas::NASMessage;
|
||||||
|
|
||||||
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
||||||
use super::information_element::{InformationElement, LteInformationElement};
|
use super::information_element::{InformationElement, LteInformationElement};
|
||||||
|
|
||||||
@@ -41,30 +46,32 @@ impl Analyzer for ImsiRequestedAnalyzer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// NAS identity request, ID type IMSI
|
// NAS identity request, ID type IMSI
|
||||||
if payload == &[0x07, 0x55, 0x01] {
|
if let NASMessage::EMMMessage(EMMMessage::EMMIdentityRequest(req)) = payload {
|
||||||
if self.packet_num < PACKET_THRESHHOLD {
|
if req.id_type.inner == IDTypeV::IMSI {
|
||||||
return Some(Event {
|
if self.packet_num < PACKET_THRESHHOLD {
|
||||||
event_type: EventType::QualitativeWarning {
|
return Some(Event {
|
||||||
severity: Severity::Medium,
|
event_type: EventType::QualitativeWarning {
|
||||||
},
|
severity: Severity::Medium,
|
||||||
message: format!(
|
},
|
||||||
"NAS IMSI identity request detected, however it was within \
|
message: format!(
|
||||||
the first {} packets of this analysis. If you just \
|
"NAS IMSI identity request detected, however it was within \
|
||||||
turned your device on, this is likely a \
|
the first {} packets of this analysis. If you just \
|
||||||
false-positive.",
|
turned your device on, this is likely a \
|
||||||
PACKET_THRESHHOLD
|
false-positive.",
|
||||||
),
|
PACKET_THRESHHOLD
|
||||||
});
|
),
|
||||||
} else {
|
});
|
||||||
return Some(Event {
|
} else {
|
||||||
event_type: EventType::QualitativeWarning {
|
return Some(Event {
|
||||||
severity: Severity::High,
|
event_type: EventType::QualitativeWarning {
|
||||||
},
|
severity: Severity::High,
|
||||||
message: format!(
|
},
|
||||||
"NAS IMSI identity request detected (packet {})",
|
message: format!(
|
||||||
self.packet_num
|
"NAS IMSI identity request detected (packet {})",
|
||||||
),
|
self.packet_num
|
||||||
});
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -5,17 +5,20 @@
|
|||||||
|
|
||||||
use crate::gsmtap::{GsmtapMessage, GsmtapType, LteNasSubtype, LteRrcSubtype};
|
use crate::gsmtap::{GsmtapMessage, GsmtapType, LteNasSubtype, LteRrcSubtype};
|
||||||
use telcom_parser::{decode, lte_rrc};
|
use telcom_parser::{decode, lte_rrc};
|
||||||
|
use pycrate_rs::nas::NASMessage;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum InformationElementError {
|
pub enum InformationElementError {
|
||||||
#[error("Failed decoding")]
|
#[error("Failed decoding RRC message")]
|
||||||
DecodingError(#[from] telcom_parser::ParsingError),
|
RRCDecodingError(#[from] telcom_parser::ParsingError),
|
||||||
|
#[error("Failed decoding NAS message")]
|
||||||
|
NASDecodingError(#[from] pycrate_rs::nas::ParseError),
|
||||||
#[error("Unsupported LTE RRC subtype {0:?}")]
|
#[error("Unsupported LTE RRC subtype {0:?}")]
|
||||||
UnsupportedGsmtapType(GsmtapType),
|
UnsupportedGsmtapType(GsmtapType),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum InformationElement {
|
pub enum InformationElement {
|
||||||
GSM,
|
GSM,
|
||||||
UMTS,
|
UMTS,
|
||||||
@@ -25,7 +28,7 @@ pub enum InformationElement {
|
|||||||
FiveG,
|
FiveG,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum LteInformationElement {
|
pub enum LteInformationElement {
|
||||||
DlCcch(lte_rrc::DL_CCCH_Message),
|
DlCcch(lte_rrc::DL_CCCH_Message),
|
||||||
// This element of the enum is substantially larger than the others,
|
// This element of the enum is substantially larger than the others,
|
||||||
@@ -44,8 +47,7 @@ pub enum LteInformationElement {
|
|||||||
SbcchSlBch(lte_rrc::SBCCH_SL_BCH_Message),
|
SbcchSlBch(lte_rrc::SBCCH_SL_BCH_Message),
|
||||||
SbcchSlBchV2x(lte_rrc::SBCCH_SL_BCH_Message_V2X_r14),
|
SbcchSlBchV2x(lte_rrc::SBCCH_SL_BCH_Message_V2X_r14),
|
||||||
|
|
||||||
// FIXME: actually parse NAS messages
|
NAS(NASMessage),
|
||||||
NAS(Vec<u8>),
|
|
||||||
// FIXME: unclear which message these "NB" types map to
|
// FIXME: unclear which message these "NB" types map to
|
||||||
//DlCcchNb(),
|
//DlCcchNb(),
|
||||||
//DlDcchNb(),
|
//DlDcchNb(),
|
||||||
@@ -89,9 +91,10 @@ impl TryFrom<&GsmtapMessage> for InformationElement {
|
|||||||
};
|
};
|
||||||
Ok(InformationElement::LTE(Box::new(lte)))
|
Ok(InformationElement::LTE(Box::new(lte)))
|
||||||
}
|
}
|
||||||
GsmtapType::LteNas(LteNasSubtype::Plain) => Ok(InformationElement::LTE(Box::new(
|
GsmtapType::LteNas(LteNasSubtype::Plain) => {
|
||||||
LteInformationElement::NAS(gsmtap_msg.payload.clone()),
|
let msg = NASMessage::parse(&gsmtap_msg.payload)?;
|
||||||
))),
|
Ok(InformationElement::LTE(Box::new(LteInformationElement::NAS(msg))))
|
||||||
|
}
|
||||||
_ => Err(InformationElementError::UnsupportedGsmtapType(
|
_ => Err(InformationElementError::UnsupportedGsmtapType(
|
||||||
gsmtap_msg.header.gsmtap_type,
|
gsmtap_msg.header.gsmtap_type,
|
||||||
)),
|
)),
|
||||||
|
|||||||
Reference in New Issue
Block a user