Skip to content

Commit

Permalink
whitelisting inital (probably buggy) push
Browse files Browse the repository at this point in the history
  • Loading branch information
Ragnt committed Jan 17, 2024
1 parent 23c1a6a commit 06c3c5a
Show file tree
Hide file tree
Showing 6 changed files with 429 additions and 20 deletions.
28 changes: 28 additions & 0 deletions src/attack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub fn csa_attack(oxide: &mut OxideRuntime, beacon: Beacon) -> Result<(), String
return Ok(());
}

if oxide.target_data.whitelist.is_whitelisted(ap_data) {
return Ok(());
}

// If we already have a 4whs, don't continue.
if oxide
.handshake_storage
Expand Down Expand Up @@ -111,6 +115,10 @@ pub fn m1_retrieval_attack(oxide: &mut OxideRuntime, ap_mac: &MacAddress) -> Res
return Ok(());
}

if oxide.target_data.whitelist.is_whitelisted(ap_data) {
return Ok(());
}

// If we already have a 4whs, don't continue.
if oxide
.handshake_storage
Expand Down Expand Up @@ -182,6 +190,10 @@ pub fn m1_retrieval_attack_phase_2(
return Ok(());
}

if oxide.target_data.whitelist.is_whitelisted(ap_data) {
return Ok(());
}

// Is our sequence state 1?
if ap_data.auth_sequence.state != 1 {
return Ok(());
Expand Down Expand Up @@ -252,6 +264,10 @@ pub fn deauth_attack(oxide: &mut OxideRuntime, ap_mac: &MacAddress) -> Result<()
return Ok(());
}

if oxide.target_data.whitelist.is_whitelisted(ap_data) {
return Ok(());
}

if oxide
.handshake_storage
.has_complete_handshake_for_ap(ap_mac)
Expand Down Expand Up @@ -356,6 +372,10 @@ pub fn anon_reassociation_attack(
return Ok(());
}

if oxide.target_data.whitelist.is_whitelisted(ap) {
return Ok(());
}

let pcs = if ap.information.cs_ccmp.is_some_and(|x| x) {
RsnCipherSuite::CCMP
} else if ap.information.cs_tkip.is_some_and(|x| x) {
Expand Down Expand Up @@ -434,6 +454,10 @@ pub fn rogue_m2_attack_directed(

// If we have an AP for this SSID, we will use as many of the same details as possible
if let Some(ap) = oxide.access_points.get_device_by_ssid(&ssid) {
if oxide.target_data.whitelist.is_whitelisted(ap) {
return Ok(());
}

// Make sure this AP is a target and that this AP is
if !oxide.target_data.targets.is_target(ap)
|| oxide
Expand Down Expand Up @@ -498,6 +522,10 @@ pub fn rogue_m2_attack_undirected(
{
return Ok(());
}

if oxide.target_data.whitelist.is_whitelisted(ap) {
return Ok(());
}
}

// Do we already have a rogue-M2 from this station (for this SSID)
Expand Down
29 changes: 27 additions & 2 deletions src/devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ pub struct AccessPoint {
pub has_hs: bool,
pub has_pmkid: bool,
pub is_target: bool,
pub is_whitelisted: bool,
}

impl WiFiDeviceType for AccessPoint {}
Expand All @@ -124,6 +125,7 @@ impl Default for AccessPoint {
has_hs: false,
has_pmkid: false,
is_target: false,
is_whitelisted: false,
}
}
}
Expand Down Expand Up @@ -167,6 +169,7 @@ impl AccessPoint {
has_hs: false,
has_pmkid: false,
is_target: false,
is_whitelisted: false,
}
}

Expand Down Expand Up @@ -208,6 +211,7 @@ impl AccessPoint {
has_hs: false,
has_pmkid: false,
is_target: false,
is_whitelisted: false,
}
}

Expand Down Expand Up @@ -241,6 +245,11 @@ impl AccessPoint {
pub fn is_target(&self) -> bool {
self.is_target
}

pub fn is_whitelisted(&self) -> bool {
self.is_whitelisted
}

}

