From 9fe160801ad245a7f1c1fd0c2143f5bfdca93ba7 Mon Sep 17 00:00:00 2001 From: Khaled Nassar Date: Mon, 25 Apr 2022 00:52:43 +0200 Subject: [PATCH] Better output --- scanners/src/lib.rs | 2 +- scanners/src/model.rs | 1 - scanners/src/scan.rs | 8 ++- scanners/src/scan/xss/mod.rs | 110 +++++++++++++++++------------------ 4 files changed, 61 insertions(+), 60 deletions(-) diff --git a/scanners/src/lib.rs b/scanners/src/lib.rs index 04ca6364..dfa7c6a0 100644 --- a/scanners/src/lib.rs +++ b/scanners/src/lib.rs @@ -1,5 +1,5 @@ -pub mod scan; pub mod model; +pub mod scan; pub use urlencoding::encode as url_encode; #[cfg(test)] diff --git a/scanners/src/model.rs b/scanners/src/model.rs index 0d3bcc80..70634edc 100644 --- a/scanners/src/model.rs +++ b/scanners/src/model.rs @@ -5,4 +5,3 @@ pub struct Report { pub curl: String, pub url: String, } - diff --git a/scanners/src/scan.rs b/scanners/src/scan.rs index 22ec768b..abb0373a 100644 --- a/scanners/src/scan.rs +++ b/scanners/src/scan.rs @@ -6,7 +6,7 @@ use std::fs::read_to_string; use yaml_rust::YamlLoader; mod xss; -use xss::{accept_html,XssPayloads, XssUrlParamsValue}; +use xss::{accept_html, XssPayloads, XssUrlParamsValue}; #[derive(Debug)] pub enum Payloads { @@ -174,9 +174,11 @@ impl Scanner { .start_handler(move |_| { log::info!("Thread pool is starting"); }) - .num_threads(concurrency).build().unwrap(); + .num_threads(concurrency) + .build() + .unwrap(); - threader.install(||{ + threader.install(|| { self.requests.par_iter().for_each(|request| { self.modules.iter().for_each(|module| { let module = module.as_str(); diff --git a/scanners/src/scan/xss/mod.rs b/scanners/src/scan/xss/mod.rs index 3924206a..e49bdcd3 100644 --- a/scanners/src/scan/xss/mod.rs +++ b/scanners/src/scan/xss/mod.rs @@ -1,14 +1,14 @@ extern crate scant3r_utils; use crate::model::Report; +use console::style; use indicatif::ProgressBar; use log::error; use scant3r_utils::{ + injector::{Injector, Urlinjector}, random_str, requests::{Curl, Msg}, - injector::{Injector, Urlinjector}, }; -use console::style; mod parser; use parser::{html_parse, html_search}; @@ -16,9 +16,19 @@ use parser::{html_parse, html_search}; mod bypass; pub use bypass::{PayloadGen, XssPayloads}; - -pub fn print_poc(report: &Report) { - println!("{} Valid XSS\n{} URL: {}\n{} CURL: {}\n{} MATCH: {}\n{} PAYLOAD: \"{}\"", style("[+]").green(), style("[!]").yellow(), report.url, style("[!]").yellow(),report.curl,style("[!]").yellow(),report.match_payload,style("[!]").yellow(),report.payload.replace("\"","\\\"")); +pub fn print_poc(report: &Report) -> String { + format!( + "{} Valid XSS\n{} URL: {}\n{} MATCH: {}\n{} PAYLOAD: \"{}\"\n{} CURL: {}\n", + style("[+]").green(), + style("[!]").yellow(), + report.url, + style("[!]").yellow(), + report.match_payload, + style("[!]").yellow(), + report.payload.replace("\"", "\\\""), + style("[!]").yellow(), + report.curl, + ) } pub struct Xss<'t> { @@ -29,8 +39,8 @@ pub struct Xss<'t> { pub trait XssUrlParamsValue { // scan url params value - fn value_reflected(&self) -> Vec; - fn value_scan(&self, _prog: &ProgressBar) -> Vec; + fn value_reflected(&self) -> Vec; + fn value_scan(&self, _prog: &ProgressBar) -> Vec; } impl Xss<'_> { @@ -47,43 +57,40 @@ impl Xss<'_> { } pub fn accept_html(req: &Msg) -> bool { - let block_headers = vec![ - "application/json", - "application/javascript", - "text/javascript", - "text/plain", - "text/css", - "image/jpeg", - "image/png", - "image/bmp", - "image/gif", - "application/rss+xml", - ]; + let block_headers = vec![ + "application/json", + "application/javascript", + "text/javascript", + "text/plain", + "text/css", + "image/jpeg", + "image/png", + "image/bmp", + "image/gif", + "application/rss+xml", + ]; - let mut is_html = false; - match req.send() { - Ok(resp) => { - block_headers.iter().for_each(|header| { - if resp.headers.contains_key("Content-Type") { - if resp.headers.get("Content-Type").unwrap() == header { - is_html = true; - } - } else { - is_html = true; - } - }) - }, - Err(e) => { - error!("{}", e); - return false; - }, + let mut is_html = false; + match req.send() { + Ok(resp) => block_headers.iter().for_each(|header| { + if resp.headers.contains_key("Content-Type") { + if resp.headers.get("Content-Type").unwrap() == header { + is_html = true; + } + } else { + is_html = true; + } + }), + Err(e) => { + error!("{}", e); + return false; } - is_html } + is_html +} impl XssUrlParamsValue for Xss<'_> { - - fn value_reflected(&self) -> Vec { + fn value_reflected(&self) -> Vec { let mut reflected_parameters: Vec = Vec::new(); let payload = random_str(5); let check_requests = self.injector.url_value(&payload); @@ -109,7 +116,7 @@ impl XssUrlParamsValue for Xss<'_> { reflected_parameters } - fn value_scan(&self, _prog: &ProgressBar) -> Vec { + fn value_scan(&self, _prog: &ProgressBar) -> Vec { let mut _found: Vec = Vec::new(); for param in self.value_reflected() { let mut req = self.request.clone(); @@ -130,27 +137,20 @@ impl XssUrlParamsValue for Xss<'_> { req.url = self.injector.set_urlvalue(¶m, &pay.payload); match req.send() { Ok(resp) => { - let d = html_search(resp.body.as_str(), &pay.search); - if d.len() > count.len() { - /*_prog.println(format!( - "FOUND XSS \nReflect: {:?}\nPayload: {}\nMatch: {}\nCURL: \n{}", - reflect, - pay.payload, - d, - req.curl() - ));*/ - print_poc(&Report{ + let payload_found = html_search(resp.body.as_str(), &pay.search); + if payload_found.len() > count.len() { + _found.push(Report { url: req.url.to_string(), - match_payload: d, + match_payload: payload_found.clone(), payload: pay.payload.to_string(), curl: req.curl(), }); - /*_found.push(Report{ + _prog.println(print_poc(&Report { url: req.url.to_string(), - match_payload: d, + match_payload: payload_found, payload: pay.payload.to_string(), curl: req.curl(), - });*/ + })); break; } } @@ -162,5 +162,5 @@ impl XssUrlParamsValue for Xss<'_> { } } _found - } + } }