Updated protocol and tls
This commit is contained in:
Generated
+4
-1353
File diff suppressed because it is too large
Load Diff
@@ -9,9 +9,4 @@ name = "ghostnet-rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rustls = "0.23.31"
|
rustls = "0.23.31"
|
||||||
rustls-native-certs = "0.8.1"
|
rustls-native-certs = "0.8.1"
|
||||||
|
|
||||||
reqwest = { version = "0.12.23", features = ["blocking"] }
|
|
||||||
|
|
||||||
hyper = { version = "0.14", features = ["full"] }
|
|
||||||
tokio = { version = "1", features = ["full"] }
|
|
||||||
webpki-roots = "1.0.2"
|
webpki-roots = "1.0.2"
|
||||||
|
|||||||
+31
-7
@@ -22,18 +22,42 @@ impl Request {
|
|||||||
|
|
||||||
impl Request {
|
impl Request {
|
||||||
pub fn send(&self) -> String {
|
pub fn send(&self) -> String {
|
||||||
let mut tcp = TcpStream::connect((self.host.as_str(), 443)).unwrap();
|
let tcp = TcpStream::connect((self.host.as_str(), 443)).unwrap();
|
||||||
let mut conn = tls::tls13_handshake(&self.host, &mut tcp).unwrap();
|
send_request(tcp, &self.host, &self.to_string())
|
||||||
let mut tls = rustls::Stream::new(&mut conn, &mut tcp);
|
}
|
||||||
write!(
|
|
||||||
tls,
|
pub fn send_routed(&self, router: &str) -> String {
|
||||||
|
let mut tcp = TcpStream::connect((router, 80)).unwrap();
|
||||||
|
tcp.write_all(format!("ROUTE {}:443", self.host).as_bytes())
|
||||||
|
.unwrap();
|
||||||
|
tcp.read(&mut [0; 32]).unwrap();
|
||||||
|
send_request(tcp, &self.host, &self.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_routed_secure(&self, router: &str) -> String {
|
||||||
|
let tcp = TcpStream::connect((router, 443)).unwrap();
|
||||||
|
send_request(
|
||||||
|
tcp.try_clone().unwrap(),
|
||||||
|
&self.host,
|
||||||
|
&format!("ROUTE {}:443", self.host),
|
||||||
|
);
|
||||||
|
send_request(tcp, &self.host, &self.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_string(&self) -> String {
|
||||||
|
format!(
|
||||||
"GET {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nUser-Agent: rustls/0.23\r\n\r\n",
|
"GET {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nUser-Agent: rustls/0.23\r\n\r\n",
|
||||||
self.path, self.host
|
self.path, self.host
|
||||||
)
|
)
|
||||||
.unwrap();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_request(mut stream: TcpStream, host: &str, send: &str) -> String {
|
||||||
|
let mut conn = tls::tls13_handshake(&host, &mut stream).unwrap();
|
||||||
|
let mut tls = rustls::Stream::new(&mut conn, &mut stream);
|
||||||
|
tls.write_all(send.as_bytes()).unwrap();
|
||||||
tls.flush().unwrap();
|
tls.flush().unwrap();
|
||||||
let mut resp = Vec::new();
|
let mut resp = Vec::new();
|
||||||
tls.read_to_end(&mut resp).unwrap();
|
tls.read_to_end(&mut resp).unwrap();
|
||||||
String::from_utf8(resp).unwrap()
|
String::from_utf8(resp).unwrap()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
+4
-2
@@ -1,6 +1,8 @@
|
|||||||
use ghostnet_rs::Request;
|
use ghostnet_rs::Request;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let req = Request::new("example.com");
|
ghostnet_rs::server::run();
|
||||||
println!("{}", req.send());
|
// println!("{}", Request::new("example.com").send_routed_secure("localhost"));
|
||||||
|
// println!("{}", Request::new("example.com").send_routed("localhost"));
|
||||||
|
// println!("{}", Request::new("example.com").send());
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-88
@@ -1,97 +1,63 @@
|
|||||||
use hyper::service::{make_service_fn, service_fn};
|
use std::{
|
||||||
use hyper::{Body, Request, Response, Server};
|
io::{Read, Write},
|
||||||
use reqwest;
|
net::{TcpListener, TcpStream},
|
||||||
use reqwest::header::{HeaderName, HeaderValue};
|
};
|
||||||
use std::convert::Infallible;
|
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use tokio;
|
|
||||||
|
|
||||||
const DEFAULT_TARGET: &str = "https://crackmes.one";
|
pub fn run() {
|
||||||
const GHOST_ROUTE_HEADER: &str = "ghost-route";
|
let server = TcpListener::bind(format!(
|
||||||
|
"0.0.0.0:{}",
|
||||||
async fn handle_request(mut req: Request<Body>) -> Result<Response<Body>, Infallible> {
|
std::env::var("PORT").unwrap_or("80".to_string())
|
||||||
let target_url = req
|
|
||||||
.headers()
|
|
||||||
.get(GHOST_ROUTE_HEADER)
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or(DEFAULT_TARGET)
|
|
||||||
.to_string();
|
|
||||||
|
|
||||||
let url_params = req
|
|
||||||
.uri()
|
|
||||||
.path_and_query()
|
|
||||||
.map(|pq| pq.as_str())
|
|
||||||
.unwrap_or("");
|
|
||||||
|
|
||||||
let client = reqwest::Client::new();
|
|
||||||
|
|
||||||
let builder = client
|
|
||||||
.request(
|
|
||||||
reqwest::Method::from_str(req.method().as_str()).unwrap(),
|
|
||||||
format!("{}/{}", target_url.trim_end_matches('/'), url_params),
|
|
||||||
)
|
|
||||||
.headers(reqwest::header::HeaderMap::from_iter(
|
|
||||||
req.headers()
|
|
||||||
.into_iter()
|
|
||||||
.map(|h| {
|
|
||||||
if h.0.as_str() == "host" {
|
|
||||||
(
|
|
||||||
HeaderName::from_str("host").unwrap(),
|
|
||||||
HeaderValue::from_bytes(
|
|
||||||
reqwest::Url::from_str(&target_url)
|
|
||||||
.unwrap()
|
|
||||||
.host_str()
|
|
||||||
.unwrap()
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
HeaderName::from_str(h.0.as_str()).unwrap(),
|
|
||||||
HeaderValue::from_bytes(h.1.as_bytes()).unwrap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
))
|
))
|
||||||
.body(hyper::body::to_bytes(req.body_mut()).await.unwrap());
|
.unwrap();
|
||||||
|
|
||||||
let response = builder.send().await.unwrap();
|
for stream in server.incoming() {
|
||||||
|
match stream {
|
||||||
|
Ok(mut client) => {
|
||||||
|
println!("Client connected");
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
|
||||||
return Ok(Response::new(Body::from(response.text().await.unwrap())));
|
let buf_len = client.read(&mut buf).unwrap();
|
||||||
|
|
||||||
|
let req = String::from_utf8_lossy(&buf[..buf_len]);
|
||||||
|
let req = req.lines().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if req[0].starts_with("ROUTE") {
|
||||||
|
println!("Route mode");
|
||||||
|
let addr = req[0].split_once(' ').unwrap().1;
|
||||||
|
println!("Connecting to {addr}");
|
||||||
|
let mut target = TcpStream::connect(addr).unwrap();
|
||||||
|
let mut target_t = target.try_clone().unwrap();
|
||||||
|
let mut client_t = client.try_clone().unwrap();
|
||||||
|
println!("Connected to {addr}");
|
||||||
|
client.write_all("CONN EST".as_bytes()).unwrap();
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
loop {
|
||||||
|
let mut buf = [0; 2048];
|
||||||
|
let buf_len = client_t.read(&mut buf).unwrap();
|
||||||
|
if buf_len == 0 {
|
||||||
|
target_t.shutdown(std::net::Shutdown::Both).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
println!("Client -> Target {:?}", &buf[..buf_len]);
|
||||||
|
target_t.write_all(&buf[..buf_len]).unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut buf = [0; 2048];
|
||||||
|
let buf_len = target.read(&mut buf).unwrap();
|
||||||
|
if buf_len == 0 {
|
||||||
|
client.shutdown(std::net::Shutdown::Both).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
println!("Target -> Client {:?}", &buf[..buf_len]);
|
||||||
|
client.write_all(&buf[..buf_len]).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn shutdown_signal() {
|
Err(_) => {}
|
||||||
tokio::signal::ctrl_c()
|
|
||||||
.await
|
|
||||||
.expect("Failed to install CTRL+C signal handler");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
||||||
// Server address
|
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
|
||||||
|
|
||||||
// Create service
|
|
||||||
let make_svc =
|
|
||||||
make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle_request)) });
|
|
||||||
|
|
||||||
// Create server
|
|
||||||
let server = Server::bind(&addr).serve(make_svc);
|
|
||||||
|
|
||||||
println!("HTTP Proxy Server running on http://{}", addr);
|
|
||||||
println!("Usage:");
|
|
||||||
println!(" - Add 'Ghost-Route: https://target.com' header to route to specific server");
|
|
||||||
println!(" - Without header, routes to default: {}", DEFAULT_TARGET);
|
|
||||||
println!("Press Ctrl+C to stop");
|
|
||||||
|
|
||||||
// Run server with graceful shutdown
|
|
||||||
let graceful = server.with_graceful_shutdown(shutdown_signal());
|
|
||||||
|
|
||||||
if let Err(e) = graceful.await {
|
|
||||||
eprintln!("Server error: {}", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user