Skip to content

Commit

Permalink
Merge pull request #20 from Ragnt/dev
Browse files Browse the repository at this point in the history
Merge Dev to v0.8.5
  • Loading branch information
Ragnt authored Feb 10, 2024
2 parents 220523d + d42efd7 commit f39e312
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 234 deletions.
217 changes: 117 additions & 100 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
members = ["libs/libwifi", "libs/libwifi_macros", "libs/pcap-file"]

[workspace.package]
version = "0.8.3"
version = "0.8.5"
authors = ["Ryan Butler"]
description = "80211 Attack Tool"
license = "MIT"
Expand All @@ -24,7 +24,7 @@ path = "src/main.rs"
[dependencies]
libwifi = { version = "0.3.1", path = "libs/libwifi" }
pcap-file = { version = "2.0.0", path = "libs/pcap-file" }
nl80211-ng = "0.2.7"
nl80211-ng = "0.2.9"
byteorder = "1.5.0"
libc = "0.2.149"
nix = { version = "0.27.1", features = [
Expand Down
2 changes: 1 addition & 1 deletion libs/libwifi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod frame;
/// Enums representing frame types and frame subtypes.
mod frame_types;
/// [nom] parsers for internal usage.
mod parsers;
pub mod parsers;
/// All traits used or provided by this library.
mod traits;

Expand Down
2 changes: 1 addition & 1 deletion libs/libwifi/src/parsers/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod station_info;
pub use frame_control::parse_frame_control;
pub use header::*;
pub use sequence_control::parse_sequence_control;
pub use station_info::parse_station_info;
pub use station_info::{parse_rsn_information, parse_station_info};

/// Parse mac addresses.
/// Just take 6 bytes, clone them and create a new MacAddress struct from those bytes.
Expand Down
4 changes: 1 addition & 3 deletions libs/libwifi/src/parsers/components/station_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ use crate::frame::components::{
WpaAkmSuite, WpaCipherSuite, WpaInformation, WpsInformation, WpsSetupState,
};



/// Parse variable length and variable field information.
/// The general structure of the data looks like this:
///
Expand Down Expand Up @@ -379,7 +377,7 @@ fn parse_string_from_bytes(data: &[u8]) -> Result<String, &'static str> {
}
}

