Skip to content

Commit

Permalink
Merge pull request #35 from XOR-op/mitm-script
Browse files Browse the repository at this point in the history
[Feat] Enable to use script in http(s) interception
  • Loading branch information
XOR-op authored Oct 14, 2023
2 parents 058eb7d + 28c5022 commit 346ad47
Show file tree
Hide file tree
Showing 18 changed files with 1,181 additions and 605 deletions.
285 changes: 263 additions & 22 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 16 additions & 5 deletions boltapi/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,27 @@ pub struct GetInterceptDataReq {
pub id: u32,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields, tag = "type")]
pub enum CapturedBodySchema {
#[serde(rename = "empty")]
Empty,
#[serde(rename = "warning")]
Warning { content: String },
#[serde(rename = "body")]
Body {
#[serde(with = "base64ext")]
content: Vec<u8>,
},
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct GetInterceptDataResp {
pub req_header: Vec<String>,
#[serde(with = "base64ext")]
pub req_body: Vec<u8>,
pub req_body: CapturedBodySchema,
pub resp_header: Vec<String>,
#[serde(with = "base64ext")]
pub resp_body: Vec<u8>,
pub warning: Option<String>,
pub resp_body: CapturedBodySchema,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
Expand Down
6 changes: 5 additions & 1 deletion boltconn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ boringtun = "0.6.0"
byteorder = "1.4.3"
bytes = "1.2.1"
chrono = { version = "0.4.31", default-features = false, features = ["clock", "std"] }
clap = {version = "4.4.6", features = ["derive"]}
clap = { version = "4.4.6", features = ["derive"] }
colored = "2.0.0"
dashmap = "5.5.3"
fast-socks5 = "0.9.1"
Expand All @@ -46,6 +46,7 @@ rand = { version = "0.8.5", features = ["small_rng"] }
rcgen = { version = "0.11.0", features = ["pem", "x509-parser"] }
regex = "1.7.0"
reqwest = { version = "0.11.20", default-features = false, features = ["rustls-tls", "json"] }
rquickjs = { version = "0.4.0-beta.4", features = ["bindgen", "futures", "macro", "classes"] }
rusqlite = { version = "0.29.0", features = ["bundled"] }
rustls-pemfile = "1.0.1"
scopeguard = "1.1.0"
Expand Down Expand Up @@ -81,3 +82,6 @@ netlink-sys = "0.8.3"
netlink-packet-core = "0.5.0"
netlink-packet-sock-diag = "0.4.0"
procfs = "0.15.1"

[dev-dependencies]
tracing-test = "0.2.4"
2 changes: 1 addition & 1 deletion boltconn/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl App {
) -> anyhow::Result<Self> {
// tracing
let stream_logger = StreamLoggerSend::new();
external::init_tracing(&stream_logger);
external::init_tracing(&stream_logger)?;

// interface
let (_, real_iface_name) =
Expand Down
25 changes: 14 additions & 11 deletions boltconn/src/cli/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::cli::request_uds::UdsConnector;
use crate::cli::request_web::WebConnector;
use anyhow::{anyhow, Result};
use boltapi::CapturedBodySchema;
use colored::Colorize;
use std::ops::Add;
use std::path::PathBuf;
Expand Down Expand Up @@ -161,23 +162,25 @@ impl Requester {
println!("Header:");
result.req_header.iter().for_each(|l| println!("{}", l));
println!();
if let Ok(data) = std::str::from_utf8(result.req_body.as_slice()) {
println!("Body:");
println!("{}", data);
} else {
println!("Body is not UTF-8 encoded");
fn get_text_body(body: &CapturedBodySchema) {
if let CapturedBodySchema::Body { content } = body {
if let Ok(data) = std::str::from_utf8(content.as_slice()) {
println!("Body:");
println!("{}", data);
} else {
println!("Body is not UTF-8 encoded");
}
} else {
println!("Body is not fully captured");
}
}
get_text_body(&result.req_body);
println!();
println!("================== Response ==================");
println!("Header:");
result.resp_header.iter().for_each(|l| println!("{}", l));
println!();
if let Ok(data) = std::str::from_utf8(result.resp_body.as_slice()) {
println!("Body:");
println!("{}", data);
} else {
println!("Body is not UTF-8 encoded");
}
get_text_body(&result.resp_body);
Ok(())
}

Expand Down
19 changes: 18 additions & 1 deletion boltconn/src/config/interception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,22 @@ use serde::{Deserialize, Serialize};
pub struct InterceptionConfig {
pub name: Option<String>,
pub filters: Vec<String>,
pub actions: Vec<String>,
pub actions: Vec<ActionConfig>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(untagged)]
pub enum ActionConfig {
Script(ScriptActionConfig),
Standard(String),
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ScriptActionConfig {
#[serde(alias = "script-name")]
pub name: Option<String>,
#[serde(alias = "type")]
pub script_type: String,
pub pattern: Option<String>,
pub script: String,
}
12 changes: 3 additions & 9 deletions boltconn/src/external/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::dispatch::{GeneralProxy, Latency};
use crate::external::{SharedDispatching, StreamLoggerRecv, StreamLoggerSend};
use crate::network::configure::TunConfigure;
use crate::proxy::{
latency_test, BodyOrWarning, ContextManager, Dispatcher, HttpCapturer, HttpInterceptData,
SessionManager,
latency_test, ContextManager, Dispatcher, HttpCapturer, HttpInterceptData, SessionManager,
};
use boltapi::{
ConnectionSchema, GetGroupRespSchema, GetInterceptDataResp, GetInterceptRangeReq,
Expand Down Expand Up @@ -213,16 +212,11 @@ impl Controller {
req,
resp,
} = list.get(0).unwrap();
let (body, warning) = match &resp.body {
BodyOrWarning::Body(b) => (b.to_vec(), None),
BodyOrWarning::Warning(w) => (vec![], Some(w.clone())),
};
let result = GetInterceptDataResp {
req_header: req.collect_headers(),
req_body: req.body.to_vec(),
req_body: req.body.to_captured_schema(),
resp_header: resp.collect_headers(),
resp_body: body,
warning,
resp_body: resp.body.to_captured_schema(),
};
return Some(result);
}
Expand Down
12 changes: 8 additions & 4 deletions boltconn/src/external/database.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::platform::get_user_info;
use crate::proxy::{BodyOrWarning, ConnContext, HttpInterceptData};
use crate::proxy::{CapturedBody, ConnContext, HttpInterceptData};
use anyhow::anyhow;
use rusqlite::{params, Error, ErrorCode, OpenFlags};
use std::path::PathBuf;
Expand Down Expand Up @@ -205,9 +205,13 @@ impl DatabaseHandle {
let mut stmt = tx
.prepare_cached("INSERT INTO Intercept (process,uri,method,status,size,time,req_header,req_body,resp_header,resp_body) VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10)")?;
for c in intes.iter() {
let req_body = match &c.req.body {
CapturedBody::FullCapture(b) => Some(b.as_ref()),
_ => None,
};
let resp_body = match &c.resp.body {
BodyOrWarning::Body(b) => Some(b.as_ref()),
BodyOrWarning::Warning(_) => None,
CapturedBody::FullCapture(b) => Some(b.as_ref()),
_ => None,
};
stmt.execute(params![
c.process_info.as_ref().map(|proc| &proc.name),
Expand All @@ -217,7 +221,7 @@ impl DatabaseHandle {
c.resp.body_len(),
(c.resp.time - c.req.time).as_millis() as u64,
c.req.collect_headers().join("\n"),
c.req.body.as_ref(),
req_body,
c.resp.collect_headers().join("\n"),
resp_body
])?;
Expand Down
4 changes: 3 additions & 1 deletion boltconn/src/external/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl<'a> MakeWriter<'a> for LoggerMaker {
}
}

pub fn init_tracing(logger: &StreamLoggerSend) {
pub fn init_tracing(logger: &StreamLoggerSend) -> anyhow::Result<()> {
#[cfg(not(feature = "tokio-console"))]
{
let stdout_layer = fmt::layer()
Expand All @@ -113,10 +113,12 @@ pub fn init_tracing(logger: &StreamLoggerSend) {
.with(stream_layer)
.with(EnvFilter::new("boltconn=trace"))
.init();
Ok(())
}
#[cfg(feature = "tokio-console")]
{
let console_layer = console_subscriber::ConsoleLayer::builder().spawn();
tracing_subscriber::registry().with(console_layer).init();
Ok(())
}
}
Loading

0 comments on commit 346ad47

Please sign in to comment.