First attempt enabling exclude port list capability Issue #530 (#534)

* First attempt enabling exclude port list capability

* disabling a not desired println! used for debugging purpose

* fixing small typo:  dbg! by debug!

* adding emtpy commit to make CI/CD pass

* running cargo fmt and removing a TODO comment

* Actually running cargo fmt without check LoL

* fixed some clippy error

* fixing one more cargo clippy complain

---------

Co-authored-by: Wuelfhis Asuaje <wasuaje@shorecg.com>
This commit is contained in:
Wuelfhis Asuaje 2024-04-10 03:15:43 -03:00 committed by GitHub
parent 6b6b2f267c
commit 170f57c0a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 3 deletions

2
.gitignore vendored
View File

@ -120,3 +120,5 @@ fabric.properties
.idea/*
.idea
.idea*
settings.json

View File

@ -140,6 +140,10 @@ pub struct Opts {
/// For things like --script '(safe and vuln)' enclose it in quotations marks \"'(safe and vuln)'\"")
#[structopt(last = true)]
pub command: Vec<String>,
/// A list of comma separated ports to be excluded from scanning. Example: 80,443,8080.
#[structopt(short, long, use_delimiter = true)]
pub exclude_ports: Option<Vec<u16>>,
}
#[cfg(not(tarpaulin_include))]
@ -203,7 +207,7 @@ impl Opts {
self.ports = Some(ports);
}
merge_optional!(range, ulimit);
merge_optional!(range, ulimit, exclude_ports);
}
}
@ -225,6 +229,7 @@ pub struct Config {
scan_order: Option<ScanOrder>,
command: Option<Vec<String>>,
scripts: Option<ScriptsRequired>,
exclude_ports: Option<Vec<u16>>,
}
#[cfg(not(tarpaulin_include))]
@ -239,6 +244,7 @@ impl Config {
/// ports = [80, 443, 8080]
/// greppable = true
/// scan_order: "Serial"
/// exclude_ports = [8080, 9090, 80]
///
pub fn read(custom_config_path: Option<PathBuf>) -> Self {
let mut content = String::new();
@ -289,6 +295,7 @@ mod tests {
accessible: Some(true),
scan_order: Some(ScanOrder::Random),
scripts: None,
exclude_ports: None,
}
}
}
@ -311,6 +318,7 @@ mod tests {
top: false,
scripts: ScriptsRequired::Default,
config_path: None,
exclude_ports: None,
}
}
}

View File

@ -98,6 +98,9 @@ fn main() {
#[cfg(not(unix))]
let batch_size: u16 = AVERAGE_BATCH_SIZE;
// Added by wasuaje - 01/26/2024:
// exclude_ports is an exclusion port list
//
let scanner = Scanner::new(
&ips,
batch_size,
@ -106,6 +109,7 @@ fn main() {
opts.greppable,
PortStrategy::pick(&opts.range, opts.ports, opts.scan_order),
opts.accessible,
opts.exclude_ports.unwrap_or_default(),
);
debug!("Scanner finished building: {:?}", scanner);

View File

@ -21,6 +21,8 @@ use std::{
/// batch_size is how many ports at a time should be scanned
/// Timeout is the time RustScan should wait before declaring a port closed. As datatype Duration.
/// greppable is whether or not RustScan should print things, or wait until the end to print only the ip and open ports.
/// Added by wasuaje - 01/26/2024:
/// exclude_ports is an exclusion port list
#[cfg(not(tarpaulin_include))]
#[derive(Debug)]
pub struct Scanner {
@ -31,8 +33,11 @@ pub struct Scanner {
greppable: bool,
port_strategy: PortStrategy,
accessible: bool,
exclude_ports: Vec<u16>,
}
// Allowing too many arguments for clippy.
#[allow(clippy::too_many_arguments)]
impl Scanner {
pub fn new(
ips: &[IpAddr],
@ -42,6 +47,7 @@ impl Scanner {
greppable: bool,
port_strategy: PortStrategy,
accessible: bool,
exclude_ports: Vec<u16>,
) -> Self {
Self {
batch_size,
@ -51,14 +57,23 @@ impl Scanner {
port_strategy,
ips: ips.iter().map(ToOwned::to_owned).collect(),
accessible,
exclude_ports,
}
}
/// Runs scan_range with chunk sizes
/// If you want to run RustScan normally, this is the entry point used
/// Returns all open ports as Vec<u16>
/// Added by wasuaje - 01/26/2024:
/// Filtering port against exclude port list
pub async fn run(&self) -> Vec<SocketAddr> {
let ports: Vec<u16> = self.port_strategy.order();
let ports: Vec<u16> = self
.port_strategy
.order()
.iter()
.filter(|&port| !self.exclude_ports.contains(port))
.copied()
.collect();
let mut socket_iterator: SocketIterator = SocketIterator::new(&self.ips, &ports);
let mut open_sockets: Vec<SocketAddr> = Vec::new();
let mut ftrs = FuturesUnordered::new();
@ -72,7 +87,7 @@ impl Scanner {
}
}
debug!("Start scanning sockets. \nBatch size {}\nNumber of ip-s {}\nNumber of ports {}\nTargets all together {} ",
debug!("Start scanning sockets. \nBatch size {}\nNumber of ip-s {}\nNumber of ports {}\nTargets all together {} ",
self.batch_size,
self.ips.len(),
&ports.len(),
@ -195,6 +210,7 @@ mod tests {
true,
strategy,
true,
vec![9000],
);
block_on(scanner.run());
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
@ -217,6 +233,7 @@ mod tests {
true,
strategy,
true,
vec![9000],
);
block_on(scanner.run());
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
@ -238,6 +255,7 @@ mod tests {
true,
strategy,
true,
vec![9000],
);
block_on(scanner.run());
assert_eq!(1, 1);
@ -258,6 +276,7 @@ mod tests {
true,
strategy,
true,
vec![9000],
);
block_on(scanner.run());
assert_eq!(1, 1);
@ -281,6 +300,7 @@ mod tests {
true,
strategy,
true,
vec![9000],
);
block_on(scanner.run());
assert_eq!(1, 1);