MacOS stuff
This commit is contained in:
parent
39d9e14ddb
commit
8c51b1c20f
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "Inflector"
|
||||
@ -753,9 +753,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.3"
|
||||
version = "1.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
|
||||
checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
@ -1617,12 +1617,11 @@ name = "frida_core"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"cc",
|
||||
"chrono",
|
||||
"filedescriptor",
|
||||
"futures",
|
||||
"libc",
|
||||
"log",
|
||||
"nix",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
@ -205,10 +205,18 @@ pub mod desktop {
|
||||
use log::info;
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
use regex::Regex;
|
||||
|
||||
|
||||
fn cmd(cmd: &str, args: &[&str]) -> String {
|
||||
let ecode = std::process::Command::new(cmd)
|
||||
.args(args)
|
||||
.output();
|
||||
assert!(ecode.is_ok(), "Failed to execte {}", cmd);
|
||||
std::str::from_utf8(&ecode.as_ref().unwrap().stdout).unwrap().to_string()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn configure_routes(endpoint_ip: &str) {
|
||||
let mut if_out = std::process::Command::new("ip")
|
||||
@ -306,6 +314,37 @@ pub mod desktop {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn configure_routes(endpoint_ip: &str) {
|
||||
let mut if_out = cmd("route", &["-n", "get", "default"]);
|
||||
let r = std::str::from_utf8(&if_out.as_bytes()).unwrap();
|
||||
|
||||
let mut gateway = None;
|
||||
let mut if_name = None;
|
||||
|
||||
let ui = r.find("gateway: ").unwrap() + 9;
|
||||
let s = &r[ui..];
|
||||
let ei = s.find("\n").unwrap();
|
||||
gateway = Some(&s[..ei]);
|
||||
|
||||
let ui = r.find("interface: ").unwrap() + 11;
|
||||
let s = &r[ui..];
|
||||
let ei = s.find("\n").unwrap();
|
||||
if_name = Some(&s[..ei]);
|
||||
|
||||
info!("Main interface: {:?}", &if_name.unwrap());
|
||||
|
||||
let inter_name = if_name.unwrap();
|
||||
|
||||
info!("Main network interface: {:?}", &gateway.unwrap());
|
||||
|
||||
cmd("route", &["add", "-host", endpoint_ip, &gateway.unwrap()]);
|
||||
|
||||
cmd("route", &["change", "default", "-interface", "utun3"]); // todo: change that
|
||||
|
||||
cmd("route", &["add", "-host", endpoint_ip, &gateway.unwrap()]);
|
||||
}
|
||||
|
||||
pub struct DesktopClient {
|
||||
pub client_config: ClientConfiguration
|
||||
}
|
||||
@ -330,12 +369,15 @@ pub mod desktop {
|
||||
let mut client = CoreVpnClient{ client_config: self.client_config.clone(), close_token: tokio_util::sync::CancellationToken::new()};
|
||||
|
||||
info!("Platform specific code");
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
{
|
||||
let s_a: std::net::SocketAddr = self.client_config.server.endpoint.parse().unwrap();
|
||||
configure_routes(&s_a.ip().to_string());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
sock.connect(&self.client_config.server.endpoint).await.unwrap();
|
||||
|
||||
client.start(sock, dev_reader, dev_writer, mtu).await;
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,11 @@ tokio = { workspace = true }
|
||||
[target.'cfg(target_os="windows")'.dependencies]
|
||||
wintun = "0.5.0"
|
||||
|
||||
[target.'cfg(target_os="macos")'.dependencies]
|
||||
nix = { version = "0.29.0", features = ["socket"] }
|
||||
|
||||
[target.'cfg(target_os="linux")'.dependencies]
|
||||
tokio-tun = "0.12.1"
|
||||
|
||||
[target.'cfg(target_os="android")'.dependencies]
|
||||
libc = "0.2"
|
||||
filedescriptor = "0.8.2"
|
||||
filedescriptor = "0.8.2"
|
||||
|
||||
[target.'cfg(target_os="macos")'.build-dependencies]
|
||||
cc = "1.2.13"
|
7
frida_core/build.rs
Normal file
7
frida_core/build.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use cc;
|
||||
|
||||
fn main() {
|
||||
if cfg!(target_os = "macos") {
|
||||
cc::Build::new().file("src/c/utun.c").compile("utun");
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
//use tokio::fs::File;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use std::error::Error;
|
||||
use std::os::fd::FromRawFd;
|
||||
@ -6,7 +5,6 @@ use std::os::fd::FromRawFd;
|
||||
use std::fs::File;
|
||||
use std::io::{Write, Read};
|
||||
|
||||
use libc::fdopen;
|
||||
use std::ffi::CString;
|
||||
|
||||
pub fn create(cfg: i32) -> (DeviceReader, DeviceWriter) {
|
||||
|
43
frida_core/src/c/utun.c
Normal file
43
frida_core/src/c/utun.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/kern_control.h>
|
||||
#include <net/if_utun.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kern_event.h>
|
||||
|
||||
int32_t open_utun(uint64_t num) {
|
||||
int err;
|
||||
int fd;
|
||||
struct sockaddr_ctl addr;
|
||||
struct ctl_info info;
|
||||
|
||||
fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
|
||||
if (fd < 0) {
|
||||
return fd;
|
||||
}
|
||||
memset(&info, 0, sizeof (info));
|
||||
strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
|
||||
err = ioctl(fd, CTLIOCGINFO, &info);
|
||||
if (err < 0) {
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
addr.sc_id = info.ctl_id;
|
||||
addr.sc_len = sizeof(addr);
|
||||
addr.sc_family = AF_SYSTEM;
|
||||
addr.ss_sysaddr = AF_SYS_CONTROL;
|
||||
addr.sc_unit = num + 1; // utunX where X is sc.sc_unit -1
|
||||
|
||||
err = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
|
||||
if (err < 0) {
|
||||
// this utun is in use
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
return fd;
|
||||
}
|
@ -3,80 +3,39 @@ use std::{ffi::CString, process::Command};
|
||||
use std::sync::Arc;
|
||||
use std::error::Error;
|
||||
use log::info;
|
||||
use nix::errno::Errno;
|
||||
use nix::libc::{connect, sockaddr_ctl, CTLIOCGINFO};
|
||||
use nix::sys::socket::{SockaddrLike, SockaddrStorage, UnixAddr};
|
||||
use nix::{libc::{ctl_info, PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL}, sys::socket::{socket, AddressFamily, SockFlag, SockProtocol, SockType, sockaddr}};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
use crate::device::AbstractDevice;
|
||||
|
||||
fn cmd(cmd: &str, args: &[&str]) {
|
||||
let ecode = Command::new("ip")
|
||||
extern "C" {
|
||||
fn open_utun(num: u64) -> i32;
|
||||
}
|
||||
|
||||
fn cmd(cmd: &str, args: &[&str]) -> String {
|
||||
let ecode = Command::new(cmd)
|
||||
.args(args)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(ecode.success(), "Failed to execte {}", cmd);
|
||||
.output();
|
||||
assert!(ecode.is_ok(), "Failed to execte {}", cmd);
|
||||
std::str::from_utf8(&ecode.as_ref().unwrap().stdout).unwrap().to_string()
|
||||
}
|
||||
|
||||
fn get_utun() -> (i32, String) {
|
||||
for utun_n in 0..255 {
|
||||
let fd = unsafe { open_utun(utun_n) };
|
||||
if fd >= 0 {
|
||||
let name = format!("utun{}", utun_n);
|
||||
return (fd, name);
|
||||
}
|
||||
}
|
||||
panic!("{}", std::io::Error::last_os_error())
|
||||
}
|
||||
|
||||
pub fn create(cfg: AbstractDevice) -> (DeviceReader, DeviceWriter) {
|
||||
|
||||
let fd = socket(
|
||||
AddressFamily::System,
|
||||
SockType::Datagram,
|
||||
SockFlag::empty(),
|
||||
Some(SockProtocol::KextControl)
|
||||
);
|
||||
|
||||
if let Err(e) = fd {
|
||||
panic!("Unable to open socket! Error: {:?}", e);
|
||||
}
|
||||
|
||||
let fd = fd.unwrap();
|
||||
|
||||
let mut info: ctl_info = unsafe { std::mem::zeroed() };
|
||||
let ctl_name = CString::new("com.apple.net.utun_control").unwrap();
|
||||
ctl_name.as_bytes_with_nul()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, &c)| info.ctl_name[i] = c as i8);
|
||||
|
||||
if unsafe { nix::libc::ioctl(fd.as_raw_fd(), CTLIOCGINFO, &mut info) } < 0 {
|
||||
let err = Errno::last();
|
||||
panic!("ioctl CTLIOCGINFO failed: {}", err);
|
||||
}
|
||||
|
||||
let mut sc = sockaddr_ctl {
|
||||
sc_len: std::mem::size_of::<sockaddr_ctl>() as u8,
|
||||
sc_family: nix::libc::AF_SYSTEM as u8,
|
||||
ss_sysaddr: nix::libc::AF_SYS_CONTROL as u16,
|
||||
sc_id: info.ctl_id,
|
||||
sc_unit: 0,
|
||||
sc_reserved: [0; 5]
|
||||
};
|
||||
|
||||
let asc = &sc as *const sockaddr_ctl as *const sockaddr;
|
||||
let f = unsafe { connect(fd.as_raw_fd(), asc, size_of::<sockaddr_ctl>() as u32 ) };
|
||||
|
||||
info!("utun interface created successfully, fd: {:?}", f);
|
||||
|
||||
let mut reader = unsafe { File::from_raw_fd(f) };
|
||||
let mut writer = unsafe { File::from_raw_fd(f) };
|
||||
|
||||
let mut address = cfg.address.unwrap().to_string();
|
||||
address.push_str("/24");
|
||||
|
||||
/*
|
||||
cmd("ip", &["addr", "add", "dev", iface.name(), &address]);
|
||||
cmd("ip", &["link", "set", "up", "dev", iface.name()]);
|
||||
|
||||
let iface = Arc::new(iface);
|
||||
let writer = Arc::clone(&iface);
|
||||
let reader = Arc::clone(&iface);*/
|
||||
|
||||
let (fd, if_name) = get_utun();
|
||||
let reader = unsafe { File::from_raw_fd(fd) };
|
||||
let writer = unsafe { File::from_raw_fd(fd) };
|
||||
cmd("ifconfig", &[&if_name, &cfg.address.unwrap().to_string(), &cfg.destination.unwrap().to_string(), "netmask", &cfg.netmask.unwrap().to_string(), "up"]);
|
||||
(DeviceReader {reader}, DeviceWriter {writer})
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user