Compare commits

..

29 Commits

Author SHA1 Message Date
epi
393e775285 satisfied clippy 2021-05-08 16:10:01 -05:00
epi
cf6c02307c bumped version to 2.2.4 2021-05-08 16:01:23 -05:00
epi
88b9bc3a01 Merge pull request #270 from epi052/268-cancel-scan-by-range
updated scan cancel input to support comma and range delimited values
2021-05-08 15:57:28 -05:00
epi
d1f90efb09 bumped lib versions 2021-05-05 06:12:50 -05:00
epi
df4fad07a9 Merge branch 'main' into 268-cancel-scan-by-range 2021-05-05 06:06:19 -05:00
epi
56d533117e updated docs with new cancel scan info 2021-05-05 05:56:54 -05:00
epi
9549e27f19 updated cancel menu footer with description about -f 2021-04-20 11:57:56 -05:00
epi
1677b51c2d reverted workflow file 2021-04-20 11:43:05 -05:00
epi
d4f9442d38 examining codecov env 2021-04-20 11:05:17 -05:00
epi
8191fa1a5e updated scan cancel input to support comma and range delimd values 2021-04-20 07:39:11 -05:00
epi
4811b37aa4 Merge pull request #267 from epi052/restyled/pull-266
check for unzip before continuing
2021-04-15 05:15:59 -05:00
Restyled.io
941cad5844 Restyled by shfmt 2021-04-14 17:37:28 +00:00
Restyled.io
d59af94f62 Restyled by shellharden 2021-04-14 17:37:26 +00:00
Craig
cf403c4d4a check for unzip before continuing 2021-04-14 19:35:24 +02:00
epi
57a2b1cbab bumped ctrlc, tokio, reqwest, tokio-util, and futures 2021-04-14 05:59:35 -05:00
epi
ef195bd653 Merge branch 'main' of github.com:epi052/feroxbuster into main 2021-04-01 06:01:45 -05:00
epi
9b1a24bca3 updated libs; fixed new clippy errors 2021-04-01 06:00:44 -05:00
epi
c6aefbfa97 Merge pull request #249 from noraj/patch-1
add blackarch install description
2021-03-20 14:06:35 -05:00
Alexandre ZANNI
42bad85208 add blackarch install 2021-03-19 16:29:27 +01:00
epi
f5709739fa Merge pull request #247 from epi052/dependabot/cargo/regex-1.4.5
Bump regex from 1.4.4 to 1.4.5
2021-03-17 05:59:12 -05:00
epi
248f56ed7a Merge pull request #246 from epi052/dependabot/cargo/console-0.14.1
Bump console from 0.14.0 to 0.14.1
2021-03-17 05:58:55 -05:00
dependabot[bot]
3de6ed9696 Bump regex from 1.4.4 to 1.4.5
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.4 to 1.4.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.4.4...1.4.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-15 07:59:58 +00:00
dependabot[bot]
4bad39f4b9 Bump console from 0.14.0 to 0.14.1
Bumps [console](https://github.com/mitsuhiko/console) from 0.14.0 to 0.14.1.
- [Release notes](https://github.com/mitsuhiko/console/releases)
- [Changelog](https://github.com/mitsuhiko/console/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitsuhiko/console/compare/0.14.0...0.14.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-15 07:59:47 +00:00
epi
9b303d8b5a update dependencies 2021-03-14 07:29:47 -05:00
epi
7e0b003216 Merge branch 'main' of github.com:epi052/feroxbuster into main 2021-03-14 07:22:30 -05:00
epi
dc36a7bf4d updated deendencies 2021-03-14 07:22:16 -05:00
epi
d33632c421 update ko-fi 2021-03-13 07:05:01 -06:00
epi
7dc6a867a5 update ko-fi 2021-03-13 07:04:31 -06:00
epi
b937a0191e Create FUNDING.yml 2021-03-13 06:24:03 -06:00
14 changed files with 402 additions and 394 deletions

4
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
# These are supported funding model platforms
github: [epi052]
ko_fi: epi052

557
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "feroxbuster"
version = "2.2.3"
version = "2.2.4"
authors = ["Ben 'epi' Risher <epibar052@gmail.com>"]
license = "MIT"
edition = "2018"
@@ -21,12 +21,12 @@ regex = "1"
lazy_static = "1.4"
[dependencies]
futures = { version = "0.3.13"}
tokio = { version = "1.2.0", features = ["full"] }
tokio-util = {version = "0.6.3", features = ["codec"]}
futures = { version = "0.3.14"}
tokio = { version = "1.5.0", features = ["full"] }
tokio-util = {version = "0.6.6", features = ["codec"]}
log = "0.4"
env_logger = "0.8.3"
reqwest = { version = "0.11.1", features = ["socks"] }
reqwest = { version = "0.11", features = ["socks"] }
clap = "2.33"
lazy_static = "1.4"
toml = "0.5"
@@ -40,16 +40,16 @@ dirs = "3.0"
regex = "1"
crossterm = "0.19"
rlimit = "0.5.4"
ctrlc = "3.1.8"
ctrlc = "3.1.9"
fuzzyhash = "0.2.1"
anyhow = "1.0"
leaky-bucket = "0.10.0"
[dev-dependencies]
tempfile = "3.1"
httpmock = "0.5.2"
httpmock = "0.5.8"
assert_cmd = "1.0.3"
predicates = "1.0.7"
predicates = "1.0.8"
[profile.release]
lto = true

View File

@@ -225,6 +225,14 @@ Install `feroxbuster-git` on Arch Linux with your AUR helper of choice:
yay -S feroxbuster-git
```
### BlackArch install
Install `feroxbuster` on BlackArch Linux:
```
pacman -S feroxbuster
```
### Docker Install
> The following steps assume you have docker installed / setup
@@ -828,10 +836,11 @@ Below is an example of the Scan Cancel Menu™.
Using the menu is pretty simple:
- Press `ENTER` to view the menu
- Choose a scan to cancel by entering its scan index (`1`)
- more than one scan can be selected by using a comma-separated list (`1,2,3` ... etc)
- more than one scan can be selected by using a comma-separated list of indexes and/or ranges (`1-4,8,9-13` ... etc)
- Confirm selections, after which all non-cancelled scans will resume
- To skip confirmation, simply add a `-f` somewhere in your input (`3-5 -f`)
Here is a short demonstration of cancelling two in-progress scans found via recursion.
Here is a short demonstration of force cancelling a range of scans followed by a single scan with interactive prompt.
![cancel-scan](img/cancel-scan.gif)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

After

Width:  |  Height:  |  Size: 670 KiB

View File

@@ -3,59 +3,63 @@
BASE_URL=https://github.com/epi052/feroxbuster/releases/latest/download
MAC_ZIP=x86_64-macos-feroxbuster.zip
MAC_URL="${BASE_URL}/${MAC_ZIP}"
MAC_URL="$BASE_URL/$MAC_ZIP"
LIN32_ZIP=x86-linux-feroxbuster.zip
LIN32_URL="${BASE_URL}/${LIN32_ZIP}"
LIN32_URL="$BASE_URL/$LIN32_ZIP"
LIN64_ZIP=x86_64-linux-feroxbuster.zip
LIN64_URL="${BASE_URL}/${LIN64_ZIP}"
LIN64_URL="$BASE_URL/$LIN64_ZIP"
EMOJI_URL=https://gist.github.com/epi052/8196b550ea51d0907ad4b93751b1b57d/raw/6112c9f32ae07922983fdc549c54fd3fb9a38e4c/NotoColorEmoji.ttf
echo "[+] Installing feroxbuster!"
if [[ "$(uname)" == "Darwin" ]]; then
echo "[=] Found MacOS, downloading from ${MAC_URL}"
curl -sLO "${MAC_URL}"
unzip -o "${MAC_ZIP}" > /dev/null
rm "${MAC_ZIP}"
elif [[ "$(expr substr $(uname -s) 1 5)" == "Linux" ]]; then
if [[ $(getconf LONG_BIT) == 32 ]]; then
echo "[=] Found 32-bit Linux, downloading from ${LIN32_URL}"
curl -sLO "${LIN32_URL}"
unzip -o "${LIN32_ZIP}" > /dev/null
rm "${LIN32_ZIP}"
else
echo "[=] Found 64-bit Linux, downloading from ${LIN64_URL}"
curl -sLO "${LIN64_URL}"
unzip -o "${LIN64_ZIP}" > /dev/null
rm "${LIN64_ZIP}"
fi
if [[ -e ~/.fonts/NotoColorEmoji.ttf ]]; then
echo "[=] Found Noto Emoji Font, skipping install"
else
echo "[=] Installing Noto Emoji Font"
mkdir -p ~/.fonts
pushd ~/.fonts 2>&1 >/dev/null
curl -sLO "${EMOJI_URL}"
fc-cache -f -v >/dev/null
popd 2>&1 >/dev/null
echo "[+] Noto Emoji Font installed"
fi
which unzip &>/dev/null
if [ "$?" = "0" ]; then
echo "[+] unzip found"
else
echo "[ ] unzip not found, exiting. "
exit -1
fi
if [[ "$(uname)" == "Darwin" ]]; then
echo "[=] Found MacOS, downloading from $MAC_URL"
curl -sLO "$MAC_URL"
unzip -o "$MAC_ZIP" >/dev/null
rm "$MAC_ZIP"
elif [[ "$(expr substr $(uname -s) 1 5)" == "Linux" ]]; then
if [[ $(getconf LONG_BIT) == 32 ]]; then
echo "[=] Found 32-bit Linux, downloading from $LIN32_URL"
curl -sLO "$LIN32_URL"
unzip -o "$LIN32_ZIP" >/dev/null
rm "$LIN32_ZIP"
else
echo "[=] Found 64-bit Linux, downloading from $LIN64_URL"
curl -sLO "$LIN64_URL"
unzip -o "$LIN64_ZIP" >/dev/null
rm "$LIN64_ZIP"
fi
if [[ -e ~/.fonts/NotoColorEmoji.ttf ]]; then
echo "[=] Found Noto Emoji Font, skipping install"
else
echo "[=] Installing Noto Emoji Font"
mkdir -p ~/.fonts
pushd ~/.fonts 2>&1 >/dev/null
curl -sLO "$EMOJI_URL"
fc-cache -f -v >/dev/null
popd 2>&1 >/dev/null
echo "[+] Noto Emoji Font installed"
fi
fi
chmod +x ./feroxbuster
echo "[+] Installed feroxbuster version $(./feroxbuster -V)"

View File

@@ -364,9 +364,10 @@ fn config_reads_headers() {
/// parse the test config and see that the values parsed are correct
fn config_reads_queries() {
let config = setup_config_test();
let mut queries = vec![];
queries.push(("name".to_string(), "value".to_string()));
queries.push(("rick".to_string(), "astley".to_string()));
let queries = vec![
("name".to_string(), "value".to_string()),
("rick".to_string(), "astley".to_string()),
];
assert_eq!(config.queries, queries);
}

View File

@@ -139,8 +139,8 @@ impl TermOutHandler {
Self {
receiver,
tx_file,
config,
file_task,
config,
}
}

View File

@@ -31,9 +31,10 @@ impl Menu {
let separator = "".to_string();
let instructions = format!(
"Enter a {} list of indexes to {} (ex: 2,3)",
"Enter a {} list of indexes/ranges to {} ({}: 1-4,8,9-13)",
style("comma-separated").yellow(),
style("cancel").red(),
style("ex").cyan(),
);
let name = format!(
@@ -43,14 +44,22 @@ impl Menu {
"💀"
);
let force_msg = format!(
"Add {} to {} confirmation ({}: 3-5 -f)",
style("-f").yellow(),
style("skip").yellow(),
style("ex").cyan(),
);
let longest = measure_text_width(&instructions).max(measure_text_width(&name));
let border = separator.repeat(longest);
let padded_name = pad_str(&name, longest, Alignment::Center, None);
let padded_force = pad_str(&force_msg, longest, Alignment::Center, None);
let header = format!("{}\n{}\n{}", border, padded_name, border);
let footer = format!("{}\n{}\n{}", border, instructions, border);
let footer = format!("{}\n{}\n{}\n{}", border, instructions, padded_force, border);
Self {
separator,
@@ -93,23 +102,71 @@ impl Menu {
self.term.write_line(msg).unwrap_or_default();
}
/// split a string into vec of usizes
pub(super) fn split_to_nums(&self, line: &str) -> Vec<usize> {
line.split(',')
.map(|s| {
s.trim().to_string().parse::<usize>().unwrap_or_else(|e| {
self.println(&format!("Found non-numeric input: {}", e));
0
})
/// Helper for parsing a usize from a str
fn str_to_usize(&self, value: &str) -> usize {
if value.is_empty() {
return 0;
}
value
.trim()
.to_string()
.parse::<usize>()
.unwrap_or_else(|e| {
self.println(&format!("Found non-numeric input: {}: {:?}", e, value));
0
})
.filter(|m| *m != 0)
.collect()
}
/// split a comma delimited string into vec of usizes
pub(super) fn split_to_nums(&self, line: &str) -> Vec<usize> {
let mut nums = Vec::new();
let values = line.split(',');
for mut value in values {
value = value.trim();
if value.contains('-') {
// range of two values, needs further processing
let range: Vec<usize> = value
.split('-')
.map(|s| self.str_to_usize(s))
.filter(|m| *m != 0)
.collect();
if range.len() != 2 {
// expecting [1, 4] or similar, if a 0 was used, we'd be left with a vec of size 1
self.println(&format!("Found invalid range of scans: {}", value));
continue;
}
(range[0]..=range[1]).for_each(|n| {
// iterate from lower to upper bound and add all interim values, skipping
// any already known
if !nums.contains(&n) {
nums.push(n)
}
});
} else {
let value = self.str_to_usize(value);
if value != 0 && !nums.contains(&value) {
// the zeroth scan is always skipped, skip already known values
nums.push(value);
}
}
}
nums
}
/// get comma-separated list of scan indexes from the user
pub(super) fn get_scans_from_user(&self) -> Option<Vec<usize>> {
pub(super) fn get_scans_from_user(&self) -> Option<(Vec<usize>, bool)> {
if let Ok(line) = self.term.read_line() {
Some(self.split_to_nums(&line))
let force = line.contains("-f");
let line = line.replace("-f", "");
Some((self.split_to_nums(&line), force))
} else {
None
}

View File

@@ -252,7 +252,7 @@ impl FeroxScans {
}
/// Given a list of indexes, cancel their associated FeroxScans
async fn cancel_scans(&self, indexes: Vec<usize>) -> usize {
async fn cancel_scans(&self, indexes: Vec<usize>, force: bool) -> usize {
let menu_pause_duration = Duration::from_millis(SLEEP_DURATION);
let mut num_cancelled = 0_usize;
@@ -273,7 +273,11 @@ impl FeroxScans {
Err(..) => continue,
};
let input = self.menu.confirm_cancellation(&selected.url);
let input = if force {
'y'
} else {
self.menu.confirm_cancellation(&selected.url)
};
if input == 'y' || input == '\n' {
self.menu.println(&format!("Stopping {}...", selected.url));
@@ -305,8 +309,8 @@ impl FeroxScans {
let mut num_cancelled = 0_usize;
if let Some(input) = self.menu.get_scans_from_user() {
num_cancelled += self.cancel_scans(input).await;
if let Some((input, force)) = self.menu.get_scans_from_user() {
num_cancelled += self.cancel_scans(input, force).await;
};
self.menu.clear_screen();

View File

@@ -47,7 +47,7 @@ impl FeroxSerialize for FeroxState {
/// Simple call to produce a JSON string using the given FeroxState
fn as_json(&self) -> Result<String> {
Ok(serde_json::to_string(&self)
.with_context(|| fmt_err("Could not convert scan's running state to JSON"))?)
serde_json::to_string(&self)
.with_context(|| fmt_err("Could not convert scan's running state to JSON"))
}
}

View File

@@ -521,9 +521,13 @@ fn menu_print_header_and_footer() {
fn split_to_nums_is_correct() {
let menu = Menu::new();
let nums = menu.split_to_nums("1, 3, 4");
let nums = menu.split_to_nums("1, 3, 4, 7 - 12, 10-10, 10-11, 9-12, 12-6, -1, 4-");
assert_eq!(nums, vec![1, 3, 4]);
assert_eq!(nums, vec![1, 3, 4, 7, 8, 9, 10, 11, 12]);
assert_eq!(menu.split_to_nums("9-12"), vec![9, 10, 11, 12]);
assert!(menu.split_to_nums("-12").is_empty());
assert!(menu.split_to_nums("12-").is_empty());
assert!(menu.split_to_nums("\n").is_empty());
}
#[test]

View File

@@ -41,7 +41,7 @@ pub async fn start_max_time_thread(handles: Arc<Handles>) {
log::trace!("exit: start_max_time_thread");
#[cfg(test)]
panic!(handles);
panic!("{:?}", handles);
#[cfg(not(test))]
let _ = TermInputHandler::sigint_handler(handles.clone());
}