Compare commits

..
6 Commits
Author SHA1 Message Date
Bee bd32f4ead4 2.1.1 2022-11-07 10:21:47 +00:00
Artem IvanovandBee 8625f939bf Minor cosmetic changes (#453)
* Minor cosmetic changes

* Minor cosmetic changes

* Update discord link

Co-authored-by: Bee <[email protected]>
2022-11-07 10:16:14 +00:00
Thijs0x57andBee 8f608eaf99 fix links to Docker & Kali wiki (#433)
In the readme there are 2 links to docker & kali, 'Usage' and 'Read the install guide'. These links weren't working.

Co-authored-by: Bee <[email protected]>
2022-11-03 10:08:03 +00:00
NugineandBee f9f2bf6cf8 Upgrade rlimit (#449)
Co-authored-by: Bee <[email protected]>
2022-11-03 09:56:54 +00:00
Callum Haughtey-WilkinsonandBee 6fb1196244 Improve doc for addresses (#457)
Improve documentation for addresses CLI arg to make it
clear that file parsing of addresses is already supported

(#452)

Co-authored-by: Bee <[email protected]>
2022-11-02 15:23:02 +00:00
Callum Haughtey-Wilkinson 61c43dd5d0 Allow CLI customisation of config file path (#456)
Allow CLI customisation of config file path with new
optional argument.

(#437)
2022-11-02 15:17:07 +00:00
5 changed files with 72 additions and 50 deletions

No files matched your search

Generated
+3 -3
View File
@@ -1082,9 +1082,9 @@ dependencies = [
[[package]]
name = "rlimit"
version = "0.5.4"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81a9ed03edbed449d6897c2092c71ab5f7b5fb80f6f0b1a3ed6d40a6f9fc0720"
checksum = "f7278a1ec8bfd4a4e07515c589f5ff7b309a373f987393aef44813d9dcf87aa3"
dependencies = [
"libc",
]
@@ -1110,7 +1110,7 @@ dependencies = [
[[package]]
name = "rustscan"
version = "2.0.0"
version = "2.1.0"
dependencies = [
"ansi_term",
"anyhow",
+3 -3
View File
@@ -1,7 +1,7 @@
[package]
name = "rustscan"
version = "2.1.0"
authors = ["Bee <brando[email protected]>"]
version = "2.1.1"
authors = ["Autumn <autum[email protected]>"]
edition = "2018"
description = "Faster Nmap Scanning with Rust"
homepage = "https://github.com/rustscan/rustscan"
@@ -21,7 +21,7 @@ colored = "2.0.0"
structopt = "0.3.20"
async-std = "1.7.0"
futures = "0.3"
rlimit = "0.5.4"
rlimit = "0.8.3"
shell-words = "1.0.0"
log = "0.4.0"
env_logger = "0.8.2"
+1 -1
View File
@@ -23,7 +23,7 @@
| <p align="center"><a href="https://hub.docker.com/r/cmnatic/rustscan">🐋 Docker (Recommended) </a></p> | <p align="center"><a href="https://github.com/RustScan/RustScan/releases">👩‍💻 Kali / Debian </p> | <p align="center"><a href="https://aur.archlinux.org/packages/rustscan/">🏗️ Arch </a></p> | <p align="center"><a href="https://crates.io/crates/rustscan">🔧 Homebrew </a></p> |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/docker.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/kali.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/arch.png?raw=true" /></p> | <p align="center"><img src="https://raw.githubusercontent.com/RustScan/RustScan/master/pictures/apple.png" /></p> |
| `docker pull rustscan/rustscan:2.0.0` <p>[Usage](https://github.com/RustScan/RustScan#docker-whale) | [Read the install guide](https://github.com/Rustscan/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `brew install rustscan` |
| `docker pull rustscan/rustscan:2.0.0` <p>[Usage](https://github.com/RustScan/RustScan/wiki/Installation-Guide#docker-whale) | [Read the install guide](https://github.com/RustScan/RustScan/wiki/Installation-Guide#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `brew install rustscan` |
<hr>
+23 -12
View File
@@ -1,6 +1,7 @@
use serde_derive::Deserialize;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use structopt::{clap::arg_enum, StructOpt};
const LOWEST_PORT_NUMBER: u16 = 1;
@@ -70,7 +71,7 @@ fn parse_range(input: &str) -> Result<PortRange, String> {
/// - Discord https://discord.gg/GFrQsGy
/// - GitHub https://github.com/RustScan/RustScan
pub struct Opts {
/// A list of comma separated CIDRs, IPs, or hosts to be scanned.
/// A comma-delimited list or newline-delimited file of separated CIDRs, IPs, or hosts to be scanned.
#[structopt(short, long, use_delimiter = true)]
pub addresses: Vec<String>,
@@ -86,6 +87,10 @@ pub struct Opts {
#[structopt(short, long)]
pub no_config: bool,
/// Custom path to config file
#[structopt(short, long, parse(from_os_str))]
pub config_path: Option<PathBuf>,
/// Greppable mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
#[structopt(short, long)]
pub greppable: bool,
@@ -112,7 +117,7 @@ pub struct Opts {
/// Automatically ups the ULIMIT with the value you provided.
#[structopt(short, long)]
pub ulimit: Option<rlimit::RawRlim>,
pub ulimit: Option<u64>,
/// The order of scanning to be performed. The "serial" option will
/// scan ports in ascending order while the "random" option will scan
@@ -216,7 +221,7 @@ pub struct Config {
batch_size: Option<u16>,
timeout: Option<u32>,
tries: Option<u8>,
ulimit: Option<rlimit::RawRlim>,
ulimit: Option<u64>,
scan_order: Option<ScanOrder>,
command: Option<Vec<String>>,
scripts: Option<ScriptsRequired>,
@@ -234,16 +239,11 @@ impl Config {
/// greppable = true
/// scan_order: "Serial"
///
pub fn read() -> Self {
let mut home_dir = match dirs::home_dir() {
Some(dir) => dir,
None => panic!("Could not infer config file path."),
};
home_dir.push(".rustscan.toml");
pub fn read(custom_config_path: Option<PathBuf>) -> Self {
let mut content = String::new();
if home_dir.exists() {
content = match fs::read_to_string(home_dir) {
let config_path = custom_config_path.unwrap_or_else(default_config_path);
if config_path.exists() {
content = match fs::read_to_string(config_path) {
Ok(content) => content,
Err(_) => String::new(),
}
@@ -261,6 +261,16 @@ impl Config {
}
}
/// Constructs default path to config toml
pub fn default_config_path() -> PathBuf {
let mut config_path = match dirs::home_dir() {
Some(dir) => dir,
None => panic!("Could not infer config file path."),
};
config_path.push(".rustscan.toml");
config_path
}
#[cfg(test)]
mod tests {
use super::{Config, Opts, PortRange, ScanOrder, ScriptsRequired};
@@ -300,6 +310,7 @@ mod tests {
no_config: true,
top: false,
scripts: ScriptsRequired::Default,
config_path: None,
}
}
}
+42 -31
View File
@@ -24,9 +24,7 @@ use scripts::{init_scripts, Script, ScriptFile};
use cidr_utils::cidr::IpCidr;
use colorful::{Color, Colorful};
use futures::executor::block_on;
use rlimit::{getrlimit, setrlimit, RawRlim, Resource, Rlim};
use std::collections::HashMap;
use std::convert::TryInto;
use std::fs::File;
use std::io::{prelude::*, BufReader};
use std::net::{IpAddr, ToSocketAddrs};
@@ -42,9 +40,10 @@ extern crate colorful;
extern crate dirs;
// Average value for Ubuntu
const DEFAULT_FILE_DESCRIPTORS_LIMIT: RawRlim = 8000;
#[cfg(unix)]
const DEFAULT_FILE_DESCRIPTORS_LIMIT: u64 = 8000;
// Safest batch size based on experimentation
const AVERAGE_BATCH_SIZE: RawRlim = 3000;
const AVERAGE_BATCH_SIZE: u16 = 3000;
#[macro_use]
extern crate log;
@@ -59,7 +58,7 @@ fn main() {
let mut rustscan_bench = NamedTimer::start("RustScan");
let mut opts: Opts = Opts::read();
let config = Config::read();
let config = Config::read(opts.config_path.clone());
opts.merge(&config);
debug!("Main() `opts` arguments are {:?}", opts);
@@ -93,8 +92,11 @@ fn main() {
std::process::exit(1);
}
let ulimit: RawRlim = adjust_ulimit_size(&opts);
let batch_size: u16 = infer_batch_size(&opts, ulimit);
#[cfg(unix)]
let batch_size: u16 = infer_batch_size(&opts, adjust_ulimit_size(&opts));
#[cfg(not(unix))]
let batch_size: u16 = AVERAGE_BATCH_SIZE;
let scanner = Scanner::new(
&ips,
@@ -205,22 +207,29 @@ fn main() {
/// Prints the opening title of RustScan
fn print_opening(opts: &Opts) {
debug!("Printing opening");
let s = r#".----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner."#;
let s = format!(
"{}\n{}\n{}\n{}\n{}",
r#".----. .-. .-. .----..---. .----. .---. .--. .-. .-."#,
r#"| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |"#,
r#"| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |"#,
r#"`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'"#,
r#"The Modern Day Port Scanner."#
);
println!("{}", s.gradient(Color::Green).bold());
let info = r#"________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------"#;
let info = format!(
"{}\n{}\n{}\n{}",
r#"________________________________________"#,
r#": http://discord.skerritt.blog :"#,
r#": https://github.com/RustScan/RustScan :"#,
r#" --------------------------------------"#
);
println!("{}", info.gradient(Color::Yellow).bold());
funny_opening!();
let config_path = dirs::home_dir()
.expect("Could not infer config file path.")
.join(".rustscan.toml");
let config_path = opts
.config_path
.clone()
.unwrap_or_else(input::default_config_path);
detail!(
format!("The config file is expected to be at {:?}", config_path),
@@ -327,11 +336,11 @@ fn read_ips_from_file(
Ok(ips)
}
fn adjust_ulimit_size(opts: &Opts) -> RawRlim {
if opts.ulimit.is_some() {
let limit: Rlim = Rlim::from_raw(opts.ulimit.unwrap());
if setrlimit(Resource::NOFILE, limit, limit).is_ok() {
#[cfg(unix)]
fn adjust_ulimit_size(opts: &Opts) -> u64 {
use rlimit::Resource;
if let Some(limit) = opts.ulimit {
if Resource::NOFILE.set(limit, limit).is_ok() {
detail!(
format!("Automatically increasing ulimit value to {}.", limit),
opts.greppable,
@@ -346,13 +355,15 @@ fn adjust_ulimit_size(opts: &Opts) -> RawRlim {
}
}
let (rlim, _) = getrlimit(Resource::NOFILE).unwrap();
rlim.as_raw()
let (soft, _) = Resource::NOFILE.get().unwrap();
soft
}
fn infer_batch_size(opts: &Opts, ulimit: RawRlim) -> u16 {
let mut batch_size: RawRlim = opts.batch_size.into();
#[cfg(unix)]
fn infer_batch_size(opts: &Opts, ulimit: u64) -> u16 {
use std::convert::TryInto;
let mut batch_size: u64 = opts.batch_size.into();
// Adjust the batch size when the ulimit value is lower than the desired batch size
if ulimit < batch_size {
@@ -363,7 +374,7 @@ fn infer_batch_size(opts: &Opts, ulimit: RawRlim) -> u16 {
// When the OS supports high file limits like 8000, but the user
// selected a batch size higher than this we should reduce it to
// a lower number.
if ulimit < AVERAGE_BATCH_SIZE {
if ulimit < AVERAGE_BATCH_SIZE.into() {
// ulimit is smaller than aveage batch size
// user must have very small ulimit
// decrease batch size to half of ulimit
@@ -372,7 +383,7 @@ fn infer_batch_size(opts: &Opts, ulimit: RawRlim) -> u16 {
batch_size = ulimit / 2;
} else if ulimit > DEFAULT_FILE_DESCRIPTORS_LIMIT {
info!("Batch size is now average batch size");
batch_size = AVERAGE_BATCH_SIZE;
batch_size = AVERAGE_BATCH_SIZE.into();
} else {
batch_size = ulimit - 100;
}