Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ serde_derive = "1.0.116"
cidr-utils = "0.5.0"
itertools = "0.9.0"
trust-dns-resolver = { version = "0.19.5", features = ["dns-over-rustls"] }
anyhow = "1.0.33"
subprocess = "0.2.6"
text_placeholder = { version = "0.4", features = ["struct_context"] }

[dev-dependencies]
wait-timeout = "0.2"
Expand Down
14 changes: 14 additions & 0 deletions fixtures/test_rustscan_scripts.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Test/Example ScriptConfig file

# Tags to filter on scripts. Only scripts containing all these tags will run.
tags = ["core_approved", "example"]
Comment thread
bergabman marked this conversation as resolved.

# If it's present then only those scripts will run which has a tag ports = "80". Not yet implemented.
#
# ex.:
# ports = [80]
# ports = [80,81,8080]
ports = [80]

# Only this developer(s) scripts to run. Not yet implemented.
developer = ["example"]
23 changes: 23 additions & 0 deletions fixtures/test_script.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/perl
#tags = ["core_approved", "example",]
#developer = [ "example", "https://example.org" ]
#ports_separator = ","
#call_format = "perl {{script}} {{ip}} {{port}}"

# Sriptfile parser stops at the first blank line with parsing.
# This script will run itself as an argument with the system installed perl interpreter, ports will be concatenated with "," .
# Unused field: trigger_port = "80"
# get total arg passed to this script
my $total = $#ARGV + 1;
my $counter = 1;

# get script name
my $scriptname = $0;

print "Total args passed to $scriptname : $total\n";

# Use loop to print all args stored in an array called @ARGV
foreach my $a(@ARGV) {
print "Arg # $counter : $a\n";
$counter++;
}
13 changes: 13 additions & 0 deletions fixtures/test_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/python3
#tags = ["core_approved", "example",]
#developer = [ "example", "https://example.org" ]
#trigger_port = "80"
#call_format = "python3 {{script}} {{ip}} {{port}}"

# Sriptfile parser stops at the first blank line with parsing.
# This script will run itself as an argument with the system installed python interpreter, only scanning port 80.
# Unused filed: ports_separator = ","

import sys

print('Python script ran with arguments', str(sys.argv))
12 changes: 12 additions & 0 deletions fixtures/test_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
#tags = ["core_approved", "example",]
#developer = [ "example", "https://example.org" ]
#ports_separator = ","
#call_format = "bash {{script}} {{ip}} {{port}}"

# Sriptfile parser stops at the first blank line with parsing.
# This script will run itself as an argument with the system installed bash interpreter, scanning all ports concatenated with "," .
# Unused filed: trigger_port = "80"

# print all arguments passed to the script
echo $@
9 changes: 9 additions & 0 deletions fixtures/test_script.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!intentional_blank_line
#tags = ["core_approved", "example"]
#developer = [ "example", "https://example.org" ]
#ports_separator = ","
#call_format = "nmap -vvv -p {{port}} {{ip}}"

# Sriptfile parser stops at the first blank line with parsing.
# This script will run the system installed nmap, ports will be concatenated with "," .
# Unused field: trigger_port = "80"
46 changes: 30 additions & 16 deletions src/input.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use serde_derive::Deserialize;
use std::collections::HashMap;
use std::fs;

use structopt::{clap::arg_enum, StructOpt};

const LOWEST_PORT_NUMBER: u16 = 1;
Expand All @@ -18,6 +17,19 @@ arg_enum! {
}
}

arg_enum! {
/// Represents the scripts variant.
/// - none will avoid running any script, only portscan results will be shown.
/// - default will run the default embedded nmap script, that's part of RustScan since the beginning.
/// - custom will read the ScriptConfig file and the available scripts in the predefined folders
#[derive(Deserialize, Debug, StructOpt, Clone, PartialEq, Copy)]
pub enum ScriptsRequired {
None,
Default,
Custom,
}
}

