diff --git a/Cargo.lock b/Cargo.lock index 622c1cf..ccebcd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "aap" -version = "0.1.1" +version = "0.2.1" dependencies = [ "clap", "fakeit", diff --git a/Cargo.toml b/Cargo.toml index 2d673e5..7475271 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aap" -version = "0.1.1" +version = "0.2.1" authors = ["Chad Baxter "] edition = "2018" description = "Saturate the bad guys' databases." diff --git a/README.md b/README.md index 000b760..83b9086 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ You can use the ActiveAntiPhish command line application by compiling it with th ## `aap` Help ``` -ActiveAntiPhish 0.1.1 GNU-GPL-3.0 +ActiveAntiPhish 0.2.1 GNU-GPL-3.0 Chad Baxter Saturate the bad guys' databases. @@ -30,14 +30,17 @@ USAGE: aap [FLAGS] [OPTIONS] --time --threads --url FLAGS: - -g, --debug Locks application to one thread and displays HTTP response data. - -h, --help Prints help information - -V, --version Prints version information + -g, --debug Locks application to one thread and displays HTTP response data. + -h, --help Prints help information + -m, --multipart The form uses multipart data. + -w, --urlencoded The form uses www-urlencoded data. + -V, --version Prints version information OPTIONS: -c, --ccn The form field where a credit card number should be populated. -v, --cvv The form field where a credit card verification value should be populated. - -d, --domain The domain of the email server associated with your organization (otherwise random domains will be used). For example: example.com or mail.example.com + -d, --domain The domain of the email server associated with your organization (otherwise random + domains will be used). For example: example.com or mail.example.com -e, --email The form field where an email should be populated. -x, --exp The form field where a credit card expiration date should be populated. -f, --fname The form field where a first name should be populated. diff --git a/src/main.rs b/src/main.rs index c38ce91..39c086e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,33 @@ fn main() { .multiple(false) .required(true) ) + .arg( + Arg::with_name("multipart") + .help("The form uses multipart data.") + .short("-m") + .long("--multipart") + .takes_value(false) + .multiple(false) + .required(false) + ) + .arg( + Arg::with_name("urlencoded") + .help("The form uses www-urlencoded data.") + .short("-w") + .long("--urlencoded") + .takes_value(false) + .multiple(false) + .required(false) + ) + .arg( + Arg::with_name("url") + .help("The path to the endpoint to POST fake data to.") + .short("-u") + .long("--url") + .takes_value(true) + .multiple(false) + .required(true) + ) .arg( Arg::with_name("domain") .help("The domain of the email server associated with your organization (otherwise random domains will be used). For example: example.com or mail.example.com") @@ -209,10 +236,24 @@ fn main() { } }; + let mut form_type: u8 = 0; + if matches.is_present("multipart") { + form_type = form_type + 1; + } + if matches.is_present("urlencoded") { + form_type = form_type + 1; + } + + if form_type == 0 { + eprintln!("Must specify either URLEncoded or Multipart for form data format."); + std::process::exit(1); + } + + if matches.is_present("debug") { - execute(fields, url, domain, 1, true); + execute(form_type, fields, url, domain, 1, true); } else { - execute(fields, url, domain, threads, false); + execute(form_type, fields, url, domain, threads, false); } std::thread::sleep(std::time::Duration::from_secs(sleep)); } diff --git a/src/request_builder.rs b/src/request_builder.rs index 4072967..5852d81 100644 --- a/src/request_builder.rs +++ b/src/request_builder.rs @@ -2,7 +2,7 @@ use crate::types::{PostFields, PostData}; use reqwest::blocking::*; -pub fn build_form(fields: PostFields, data: PostData) -> multipart::Form { +pub fn build_form_multipart(fields: PostFields, data: PostData) -> multipart::Form { let mut form = multipart::Form::new(); if fields.email.is_some() & data.email.is_some() { form = form.text(fields.email.unwrap().to_string(), data.email.unwrap()); @@ -31,7 +31,42 @@ pub fn build_form(fields: PostFields, data: PostData) -> multipart::Form { return form; } -pub fn build_request(form: multipart::Form, url: String) -> Request { - let client = reqwest::blocking::Client::builder().user_agent(fakeit::user_agent::random_platform()).build().unwrap(); - return client.post(url).multipart(form).build().unwrap(); +pub fn build_form_urlencoded(fields: PostFields, data: PostData) -> std::collections::HashMap { + let mut form: std::collections::HashMap = std::collections::HashMap::new(); + + if fields.email.is_some() & data.email.is_some() { + form.insert(fields.email.unwrap().to_string(), data.email.unwrap()); + } + if fields.password.is_some() & data.password.is_some() { + form.insert(fields.password.unwrap().to_string(), data.password.unwrap()); + } + if fields.phone.is_some() & data.phone.is_some() { + form.insert(fields.phone.unwrap().to_string(), data.phone.unwrap()); + } + if fields.fname.is_some() & data.fname.is_some() { + form.insert(fields.fname.unwrap().to_string(), data.fname.unwrap()); + } + if fields.lname.is_some() & data.lname.is_some() { + form.insert(fields.lname.unwrap().to_string(), data.lname.unwrap()); + } + if fields.ccn.is_some() & data.ccn.is_some() { + form.insert(fields.ccn.unwrap().to_string(), data.ccn.unwrap()); + } + if fields.exp.is_some() & data.exp.is_some() { + form.insert(fields.exp.unwrap().to_string(), data.exp.unwrap()); + } + if fields.cvv.is_some() & data.cvv.is_some() { + form.insert(fields.cvv.unwrap().to_string(), data.cvv.unwrap()); + } + return form; +} + +pub fn build_request(multipart: Option, urlencoded: Option>, url: String) -> Request { + if multipart.is_some() { + let client = reqwest::blocking::Client::builder().user_agent(fakeit::user_agent::random_platform()).build().unwrap(); + return client.post(url).multipart(multipart.unwrap()).build().unwrap(); + } else { + let client = reqwest::blocking::Client::builder().user_agent(fakeit::user_agent::random_platform()).build().unwrap(); + return client.post(url).form(&urlencoded.unwrap()).build().unwrap(); + } } diff --git a/src/thread_manager.rs b/src/thread_manager.rs index 54c7e9a..a76d49a 100644 --- a/src/thread_manager.rs +++ b/src/thread_manager.rs @@ -4,12 +4,13 @@ use crate::generator::*; use std::io::Write; -pub fn execute(fields: PostFields, url: String, domain: String, threads: u64, debug: bool) { +pub fn execute(form_type: u8, fields: PostFields, url: String, domain: String, threads: u64, debug: bool) { for _ in 0..threads { let fields_clone = fields.clone(); let domain_clone = domain.clone(); let url_clone = url.clone(); let debug_clone = debug.clone(); + let form_type_clone = form_type.clone(); std::thread::spawn(move || { loop { let domain_clone1 = domain_clone.clone(); @@ -17,18 +18,38 @@ pub fn execute(fields: PostFields, url: String, domain: String, threads: u64, de let fields_clone1 = fields_clone.clone(); let fields_clone2 = fields_clone.clone(); let debug_clone1 = debug_clone.clone(); + let form_type_clone1 = form_type_clone.clone(); let client = reqwest::blocking::Client::builder().redirect(reqwest::redirect::Policy::none()).build().unwrap(); let response = match client.execute( - build_request( - build_form( - fields_clone1, - generate_from_fields( - fields_clone2, - domain_clone1 - ) - ), - url_clone1 - ) + if form_type_clone1 == 1 { + build_request( + Some( + build_form_multipart( + fields_clone1, + generate_from_fields( + fields_clone2, + domain_clone1 + ) + ) + ), + None, + url_clone1 + ) + } else { + build_request( + None, + Some( + build_form_urlencoded( + fields_clone1, + generate_from_fields( + fields_clone2, + domain_clone1 + ) + ) + ), + url_clone1 + ) + } ) { Ok(o) => Some(o), Err(e) => {