#[derive(Clone, Debug, Default)]
Expand Down Expand Up @@ -566,7 +575,23 @@ impl WiFiDeviceList<AccessPoint> {
.map(|(_, access_point)| access_point)
.collect();
match sort {
0 => access_points.sort_by_key(|b| std::cmp::Reverse(b.is_target())), // TGT
0 => access_points.sort_by(|a, b| { // TGT
match (a.is_target(), a.is_whitelisted(), b.is_target(), b.is_whitelisted()) {
// Highest priority: is_target() = true, is_whitelist() = false
(true, false, _, _) => std::cmp::Ordering::Less,
(_, _, true, false) => std::cmp::Ordering::Greater,

// Middle priority: is_target() = false, is_whitelist() = false
(false, false, false, true) => std::cmp::Ordering::Less,
(false, true, false, false) => std::cmp::Ordering::Greater,

// Lowest priority: is_target() = false, is_whitelist() = true
// This case is covered implicitly by the previous matches

// Fallback for equal cases
_ => std::cmp::Ordering::Equal,
}
}),
1 => access_points.sort_by(|a, b| b.channel.cmp(&a.channel)), // CH
2 => access_points.sort_by(|a, b| {
// RSSI
Expand Down Expand Up @@ -602,7 +627,7 @@ impl WiFiDeviceList<AccessPoint> {
let mut rows: Vec<(Vec<String>, u16)> = Vec::new();
for (idx, ap) in access_points.iter().enumerate() {
let mut ap_row = vec![
format!("{}", if ap.is_target() { "\u{274E}" } else { "" }), // TGT
format!("{}", if ap.is_target() { "\u{274E}" } else if ap.is_whitelisted() { "\u{2B1C}" } else { "" }), // TGT
format!("{}", ap.mac_address), // MAC Address
ap.channel
.as_ref()
Expand Down
104 changes: 98 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod snowstorm;
mod status;
mod tabbedblock;
mod targets;
mod whitelist;
mod tx;
mod ui;
mod util;
Expand Down Expand Up @@ -42,7 +43,7 @@ use nix::unistd::geteuid;

use nl80211_ng::attr::Nl80211Iftype;
use nl80211_ng::channels::{map_str_to_band_and_channel, WiFiBand, WiFiChannel};
use nl80211_ng::{set_interface_chan, Interface, Nl80211};
use nl80211_ng::{set_interface_chan, Interface, Nl80211, get_interface_info_idx};

use flate2::write::GzEncoder;
use flate2::Compression;
Expand All @@ -64,6 +65,7 @@ use tx::{
};
use ui::UiState;
use uuid::Uuid;
use whitelist::WhiteList;

use crate::ascii::get_art;
use crate::auth::HandshakeStorage;
Expand All @@ -74,6 +76,7 @@ use crate::snowstorm::Snowstorm;
use crate::status::*;
use crate::ui::{print_ui, MenuType};
use crate::util::parse_ip_address_port;
use crate::whitelist::{White, WhiteMAC, WhiteSSID};

use libwifi::{Addresses, Frame};

Expand Down Expand Up @@ -113,6 +116,9 @@ struct Arguments {
/// Optional - Target (MAC or SSID) to attack - will attack everything if none specified.
target: Option<Vec<String>>,
#[arg(short, long)]
/// Optional - Whitelist (MAC or SSID) to NOT attack.
whitelist: Option<Vec<String>>,
#[arg(short, long)]
/// Optional - Output filename.
output: Option<String>,
#[arg(short, long)]
Expand Down Expand Up @@ -228,6 +234,7 @@ pub struct IfHardware {
}

pub struct TargetData {
whitelist: WhiteList,
targets: TargetList,
rogue_client: MacAddress,
rogue_m1: EapolKey,
Expand Down Expand Up @@ -264,6 +271,7 @@ impl OxideRuntime {
let rogue = cli_args.rogue.clone();
let interface_name = cli_args.interface.clone();
let targets = cli_args.target.clone();
let wh_list = cli_args.whitelist.clone();
let mut notransmit = cli_args.notransmit.clone();

// Setup initial lists / logs
Expand Down Expand Up @@ -339,6 +347,61 @@ impl OxideRuntime {

let targ_list = TargetList::from_vec(target_vec.clone());

// Setup Whitelist
let whitelist_vec: Vec<White> = if let Some(vec_whitelist) = wh_list {
vec_whitelist
.into_iter()
.filter_map(|f| {
match MacAddress::from_str(&f) {
Ok(mac) => {
if targ_list.is_target_mac(&mac) {
println!("Whitelist {} is a target. Cannot add to whitelist.", mac);
None
} else {
Some(White::MAC(WhiteMAC::new(mac)))
}
},
Err(_) => {
if targ_list.is_target_ssid(&f) {
println!("Whitelist {} is a target. Cannot add to whitelist.", f);
None
} else {
Some(White::SSID(WhiteSSID::new(&f)))
}
},
}
})
.collect()
} else {
vec![]
};

if !whitelist_vec.is_empty() {
println!();
println!("========= White List =========");
for (index, device) in whitelist_vec.iter().enumerate() {
let tree = if index == whitelist_vec.len() - 1 {
"└"
} else {
"├"
};
match device {
White::MAC(dev) => {
println!(" {} MAC: {}", tree, dev.addr)
}
White::SSID(dev) => {
println!(" {} SSID: {}", tree, dev.ssid)
}
}
}
println!("========== Total: {:<2} ==========", whitelist_vec.len());
println!();
} else {
println!("💲 No whitelist list provided.");
}

let white_list = WhiteList::from_vec(whitelist_vec.clone());

/////////////////////////////////////////////////////////////////////

//// Setup Channels ////
Expand Down Expand Up @@ -698,6 +761,7 @@ impl OxideRuntime {
};

let target_data: TargetData = TargetData {
whitelist: white_list,
targets: targ_list,
rogue_client,
rogue_m1,
Expand Down Expand Up @@ -927,20 +991,30 @@ fn process_frame(oxide: &mut OxideRuntime, packet: &[u8]) -> Result<(), String>
),
);

// Proliferate whitelist
let _ = oxide.target_data.whitelist.get_whitelisted(ap);

// Proliferate the SSID / MAC to targets (if this is a target)
// Also handle adding the target channel to autohunt params.
if let Ok(targets) = oxide.target_data.targets.get_targets(ap) {

let targets = oxide.target_data.targets.get_targets(ap);
if !targets.is_empty() {
// This is a target_data target
if let Some(channel) = station_info.ds_parameter_set {
// We have a channel in the broadcast (real channel)
if oxide.config.autohunt
&& oxide
.if_hardware
.hop_channels
.contains(&(band.to_u8(), channel))
{
// We are autohunting and our current channel is real (band/channel match)
for target in targets {
// Go through all the target matches we got (which could be a Glob SSID, Match SSID, and MAC!)
if let Some(vec) =
oxide.if_hardware.target_chans.get_mut(&target)
{
// This target is inside hop_chans
// Update the target with this band/channel (if it isn't already there)
if !vec.contains(&(band.to_u8(), channel)) {
vec.push((band.to_u8(), channel));
Expand Down Expand Up @@ -1121,9 +1195,15 @@ fn process_frame(oxide: &mut OxideRuntime, packet: &[u8]) -> Result<(), String>
oxide.target_data.rogue_client,
),
);

// Proliferate whitelist
let _ = oxide.target_data.whitelist.get_whitelisted(ap);

// Proliferate the SSID / MAC to targets (if this is a target)
// Also handle adding the target channel to autohunt params.
if let Ok(targets) = oxide.target_data.targets.get_targets(ap) {

let targets = oxide.target_data.targets.get_targets(ap);
if !targets.is_empty() {
// This is a target_data target
if let Some(channel) = station_info.ds_parameter_set {
// We have a channel in the broadcast (real channel)
Expand Down Expand Up @@ -2275,7 +2355,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let start_time = Instant::now();

let mut err: Option<ErrorKind> = None;
let mut err: Option<String> = None;
let mut exit_on_succ = false;
let mut terminal =
Terminal::new(CrosstermBackend::new(stdout())).expect("Cannot allocate terminal");
Expand All @@ -2296,6 +2376,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}

while running.load(Ordering::SeqCst) {
// Update our interface
oxide.if_hardware.interface = match get_interface_info_idx(oxide.if_hardware.interface.index.unwrap()) {
Ok(interface) => interface,
Err(e) => {
// Uh oh... no interface
err = Some(e);
running.store(false, Ordering::SeqCst);
break;
}
};


// Handle Hunting
let target_chans = oxide.if_hardware.target_chans.clone();
if oxide.config.autohunt
Expand Down Expand Up @@ -2462,8 +2554,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
Err(code) => {
// This will result in "a serious packet read error" message.
err = Some(code.kind());
running.store(false, Ordering::SeqCst);
// err = Some(code.kind());
// running.store(false, Ordering::SeqCst);
}
};

Expand Down
Loading

0 comments on commit 06c3c5a

Please sign in to comment.