mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-30 09:29:27 -07:00
add incomplete sib heuristic
This commit is contained in:
committed by
Will Greenberg
parent
07d43b5924
commit
fd216ecb72
@@ -195,6 +195,18 @@
|
||||
NAS Null Cipher Heuristic
|
||||
</label>
|
||||
</div>
|
||||
j
|
||||
<div class="flex items-center">
|
||||
<input
|
||||
id="incomplete_sib"
|
||||
type="checkbox"
|
||||
bind:checked={config.analyzers.incomplete_sib}
|
||||
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded"
|
||||
/>
|
||||
<label for="nas_null_cipher" class="ml-2 block text-sm text-gray-700">
|
||||
Incomplete SIB Heuristic
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ export interface AnalyzerConfig {
|
||||
lte_sib6_and_7_downgrade: boolean;
|
||||
null_cipher: boolean;
|
||||
nas_null_cipher: boolean;
|
||||
incomplete_sib: boolean;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
|
||||
1
dist/config.toml.in
vendored
1
dist/config.toml.in
vendored
@@ -31,3 +31,4 @@ connection_redirect_2g_downgrade = true
|
||||
lte_sib6_and_7_downgrade = true
|
||||
null_cipher = true
|
||||
nas_null_cipher = true
|
||||
incomplete_sib = true
|
||||
|
||||
@@ -21,3 +21,4 @@ Rayhunter includes several analyzers to detect potential IMSI catcher activity.
|
||||
which include 2G/3G frequencies with higher priorities
|
||||
- **Null Cipher**: Tests whether the cell suggests using a null cipher (EEA0) in the RRC layer.
|
||||
- **NAS Null Cipher**: Tests whether the security mode command at the NAS layer suggests using a null cipher (EEA0). This would usually only happen after a UE has successfully authenticated with the MME but still it shouldn't happen at all, this could be indicative of an attack though using SS7 to get key material from the HLR of the UE for a succesful authentication. It could also indicate an IMSI catcher which is connected to the mobile network MME and HLR through cooperation between government and telco. Or it could be a false positive if the telco is intending to use null ciphers (if encryption is illegal or something.)
|
||||
- **Incomplete SIB**: Tests whether the Sib1 message contains a complete SIB chain (sib3, sib5, etc.) A legitimate SIB1 should contain timing information for at least 2 additional sibs (sib3, 4, and 5 being the most common) but a fake base station will often not bother to send additional SIBs beyond 1 and 2. On its own this might just be a misconfigured base station (though we have only seen it in the wild under suspicious circumstances) but combined with other heuristics such as **ISMI Requested** detection it should be considered a strong indicator of malicious activity.
|
||||
@@ -9,9 +9,9 @@ use crate::{diag::MessagesContainer, gsmtap_parser};
|
||||
|
||||
use super::{
|
||||
connection_redirect_downgrade::ConnectionRedirect2GDowngradeAnalyzer,
|
||||
imsi_requested::ImsiRequestedAnalyzer, information_element::InformationElement,
|
||||
nas_null_cipher::NasNullCipherAnalyzer, null_cipher::NullCipherAnalyzer,
|
||||
priority_2g_downgrade::LteSib6And7DowngradeAnalyzer,
|
||||
imsi_requested::ImsiRequestedAnalyzer, incomplete_sib::IncompleteSibAnalyzer,
|
||||
information_element::InformationElement, nas_null_cipher::NasNullCipherAnalyzer,
|
||||
null_cipher::NullCipherAnalyzer, priority_2g_downgrade::LteSib6And7DowngradeAnalyzer,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
@@ -22,6 +22,7 @@ pub struct AnalyzerConfig {
|
||||
pub lte_sib6_and_7_downgrade: bool,
|
||||
pub null_cipher: bool,
|
||||
pub nas_null_cipher: bool,
|
||||
pub incomplete_sib: bool,
|
||||
}
|
||||
|
||||
impl Default for AnalyzerConfig {
|
||||
@@ -32,6 +33,7 @@ impl Default for AnalyzerConfig {
|
||||
lte_sib6_and_7_downgrade: true,
|
||||
null_cipher: true,
|
||||
nas_null_cipher: true,
|
||||
incomplete_sib: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,6 +171,10 @@ impl Harness {
|
||||
harness.add_analyzer(Box::new(NasNullCipherAnalyzer::new()))
|
||||
}
|
||||
|
||||
if analyzer_config.incomplete_sib {
|
||||
harness.add_analyzer(Box::new(IncompleteSibAnalyzer::new()))
|
||||
}
|
||||
|
||||
harness
|
||||
}
|
||||
|
||||
|
||||
68
lib/src/analysis/incomplete_sib.rs
Normal file
68
lib/src/analysis/incomplete_sib.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use telcom_parser::lte_rrc::{BCCH_DL_SCH_MessageType, BCCH_DL_SCH_MessageType_c1};
|
||||
|
||||
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
||||
use super::information_element::{InformationElement, LteInformationElement};
|
||||
|
||||
pub struct IncompleteSibAnalyzer {
|
||||
packet_num: usize,
|
||||
}
|
||||
|
||||
impl Default for IncompleteSibAnalyzer {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl IncompleteSibAnalyzer {
|
||||
pub fn new() -> Self {
|
||||
Self { packet_num: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Analyzer for IncompleteSibAnalyzer {
|
||||
fn get_name(&self) -> Cow<str> {
|
||||
Cow::from("Incomplete SIB")
|
||||
}
|
||||
|
||||
fn get_description(&self) -> Cow<str> {
|
||||
Cow::from("Tests whether a SIB1 message contains a full chain of followup sibs")
|
||||
}
|
||||
|
||||
fn get_version(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
fn analyze_information_element(&mut self, ie: &InformationElement) -> Option<Event> {
|
||||
self.packet_num += 1;
|
||||
|
||||
let sch_msg = match ie {
|
||||
InformationElement::LTE(lte_ie) => match &**lte_ie {
|
||||
LteInformationElement::BcchDlSch(sch_msg) => sch_msg,
|
||||
_ => return None,
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
let BCCH_DL_SCH_MessageType::C1(BCCH_DL_SCH_MessageType_c1::SystemInformationBlockType1(
|
||||
sib1,
|
||||
)) = &sch_msg.message
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if sib1.scheduling_info_list.0.len() < 2 {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::Medium,
|
||||
},
|
||||
message: format!(
|
||||
"SIB1 scheduling info list was malformed (packet {})",
|
||||
self.packet_num
|
||||
)
|
||||
.to_string(),
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod analyzer;
|
||||
pub mod connection_redirect_downgrade;
|
||||
pub mod imsi_requested;
|
||||
pub mod incomplete_sib;
|
||||
pub mod information_element;
|
||||
pub mod nas_null_cipher;
|
||||
pub mod null_cipher;
|
||||
|
||||
Reference in New Issue
Block a user