modified: Cargo.lock
modified: frida_cli/Cargo.toml modified: frida_cli/src/main.rs modified: frida_client/Cargo.toml modified: frida_client/src/client.rs new file: frida_client/src/lib.rs renamed: frida_cli/src/config/mod.rs -> frida_core/src/config.rs modified: frida_core/src/device.rs modified: frida_core/src/lib.rs modified: frida_core/src/linux_tun.rs renamed: frida_cli/src/obfs.rs -> frida_core/src/obfs.rs renamed: frida_cli/src/udp.rs -> frida_core/src/udp.rs modified: frida_core/src/win_tun.rs
This commit is contained in:
parent
c3b886c21f
commit
3c23c38d25
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -1646,6 +1646,18 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "frida_cli"
|
name = "frida_cli"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"env_logger",
|
||||||
|
"frida_client",
|
||||||
|
"frida_core",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_yaml",
|
||||||
|
"tokio 1.42.0",
|
||||||
|
"tokio-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "frida_client"
|
name = "frida_client"
|
||||||
|
@ -10,3 +10,13 @@ readme = "../README.md"
|
|||||||
workspace = "../"
|
workspace = "../"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clap = "2.33"
|
||||||
|
env_logger = "0.9"
|
||||||
|
log = "0.4.20"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_derive = "1.0.190"
|
||||||
|
serde_yaml = "0.9.34"
|
||||||
|
tokio = { version = "1", features = ["full", "signal", "tracing"] }
|
||||||
|
tokio-util = "0.7.12"
|
||||||
|
frida_core = { path = "../frida_core" }
|
||||||
|
frida_client = { path = "../frida_client" }
|
@ -1,16 +1,12 @@
|
|||||||
|
|
||||||
use std::{fs, net::{Ipv4Addr}, str};
|
use std::{fs, net::{Ipv4Addr}, str};
|
||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{crate_authors, crate_name, crate_version, App, Arg, ArgMatches};
|
||||||
use env_logger::Builder;
|
use env_logger::Builder;
|
||||||
use log::{error, LevelFilter};
|
use log::{error, LevelFilter};
|
||||||
use crate::config::{ ServerConfiguration, ClientConfiguration, ObfsProtocol, ServerPeer };
|
use frida_core::config::{ ServerConfiguration, ClientConfiguration, ObfsProtocol, ServerPeer };
|
||||||
use crate::client::{desktop::DesktopClient, general::VpnClient};
|
use frida_client::client::{desktop::DesktopClient, general::VpnClient};
|
||||||
|
|
||||||
mod obfs;
|
//mod server;
|
||||||
mod server;
|
|
||||||
mod client;
|
|
||||||
mod udp;
|
|
||||||
mod config;
|
|
||||||
|
|
||||||
fn generate_server_config(matches: &ArgMatches, config_path: &str) {
|
fn generate_server_config(matches: &ArgMatches, config_path: &str) {
|
||||||
let bind_address = matches.value_of("bind-address").expect("No bind address specified");
|
let bind_address = matches.value_of("bind-address").expect("No bind address specified");
|
||||||
@ -62,7 +58,7 @@ fn generate_peer_config(matches: &ArgMatches, config_path: &str, cfg_raw: &Strin
|
|||||||
|
|
||||||
async fn init_server(cfg_raw: &str, s_interface: Option<&str>) {
|
async fn init_server(cfg_raw: &str, s_interface: Option<&str>) {
|
||||||
let config: ServerConfiguration = serde_yaml::from_str(cfg_raw).expect("Bad server config file structure");
|
let config: ServerConfiguration = serde_yaml::from_str(cfg_raw).expect("Bad server config file structure");
|
||||||
server::server_mode(config, s_interface).await;
|
//server::server_mode(config, s_interface).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn init_client(cfg_raw: &str, s_interface: Option<String>) {
|
async fn init_client(cfg_raw: &str, s_interface: Option<String>) {
|
||||||
@ -74,16 +70,14 @@ async fn init_client(cfg_raw: &str, s_interface: Option<String>) {
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
//console_subscriber::init();
|
|
||||||
|
|
||||||
// Initialize the logger with 'info' as the default level
|
// Initialize the logger with 'info' as the default level
|
||||||
Builder::new()
|
Builder::new()
|
||||||
.filter(None, LevelFilter::Info)
|
.filter(None, LevelFilter::Info)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let matches = App::new("Frida")
|
let matches = App::new(crate_name!())
|
||||||
.version("0.1.2")
|
.version(crate_version!())
|
||||||
.author("alterwain")
|
.author(crate_authors!())
|
||||||
.about("VPN software")
|
.about("VPN software")
|
||||||
.arg(Arg::with_name("mode")
|
.arg(Arg::with_name("mode")
|
||||||
.required(true)
|
.required(true)
|
||||||
|
@ -8,9 +8,8 @@ keywords = ["tun", "network", "tunnel", "vpn"]
|
|||||||
categories = ["network-programming", "asynchronous"]
|
categories = ["network-programming", "asynchronous"]
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
|
|
||||||
[[bin]]
|
[lib]
|
||||||
name = "frida_client"
|
crate-type = ["staticlib", "cdylib", "lib"]
|
||||||
path = "src/client.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
frida_core = { path = "../frida_core", package = "frida_core" }
|
frida_core = { path = "../frida_core", package = "frida_core" }
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
pub mod general {
|
pub mod general {
|
||||||
use crate::config::ClientConfiguration;
|
use frida_core::config::ClientConfiguration;
|
||||||
use async_channel::{Receiver, Sender};
|
|
||||||
use futures::{stream::{SplitSink, SplitStream}, SinkExt, StreamExt};
|
|
||||||
use tokio_util::{codec::Framed, sync::CancellationToken};
|
use tokio_util::{codec::Framed, sync::CancellationToken};
|
||||||
use tokio::{net::UdpSocket, sync::{Mutex, mpsc}, io::{AsyncWriteExt, AsyncReadExt}, fs::File};
|
use tokio::{net::UdpSocket, sync::{Mutex, mpsc}, io::{AsyncWriteExt, AsyncReadExt}, fs::File};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
@ -13,9 +11,7 @@ pub mod general {
|
|||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use x25519_dalek::{PublicKey, StaticSecret};
|
use x25519_dalek::{PublicKey, StaticSecret};
|
||||||
use crate::udp::{UDPVpnPacket, UDPVpnHandshake, UDPSerializable};
|
use frida_core::udp::{UDPVpnPacket, UDPVpnHandshake, UDPSerializable};
|
||||||
|
|
||||||
use frida_core::tun::create_tun;
|
|
||||||
use frida_core::{DeviceReader, DeviceWriter};
|
use frida_core::{DeviceReader, DeviceWriter};
|
||||||
|
|
||||||
pub trait VpnClient {
|
pub trait VpnClient {
|
||||||
@ -24,13 +20,11 @@ pub mod general {
|
|||||||
|
|
||||||
pub struct CoreVpnClient {
|
pub struct CoreVpnClient {
|
||||||
pub client_config: ClientConfiguration,
|
pub client_config: ClientConfiguration,
|
||||||
pub dev_reader: DeviceReader,
|
|
||||||
pub dev_writer: DeviceWriter,
|
|
||||||
pub close_token: CancellationToken
|
pub close_token: CancellationToken
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CoreVpnClient {
|
impl CoreVpnClient {
|
||||||
pub async fn start(&mut self, sock: UdpSocket) {
|
pub async fn start(&mut self, sock: UdpSocket, dev_reader: DeviceReader, dev_writer: DeviceWriter) {
|
||||||
info!("Starting client...");
|
info!("Starting client...");
|
||||||
|
|
||||||
let dr_cancel: CancellationToken = CancellationToken::new();
|
let dr_cancel: CancellationToken = CancellationToken::new();
|
||||||
@ -59,11 +53,23 @@ pub mod general {
|
|||||||
|
|
||||||
let s_cipher = cipher_shared.clone();
|
let s_cipher = cipher_shared.clone();
|
||||||
|
|
||||||
let _ = self.dev_writer.write(handshake.serialize()).await;
|
let _ = dev_writer.write(&handshake.serialize()).await;
|
||||||
|
|
||||||
let mut buf = vec![0; 1400]; // mtu
|
|
||||||
let mut buf1 = vec![0; 4096]; // should be changed to less bytes
|
let mut buf1 = vec![0; 4096]; // should be changed to less bytes
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut buf = vec![0; 1400]; // mtu
|
||||||
|
loop {
|
||||||
|
match dev_reader.read(&mut buf).await {
|
||||||
|
Ok(n) => {
|
||||||
|
info!("Read from tun."); // hex::encode(&buf[..n])
|
||||||
|
dx.send(buf[..n].to_vec()).unwrap();
|
||||||
|
},
|
||||||
|
Err(e) => { error!("{}", e); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = self.close_token.cancelled() => {
|
_ = self.close_token.cancelled() => {
|
||||||
@ -76,7 +82,7 @@ pub mod general {
|
|||||||
if let Some(bytes) = rr {
|
if let Some(bytes) = rr {
|
||||||
info!("Write to tun. len={:?}", bytes.len());
|
info!("Write to tun. len={:?}", bytes.len());
|
||||||
|
|
||||||
if let Err(e) = self.dev_writer.write(&bytes).await {
|
if let Err(e) = dev_writer.write(&bytes).await {
|
||||||
error!("Writing error: {:?}", e);
|
error!("Writing error: {:?}", e);
|
||||||
}
|
}
|
||||||
/* if let Err(e) = self.dev_writer.flush().await {
|
/* if let Err(e) = self.dev_writer.flush().await {
|
||||||
@ -86,6 +92,7 @@ pub mod general {
|
|||||||
}
|
}
|
||||||
rr2 = mx.recv() => {
|
rr2 = mx.recv() => {
|
||||||
if let Some(bytes) = rr2 {
|
if let Some(bytes) = rr2 {
|
||||||
|
info!("Got info for sending");
|
||||||
let s_c = s_cipher.lock().await;
|
let s_c = s_cipher.lock().await;
|
||||||
|
|
||||||
if s_c.is_some() {
|
if s_c.is_some() {
|
||||||
@ -106,12 +113,6 @@ pub mod general {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rr = self.dev_reader.read(&mut buf) => {
|
|
||||||
if let Ok(n) = rr {
|
|
||||||
info!("Read from tun."); // hex::encode(&buf[..n])
|
|
||||||
dx.send(buf[..n].to_vec()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rr = sock_rec.recv(&mut buf1) => {
|
rr = sock_rec.recv(&mut buf1) => {
|
||||||
if let Ok(l) = rr {
|
if let Ok(l) = rr {
|
||||||
info!("Read from socket");
|
info!("Read from socket");
|
||||||
@ -190,11 +191,12 @@ pub mod android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod desktop {
|
pub mod desktop {
|
||||||
use crate::client::general::{CoreVpnClient, DevReader, DevWriter, VpnClient};
|
use std::net::Ipv4Addr;
|
||||||
use crate::config::ClientConfiguration;
|
|
||||||
use frida_core::create;
|
use crate::client::general::{CoreVpnClient, VpnClient};
|
||||||
|
use frida_core::config::ClientConfiguration;
|
||||||
|
use frida_core::tun::create_tun;
|
||||||
use frida_core::device::AbstractDevice;
|
use frida_core::device::AbstractDevice;
|
||||||
use futures::{SinkExt, StreamExt};
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
@ -270,21 +272,19 @@ pub mod desktop {
|
|||||||
info!("s_interface: {:?}", &self.s_interface);
|
info!("s_interface: {:?}", &self.s_interface);
|
||||||
info!("client_address: {:?}", &self.client_config.client.address);
|
info!("client_address: {:?}", &self.client_config.client.address);
|
||||||
let mut config = AbstractDevice::default();
|
let mut config = AbstractDevice::default();
|
||||||
config.address(&self.client_config.client.address)
|
config.address(self.client_config.client.address.parse().unwrap())
|
||||||
.netmask("255.255.255.255")
|
.netmask(std::net::IpAddr::V4(Ipv4Addr::new(255, 255, 255, 255)))
|
||||||
.destination("10.66.66.1")
|
.destination(std::net::IpAddr::V4(Ipv4Addr::new(10, 66, 66, 1)))
|
||||||
.mtu(1400)
|
.mtu(1400)
|
||||||
.tun_name("tun0")
|
.tun_name("tun0");
|
||||||
.up();
|
|
||||||
|
|
||||||
info!("SSS: {:?}", &self.client_config.server.endpoint);
|
info!("SSS: {:?}", &self.client_config.server.endpoint);
|
||||||
let sock = UdpSocket::bind(("0.0.0.0", 0)).await.unwrap();
|
let sock = UdpSocket::bind(("0.0.0.0", 0)).await.unwrap();
|
||||||
sock.connect(&self.client_config.server.endpoint).await.unwrap();
|
sock.connect(&self.client_config.server.endpoint).await.unwrap();
|
||||||
|
|
||||||
let dev = create(&config).unwrap();
|
let (dev_reader, dev_writer) = create_tun(config);
|
||||||
let (mut dev_writer , mut dev_reader) = dev.into_framed().split();
|
|
||||||
|
|
||||||
let mut client = CoreVpnClient{ client_config: self.client_config.clone(), dev_reader: DevReader{ dr: dev_reader }, dev_writer: DevWriter{dr: dev_writer }, close_token: tokio_util::sync::CancellationToken::new()};
|
let mut client = CoreVpnClient{ client_config: self.client_config.clone(), close_token: tokio_util::sync::CancellationToken::new()};
|
||||||
|
|
||||||
info!("Platform specific code");
|
info!("Platform specific code");
|
||||||
/* #[cfg(target_os = "linux")]
|
/* #[cfg(target_os = "linux")]
|
||||||
@ -293,7 +293,7 @@ pub mod desktop {
|
|||||||
configure_routes(&s_a.ip().to_string(), self.s_interface.clone());
|
configure_routes(&s_a.ip().to_string(), self.s_interface.clone());
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
client.start(sock).await;
|
client.start(sock, dev_reader, dev_writer).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
1
frida_client/src/lib.rs
Normal file
1
frida_client/src/lib.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod client;
|
@ -3,11 +3,11 @@ use std::net::IpAddr;
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct AbstractDevice {
|
pub struct AbstractDevice {
|
||||||
address: Option<IpAddr>,
|
pub(crate) address: Option<IpAddr>,
|
||||||
netmask: Option<IpAddr>,
|
pub(crate) netmask: Option<IpAddr>,
|
||||||
destination: Option<IpAddr>,
|
pub(crate) destination: Option<IpAddr>,
|
||||||
mtu: Option<u16>,
|
pub(crate) mtu: Option<u16>,
|
||||||
tun_name: Option<String>
|
pub(crate) tun_name: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractDevice {
|
impl AbstractDevice {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
pub mod device;
|
pub mod device;
|
||||||
pub mod tun;
|
pub mod tun;
|
||||||
|
pub mod obfs;
|
||||||
|
pub mod udp;
|
||||||
|
pub mod config;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
mod win_tun;
|
mod win_tun;
|
||||||
|
@ -7,9 +7,11 @@ use std::os::unix::io::AsRawFd;
|
|||||||
pub fn create(cfg: AbstractDevice) -> (DeviceReader, DeviceWriter) {
|
pub fn create(cfg: AbstractDevice) -> (DeviceReader, DeviceWriter) {
|
||||||
let tun = Arc::new(
|
let tun = Arc::new(
|
||||||
Tun::builder()
|
Tun::builder()
|
||||||
.name("") // if name is empty, then it is set by kernel.
|
.name(cfg.tun_name.unwrap()) // if name is empty, then it is set by kernel.
|
||||||
.tap() // uses TAP instead of TUN (default).
|
.mtu(cfg.mtu.unwrap())
|
||||||
.packet_info() // avoids setting IFF_NO_PI.
|
.address(cfg.address.unwrap())
|
||||||
|
.netmask(cfg.netmask.unwrap())
|
||||||
|
.destination(cfg.destination.unwrap())
|
||||||
.up() // or set it up manually using `sudo ip link set <tun-name> up`.
|
.up() // or set it up manually using `sudo ip link set <tun-name> up`.
|
||||||
.try_build() // or `.try_build_mq(queues)` for multi-queue support.
|
.try_build() // or `.try_build_mq(queues)` for multi-queue support.
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
@ -10,15 +10,57 @@ pub fn create(cfg: AbstractDevice) -> (DeviceReader, DeviceWriter) {
|
|||||||
let wintun = unsafe { wintun::load_from_path("wintun.dll") }
|
let wintun = unsafe { wintun::load_from_path("wintun.dll") }
|
||||||
.expect("Failed to load wintun dll");
|
.expect("Failed to load wintun dll");
|
||||||
|
|
||||||
//Try to open an adapter with the name "Demo"
|
let tun_name = match cfg.tun_name {
|
||||||
let adapter = match wintun::Adapter::open(&wintun, "Demo") {
|
Some(n) => n,
|
||||||
|
None => "Demo".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
//Try to open an adapter with the certain name
|
||||||
|
let adapter = match wintun::Adapter::open(&wintun, &tun_name) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
wintun::Adapter::create(&wintun, "Demo", "Example", None)
|
wintun::Adapter::create(&wintun, &tun_name, "FridaVPN", None)
|
||||||
.expect("Failed to create wintun adapter!")
|
.expect("Failed to create wintun adapter!")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let args = &["interface", "ipv4", "set", "interface", &tun_name, "metric=5"];
|
||||||
|
let _ = wintun::run_command("netsh", args).unwrap();
|
||||||
|
|
||||||
|
let mut gateway = "gateway=".to_owned();
|
||||||
|
gateway.push_str(&cfg.destination.unwrap().to_string());
|
||||||
|
|
||||||
|
let mut address = cfg.address.unwrap().to_string().to_owned();
|
||||||
|
address.push_str("/32");
|
||||||
|
|
||||||
|
let args = &[
|
||||||
|
"interface",
|
||||||
|
"ipv4",
|
||||||
|
"set",
|
||||||
|
"address",
|
||||||
|
&tun_name,
|
||||||
|
"static",
|
||||||
|
&address,
|
||||||
|
&gateway,
|
||||||
|
];
|
||||||
|
|
||||||
|
let _ = wintun::run_command("netsh", args).unwrap();
|
||||||
|
|
||||||
|
let mut mtu = "mtu=".to_owned();
|
||||||
|
mtu.push_str(&cfg.mtu.unwrap().to_string());
|
||||||
|
|
||||||
|
let args = &[
|
||||||
|
"interface",
|
||||||
|
"ipv4",
|
||||||
|
"set",
|
||||||
|
"subinterface",
|
||||||
|
&tun_name,
|
||||||
|
&mtu,
|
||||||
|
"store=persistent"
|
||||||
|
];
|
||||||
|
|
||||||
|
let _ = wintun::run_command("netsh", args).unwrap();
|
||||||
|
|
||||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap());
|
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap());
|
||||||
let reader_session = session.clone();
|
let reader_session = session.clone();
|
||||||
let writer_session = session.clone();
|
let writer_session = session.clone();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user