/// Represents the range of ports to be scanned.
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct PortRange {
Expand Down Expand Up @@ -49,7 +61,7 @@ fn parse_range(input: &str) -> Result<PortRange, String> {
}
}

#[derive(StructOpt, Debug)]
#[derive(StructOpt, Debug, Clone)]
#[structopt(name = "rustscan", setting = structopt::clap::AppSettings::TrailingVarArg)]
/// Fast Port Scanner built in Rust.
/// WARNING Do not use this program against sensitive infrastructure since the
Expand Down Expand Up @@ -81,10 +93,6 @@ pub struct Opts {
#[structopt(long)]
pub accessible: bool,

/// Turns off Nmap.
#[structopt(long)]
pub no_nmap: bool,

/// The batch size for port scanning, it increases or slows the speed of
/// scanning. Depends on the open file limit of your OS. If you do 65535
/// it will do every port at the same time. Although, your OS may not
Expand All @@ -111,17 +119,21 @@ pub struct Opts {
#[structopt(long, possible_values = &ScanOrder::variants(), case_insensitive = true, default_value = "serial")]
pub scan_order: ScanOrder,

/// The Nmap arguments to run.
/// Level of scripting required for the run.
#[structopt(long, possible_values = &ScriptsRequired::variants(), case_insensitive = true, default_value = "default")]
pub scripts: ScriptsRequired,

/// Use the top 1000 ports.
#[structopt(long)]
pub top: bool,
Comment thread
bergabman marked this conversation as resolved.

/// The Script arguments to run.
/// To use the argument -A, end RustScan's args with '-- -A'.
/// Example: 'rustscan -T 1500 127.0.0.1 -- -A -sC'.
/// This command adds -Pn -vvv -p $PORTS automatically to nmap.
/// For things like --script '(safe and vuln)' enclose it in quotations marks \"'(safe and vuln)'\"")
#[structopt(last = true)]
pub command: Vec<String>,

/// Use the top 1000 ports.
#[structopt(long)]
pub top: bool,
}

#[cfg(not(tarpaulin_include))]
Expand Down Expand Up @@ -160,7 +172,8 @@ impl Opts {
}

merge_required!(
addresses, greppable, accessible, batch_size, timeout, tries, scan_order, command
addresses, greppable, accessible, batch_size, timeout, tries, scan_order, scripts,
command
);
}

Expand Down Expand Up @@ -204,10 +217,10 @@ pub struct Config {
batch_size: Option<u16>,
timeout: Option<u32>,
tries: Option<u8>,
no_nmap: Option<bool>,
ulimit: Option<rlimit::RawRlim>,
scan_order: Option<ScanOrder>,
command: Option<Vec<String>>,
scripts: Option<ScriptsRequired>,
}

#[cfg(not(tarpaulin_include))]
Expand Down Expand Up @@ -251,7 +264,7 @@ impl Config {

#[cfg(test)]
mod tests {
use super::{Config, Opts, PortRange, ScanOrder};
use super::{Config, Opts, PortRange, ScanOrder, ScriptsRequired};
impl Config {
fn default() -> Self {
Self {
Expand All @@ -263,10 +276,10 @@ mod tests {
timeout: Some(1_000),
tries: Some(1),
ulimit: None,
no_nmap: Some(false),
command: Some(vec!["-A".to_owned()]),
accessible: Some(true),
scan_order: Some(ScanOrder::Random),
scripts: None,
}
}
}
Expand All @@ -284,10 +297,10 @@ mod tests {
ulimit: None,
command: vec![],
accessible: false,
no_nmap: false,
scan_order: ScanOrder::Serial,
no_config: true,
top: false,
scripts: ScriptsRequired::Default,
}
}
}
Expand Down Expand Up @@ -320,6 +333,7 @@ mod tests {
assert_eq!(opts.command, config.command.unwrap());
assert_eq!(opts.accessible, config.accessible.unwrap());
assert_eq!(opts.scan_order, config.scan_order.unwrap());
assert_eq!(opts.scripts, ScriptsRequired::Default)
}

#[test]
Expand Down
Loading