fn parse_rsn_information(data: &[u8]) -> Result<RsnInformation, &'static str> {
pub fn parse_rsn_information(data: &[u8]) -> Result<RsnInformation, &'static str> {
if data.len() < 10 {
return Err("RSN Information data too short");
}
Expand Down
70 changes: 49 additions & 21 deletions src/attack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{

use libwifi::{
frame::{
components::{MacAddress, RsnCipherSuite},
components::{MacAddress, RsnAkmSuite, RsnCipherSuite, RsnInformation},
Beacon, DeauthenticationReason, ProbeRequest,
},
parse_frame, Addresses, Frame,
Expand All @@ -19,8 +19,8 @@ use crate::{
tx::{
build_association_request_rg, build_authentication_frame_noack, build_csa_beacon,
build_deauthentication_fm_ap, build_deauthentication_fm_client,
build_disassocation_from_ap, build_disassocation_from_client,
build_probe_response, build_reassociation_request,
build_disassocation_from_ap, build_disassocation_from_client, build_probe_response,
build_reassociation_request,
},
write_packet, OxideRuntime,
};
Expand Down Expand Up @@ -145,7 +145,7 @@ pub fn disassoc_attack(oxide: &mut OxideRuntime, ap_mac: &MacAddress) -> Result<
if ap_data
.channel
.clone()
.is_some_and(|f| f.get_band() == WiFiBand::Band6GHz)
.is_some_and(|f| f.0 == WiFiBand::Band6GHz)
{
let frx = build_disassocation_from_ap(
ap_mac,
Expand Down Expand Up @@ -473,20 +473,49 @@ pub fn anon_reassociation_attack(
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) {
RsnCipherSuite::TKIP
let rsn = if ap
.pr_station
.clone()
.is_some_and(|station| station.rsn_information.is_some())
{
ap.pr_station
.clone()
.unwrap()
.rsn_information
.unwrap()
.clone()
} else {
return Ok(());
};
let pairwise_cipher_suites = if ap.information.cs_ccmp.is_some_and(|x| x) {
vec![RsnCipherSuite::CCMP]
} else if ap.information.cs_tkip.is_some_and(|x| x) {
vec![RsnCipherSuite::TKIP]
} else {
return Ok(());
};

let gcs = if ap.information.gs_ccmp.is_some_and(|x| x) {
RsnCipherSuite::CCMP
} else if ap.information.gs_tkip.is_some_and(|x| x) {
RsnCipherSuite::TKIP
} else {
return Ok(());
let group_cipher_suite = if ap.information.gs_ccmp.is_some_and(|x| x) {
RsnCipherSuite::CCMP
} else if ap.information.gs_tkip.is_some_and(|x| x) {
RsnCipherSuite::TKIP
} else {
return Ok(());
};
RsnInformation {
version: 1,
group_cipher_suite,
pairwise_cipher_suites,
akm_suites: vec![RsnAkmSuite::PSK],
mfp_required: false,
pre_auth: false,
no_pairwise: false,
ptksa_replay_counter: 0,
gtksa_replay_counter: 0,
mfp_capable: true,
joint_multi_band_rsna: false,
peerkey_enabled: false,
extended_key_id: false,
ocvc: false,
}
};

// Send a (anonymous) reassociation request to the AP
Expand All @@ -495,8 +524,7 @@ pub fn anon_reassociation_attack(
&MacAddress::broadcast(),
ap.ssid.clone(),
oxide.counters.sequence3(),
gcs,
vec![pcs],
rsn,
);
let _ = write_packet(oxide.raw_sockets.tx_socket.as_raw_fd(), &frx);

Expand Down Expand Up @@ -570,7 +598,7 @@ pub fn rogue_m2_attack_directed(
&probe.header.address_1,
&ssid,
oxide.counters.sequence3(),
oxide.if_hardware.current_channel.get_channel_number(),
oxide.if_hardware.current_channel.try_into().unwrap(),
);
write_packet(oxide.raw_sockets.tx_socket.as_raw_fd(), &frx)?;
station.interactions += 1;
Expand Down Expand Up @@ -635,7 +663,7 @@ pub fn rogue_m2_attack_undirected(
&oxide.target_data.rogue_client,
&ssid,
oxide.counters.sequence3(),
oxide.if_hardware.current_channel.get_channel_number(),
oxide.if_hardware.current_channel,
);
write_packet(oxide.raw_sockets.tx_socket.as_raw_fd(), &frx)?;
station.interactions += 1;
Expand Down Expand Up @@ -671,7 +699,7 @@ pub fn rogue_m2_attack_undirected(
&oxide.target_data.rogue_client,
&ap.ssid.clone().unwrap(),
oxide.counters.sequence3(),
oxide.if_hardware.current_channel.get_channel_number(),
oxide.if_hardware.current_channel,
);
write_packet(oxide.raw_sockets.tx_socket.as_raw_fd(), &frx)?;

Expand Down
37 changes: 33 additions & 4 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ use std::{

use chrono::{DateTime, Local};

use libwifi::frame::{components::MacAddress, EapolKey, MessageType, Pmkid};
use libwifi::frame::{
components::{MacAddress, RsnAkmSuite},
EapolKey, MessageType, Pmkid,
};

use libwifi::parsers::parse_rsn_information;

use crate::util::{eapol_to_json_str, slice_to_hex_string, system_time_to_iso8601};

Expand All @@ -18,6 +23,7 @@ pub struct FourWayHandshake {
pub msg4: Option<EapolKey>,
pub last_msg: Option<EapolKey>,
pub eapol_client: Option<Vec<u8>>,
pub rsn_type: Option<Vec<RsnAkmSuite>>,
pub mic: Option<[u8; 16]>,
pub anonce: Option<[u8; 32]>,
pub snonce: Option<[u8; 32]>,
Expand Down Expand Up @@ -72,6 +78,7 @@ impl FourWayHandshake {
msg4: None,
last_msg: None,
eapol_client: None,
rsn_type: None,
mic: None,
anonce: None,
snonce: None,
Expand Down Expand Up @@ -178,6 +185,17 @@ impl FourWayHandshake {
|| self.has_pmkid()
}

pub fn is_wpa3(&self) -> bool {
if let Some(rsn) = self.rsn_type.clone() {
if rsn == vec![RsnAkmSuite::SAE] {
return true;
} else {
return false;
}
}
false
}

pub fn written(&self) -> bool {
self.written
}
Expand Down Expand Up @@ -250,7 +268,11 @@ impl FourWayHandshake {
};

tuple.5 = if self.complete() {
"\u{2705}".to_string()
if self.is_wpa3() {
"\u{274c}".to_string() // Display a red X if it is SAE
} else {
"\u{2705}".to_string() // Display a check if we don't knoww if it's SAE
}
} else {
"--".to_string()
};
Expand Down Expand Up @@ -334,6 +356,7 @@ impl FourWayHandshake {
if let Ok(pmkid) = new_key.has_pmkid() {
self.pmkid = Some(pmkid)
};

// Only update the anonce if there isn't one, because if we have one we have a msg3 already.
if self.anonce.is_none() {
self.anonce = Some(new_key.key_nonce);
Expand Down Expand Up @@ -379,6 +402,12 @@ impl FourWayHandshake {
self.nc = true;
}

if let Ok(rsn_info) = parse_rsn_information(&new_key.key_data[2..]) {
self.rsn_type = Some(rsn_info.akm_suites);
} else {
return Err("RSN Not Parsed");
}

self.snonce = Some(new_key.key_nonce);
self.msg2 = Some(new_key.clone());
self.last_msg = Some(new_key.clone());
Expand Down Expand Up @@ -507,9 +536,9 @@ impl FourWayHandshake {
}
}

if !self.complete() && output.is_empty() {
if !self.has_4whs() && output.is_empty() {
return None;
} else if !self.complete() && !output.is_empty() {
} else if !self.has_4whs() && !output.is_empty() {
return Some(output);
}

Expand Down
24 changes: 14 additions & 10 deletions src/devices.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use globset::Glob;
use libwifi::frame::components::{MacAddress, WpsInformation};
use nl80211_ng::channels::{WiFiBand, WiFiChannel};
use libwifi::frame::components::{MacAddress, StationInfo, WpsInformation};
use nl80211_ng::channels::{WiFiBand};
use radiotap::field::{AntennaSignal, Field};
use rand::seq::IteratorRandom;
use rand::thread_rng;
Expand Down Expand Up @@ -89,9 +89,10 @@ pub struct AccessPoint {
pub last_recv: u64,
pub interactions: u64,
pub ssid: Option<String>,
pub channel: Option<WiFiChannel>,
pub channel: Option<(WiFiBand, u32)>,
pub client_list: WiFiDeviceList<Station>,
pub information: APFlags,
pub pr_station: Option<StationInfo>,
pub beacon_count: u32,
pub auth_sequence: AuthSequence,
pub has_hs: bool,
Expand Down Expand Up @@ -121,6 +122,7 @@ impl Default for AccessPoint {
channel: None,
client_list: WiFiDeviceList::default(),
information: APFlags::default(),
pr_station: None,
beacon_count: 0,
auth_sequence: AuthSequence::new(MacAddress([255, 255, 255, 255, 255, 255])),
has_hs: false,
Expand All @@ -137,7 +139,7 @@ impl AccessPoint {
mac_address: MacAddress,
last_signal_strength: AntennaSignal,
ssid: Option<String>,
channel: Option<(WiFiBand, u8)>,
channel: Option<(WiFiBand, u32)>,
information: Option<APFlags>,
rogue_mac: MacAddress,
wps_data: Option<WpsInformation>,
Expand All @@ -150,7 +152,7 @@ impl AccessPoint {
.as_secs();

let chan = if let Some(channel) = channel {
WiFiChannel::new(channel.1, channel.0)
Some((channel.0, channel.1))
} else {
None
};
Expand All @@ -170,6 +172,7 @@ impl AccessPoint {
} else {
APFlags::default()
},
pr_station: None,
auth_sequence: AuthSequence::new(rogue_mac),
has_hs: false,
has_pmkid: false,
Expand All @@ -183,7 +186,7 @@ impl AccessPoint {
mac_address: MacAddress,
last_signal_strength: AntennaSignal,
ssid: Option<String>,
channel: Option<(WiFiBand, u8)>,
channel: Option<(WiFiBand, u32)>,
information: Option<APFlags>,
client_list: WiFiDeviceList<Station>,
rogue_mac: MacAddress,
Expand All @@ -196,7 +199,7 @@ impl AccessPoint {
.as_secs();

let chan = if let Some(channel) = channel {
WiFiChannel::new(channel.1, channel.0)
Some((channel.0, channel.1))
} else {
None
};
Expand All @@ -216,6 +219,7 @@ impl AccessPoint {
} else {
APFlags::default()
},
pr_station: None,
auth_sequence: AuthSequence::new(rogue_mac),
has_hs: false,
has_pmkid: false,
Expand Down Expand Up @@ -270,7 +274,7 @@ impl AccessPoint {
self.ssid.as_ref().unwrap_or(&"".to_string()).clone(),
self.channel
.as_ref()
.map_or("".to_string(), |ch| ch.short_string().to_string()),
.map_or("".to_string(), |ch| ch.1.to_string()),
self.client_list.get_all_json(),
self.information.to_json_str(),
wps_to_json(&self.wps_data),
Expand Down Expand Up @@ -641,7 +645,7 @@ impl WiFiDeviceList<AccessPoint> {
_ => std::cmp::Ordering::Equal,
}
}),
1 => access_points.sort_by(|a, b| b.channel.cmp(&a.channel)), // CH
1 => access_points.sort_by(|a, b| b.channel.clone().unwrap_or((WiFiBand::Unknown, 0)).1.cmp(&a.channel.clone().unwrap_or((WiFiBand::Unknown, 0)).1)), // CH
2 => access_points.sort_by(|a, b| {
// RSSI
let a_val = a.last_signal_strength.value;
Expand Down Expand Up @@ -782,7 +786,7 @@ impl WiFiDeviceList<AccessPoint> {
format!("{}", ap.mac_address), // MAC Address
ap.channel
.as_ref()
.map_or("".to_string(), |ch| ch.short_string().to_string()), // CH
.map_or("".to_string(), |ch| ch.1.to_string()), // CH
format!(
"{}",
match ap.last_signal_strength.value {
Expand Down
Loading

0 comments on commit f39e312

Please sign in to comment.