mirror of
https://github.com/epi052/feroxbuster.git
synced 2026-05-26 07:41:12 -03:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d96658c79 | ||
|
|
46d00507b0 | ||
|
|
d561e59ec9 | ||
|
|
b786578c03 | ||
|
|
bd54ad0087 | ||
|
|
d98c6a7457 | ||
|
|
c493d001b5 | ||
|
|
bd4566fa7b | ||
|
|
8fbf9d0274 | ||
|
|
d6b10c6476 | ||
|
|
a5e845864c | ||
|
|
b02358678b | ||
|
|
1b8fdcec17 | ||
|
|
92cc2ab448 | ||
|
|
0b0e08ae4f | ||
|
|
25762395b1 | ||
|
|
55b4034bd0 | ||
|
|
ffa409ca3d | ||
|
|
bb4a335299 | ||
|
|
1e0ec5c833 | ||
|
|
b5fa6b149e | ||
|
|
04a43a0892 | ||
|
|
8a72e498e6 | ||
|
|
2987a84776 | ||
|
|
8add5599fb | ||
|
|
9f557329eb | ||
|
|
c04bf4a703 | ||
|
|
03e8625c6e | ||
|
|
5d6b85fe12 | ||
|
|
771041d225 | ||
|
|
b5debed322 | ||
|
|
30407cd338 | ||
|
|
ba4b26f2cd | ||
|
|
4fdf558936 | ||
|
|
2ffb0df516 | ||
|
|
10260f9db7 | ||
|
|
4067be2f82 | ||
|
|
7cb9c1c914 | ||
|
|
99cbd657a5 | ||
|
|
703da383a7 | ||
|
|
aa83e40c4f | ||
|
|
a77c436e04 | ||
|
|
c3455d123e | ||
|
|
6431f01f12 | ||
|
|
fd0f31705d | ||
|
|
5252587e65 |
@@ -550,7 +550,17 @@
|
||||
"profile": "https://petruknisme.com",
|
||||
"contributions": [
|
||||
"code",
|
||||
"infra"
|
||||
"infra",
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "imBigo",
|
||||
"name": "Simon",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/54672433?v=4",
|
||||
"profile": "https://github.com/imBigo",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -30,3 +30,6 @@ ferox-*.state
|
||||
|
||||
# python stuff cuz reasons
|
||||
Pipfile*
|
||||
|
||||
# ignore choco_package generated nupkg
|
||||
/choco_package/*.nupkg
|
||||
|
||||
424
Cargo.lock
generated
424
Cargo.lock
generated
@@ -2,6 +2,12 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
@@ -23,10 +29,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.69"
|
||||
name = "anstyle"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
|
||||
checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||
|
||||
[[package]]
|
||||
name = "ascii-canvas"
|
||||
@@ -49,10 +61,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.8"
|
||||
version = "2.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9834fcc22e0874394a010230586367d4a3e9f11b560f469262678547e1d2575e"
|
||||
checksum = "ec0b2340f55d9661d76793b2bfc2eb0e62689bd79d067a95707ea762afd5e9dd"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"bstr",
|
||||
"doc-comment",
|
||||
"predicates",
|
||||
@@ -192,13 +205,13 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.66"
|
||||
version = "0.1.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
|
||||
checksum = "86ea188f25f0255d8f92797797c97ebf5631fa88178beb1a46fdf5622c9a00e4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -293,9 +306,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1"
|
||||
checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"once_cell",
|
||||
@@ -341,9 +354,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.8"
|
||||
version = "4.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5"
|
||||
checksum = "ce38afc168d8665cfc75c7b1dd9672e50716a137f433f070991619744a67342a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
@@ -356,18 +369,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.1.4"
|
||||
version = "4.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501ff0a401473ea1d4c3b125ff95506b62c5bc5768d818634195fbb7c4ad5ff4"
|
||||
checksum = "37686beaba5ac9f3ab01ee3172f792fc6ffdd685bfb9e63cfef02c0571a4e8e1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09"
|
||||
checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
@@ -425,6 +438,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.7"
|
||||
@@ -513,7 +535,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"smallvec",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -523,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -533,7 +555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -587,7 +609,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -687,9 +709,9 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
version = "0.14.1"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2e5d13ca2353ab7d0230988629def93914a8c4015f621f9b13ed2955614731d"
|
||||
checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
@@ -760,7 +782,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "feroxbuster"
|
||||
version = "2.9.0"
|
||||
version = "2.9.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
@@ -774,7 +796,7 @@ dependencies = [
|
||||
"futures",
|
||||
"gaoya",
|
||||
"httpmock",
|
||||
"indicatif",
|
||||
"indicatif 0.15.0",
|
||||
"lazy_static",
|
||||
"leaky-bucket",
|
||||
"log",
|
||||
@@ -784,6 +806,7 @@ dependencies = [
|
||||
"reqwest",
|
||||
"rlimit",
|
||||
"scraper",
|
||||
"self_update",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_regex",
|
||||
@@ -795,12 +818,34 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
@@ -858,9 +903,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
|
||||
checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -873,9 +918,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
|
||||
checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -883,15 +928,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
|
||||
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
|
||||
checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@@ -900,9 +945,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
|
||||
checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
@@ -921,32 +966,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
|
||||
checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
|
||||
checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
|
||||
checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.26"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
|
||||
checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -1104,7 +1149,7 @@ dependencies = [
|
||||
"markup5ever",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1177,9 +1222,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.24"
|
||||
version = "0.14.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c"
|
||||
checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@@ -1240,10 +1285,22 @@ checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
"number_prefix",
|
||||
"number_prefix 0.3.0",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indicatif"
|
||||
version = "0.17.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729"
|
||||
dependencies = [
|
||||
"console",
|
||||
"number_prefix 0.4.0",
|
||||
"portable-atomic",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
@@ -1255,10 +1312,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3"
|
||||
checksum = "76e86b86ae312accbf05ade23ce76b625e0e47a255712b7414037385a1c05380"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
@@ -1398,9 +1456,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
version = "0.2.140"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
|
||||
[[package]]
|
||||
name = "libnghttp2-sys"
|
||||
@@ -1497,6 +1555,15 @@ version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.6"
|
||||
@@ -1582,6 +1649,12 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
|
||||
|
||||
[[package]]
|
||||
name = "number_prefix"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
@@ -1596,9 +1669,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.45"
|
||||
version = "0.10.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
|
||||
checksum = "fd2523381e46256e40930512c7fd25562b9eae4812cb52078f155e87217c9d1e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
@@ -1617,7 +1690,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1637,9 +1710,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.80"
|
||||
version = "0.9.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7"
|
||||
checksum = "176be2629957c157240f68f61f2d0053ad3a4ecfdd9ebf1e6521d18d9635cf67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
@@ -1771,7 +1844,7 @@ dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1815,7 +1888,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1838,18 +1911,26 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.5.2"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6"
|
||||
checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"libc",
|
||||
"log",
|
||||
"wepoll-ffi",
|
||||
"windows-sys 0.42.0",
|
||||
"pin-project-lite",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
@@ -1864,10 +1945,11 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "2.1.5"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd"
|
||||
checksum = "1ba7d6ead3e3966038f68caa9fc1f860185d95a793180bbcfe0d0da47b3961ed"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"difflib",
|
||||
"float-cmp",
|
||||
"itertools",
|
||||
@@ -1878,15 +1960,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.5"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2"
|
||||
checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.7"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d"
|
||||
checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"termtree",
|
||||
@@ -1900,18 +1982,27 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
name = "quick-xml"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -2288,29 +2379,51 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.16"
|
||||
name = "self_update"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
|
||||
checksum = "ca4e4e6f29fddb78b3e7a6e5a395e8274d4aca2d36b2278a297fa49673a5b7c7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"flate2",
|
||||
"hyper",
|
||||
"indicatif 0.17.3",
|
||||
"log",
|
||||
"quick-xml",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"semver",
|
||||
"serde_json",
|
||||
"tar",
|
||||
"tempfile",
|
||||
"urlencoding",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
version = "1.0.157"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
checksum = "707de5fcf5df2b5788fca98dd7eab490bc2fd9b7ef1404defc462833b83f25ca"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.152"
|
||||
version = "1.0.157"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
checksum = "78997f4555c22a7971214540c4a661291970619afd56de19f77e0de86296e1e5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2476,9 +2589,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.6"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d69e88b23f23030bf4d0e9ca7b07434f70e1c1f4d3ca7e93ce958b373654d9f"
|
||||
checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
|
||||
dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"once_cell",
|
||||
@@ -2517,6 +2630,28 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cff13bb1732bccfe3b246f3fdb09edfd51c01d6f5299b7ccd9457c2e4e37774"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.4.0"
|
||||
@@ -2573,30 +2708,46 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "termtree"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8"
|
||||
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
@@ -2649,7 +2800,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2690,9 +2841,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6"
|
||||
checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
@@ -2711,9 +2862,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.4"
|
||||
version = "0.19.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825"
|
||||
checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@@ -2749,7 +2900,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2795,9 +2946,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.10"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
|
||||
checksum = "7d502c968c6a838ead8e69b2ee18ec708802f99db92a0d156705ec9ef801993b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
@@ -2838,6 +2989,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urlencoding"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
@@ -2933,7 +3090,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -2967,7 +3124,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -2988,15 +3145,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wepoll-ffi"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@@ -3054,9 +3202,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
@@ -3069,51 +3217,51 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.1"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee7b2c67f962bf5042bfd8b6a916178df33a26eec343ae064cb8e069f638fa6f"
|
||||
checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -3126,3 +3274,25 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"flate2",
|
||||
"time",
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "feroxbuster"
|
||||
version = "2.9.0"
|
||||
version = "2.9.2"
|
||||
authors = ["Ben 'epi' Risher (@epi052)"]
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
@@ -56,12 +56,13 @@ ctrlc = "3.2.2"
|
||||
anyhow = "1.0.69"
|
||||
leaky-bucket = "0.12.1"
|
||||
gaoya = "0.1.2"
|
||||
self_update = {version = "0.36.0", features = ["archive-tar", "compression-flate2", "archive-zip", "compression-zip-deflate"]}
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.3.0"
|
||||
httpmock = "0.6.6"
|
||||
assert_cmd = "2.0.4"
|
||||
predicates = "2.1.1"
|
||||
predicates = "3.0.1"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 epi
|
||||
Copyright (c) 2020-2023 epi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
22
README.md
22
README.md
@@ -101,6 +101,11 @@ sudo apt update && sudo apt install -y feroxbuster
|
||||
curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/master/install-nix.sh | bash
|
||||
```
|
||||
|
||||
#### MacOS via Homebrew
|
||||
|
||||
```
|
||||
brew install feroxbuster
|
||||
```
|
||||
|
||||
#### Windows x86_64
|
||||
|
||||
@@ -110,10 +115,22 @@ Expand-Archive .\feroxbuster.zip
|
||||
.\feroxbuster\feroxbuster.exe -V
|
||||
```
|
||||
|
||||
#### Windows via Chocolatey
|
||||
|
||||
```
|
||||
choco install feroxbuster
|
||||
```
|
||||
|
||||
#### All others
|
||||
|
||||
Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
|
||||
### Updating feroxbuster (new in v2.9.1)
|
||||
|
||||
```
|
||||
./feroxbuster --update
|
||||
```
|
||||
|
||||
## 🧰 Example Usage
|
||||
|
||||
Here are a few brief examples to get you started. Please note, feroxbuster can do a **lot more** than what's listed below. As a result, there are **many more** examples, with **demonstration gifs** that highlight specific features, in the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
@@ -167,6 +184,8 @@ cat targets | ./feroxbuster --stdin --silent -s 200 301 302 --redirects -x js |
|
||||
./feroxbuster -u http://127.1 --query token=0123456789ABCDEF
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 🚀 Documentation has **moved** 🚀
|
||||
|
||||
For realsies, there used to be over 1300 lines in this README, but it's all been moved to the [new documentation site](https://epi052.github.io/feroxbuster-docs/docs/). Go check it out!
|
||||
@@ -257,7 +276,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xaeroborg"><img src="https://avatars.githubusercontent.com/u/33274680?v=4?s=100" width="100px;" alt="xaeroborg"/><br /><sub><b>xaeroborg</b></sub></a><br /><a href="#ideas-xaeroborg" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Luoooio"><img src="https://avatars.githubusercontent.com/u/26653157?v=4?s=100" width="100px;" alt="Luoooio"/><br /><sub><b>Luoooio</b></sub></a><br /><a href="#ideas-Luoooio" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://petruknisme.com"><img src="https://avatars.githubusercontent.com/u/6284204?v=4?s=100" width="100px;" alt="Aan"/><br /><sub><b>Aan</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/commits?author=aancw" title="Code">💻</a> <a href="#infra-aancw" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://petruknisme.com"><img src="https://avatars.githubusercontent.com/u/6284204?v=4?s=100" width="100px;" alt="Aan"/><br /><sub><b>Aan</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/commits?author=aancw" title="Code">💻</a> <a href="#infra-aancw" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-aancw" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/imBigo"><img src="https://avatars.githubusercontent.com/u/54672433?v=4?s=100" width="100px;" alt="Simon"/><br /><sub><b>Simon</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/issues?q=author%3AimBigo" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
79
choco_package/feroxbuster.nuspec
Normal file
79
choco_package/feroxbuster.nuspec
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>feroxbuster</id>
|
||||
<version>2.8.0</version>
|
||||
<packageSourceUrl>https://github.com/epi052/feroxbuster/releases/</packageSourceUrl>
|
||||
<owners>epi052</owners>
|
||||
<title>feroxbuster (Install)</title>
|
||||
<authors>epi052</authors>
|
||||
<projectUrl>https://github.com/epi052/feroxbuster</projectUrl>
|
||||
<iconUrl>https://rawcdn.githack.com/epi052/feroxbuster/2d381e7e057ce60c580b324dd36c9abaf30c2ec7/img/logo/logo.png</iconUrl>
|
||||
<copyright>2020-2023</copyright>
|
||||
<licenseUrl>https://github.com/epi052/feroxbuster/blob/main/LICENSE</licenseUrl>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<projectSourceUrl>https://github.com/epi052/feroxbuster</projectSourceUrl>
|
||||
<docsUrl>https://epi052.github.io/feroxbuster-docs/docs/</docsUrl>
|
||||
<!--<mailingListUrl></mailingListUrl>-->
|
||||
<bugTrackerUrl>https://github.com/epi052/feroxbuster/issues</bugTrackerUrl>
|
||||
<tags>content-discovery pentesting-tool url-bruteforcer</tags>
|
||||
<summary>A simple, fast, recursive content discovery tool written in Rust</summary>
|
||||
<description>
|
||||
A simple, fast, recursive content discovery tool written in Rust
|
||||
[](https://github.com/epi052/feroxbuster)
|
||||
|
||||
## What the heck is a ferox anyway?
|
||||
|
||||
Ferox is short for Ferric Oxide. Ferric Oxide, simply put, is rust. The name rustbuster was taken, so I decided on a
|
||||
variation.
|
||||
|
||||
## What's it do tho?
|
||||
|
||||
`feroxbuster` is a tool designed to perform [Forced Browsing](https://owasp.org/www-community/attacks/Forced_browsing).
|
||||
|
||||
Forced browsing is an attack where the aim is to enumerate and access resources that are not referenced by the web
|
||||
application, but are still accessible by an attacker.
|
||||
|
||||
`feroxbuster` uses brute force combined with a wordlist to search for unlinked content in target directories. These
|
||||
resources may store sensitive information about web applications and operational systems, such as source code,
|
||||
credentials, internal network addressing, etc...
|
||||
|
||||
This attack is also known as Predictable Resource Location, File Enumeration, Directory Enumeration, and Resource
|
||||
Enumeration.
|
||||
|
||||
## Quick Start
|
||||
|
||||
This section will cover the minimum amount of information to get up and running with feroxbuster. Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/), as it's much more comprehensive.
|
||||
|
||||
### Installation
|
||||
|
||||
There are quite a few other [installation methods](https://epi052.github.io/feroxbuster-docs/docs/installation/), but these snippets should cover the majority of users.
|
||||
|
||||
#### All others Docs
|
||||
|
||||
Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
|
||||
## Example Usage
|
||||
|
||||
Here are a few brief examples to get you started. Please note, feroxbuster can do a **lot more** than what's listed below. As a result, there are **many more** examples, with **demonstration gifs** that highlight specific features, in the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
|
||||
### Multiple Values
|
||||
|
||||
Options that take multiple values are very flexible. Consider the following ways of specifying extensions:
|
||||
|
||||
```
|
||||
./feroxbuster -u http://127.1 -x pdf -x js,html -x php txt json,docx
|
||||
```
|
||||
|
||||
The command above adds .pdf, .js, .html, .php, .txt, .json, and .docx to each url
|
||||
|
||||
All of the methods above (multiple flags, space separated, comma separated, etc...) are valid and interchangeable. The
|
||||
same goes for urls, headers, status codes, queries, and size filters.
|
||||
</description>
|
||||
<!-- <releaseNotes>__REPLACE_OR_REMOVE__MarkDown_Okay</releaseNotes> -->
|
||||
</metadata>
|
||||
<files>
|
||||
<!-- this section controls what actually gets packaged into the Chocolatey package -->
|
||||
<file src="tools\**" target="tools" />
|
||||
</files>
|
||||
</package>
|
||||
26
choco_package/legal/LICENSE.txt
Normal file
26
choco_package/legal/LICENSE.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
From: https://github.com/epi052/feroxbuster/blob/main/LICENSE
|
||||
|
||||
LICENSE
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 epi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
5
choco_package/legal/VERIFICATION.txt
Normal file
5
choco_package/legal/VERIFICATION.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
VERIFICATION
|
||||
|
||||
checksum -t sha512 -f .\x86-windows-feroxbuster.exe.zip
|
||||
checksum -t sha512 -f .\x86_64-windows-feroxbuster.exe.zip
|
||||
27
choco_package/tools/chocolateyinstall.ps1
Normal file
27
choco_package/tools/chocolateyinstall.ps1
Normal file
@@ -0,0 +1,27 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||
$version = '2.8.0'
|
||||
$url = "https://github.com/epi052/feroxbuster/releases/download/v$version/x86-windows-feroxbuster.exe.zip"
|
||||
$url64 = "https://github.com/epi052/feroxbuster/releases/download/v$version/x86_64-windows-feroxbuster.exe.zip"
|
||||
|
||||
$packageArgs = @{
|
||||
packageName = $env:ChocolateyPackageName
|
||||
unzipLocation = $toolsDir
|
||||
fileType = 'exe' #only one of these: exe, msi, msu
|
||||
url = $url
|
||||
url64bit = $url64
|
||||
#file = $fileLocation
|
||||
|
||||
softwareName = 'feroxbuster*'
|
||||
|
||||
# Checksums are now required as of 0.10.0.
|
||||
# To determine checksums, you can get that from the original site if provided.
|
||||
# You can also use checksum.exe (choco install checksum) and use it
|
||||
# e.g. checksum -t sha256 -f path\to\file
|
||||
checksum = 'e5cac59c737260233903a17706a68bac11fe0d7a15169e1c5a9637cc221e7230fd6ddbfc1a7243833dde6472ad053c033449ca8338164654f7354363da54ba88'
|
||||
checksumType = 'sha512'
|
||||
checksum64 = 'cce58d6eacef7e12c31076f5a00fee9742a4e3fdfc69d807d98736200e50469f77359978e137ecafd87b14460845c65c6808d1f8b23ae561f7e7c637e355dee3'
|
||||
checksumType64= 'sha512'
|
||||
}
|
||||
Install-ChocolateyZipPackage @packageArgs # https://docs.chocolatey.org/en-us/create/functions/install-chocolateyzippackage
|
||||
47
choco_package/tools/chocolateyuninstall.ps1
Normal file
47
choco_package/tools/chocolateyuninstall.ps1
Normal file
@@ -0,0 +1,47 @@
|
||||
$ErrorActionPreference = 'Stop' # stop on all errors
|
||||
$packageArgs = @{
|
||||
packageName = $env:ChocolateyPackageName
|
||||
softwareName = 'feroxbuster*' #part or all of the Display Name as you see it in Programs and Features. It should be enough to be unique
|
||||
fileType = 'exe' #only one of these: MSI or EXE (ignore MSU for now)
|
||||
}
|
||||
|
||||
# Get-UninstallRegistryKey is new to 0.9.10, if supporting 0.9.9.x and below,
|
||||
# take a dependency on "chocolatey-core.extension" in your nuspec file.
|
||||
# This is only a fuzzy search if $softwareName includes '*'. Otherwise it is
|
||||
# exact. In the case of versions in key names, we recommend removing the version
|
||||
# and using '*'.
|
||||
[array]$key = Get-UninstallRegistryKey -SoftwareName $packageArgs['softwareName']
|
||||
|
||||
if ($key.Count -eq 1) {
|
||||
$key | % {
|
||||
$packageArgs['file'] = "$($_.UninstallString)" #NOTE: You may need to split this if it contains spaces, see below
|
||||
|
||||
if ($packageArgs['fileType'] -eq 'MSI') {
|
||||
# The Product Code GUID is all that should be passed for MSI, and very
|
||||
# FIRST, because it comes directly after /x, which is already set in the
|
||||
# Uninstall-ChocolateyPackage msiargs (facepalm).
|
||||
$packageArgs['silentArgs'] = "$($_.PSChildName) $($packageArgs['silentArgs'])"
|
||||
|
||||
# Don't pass anything for file, it is ignored for msi (facepalm number 2)
|
||||
# Alternatively if you need to pass a path to an msi, determine that and
|
||||
# use it instead of the above in silentArgs, still very first
|
||||
$packageArgs['file'] = ''
|
||||
} else {
|
||||
# NOTES:
|
||||
# - You probably will need to sanitize $packageArgs['file'] as it comes from the registry and could be in a variety of fun but unusable formats
|
||||
# - Split args from exe in $packageArgs['file'] and pass those args through $packageArgs['silentArgs'] or ignore them
|
||||
# - Ensure you don't pass double quotes in $file (aka $packageArgs['file']) - otherwise you will get "Illegal characters in path when you attempt to run this"
|
||||
# - Review the code for auto-uninstaller for all of the fun things it does in sanitizing - https://github.com/chocolatey/choco/blob/bfe351b7d10c798014efe4bfbb100b171db25099/src/chocolatey/infrastructure.app/services/AutomaticUninstallerService.cs#L142-L192
|
||||
}
|
||||
|
||||
Uninstall-ChocolateyPackage @packageArgs
|
||||
}
|
||||
} elseif ($key.Count -eq 0) {
|
||||
Write-Warning "$packageName has already been uninstalled by other means."
|
||||
} elseif ($key.Count -gt 1) {
|
||||
Write-Warning "$($key.Count) matches found!"
|
||||
Write-Warning "To prevent accidental data loss, no programs will be uninstalled."
|
||||
Write-Warning "Please alert package maintainer the following keys were matched:"
|
||||
$key | % {Write-Warning "- $($_.DisplayName)"}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ _feroxbuster() {
|
||||
'--replay-proxy=[Send only unfiltered requests through a Replay Proxy, instead of all requests]:REPLAY_PROXY:_urls' \
|
||||
'*-R+[Status Codes to send through a Replay Proxy when found (default: --status-codes value)]:REPLAY_CODE: ' \
|
||||
'*--replay-codes=[Status Codes to send through a Replay Proxy when found (default: --status-codes value)]:REPLAY_CODE: ' \
|
||||
'-a+[Sets the User-Agent (default: feroxbuster/2.9.0)]:USER_AGENT: ' \
|
||||
'--user-agent=[Sets the User-Agent (default: feroxbuster/2.9.0)]:USER_AGENT: ' \
|
||||
'-a+[Sets the User-Agent (default: feroxbuster/2.9.2)]:USER_AGENT: ' \
|
||||
'--user-agent=[Sets the User-Agent (default: feroxbuster/2.9.2)]:USER_AGENT: ' \
|
||||
'*-x+[File extension(s) to search for (ex: -x php -x pdf js)]:FILE_EXTENSION: ' \
|
||||
'*--extensions=[File extension(s) to search for (ex: -x php -x pdf js)]:FILE_EXTENSION: ' \
|
||||
'*-m+[Which HTTP request method(s) should be sent (default: GET)]:HTTP_METHODS: ' \
|
||||
@@ -62,8 +62,8 @@ _feroxbuster() {
|
||||
'--parallel=[Run parallel feroxbuster instances (one child process per url passed via stdin)]:PARALLEL_SCANS: ' \
|
||||
'(--auto-tune)--rate-limit=[Limit number of requests per second (per directory) (default: 0, i.e. no limit)]:RATE_LIMIT: ' \
|
||||
'--time-limit=[Limit total run time of all scans (ex: --time-limit 10m)]:TIME_SPEC: ' \
|
||||
'-w+[Path to the wordlist]:FILE:_files' \
|
||||
'--wordlist=[Path to the wordlist]:FILE:_files' \
|
||||
'-w+[Path or URL of the wordlist]:FILE:_files' \
|
||||
'--wordlist=[Path or URL of the wordlist]:FILE:_files' \
|
||||
'*-I+[File extension(s) to Ignore while collecting extensions (only used with --collect-extensions)]:FILE_EXTENSION: ' \
|
||||
'*--dont-collect=[File extension(s) to Ignore while collecting extensions (only used with --collect-extensions)]:FILE_EXTENSION: ' \
|
||||
'-o+[Output file to write results to (use w/ --json for JSON entries)]:FILE:_files' \
|
||||
@@ -72,7 +72,7 @@ _feroxbuster() {
|
||||
'(-u --url)--stdin[Read url(s) from STDIN]' \
|
||||
'(-p --proxy -k --insecure --burp-replay)--burp[Set --proxy to http://127.0.0.1:8080 and set --insecure to true]' \
|
||||
'(-P --replay-proxy -k --insecure)--burp-replay[Set --replay-proxy to http://127.0.0.1:8080 and set --insecure to true]' \
|
||||
'(--rate-limit --auto-bail)--smart[Set --extract-links, --auto-tune, --collect-words, and --collect-backups to true]' \
|
||||
'(--rate-limit --auto-bail)--smart[Set --auto-tune, --collect-words, and --collect-backups to true]' \
|
||||
'(--rate-limit --auto-bail)--thorough[Use the same settings as --smart and set --collect-extensions to true]' \
|
||||
'-A[Use a random User-Agent]' \
|
||||
'--random-agent[Use a random User-Agent]' \
|
||||
@@ -85,8 +85,9 @@ _feroxbuster() {
|
||||
'-n[Do not scan recursively]' \
|
||||
'--no-recursion[Do not scan recursively]' \
|
||||
'(-n --no-recursion)--force-recursion[Force recursion attempts on all '\''found'\'' endpoints (still respects recursion depth)]' \
|
||||
'-e[Extract links from response body (html, javascript, etc...); make new requests based on findings]' \
|
||||
'--extract-links[Extract links from response body (html, javascript, etc...); make new requests based on findings]' \
|
||||
'-e[Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)]' \
|
||||
'--extract-links[Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)]' \
|
||||
'--dont-extract-links[Don'\''t extract links from response body (html, javascript, etc...)]' \
|
||||
'(--auto-bail)--auto-tune[Automatically lower scan rate when an excessive amount of errors are encountered]' \
|
||||
'--auto-bail[Automatically stop scanning when an excessive amount of errors are encountered]' \
|
||||
'-D[Don'\''t auto-filter wildcard responses]' \
|
||||
@@ -104,6 +105,8 @@ _feroxbuster() {
|
||||
'--quiet[Hide progress bars and banner (good for tmux windows w/ notifications)]' \
|
||||
'--json[Emit JSON logs to --output and --debug-log instead of normal text]' \
|
||||
'--no-state[Disable state output file (*.state)]' \
|
||||
'-U[Update feroxbuster to the latest version]' \
|
||||
'--update[Update feroxbuster to the latest version]' \
|
||||
'-h[Print help (see more with '\''--help'\'')]' \
|
||||
'--help[Print help (see more with '\''--help'\'')]' \
|
||||
'-V[Print version]' \
|
||||
|
||||
@@ -30,8 +30,8 @@ Register-ArgumentCompleter -Native -CommandName 'feroxbuster' -ScriptBlock {
|
||||
[CompletionResult]::new('--replay-proxy', 'replay-proxy', [CompletionResultType]::ParameterName, 'Send only unfiltered requests through a Replay Proxy, instead of all requests')
|
||||
[CompletionResult]::new('-R', 'R', [CompletionResultType]::ParameterName, 'Status Codes to send through a Replay Proxy when found (default: --status-codes value)')
|
||||
[CompletionResult]::new('--replay-codes', 'replay-codes', [CompletionResultType]::ParameterName, 'Status Codes to send through a Replay Proxy when found (default: --status-codes value)')
|
||||
[CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'Sets the User-Agent (default: feroxbuster/2.9.0)')
|
||||
[CompletionResult]::new('--user-agent', 'user-agent', [CompletionResultType]::ParameterName, 'Sets the User-Agent (default: feroxbuster/2.9.0)')
|
||||
[CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'Sets the User-Agent (default: feroxbuster/2.9.2)')
|
||||
[CompletionResult]::new('--user-agent', 'user-agent', [CompletionResultType]::ParameterName, 'Sets the User-Agent (default: feroxbuster/2.9.2)')
|
||||
[CompletionResult]::new('-x', 'x', [CompletionResultType]::ParameterName, 'File extension(s) to search for (ex: -x php -x pdf js)')
|
||||
[CompletionResult]::new('--extensions', 'extensions', [CompletionResultType]::ParameterName, 'File extension(s) to search for (ex: -x php -x pdf js)')
|
||||
[CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Which HTTP request method(s) should be sent (default: GET)')
|
||||
@@ -68,8 +68,8 @@ Register-ArgumentCompleter -Native -CommandName 'feroxbuster' -ScriptBlock {
|
||||
[CompletionResult]::new('--parallel', 'parallel', [CompletionResultType]::ParameterName, 'Run parallel feroxbuster instances (one child process per url passed via stdin)')
|
||||
[CompletionResult]::new('--rate-limit', 'rate-limit', [CompletionResultType]::ParameterName, 'Limit number of requests per second (per directory) (default: 0, i.e. no limit)')
|
||||
[CompletionResult]::new('--time-limit', 'time-limit', [CompletionResultType]::ParameterName, 'Limit total run time of all scans (ex: --time-limit 10m)')
|
||||
[CompletionResult]::new('-w', 'w', [CompletionResultType]::ParameterName, 'Path to the wordlist')
|
||||
[CompletionResult]::new('--wordlist', 'wordlist', [CompletionResultType]::ParameterName, 'Path to the wordlist')
|
||||
[CompletionResult]::new('-w', 'w', [CompletionResultType]::ParameterName, 'Path or URL of the wordlist')
|
||||
[CompletionResult]::new('--wordlist', 'wordlist', [CompletionResultType]::ParameterName, 'Path or URL of the wordlist')
|
||||
[CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'File extension(s) to Ignore while collecting extensions (only used with --collect-extensions)')
|
||||
[CompletionResult]::new('--dont-collect', 'dont-collect', [CompletionResultType]::ParameterName, 'File extension(s) to Ignore while collecting extensions (only used with --collect-extensions)')
|
||||
[CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'Output file to write results to (use w/ --json for JSON entries)')
|
||||
@@ -78,7 +78,7 @@ Register-ArgumentCompleter -Native -CommandName 'feroxbuster' -ScriptBlock {
|
||||
[CompletionResult]::new('--stdin', 'stdin', [CompletionResultType]::ParameterName, 'Read url(s) from STDIN')
|
||||
[CompletionResult]::new('--burp', 'burp', [CompletionResultType]::ParameterName, 'Set --proxy to http://127.0.0.1:8080 and set --insecure to true')
|
||||
[CompletionResult]::new('--burp-replay', 'burp-replay', [CompletionResultType]::ParameterName, 'Set --replay-proxy to http://127.0.0.1:8080 and set --insecure to true')
|
||||
[CompletionResult]::new('--smart', 'smart', [CompletionResultType]::ParameterName, 'Set --extract-links, --auto-tune, --collect-words, and --collect-backups to true')
|
||||
[CompletionResult]::new('--smart', 'smart', [CompletionResultType]::ParameterName, 'Set --auto-tune, --collect-words, and --collect-backups to true')
|
||||
[CompletionResult]::new('--thorough', 'thorough', [CompletionResultType]::ParameterName, 'Use the same settings as --smart and set --collect-extensions to true')
|
||||
[CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Use a random User-Agent')
|
||||
[CompletionResult]::new('--random-agent', 'random-agent', [CompletionResultType]::ParameterName, 'Use a random User-Agent')
|
||||
@@ -91,8 +91,9 @@ Register-ArgumentCompleter -Native -CommandName 'feroxbuster' -ScriptBlock {
|
||||
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Do not scan recursively')
|
||||
[CompletionResult]::new('--no-recursion', 'no-recursion', [CompletionResultType]::ParameterName, 'Do not scan recursively')
|
||||
[CompletionResult]::new('--force-recursion', 'force-recursion', [CompletionResultType]::ParameterName, 'Force recursion attempts on all ''found'' endpoints (still respects recursion depth)')
|
||||
[CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Extract links from response body (html, javascript, etc...); make new requests based on findings')
|
||||
[CompletionResult]::new('--extract-links', 'extract-links', [CompletionResultType]::ParameterName, 'Extract links from response body (html, javascript, etc...); make new requests based on findings')
|
||||
[CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)')
|
||||
[CompletionResult]::new('--extract-links', 'extract-links', [CompletionResultType]::ParameterName, 'Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)')
|
||||
[CompletionResult]::new('--dont-extract-links', 'dont-extract-links', [CompletionResultType]::ParameterName, 'Don''t extract links from response body (html, javascript, etc...)')
|
||||
[CompletionResult]::new('--auto-tune', 'auto-tune', [CompletionResultType]::ParameterName, 'Automatically lower scan rate when an excessive amount of errors are encountered')
|
||||
[CompletionResult]::new('--auto-bail', 'auto-bail', [CompletionResultType]::ParameterName, 'Automatically stop scanning when an excessive amount of errors are encountered')
|
||||
[CompletionResult]::new('-D', 'D', [CompletionResultType]::ParameterName, 'Don''t auto-filter wildcard responses')
|
||||
@@ -110,6 +111,8 @@ Register-ArgumentCompleter -Native -CommandName 'feroxbuster' -ScriptBlock {
|
||||
[CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Hide progress bars and banner (good for tmux windows w/ notifications)')
|
||||
[CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Emit JSON logs to --output and --debug-log instead of normal text')
|
||||
[CompletionResult]::new('--no-state', 'no-state', [CompletionResultType]::ParameterName, 'Disable state output file (*.state)')
|
||||
[CompletionResult]::new('-U', 'U', [CompletionResultType]::ParameterName, 'Update feroxbuster to the latest version')
|
||||
[CompletionResult]::new('--update', 'update', [CompletionResultType]::ParameterName, 'Update feroxbuster to the latest version')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
|
||||
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version')
|
||||
|
||||
@@ -19,7 +19,7 @@ _feroxbuster() {
|
||||
|
||||
case "${cmd}" in
|
||||
feroxbuster)
|
||||
opts="-u -p -P -R -a -A -x -m -H -b -Q -f -S -X -W -N -C -s -T -r -k -t -n -d -e -L -w -D -E -B -g -I -v -q -o -h -V --url --stdin --resume-from --burp --burp-replay --smart --thorough --proxy --replay-proxy --replay-codes --user-agent --random-agent --extensions --methods --data --headers --cookies --query --add-slash --dont-scan --filter-size --filter-regex --filter-words --filter-lines --filter-status --filter-similar-to --status-codes --timeout --redirects --insecure --threads --no-recursion --depth --force-recursion --extract-links --scan-limit --parallel --rate-limit --time-limit --wordlist --auto-tune --auto-bail --dont-filter --collect-extensions --collect-backups --collect-words --dont-collect --verbosity --silent --quiet --json --output --debug-log --no-state --help --version"
|
||||
opts="-u -p -P -R -a -A -x -m -H -b -Q -f -S -X -W -N -C -s -T -r -k -t -n -d -e -L -w -D -E -B -g -I -v -q -o -U -h -V --url --stdin --resume-from --burp --burp-replay --smart --thorough --proxy --replay-proxy --replay-codes --user-agent --random-agent --extensions --methods --data --headers --cookies --query --add-slash --dont-scan --filter-size --filter-regex --filter-words --filter-lines --filter-status --filter-similar-to --status-codes --timeout --redirects --insecure --threads --no-recursion --depth --force-recursion --extract-links --dont-extract-links --scan-limit --parallel --rate-limit --time-limit --wordlist --auto-tune --auto-bail --dont-filter --collect-extensions --collect-backups --collect-words --dont-collect --verbosity --silent --quiet --json --output --debug-log --no-state --update --help --version"
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
||||
@@ -27,8 +27,8 @@ set edit:completion:arg-completer[feroxbuster] = {|@words|
|
||||
cand --replay-proxy 'Send only unfiltered requests through a Replay Proxy, instead of all requests'
|
||||
cand -R 'Status Codes to send through a Replay Proxy when found (default: --status-codes value)'
|
||||
cand --replay-codes 'Status Codes to send through a Replay Proxy when found (default: --status-codes value)'
|
||||
cand -a 'Sets the User-Agent (default: feroxbuster/2.9.0)'
|
||||
cand --user-agent 'Sets the User-Agent (default: feroxbuster/2.9.0)'
|
||||
cand -a 'Sets the User-Agent (default: feroxbuster/2.9.2)'
|
||||
cand --user-agent 'Sets the User-Agent (default: feroxbuster/2.9.2)'
|
||||
cand -x 'File extension(s) to search for (ex: -x php -x pdf js)'
|
||||
cand --extensions 'File extension(s) to search for (ex: -x php -x pdf js)'
|
||||
cand -m 'Which HTTP request method(s) should be sent (default: GET)'
|
||||
@@ -65,8 +65,8 @@ set edit:completion:arg-completer[feroxbuster] = {|@words|
|
||||
cand --parallel 'Run parallel feroxbuster instances (one child process per url passed via stdin)'
|
||||
cand --rate-limit 'Limit number of requests per second (per directory) (default: 0, i.e. no limit)'
|
||||
cand --time-limit 'Limit total run time of all scans (ex: --time-limit 10m)'
|
||||
cand -w 'Path to the wordlist'
|
||||
cand --wordlist 'Path to the wordlist'
|
||||
cand -w 'Path or URL of the wordlist'
|
||||
cand --wordlist 'Path or URL of the wordlist'
|
||||
cand -I 'File extension(s) to Ignore while collecting extensions (only used with --collect-extensions)'
|
||||
cand --dont-collect 'File extension(s) to Ignore while collecting extensions (only used with --collect-extensions)'
|
||||
cand -o 'Output file to write results to (use w/ --json for JSON entries)'
|
||||
@@ -75,7 +75,7 @@ set edit:completion:arg-completer[feroxbuster] = {|@words|
|
||||
cand --stdin 'Read url(s) from STDIN'
|
||||
cand --burp 'Set --proxy to http://127.0.0.1:8080 and set --insecure to true'
|
||||
cand --burp-replay 'Set --replay-proxy to http://127.0.0.1:8080 and set --insecure to true'
|
||||
cand --smart 'Set --extract-links, --auto-tune, --collect-words, and --collect-backups to true'
|
||||
cand --smart 'Set --auto-tune, --collect-words, and --collect-backups to true'
|
||||
cand --thorough 'Use the same settings as --smart and set --collect-extensions to true'
|
||||
cand -A 'Use a random User-Agent'
|
||||
cand --random-agent 'Use a random User-Agent'
|
||||
@@ -88,8 +88,9 @@ set edit:completion:arg-completer[feroxbuster] = {|@words|
|
||||
cand -n 'Do not scan recursively'
|
||||
cand --no-recursion 'Do not scan recursively'
|
||||
cand --force-recursion 'Force recursion attempts on all ''found'' endpoints (still respects recursion depth)'
|
||||
cand -e 'Extract links from response body (html, javascript, etc...); make new requests based on findings'
|
||||
cand --extract-links 'Extract links from response body (html, javascript, etc...); make new requests based on findings'
|
||||
cand -e 'Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)'
|
||||
cand --extract-links 'Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)'
|
||||
cand --dont-extract-links 'Don''t extract links from response body (html, javascript, etc...)'
|
||||
cand --auto-tune 'Automatically lower scan rate when an excessive amount of errors are encountered'
|
||||
cand --auto-bail 'Automatically stop scanning when an excessive amount of errors are encountered'
|
||||
cand -D 'Don''t auto-filter wildcard responses'
|
||||
@@ -107,6 +108,8 @@ set edit:completion:arg-completer[feroxbuster] = {|@words|
|
||||
cand --quiet 'Hide progress bars and banner (good for tmux windows w/ notifications)'
|
||||
cand --json 'Emit JSON logs to --output and --debug-log instead of normal text'
|
||||
cand --no-state 'Disable state output file (*.state)'
|
||||
cand -U 'Update feroxbuster to the latest version'
|
||||
cand --update 'Update feroxbuster to the latest version'
|
||||
cand -h 'Print help (see more with ''--help'')'
|
||||
cand --help 'Print help (see more with ''--help'')'
|
||||
cand -V 'Print version'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::utils::{
|
||||
depth, ignored_extensions, methods, report_and_exit, save_state, serialized_type, status_codes,
|
||||
threads, timeout, user_agent, wordlist, OutputLevel, RequesterPolicy,
|
||||
depth, extract_links, ignored_extensions, methods, report_and_exit, save_state,
|
||||
serialized_type, status_codes, threads, timeout, user_agent, wordlist, OutputLevel,
|
||||
RequesterPolicy,
|
||||
};
|
||||
use crate::config::determine_output_level;
|
||||
use crate::config::utils::determine_requester_policy;
|
||||
@@ -214,7 +215,7 @@ pub struct Configuration {
|
||||
pub no_recursion: bool,
|
||||
|
||||
/// Extract links from html/javscript
|
||||
#[serde(default)]
|
||||
#[serde(default = "extract_links")]
|
||||
pub extract_links: bool,
|
||||
|
||||
/// Append / to each request
|
||||
@@ -309,6 +310,10 @@ pub struct Configuration {
|
||||
/// override recursion logic to always attempt recursion, still respects --depth
|
||||
#[serde(default)]
|
||||
pub force_recursion: bool,
|
||||
|
||||
/// Auto update app feature
|
||||
#[serde(skip)]
|
||||
pub update_app: bool,
|
||||
}
|
||||
|
||||
impl Default for Configuration {
|
||||
@@ -324,6 +329,7 @@ impl Default for Configuration {
|
||||
let kind = serialized_type();
|
||||
let output_level = OutputLevel::Default;
|
||||
let requester_policy = RequesterPolicy::Default;
|
||||
let extract_links = extract_links();
|
||||
|
||||
Configuration {
|
||||
kind,
|
||||
@@ -332,6 +338,7 @@ impl Default for Configuration {
|
||||
user_agent,
|
||||
replay_codes,
|
||||
status_codes,
|
||||
extract_links,
|
||||
replay_client,
|
||||
requester_policy,
|
||||
dont_filter: false,
|
||||
@@ -351,13 +358,13 @@ impl Default for Configuration {
|
||||
insecure: false,
|
||||
redirects: false,
|
||||
no_recursion: false,
|
||||
extract_links: false,
|
||||
random_agent: false,
|
||||
collect_extensions: false,
|
||||
collect_backups: false,
|
||||
collect_words: false,
|
||||
save_state: true,
|
||||
force_recursion: false,
|
||||
update_app: false,
|
||||
proxy: String::new(),
|
||||
config: String::new(),
|
||||
output: String::new(),
|
||||
@@ -393,7 +400,7 @@ impl Configuration {
|
||||
///
|
||||
/// - **timeout**: `5` seconds
|
||||
/// - **redirects**: `false`
|
||||
/// - **extract-links**: `false`
|
||||
/// - **extract_links**: `true`
|
||||
/// - **wordlist**: [`DEFAULT_WORDLIST`](constant.DEFAULT_WORDLIST.html)
|
||||
/// - **config**: `None`
|
||||
/// - **threads**: `50`
|
||||
@@ -441,6 +448,7 @@ impl Configuration {
|
||||
/// - **time_limit**: `None` (no limit on length of scan imposed)
|
||||
/// - **replay_proxy**: `None` (no limit on concurrent scans imposed)
|
||||
/// - **replay_codes**: [`DEFAULT_RESPONSE_CODES`](constant.DEFAULT_RESPONSE_CODES.html)
|
||||
/// - **update_app**: `false`
|
||||
///
|
||||
/// After which, any values defined in a
|
||||
/// [ferox-config.toml](constant.DEFAULT_CONFIG_NAME.html) config file will override the
|
||||
@@ -801,11 +809,8 @@ impl Configuration {
|
||||
config.add_slash = true;
|
||||
}
|
||||
|
||||
if came_from_cli!(args, "extract_links")
|
||||
|| came_from_cli!(args, "smart")
|
||||
|| came_from_cli!(args, "thorough")
|
||||
{
|
||||
config.extract_links = true;
|
||||
if came_from_cli!(args, "dont_extract_links") {
|
||||
config.extract_links = false;
|
||||
}
|
||||
|
||||
if came_from_cli!(args, "json") {
|
||||
@@ -816,6 +821,10 @@ impl Configuration {
|
||||
config.force_recursion = true;
|
||||
}
|
||||
|
||||
if came_from_cli!(args, "update_app") {
|
||||
config.update_app = true;
|
||||
}
|
||||
|
||||
////
|
||||
// organizational breakpoint; all options below alter the Client configuration
|
||||
////
|
||||
@@ -987,11 +996,12 @@ impl Configuration {
|
||||
update_if_not_default!(&mut conf.redirects, new.redirects, false);
|
||||
update_if_not_default!(&mut conf.insecure, new.insecure, false);
|
||||
update_if_not_default!(&mut conf.force_recursion, new.force_recursion, false);
|
||||
update_if_not_default!(&mut conf.extract_links, new.extract_links, false);
|
||||
update_if_not_default!(&mut conf.extract_links, new.extract_links, extract_links());
|
||||
update_if_not_default!(&mut conf.extensions, new.extensions, Vec::<String>::new());
|
||||
update_if_not_default!(&mut conf.methods, new.methods, methods());
|
||||
update_if_not_default!(&mut conf.data, new.data, Vec::<u8>::new());
|
||||
update_if_not_default!(&mut conf.url_denylist, new.url_denylist, Vec::<Url>::new());
|
||||
update_if_not_default!(&mut conf.update_app, new.update_app, false);
|
||||
if !new.regex_denylist.is_empty() {
|
||||
// cant use the update_if_not_default macro due to the following error
|
||||
//
|
||||
|
||||
@@ -45,7 +45,7 @@ fn setup_config_test() -> Configuration {
|
||||
add_slash = true
|
||||
stdin = true
|
||||
dont_filter = true
|
||||
extract_links = true
|
||||
extract_links = false
|
||||
json = true
|
||||
save_state = false
|
||||
depth = 1
|
||||
@@ -98,7 +98,7 @@ fn default_configuration() {
|
||||
assert!(!config.add_slash);
|
||||
assert!(!config.force_recursion);
|
||||
assert!(!config.redirects);
|
||||
assert!(!config.extract_links);
|
||||
assert!(config.extract_links);
|
||||
assert!(!config.insecure);
|
||||
assert!(!config.collect_extensions);
|
||||
assert!(!config.collect_backups);
|
||||
@@ -305,7 +305,7 @@ fn config_reads_add_slash() {
|
||||
/// parse the test config and see that the value parsed is correct
|
||||
fn config_reads_extract_links() {
|
||||
let config = setup_config_test();
|
||||
assert!(config.extract_links);
|
||||
assert!(!config.extract_links);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -84,6 +84,11 @@ pub(super) fn depth() -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
/// default extract links
|
||||
pub(super) fn extract_links() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// enum representing the three possible states for informational output (not logging verbosity)
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum OutputLevel {
|
||||
|
||||
@@ -160,13 +160,17 @@ impl Handles {
|
||||
/// number of extensions plus the number of request method types plus any dynamically collected
|
||||
/// extensions
|
||||
pub fn expected_num_requests_multiplier(&self) -> usize {
|
||||
let multiplier = self.config.extensions.len()
|
||||
+ self.config.methods.len()
|
||||
+ self.num_collected_extensions();
|
||||
let mut multiplier = self.config.extensions.len().max(1);
|
||||
|
||||
// methods should always have at least 1 member, likely making this .max call unneeded
|
||||
// but leaving it for 'just in case' reasons
|
||||
multiplier.max(1)
|
||||
if multiplier > 1 {
|
||||
// when we have more than one extension, we need to account for the fact that we'll
|
||||
// be making a request for each extension and the base word (e.g. /foo.html and /foo)
|
||||
multiplier += 1;
|
||||
}
|
||||
|
||||
multiplier *= self.config.methods.len().max(1) * self.num_collected_extensions().max(1);
|
||||
|
||||
multiplier
|
||||
}
|
||||
|
||||
/// Helper to easily get the (locked) underlying FeroxScans object
|
||||
|
||||
@@ -222,7 +222,7 @@ impl ScanHandler {
|
||||
let current_expectation = self.handles.expected_num_requests_per_dir() as u64;
|
||||
|
||||
// used in the calculation of bar width down below, see explanation there
|
||||
let divisor = self.handles.expected_num_requests_multiplier() as u64 - 1;
|
||||
let divisor = (self.handles.expected_num_requests_multiplier() as u64 - 1).max(1);
|
||||
|
||||
// add another `wordlist.len` to the expected per scan tracker in the statistics handler
|
||||
self.handles
|
||||
@@ -294,12 +294,7 @@ impl ScanHandler {
|
||||
if let Ok(guard) = self.wordlist.lock().as_ref() {
|
||||
if let Some(list) = guard.as_ref() {
|
||||
return if offset > 0 {
|
||||
// the offset could be off a bit, so we'll adjust it backwards by 10%
|
||||
// of the overall wordlist size to ensure we don't miss any words
|
||||
// (hopefully)
|
||||
let adjusted_offset = offset - ((offset as f64 * 0.10) as usize);
|
||||
|
||||
Ok(Arc::new(list[adjusted_offset..].to_vec()))
|
||||
Ok(Arc::new(list[offset..].to_vec()))
|
||||
} else {
|
||||
Ok(list.clone())
|
||||
};
|
||||
@@ -337,7 +332,18 @@ impl ScanHandler {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list = self.get_wordlist(scan.requests() as usize)?;
|
||||
let divisor = self.handles.expected_num_requests_multiplier();
|
||||
|
||||
let list = if divisor > 1 && scan.requests() > 0 {
|
||||
// if there were extensions provided and/or more than a single method used, and some
|
||||
// number of requests have already been sent, we need to adjust the offset into the
|
||||
// wordlist to ensure we don't index out of bounds
|
||||
|
||||
let adjusted = scan.requests_made_so_far() as f64 / (divisor as f64 - 1.0).max(1.0);
|
||||
self.get_wordlist(adjusted as usize)?
|
||||
} else {
|
||||
self.get_wordlist(scan.requests_made_so_far() as usize)?
|
||||
};
|
||||
|
||||
log::info!("scan handler received {} - beginning scan", target);
|
||||
|
||||
|
||||
@@ -148,7 +148,12 @@ impl StatsHandler {
|
||||
);
|
||||
|
||||
self.bar.set_message(&msg);
|
||||
self.bar.inc(1);
|
||||
|
||||
if self.bar.position() < self.stats.total_expected() as u64 {
|
||||
// don't run off the end when we're a few requests over the expected total
|
||||
// due to the heuristics tests
|
||||
self.bar.inc(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize new `Stats` object and the sc side of an mpsc channel that is responsible for
|
||||
|
||||
95
src/main.rs
95
src/main.rs
@@ -1,11 +1,14 @@
|
||||
use std::io::stdin;
|
||||
use std::{
|
||||
env::args,
|
||||
env::{
|
||||
args,
|
||||
consts::{ARCH, OS},
|
||||
},
|
||||
fs::{create_dir, remove_file, File},
|
||||
io::{stderr, BufRead, BufReader},
|
||||
ops::Index,
|
||||
path::Path,
|
||||
process::Command,
|
||||
process::{exit, Command},
|
||||
sync::{atomic::Ordering, Arc},
|
||||
};
|
||||
|
||||
@@ -38,6 +41,7 @@ use feroxbuster::{
|
||||
use feroxbuster::{utils::set_open_file_limit, DEFAULT_OPEN_FILE_LIMIT};
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use self_update::cargo_crate_version;
|
||||
|
||||
lazy_static! {
|
||||
/// Limits the number of parallel scans active at any given time when using --parallel
|
||||
@@ -219,19 +223,64 @@ async fn wrapped_main(config: Arc<Configuration>) -> Result<()> {
|
||||
PROGRESS_BAR.join().unwrap();
|
||||
});
|
||||
|
||||
// cloning an Arc is cheap (it's basically a pointer into the heap)
|
||||
// so that will allow for cheap/safe sharing of a single wordlist across multi-target scans
|
||||
// as well as additional directories found as part of recursion
|
||||
let words = match get_unique_words_from_wordlist(&config.wordlist) {
|
||||
Ok(w) => w,
|
||||
Err(err) => {
|
||||
let secondary = Path::new(SECONDARY_WORDLIST);
|
||||
// check if update_app is true
|
||||
if config.update_app {
|
||||
match update_app().await {
|
||||
Err(e) => eprintln!("\n[ERROR] {}", e),
|
||||
Ok(self_update::Status::UpToDate(version)) => {
|
||||
eprintln!("\nFeroxbuster {} is up to date", version)
|
||||
}
|
||||
Ok(self_update::Status::Updated(version)) => {
|
||||
eprintln!("\nFeroxbuster updated to {} version", version)
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if secondary.exists() {
|
||||
eprintln!("Found wordlist in secondary location");
|
||||
get_unique_words_from_wordlist(SECONDARY_WORDLIST)?
|
||||
} else {
|
||||
return Err(err);
|
||||
let words = if config.wordlist.starts_with("http") {
|
||||
// found a url scheme, attempt to download the wordlist
|
||||
let response = config.client.get(&config.wordlist).send().await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
// status code isn't a 200, bail
|
||||
bail!(
|
||||
"[{}] Unable to download wordlist from url: {}",
|
||||
response.status().as_str(),
|
||||
config.wordlist
|
||||
);
|
||||
}
|
||||
|
||||
// attempt to get the filename from the url's path
|
||||
let Some(path_segments) = response
|
||||
.url()
|
||||
.path_segments() else {
|
||||
bail!("Unable to parse path from url: {}", response.url());
|
||||
};
|
||||
|
||||
let Some(filename) = path_segments.last() else {
|
||||
bail!("Unable to parse filename from url's path: {}", response.url().path());
|
||||
};
|
||||
|
||||
let filename = filename.to_string();
|
||||
|
||||
// read the body and write it to disk, then use existing code to read the wordlist
|
||||
let body = response.text().await?;
|
||||
|
||||
std::fs::write(&filename, body)?;
|
||||
|
||||
get_unique_words_from_wordlist(&filename)?
|
||||
} else {
|
||||
match get_unique_words_from_wordlist(&config.wordlist) {
|
||||
Ok(w) => w,
|
||||
Err(err) => {
|
||||
let secondary = Path::new(SECONDARY_WORDLIST);
|
||||
|
||||
if secondary.exists() {
|
||||
eprintln!("Found wordlist in secondary location");
|
||||
get_unique_words_from_wordlist(SECONDARY_WORDLIST)?
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -526,6 +575,24 @@ async fn clean_up(handles: Arc<Handles>, tasks: Tasks) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_app() -> Result<self_update::Status, Box<dyn ::std::error::Error>> {
|
||||
let target_os = format!("{}-{}", ARCH, OS);
|
||||
let status = tokio::task::spawn_blocking(move || {
|
||||
self_update::backends::github::Update::configure()
|
||||
.repo_owner("epi052")
|
||||
.repo_name("feroxbuster")
|
||||
.bin_name("feroxbuster")
|
||||
.target(target_os.as_str())
|
||||
.show_download_progress(true)
|
||||
.current_version(cargo_crate_version!())
|
||||
.build()?
|
||||
.update()
|
||||
})
|
||||
.await??;
|
||||
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = Arc::new(Configuration::new().with_context(|| "Could not create Configuration")?);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ pub fn initialize() -> Command {
|
||||
Arg::new("url")
|
||||
.short('u')
|
||||
.long("url")
|
||||
.required_unless_present_any(["stdin", "resume_from"])
|
||||
.required_unless_present_any(["stdin", "resume_from", "update_app"])
|
||||
.help_heading("Target selection")
|
||||
.value_name("URL")
|
||||
.use_value_delimiter(true)
|
||||
@@ -92,8 +92,9 @@ pub fn initialize() -> Command {
|
||||
.num_args(0)
|
||||
.help_heading("Composite settings")
|
||||
.conflicts_with_all(["rate_limit", "auto_bail"])
|
||||
.help("Set --extract-links, --auto-tune, --collect-words, and --collect-backups to true"),
|
||||
).arg(
|
||||
.help("Set --auto-tune, --collect-words, and --collect-backups to true"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("thorough")
|
||||
.long("thorough")
|
||||
.num_args(0)
|
||||
@@ -433,7 +434,15 @@ pub fn initialize() -> Command {
|
||||
.long("extract-links")
|
||||
.num_args(0)
|
||||
.help_heading("Scan settings")
|
||||
.help("Extract links from response body (html, javascript, etc...); make new requests based on findings")
|
||||
.hide(true)
|
||||
.help("Extract links from response body (html, javascript, etc...); make new requests based on findings (default: true)")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("dont_extract_links")
|
||||
.long("dont-extract-links")
|
||||
.num_args(0)
|
||||
.help_heading("Scan settings")
|
||||
.help("Don't extract links from response body (html, javascript, etc...)")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("scan_limit")
|
||||
@@ -477,7 +486,7 @@ pub fn initialize() -> Command {
|
||||
.long("wordlist")
|
||||
.value_hint(ValueHint::FilePath)
|
||||
.value_name("FILE")
|
||||
.help("Path to the wordlist")
|
||||
.help("Path or URL of the wordlist")
|
||||
.help_heading("Scan settings")
|
||||
.num_args(1),
|
||||
).arg(
|
||||
@@ -515,7 +524,8 @@ pub fn initialize() -> Command {
|
||||
.num_args(0)
|
||||
.help_heading("Dynamic collection settings")
|
||||
.help("Automatically request likely backup extensions for \"found\" urls")
|
||||
).arg(
|
||||
)
|
||||
.arg(
|
||||
Arg::new("collect_words")
|
||||
.short('g')
|
||||
.long("collect-words")
|
||||
@@ -609,6 +619,15 @@ pub fn initialize() -> Command {
|
||||
.args(["debug_log", "output"])
|
||||
.multiple(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("update_app")
|
||||
.short('U')
|
||||
.long("update")
|
||||
.exclusive(true)
|
||||
.num_args(0)
|
||||
.help_heading("Update settings")
|
||||
.help("Update feroxbuster to the latest version"),
|
||||
)
|
||||
.after_long_help(EPILOGUE);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@@ -675,9 +694,6 @@ EXAMPLES:
|
||||
Pass auth token via query parameter
|
||||
./feroxbuster -u http://127.1 --query token=0123456789ABCDEF
|
||||
|
||||
Find links in javascript/html and make additional requests based on results
|
||||
./feroxbuster -u http://127.1 --extract-links
|
||||
|
||||
Ludicrous speed... go!
|
||||
./feroxbuster -u http://127.1 --threads 200
|
||||
|
||||
|
||||
@@ -210,10 +210,14 @@ impl Menu {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if value.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let value = self.str_to_usize(value);
|
||||
|
||||
if value != 0 && !nums.contains(&value) {
|
||||
// the zeroth scan is always skipped, skip already known values
|
||||
if !nums.contains(&value) {
|
||||
// skip already known values
|
||||
nums.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ pub struct FeroxScan {
|
||||
pub scan_type: ScanType,
|
||||
|
||||
/// The order in which the scan was received
|
||||
#[allow(dead_code)] // not entirely sure this isn't used somewhere
|
||||
pub(crate) scan_order: ScanOrder,
|
||||
|
||||
/// Number of requests to populate the progress bar with
|
||||
@@ -153,7 +154,13 @@ impl FeroxScan {
|
||||
pub(super) fn stop_progress_bar(&self) {
|
||||
if let Ok(guard) = self.progress_bar.lock() {
|
||||
if guard.is_some() {
|
||||
(*guard).as_ref().unwrap().finish_at_current_pos()
|
||||
let pb = (*guard).as_ref().unwrap();
|
||||
|
||||
if pb.position() > self.num_requests {
|
||||
pb.finish()
|
||||
} else {
|
||||
pb.finish_at_current_pos()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,11 +325,6 @@ impl FeroxScans {
|
||||
let mut printed = 0;
|
||||
|
||||
for (i, scan) in scans.iter().enumerate() {
|
||||
if matches!(scan.scan_order, ScanOrder::Initial) || scan.task.try_lock().is_err() {
|
||||
// original target passed in via either -u or --stdin
|
||||
continue;
|
||||
}
|
||||
|
||||
if matches!(scan.scan_type, ScanType::Directory) {
|
||||
if printed == 0 {
|
||||
self.menu
|
||||
@@ -378,14 +373,13 @@ impl FeroxScans {
|
||||
|
||||
if input == 'y' || input == '\n' {
|
||||
self.menu.println(&format!("Stopping {}...", selected.url));
|
||||
|
||||
selected
|
||||
.abort()
|
||||
.await
|
||||
.unwrap_or_else(|e| log::warn!("Could not cancel task: {}", e));
|
||||
|
||||
let pb = selected.progress_bar();
|
||||
num_cancelled += pb.length() as usize - pb.position() as usize
|
||||
num_cancelled += pb.length() as usize - pb.position() as usize;
|
||||
} else {
|
||||
self.menu.println("Ok, doing nothing...");
|
||||
}
|
||||
@@ -459,6 +453,32 @@ impl FeroxScans {
|
||||
|
||||
self.menu.show_progress_bars();
|
||||
|
||||
let has_active_scans = if let Ok(guard) = self.scans.read() {
|
||||
guard.iter().any(|s| s.is_active())
|
||||
} else {
|
||||
// if we can't tell for sure, we'll let it ride
|
||||
//
|
||||
// i'm not sure which is the better option here:
|
||||
// either return true and let it potentially hang, or
|
||||
// return false and exit, so just going with not
|
||||
// abruptly exiting for maybe no reason
|
||||
true
|
||||
};
|
||||
|
||||
if !has_active_scans {
|
||||
// the last active scan was cancelled, so we can exit
|
||||
self.menu.println(&format!(
|
||||
" 😱 no more active scans... {}",
|
||||
style("exiting").red()
|
||||
));
|
||||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel::<bool>();
|
||||
handles
|
||||
.send_scan_command(Command::JoinTasks(tx))
|
||||
.unwrap_or_default();
|
||||
rx.await.unwrap_or_default();
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
@@ -469,7 +469,7 @@ fn feroxstates_feroxserialize_implementation() {
|
||||
r#""headers""#,
|
||||
r#""queries":[]"#,
|
||||
r#""no_recursion":false"#,
|
||||
r#""extract_links":false"#,
|
||||
r#""extract_links":true"#,
|
||||
r#""add_slash":false"#,
|
||||
r#""stdin":false"#,
|
||||
r#""depth":4"#,
|
||||
@@ -668,11 +668,7 @@ fn menu_get_command_input_from_user_returns_cancel() {
|
||||
assert!(matches!(result, MenuCmd::Cancel(_, _)));
|
||||
|
||||
if let MenuCmd::Cancel(canx_list, ret_force) = result {
|
||||
if idx == 0 {
|
||||
assert!(canx_list.is_empty());
|
||||
} else {
|
||||
assert_eq!(canx_list, vec![idx]);
|
||||
}
|
||||
assert_eq!(canx_list, vec![idx]);
|
||||
assert_eq!(force, ret_force);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,12 +286,14 @@ impl FeroxScanner {
|
||||
write!(message, " (add {} to scan)", style("-e").bright().yellow())?;
|
||||
}
|
||||
|
||||
progress_bar.reset_eta();
|
||||
progress_bar.finish_with_message(&message);
|
||||
if !self.handles.config.force_recursion {
|
||||
progress_bar.reset_eta();
|
||||
progress_bar.finish_with_message(&message);
|
||||
|
||||
ferox_scan.finish()?;
|
||||
ferox_scan.finish()?;
|
||||
|
||||
return Ok(()); // nothing left to do if we found a dir listing
|
||||
return Ok(()); // nothing left to do if we found a dir listing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1420,3 +1420,15 @@ fn banner_prints_force_recursion() {
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + force recursion
|
||||
fn banner_prints_update_app() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--update")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(predicate::str::contains("Checking target-arch..."));
|
||||
}
|
||||
|
||||
@@ -218,3 +218,46 @@ fn main_parallel_creates_output_directory() -> Result<(), Box<dyn std::error::Er
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// download a wordlist from a url
|
||||
fn main_download_wordlist_from_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let srv = MockServer::start();
|
||||
|
||||
let (tmp_dir, _) = setup_tmp_directory(&["a".to_string()], "wordlist")?;
|
||||
|
||||
let mock1 = srv.mock(|when, then| {
|
||||
when.method(GET).path("/derp");
|
||||
then.status(200).body("stuff\nthings");
|
||||
});
|
||||
|
||||
// serve endpoints stuff and things
|
||||
let mock2 = srv.mock(|when, then| {
|
||||
when.method(GET).path("/stuff");
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
let mock3 = srv.mock(|when, then| {
|
||||
when.method(GET).path("/things");
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.current_dir(&tmp_dir)
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
.arg(srv.url("/derp"))
|
||||
.assert()
|
||||
.success()
|
||||
.stderr(predicate::str::contains(srv.url("/derp")));
|
||||
|
||||
teardown_tmp_directory(tmp_dir);
|
||||
|
||||
assert_eq!(mock1.hits(), 1); // downloaded wordlist
|
||||
assert_eq!(mock2.hits(), 1); // found stuff from wordlist
|
||||
assert_eq!(mock3.hits(), 1); // found things from wordlist
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user