mirror of
https://github.com/bee-san/RustScan.git
synced 2026-11-07 09:46:04 -10:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa072bac12 | ||
|
|
ff5a4b44f8 | ||
|
|
3763c384ca | ||
|
|
7b85b9756b | ||
|
|
d23b4f1ccf | ||
|
|
a185d0fb26 | ||
|
|
64624e90b3 | ||
|
|
774213cc15 | ||
|
|
58906b7f7e |
No files matched your search
+47
-24
@@ -2,6 +2,7 @@ use serde_derive::Deserialize;
|
||||
use std::fs;
|
||||
use structopt::{clap::arg_enum, StructOpt};
|
||||
|
||||
|
||||
const LOWEST_PORT_NUMBER: u16 = 1;
|
||||
const TOP_PORT_NUMBER: u16 = 65535;
|
||||
|
||||
@@ -70,9 +71,9 @@ pub struct Opts {
|
||||
#[structopt(short, long)]
|
||||
pub no_config: bool,
|
||||
|
||||
/// Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
|
||||
/// greppable mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
|
||||
#[structopt(short, long)]
|
||||
pub quiet: bool,
|
||||
pub greppable: bool,
|
||||
|
||||
/// Accessible mode. Turns off features which negatively affect screen readers.
|
||||
#[structopt(long)]
|
||||
@@ -110,6 +111,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>,
|
||||
|
||||
/// Use the top 1000 ports.
|
||||
#[structopt(long)]
|
||||
pub top: bool,
|
||||
}
|
||||
|
||||
impl Opts {
|
||||
@@ -146,7 +151,7 @@ impl Opts {
|
||||
}
|
||||
}
|
||||
|
||||
merge_required!(addresses, quiet, accessible, batch_size, timeout, scan_order, command);
|
||||
merge_required!(addresses, greppable, accessible, batch_size, timeout, scan_order, command);
|
||||
}
|
||||
|
||||
fn merge_optional(&mut self, config: &Config) {
|
||||
@@ -160,7 +165,12 @@ impl Opts {
|
||||
}
|
||||
}
|
||||
|
||||
merge_optional!(ports, range, ulimit);
|
||||
// Only use top ports when the user asks for them
|
||||
if self.top {
|
||||
// self.ports = config.ports.clone().values().cloned().collect();
|
||||
}
|
||||
|
||||
merge_optional!(range, ulimit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +182,7 @@ pub struct Config {
|
||||
addresses: Option<Vec<String>>,
|
||||
ports: Option<Vec<u16>>,
|
||||
range: Option<PortRange>,
|
||||
quiet: Option<bool>,
|
||||
greppable: Option<bool>,
|
||||
accessible: Option<bool>,
|
||||
batch_size: Option<u16>,
|
||||
timeout: Option<u32>,
|
||||
@@ -182,6 +192,7 @@ pub struct Config {
|
||||
command: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
|
||||
impl Config {
|
||||
/// Reads the configuration file with TOML format and parses it into a
|
||||
/// Config struct.
|
||||
@@ -190,12 +201,23 @@ impl Config {
|
||||
///
|
||||
/// addresses = ["127.0.0.1", "127.0.0.1"]
|
||||
/// ports = [80, 443, 8080]
|
||||
/// quiet = true
|
||||
/// greppable = true
|
||||
/// scan_order: "Serial"
|
||||
///
|
||||
pub fn read() -> Self {
|
||||
|
||||
let config_dir = dirs::home_dir();
|
||||
|
||||
// TODO make opt.accessible use opts
|
||||
// right now its greppable=False, accessible=True
|
||||
// I want it to use opts.accessible instead of accessible=True
|
||||
crate::detail!(format!(
|
||||
"{} {:?}",
|
||||
"The config file is expected to be at", config_dir
|
||||
), false, true);
|
||||
|
||||
let mut paths = Vec::new();
|
||||
paths.push(match dirs::home_dir() {
|
||||
paths.push(match config_dir {
|
||||
Some(mut path) => {
|
||||
path.push(".rustscan.toml");
|
||||
path
|
||||
@@ -203,30 +225,26 @@ impl Config {
|
||||
None => panic!("Could not infer config file path."),
|
||||
});
|
||||
|
||||
paths.push(match dirs::config_dir() {
|
||||
Some(mut path) => {
|
||||
path.push("rustscan");
|
||||
path.push("config.toml");
|
||||
path
|
||||
}
|
||||
None => panic!("Could not infer config file path."),
|
||||
});
|
||||
|
||||
let mut contents: Option<String> = None;
|
||||
for path in paths.iter().rev() {
|
||||
println!{"path is {:?}", path};
|
||||
contents = match fs::read_to_string(path) {
|
||||
Ok(content) => {
|
||||
contents = Some(content);
|
||||
println!("contents is {:?}", contents);
|
||||
break;
|
||||
}
|
||||
Err(_) => None,
|
||||
};
|
||||
println!("contents is {:?}", contents);
|
||||
}
|
||||
// println!("{:?}", contents);
|
||||
|
||||
if contents.is_none() {
|
||||
contents = Some(String::new());
|
||||
}
|
||||
|
||||
|
||||
let config: Config = match toml::from_str(&contents.unwrap()) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
@@ -235,6 +253,8 @@ impl Config {
|
||||
}
|
||||
};
|
||||
|
||||
println!("\nconfig is {:?}", config);
|
||||
|
||||
config
|
||||
}
|
||||
}
|
||||
@@ -249,7 +269,7 @@ mod tests {
|
||||
addresses: vec![],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: false,
|
||||
greppable: false,
|
||||
batch_size: 0,
|
||||
timeout: 0,
|
||||
ulimit: None,
|
||||
@@ -258,13 +278,14 @@ mod tests {
|
||||
no_nmap: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: true,
|
||||
top: false,
|
||||
};
|
||||
|
||||
let config = Config {
|
||||
addresses: Some(vec!["127.0.0.1".to_owned()]),
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: Some(true),
|
||||
greppable: Some(true),
|
||||
batch_size: Some(25_000),
|
||||
timeout: Some(1_000),
|
||||
ulimit: None,
|
||||
@@ -277,7 +298,7 @@ mod tests {
|
||||
opts.merge(&config);
|
||||
|
||||
assert_eq!(opts.addresses, vec![] as Vec<String>);
|
||||
assert_eq!(opts.quiet, false);
|
||||
assert_eq!(opts.greppable, false);
|
||||
assert_eq!(opts.accessible, false);
|
||||
assert_eq!(opts.timeout, 0);
|
||||
assert_eq!(opts.command, vec![] as Vec<String>);
|
||||
@@ -290,7 +311,7 @@ mod tests {
|
||||
addresses: vec![],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: false,
|
||||
greppable: false,
|
||||
batch_size: 0,
|
||||
timeout: 0,
|
||||
ulimit: None,
|
||||
@@ -299,6 +320,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_nmap: false,
|
||||
no_config: false,
|
||||
top: false,
|
||||
};
|
||||
|
||||
let config = Config {
|
||||
@@ -306,7 +328,7 @@ mod tests {
|
||||
ports: None,
|
||||
no_nmap: Some(false),
|
||||
range: None,
|
||||
quiet: Some(true),
|
||||
greppable: Some(true),
|
||||
batch_size: Some(25_000),
|
||||
timeout: Some(1_000),
|
||||
ulimit: None,
|
||||
@@ -318,7 +340,7 @@ mod tests {
|
||||
opts.merge_required(&config);
|
||||
|
||||
assert_eq!(opts.addresses, config.addresses.unwrap());
|
||||
assert_eq!(opts.quiet, config.quiet.unwrap());
|
||||
assert_eq!(opts.greppable, config.greppable.unwrap());
|
||||
assert_eq!(opts.timeout, config.timeout.unwrap());
|
||||
assert_eq!(opts.command, config.command.unwrap());
|
||||
assert_eq!(opts.accessible, config.accessible.unwrap());
|
||||
@@ -331,7 +353,7 @@ mod tests {
|
||||
addresses: vec![],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: false,
|
||||
greppable: false,
|
||||
batch_size: 0,
|
||||
timeout: 0,
|
||||
ulimit: None,
|
||||
@@ -340,6 +362,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_nmap: false,
|
||||
no_config: false,
|
||||
top: false,
|
||||
};
|
||||
|
||||
let config = Config {
|
||||
@@ -349,7 +372,7 @@ mod tests {
|
||||
start: 1,
|
||||
end: 1_000,
|
||||
}),
|
||||
quiet: None,
|
||||
greppable: None,
|
||||
batch_size: None,
|
||||
timeout: None,
|
||||
no_nmap: Some(false),
|
||||
|
||||
+33
-36
@@ -1,6 +1,6 @@
|
||||
extern crate shell_words;
|
||||
|
||||
mod tui;
|
||||
pub mod tui;
|
||||
|
||||
mod input;
|
||||
use input::{Config, Opts, PortRange, ScanOrder};
|
||||
@@ -45,14 +45,14 @@ fn main() {
|
||||
|
||||
info!("Main() `opts` arguments are {:?}", opts);
|
||||
|
||||
if !opts.quiet && !opts.accessible {
|
||||
if !opts.greppable && !opts.accessible {
|
||||
print_opening();
|
||||
}
|
||||
|
||||
let ips: Vec<IpAddr> = parse_addresses(&opts);
|
||||
|
||||
if ips.is_empty() {
|
||||
warning!("No IPs could be resolved, aborting scan.", false);
|
||||
warning!("No IPs could be resolved, aborting scan.", false, opts.accessible);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ fn main() {
|
||||
&ips,
|
||||
batch_size,
|
||||
Duration::from_millis(opts.timeout.into()),
|
||||
opts.quiet,
|
||||
opts.greppable,
|
||||
PortStrategy::pick(opts.range, opts.ports, opts.scan_order),
|
||||
);
|
||||
|
||||
@@ -93,19 +93,19 @@ fn main() {
|
||||
opts.batch_size,
|
||||
(opts.batch_size / 2).to_string(),
|
||||
"'rustscan -b <batch_size> <ip address>'");
|
||||
warning!(x, opts.quiet);
|
||||
warning!(x, opts.greppable, opts.accessible);
|
||||
}
|
||||
|
||||
for (ip, ports) in ports_per_ip.iter_mut() {
|
||||
let nmap_str_ports: Vec<String> = ports.into_iter().map(|port| port.to_string()).collect();
|
||||
|
||||
detail!("Starting Nmap", opts.quiet);
|
||||
detail!("Starting Nmap", opts.greppable, opts.accessible);
|
||||
|
||||
// nmap port style is 80,443. Comma separated with no spaces.
|
||||
let ports_str = nmap_str_ports.join(",");
|
||||
|
||||
// if quiet mode is on nmap should not be spawned
|
||||
if opts.quiet {
|
||||
// if greppable mode is on nmap should not be spawned
|
||||
if opts.greppable {
|
||||
println!("{}", ports_str);
|
||||
continue;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ fn main() {
|
||||
output!(format!(
|
||||
"The Nmap command to be run is nmap {}\n",
|
||||
&nmap_args.join(" ")
|
||||
));
|
||||
), false, opts.accessible);
|
||||
|
||||
// Runs the nmap command and spawns it as a process.
|
||||
let mut child = Command::new("nmap")
|
||||
@@ -146,19 +146,7 @@ Faster Nmap scanning with Rust."#;
|
||||
println!("{}", info.gradient(Color::Yellow).bold());
|
||||
funny_opening!();
|
||||
|
||||
let config_path = match dirs::config_dir() {
|
||||
Some(mut path) => {
|
||||
path.push("rustscan");
|
||||
path.push("config.toml");
|
||||
path
|
||||
}
|
||||
None => panic!("Couldn't find config dir."),
|
||||
};
|
||||
|
||||
detail!(format!(
|
||||
"{} {:?}",
|
||||
"The config file is expected to be at", config_path
|
||||
));
|
||||
}
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn build_nmap_arguments<'a>(
|
||||
@@ -191,7 +179,7 @@ fn parse_addresses(opts: &Opts) -> Vec<IpAddr> {
|
||||
Ok(mut iter) => ips.push(iter.nth(0).unwrap().ip()),
|
||||
_ => {
|
||||
let failed_to_resolve = format!("Host {:?} could not be resolved.", ip_or_host);
|
||||
warning!(failed_to_resolve, opts.quiet);
|
||||
warning!(failed_to_resolve, opts.greppable, opts.accessible);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -208,7 +196,7 @@ fn adjust_ulimit_size(opts: &Opts) -> rlimit::rlim {
|
||||
Ok(_) => {
|
||||
detail!(
|
||||
format!("Automatically increasing ulimit value to {}.", limit),
|
||||
opts.quiet
|
||||
opts.greppable, opts.accessible
|
||||
);
|
||||
}
|
||||
Err(_) => println!("{}", "ERROR. Failed to set ulimit value."),
|
||||
@@ -226,7 +214,7 @@ fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
|
||||
// Adjust the batch size when the ulimit value is lower than the desired batch size
|
||||
if ulimit < batch_size {
|
||||
warning!("File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers",
|
||||
opts.quiet
|
||||
opts.greppable, opts.accessible
|
||||
);
|
||||
|
||||
// When the OS supports high file limits like 8000, but the user
|
||||
@@ -236,7 +224,7 @@ fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
|
||||
// ulimit is smaller than aveage batch size
|
||||
// user must have very small ulimit
|
||||
// decrease batch size to half of ulimit
|
||||
warning!("Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'. ");
|
||||
warning!("Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'. ", false, opts.accessible);
|
||||
info!("Halving batch_size because ulimit is smaller than average batch size");
|
||||
batch_size = ulimit / 2
|
||||
} else if ulimit > DEFAULT_FILE_DESCRIPTORS_LIMIT {
|
||||
@@ -252,7 +240,7 @@ fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
|
||||
detail!(format!(
|
||||
"File limit higher than batch size. Can increase speed by increasing batch size '-b {}'.",
|
||||
ulimit - 100
|
||||
), opts.quiet);
|
||||
), opts.greppable, opts.accessible);
|
||||
}
|
||||
|
||||
batch_size as u16
|
||||
@@ -271,7 +259,7 @@ mod tests {
|
||||
addresses: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -280,6 +268,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 120);
|
||||
|
||||
@@ -292,7 +281,7 @@ mod tests {
|
||||
addresses: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -301,6 +290,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 9_000);
|
||||
|
||||
@@ -314,7 +304,7 @@ mod tests {
|
||||
addresses: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -323,6 +313,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 5_000);
|
||||
|
||||
@@ -335,7 +326,7 @@ mod tests {
|
||||
addresses: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -344,6 +335,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let batch_size = adjust_ulimit_size(&opts);
|
||||
|
||||
@@ -356,12 +348,12 @@ mod tests {
|
||||
assert!(1 == 1);
|
||||
}
|
||||
#[test]
|
||||
fn test_high_ulimit_no_quiet_mode() {
|
||||
fn test_high_ulimit_no_greppable_mode() {
|
||||
let opts = Opts {
|
||||
addresses: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: false,
|
||||
greppable: false,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: None,
|
||||
@@ -370,6 +362,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
|
||||
infer_batch_size(&opts, 1_000_000);
|
||||
@@ -383,7 +376,7 @@ mod tests {
|
||||
addresses: vec!["127.0.0.1".to_owned(), "192.168.0.0/30".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -392,6 +385,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
@@ -413,7 +407,7 @@ mod tests {
|
||||
addresses: vec!["google.com".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -422,6 +416,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
@@ -434,7 +429,7 @@ mod tests {
|
||||
addresses: vec!["127.0.0.1".to_owned(), "im_wrong".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -443,6 +438,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
@@ -455,7 +451,7 @@ mod tests {
|
||||
addresses: vec!["im_wrong".to_owned(), "300.10.1.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
greppable: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
@@ -464,6 +460,7 @@ mod tests {
|
||||
scan_order: ScanOrder::Serial,
|
||||
no_config: false,
|
||||
no_nmap: false,
|
||||
top: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
|
||||
@@ -92,7 +92,6 @@ impl Scanner {
|
||||
async fn scan_socket(&self, socket: SocketAddr) -> io::Result<SocketAddr> {
|
||||
match self.connect(socket).await {
|
||||
Ok(x) => {
|
||||
// match stream_result.shutdown(Shutdown::Both)
|
||||
info!("Shutting down stream");
|
||||
match x.shutdown(Shutdown::Both) {
|
||||
_ => {}
|
||||
|
||||
+23
-21
@@ -3,44 +3,46 @@
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warning {
|
||||
($name:expr) => {
|
||||
($name:expr, $greppable:expr, $accessible:expr) => {
|
||||
use ansi_term::Colour::Red;
|
||||
println!("{} {}", Red.bold().paint("[!]"), $name);
|
||||
};
|
||||
// quiet mode
|
||||
($name:expr, $quiet:expr) => {
|
||||
use ansi_term::Colour::Red;
|
||||
if !$quiet {
|
||||
// if greppable, no else statement so do not print.
|
||||
if !$greppable {
|
||||
println!("{} {}", Red.bold().paint("[!]"), $name);
|
||||
}
|
||||
else if !$accessible{
|
||||
// Don't print the ascii art
|
||||
println!("{}", $name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! detail {
|
||||
($name:expr) => {
|
||||
($name:expr, $greppable:expr, $accessible:expr) => {
|
||||
use ansi_term::Colour::Blue;
|
||||
println!("{} {}", Blue.bold().paint("[~]"), $name);
|
||||
};
|
||||
($name:expr, $quiet:expr) => {
|
||||
use ansi_term::Colour::Blue;
|
||||
if !$quiet {
|
||||
// if greppable, no else statement so do not print.
|
||||
if !$greppable {
|
||||
println!("{} {}", Blue.bold().paint("[~]"), $name);
|
||||
}
|
||||
else if !$accessible{
|
||||
// Don't print the ascii art
|
||||
println!("{}", $name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! output {
|
||||
($name:expr, $quiet:expr) => {
|
||||
($name:expr, $greppable:expr, $accessible:expr) => {
|
||||
use ansi_term::Colour::RGB;
|
||||
if !$quiet {
|
||||
// if greppable, no else statement so do not print.
|
||||
if !$greppable {
|
||||
println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
}
|
||||
};
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::RGB;
|
||||
println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
else if !$accessible{
|
||||
// Don't print the ascii art
|
||||
println!("{}", $name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,15 +52,15 @@ macro_rules! funny_opening {
|
||||
() => {
|
||||
use rand::seq::SliceRandom;
|
||||
let quotes = vec![
|
||||
"Nmap? More like slowmap.🐢",
|
||||
"Hello, Elliot.",
|
||||
"🌍HACK THE PLANET🌍",
|
||||
"Real hackers hack time ⌛",
|
||||
"Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan",
|
||||
"😵 https://admin.tryhackme.com",
|
||||
"Mess with the best, die like the rest",
|
||||
];
|
||||
let random_quote = quotes.choose(&mut rand::thread_rng()).unwrap();
|
||||
|
||||
println!("{}\n", random_quote);
|
||||
// println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user