mirror of
https://github.com/bee-san/RustScan.git
synced 2026-11-07 17:02:04 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a7cbd701b | ||
|
|
f34ee8f5ef | ||
|
|
89c763789f | ||
|
|
5c48f1173a | ||
|
|
8d8ca1d4a0 | ||
|
|
8d8acd61e8 | ||
|
|
0ab3e53034 | ||
|
|
56493859cb | ||
|
|
2ef723ed96 | ||
|
|
e9288302ba | ||
|
|
8179511527 | ||
|
|
fbab4a4020 | ||
|
|
b425d15a98 | ||
|
|
fddda34465 | ||
|
|
125df4a2ed | ||
|
|
e670d11223 | ||
|
|
8453320586 | ||
|
|
99e9c834a9 | ||
|
|
dfbce6a636 | ||
|
|
916be1e4a2 | ||
|
|
90b4328fb6 | ||
|
|
76035d3379 | ||
|
|
4de31ecede | ||
|
|
ce9befaa1a | ||
|
|
5f6457ed7e | ||
|
|
12d3c91983 | ||
|
|
e0fd7a39dc | ||
|
|
ff0787e332 | ||
|
|
6ce6c0ce9e | ||
|
|
edf989ad5d | ||
|
|
3fede4c6db | ||
|
|
75b310f227 | ||
|
|
72c6ef1f1d | ||
|
|
83b23da32b | ||
|
|
3886a07775 | ||
|
|
f5064d3d5c | ||
|
|
22cbfc5826 | ||
|
|
a9d729300c | ||
|
|
4f5dd20e85 | ||
|
|
499ff66f36 | ||
|
|
61b87243d9 | ||
|
|
e069991c8d | ||
|
|
85c1cbf445 | ||
|
|
5551e64166 | ||
|
|
e0aa1423ad | ||
|
|
e609b3617c | ||
|
|
d0d8380296 | ||
|
|
d66ad34f8c | ||
|
|
2670ec43df | ||
|
|
90d0b03ba7 | ||
|
|
57eb3627b3 | ||
|
|
7e675b7557 | ||
|
|
fdeaa05f23 | ||
|
|
9fbf39f0cc | ||
|
|
14b6ea928d | ||
|
|
9452b1f922 | ||
|
|
ed12888e81 | ||
|
|
f68abcb955 | ||
|
|
4c91e8fb40 | ||
|
|
1d3e831066 | ||
|
|
ff6b1c40db | ||
|
|
5573d91a7b | ||
|
|
a8e56eec4b | ||
|
|
fb75c9d332 | ||
|
|
581ec27cb5 | ||
|
|
9673c8807d | ||
|
|
78818d6bc7 | ||
|
|
d0ff597be6 | ||
|
|
516ebe367a | ||
|
|
1e9660e4ff | ||
|
|
7b4dda5a19 | ||
|
|
a20b71191d | ||
|
|
18c5dd69e5 | ||
|
|
090264ac26 | ||
|
|
702681606f | ||
|
|
c58ac613c9 | ||
|
|
59bb72426d | ||
|
|
f48590c238 | ||
|
|
8b363571f1 | ||
|
|
0fa11f6e51 | ||
|
|
d423f34e7a | ||
|
|
e17f9d0bb1 | ||
|
|
3329428766 |
No files matched your search
@@ -86,6 +86,15 @@
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TGotwig",
|
||||
"name": "Thomas Gotwig",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/30773779?v=4",
|
||||
"profile": "https://tgotwig.me",
|
||||
"contributions": [
|
||||
"platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "remigourdon",
|
||||
"name": "Rémi Gourdon",
|
||||
@@ -95,6 +104,55 @@
|
||||
"doc",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cmnatic",
|
||||
"name": "Ben (CMNatic)",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/4163116?v=4",
|
||||
"profile": "https://cmnatic.co.uk",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Ferryistaken",
|
||||
"name": "Alessandro Ferrari",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/47927670?v=4",
|
||||
"profile": "https://github.com/Ferryistaken",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Phenomite",
|
||||
"name": "Phenomite",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/8285537?v=4",
|
||||
"profile": "https://github.com/Phenomite",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "SuperSandro2000",
|
||||
"name": "Sandro",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/7258858?v=4",
|
||||
"profile": "https://supersandro.de/",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "caass",
|
||||
"name": "Cass",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/25358963?v=4",
|
||||
"profile": "https://swag.lgbt",
|
||||
"contributions": [
|
||||
"platform",
|
||||
"code",
|
||||
"bug"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "src/rustscan_scripting_engine"]
|
||||
path = src/rustscan_scripting_engine
|
||||
url = https://github.com/RustScan/rustscan_scripting_engine
|
||||
+11
@@ -54,3 +54,14 @@ after_failure:
|
||||
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
|
||||
- chmod +x send.sh
|
||||
- ./send.sh failure $WEBHOOK_URL
|
||||
|
||||
after_success: |
|
||||
if [ -n "${GITHUB_TOKEN}" ]; then
|
||||
[ "${TRAVIS_BRANCH} " = master ] &&
|
||||
[ "${TRAVIS_PULL_REQUEST}" = false ] &&
|
||||
cargo doc &&
|
||||
echo "<meta http-equiv=refresh content=0;url=rustscan/index.html>" > target/doc/index.html &&
|
||||
sudo pip install ghp-import &&
|
||||
ghp-import -n target/doc &&
|
||||
git push -fq https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
||||
fi
|
||||
Generated
+94
-35
@@ -51,16 +51,63 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-std"
|
||||
version = "1.6.2"
|
||||
name = "async-executor"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00d68a33ebc8b57800847d00787307f84a562224a14db069b0acefe4c2abbf5d"
|
||||
checksum = "90f47c78ea98277cb1f5e6f60ba4fc762f5eafe9f6511bc2f7dfd8b75c225650"
|
||||
dependencies = [
|
||||
"async-io",
|
||||
"futures-lite",
|
||||
"multitask",
|
||||
"parking 1.0.6",
|
||||
"scoped-tls",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae22a338d28c75b53702b66f77979062cb29675db376d99e451af4fa79dedb3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-lite",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"parking 2.0.0",
|
||||
"polling",
|
||||
"socket2",
|
||||
"vec-arena",
|
||||
"wepoll-sys-stjepang",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-mutex"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20e85981fc34e84cdff3fc2c9219189752633fdc538a06df8b5ac45b68a4f3a9"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-std"
|
||||
version = "1.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c8da367da62b8ff2313c406c9ac091c1b31d67a165becdd2de380d846260f7"
|
||||
dependencies = [
|
||||
"async-executor",
|
||||
"async-io",
|
||||
"async-mutex",
|
||||
"async-task",
|
||||
"blocking",
|
||||
"crossbeam-utils",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"kv-log-macro",
|
||||
"log",
|
||||
"memchr",
|
||||
@@ -69,7 +116,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
"smol",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
@@ -127,15 +173,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "0.4.7"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2468ff7bf85066b4a3678fede6fe66db31846d753ff0adfbfab2c6a6e81612b"
|
||||
checksum = "76e94bf99b692f54c9d05f97454d3faf11134523fe5b180564a3fb6ed63bcc0a"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"atomic-waker",
|
||||
"futures-lite",
|
||||
"once_cell",
|
||||
"parking",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
@@ -324,7 +369,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
"parking",
|
||||
"parking 1.0.6",
|
||||
"pin-project-lite",
|
||||
"waker-fn",
|
||||
]
|
||||
@@ -465,6 +510,17 @@ version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
|
||||
[[package]]
|
||||
name = "multitask"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c09c35271e7dcdb5f709779111f2c8e8ab8e06c1b587c1c6a9e179d865aaa5b4"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
@@ -487,6 +543,12 @@ version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.23"
|
||||
@@ -519,6 +581,18 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d83023eb990619815bb41b45625b02da62b00d0f24b0a08aae37697b3f6c94"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wepoll-sys-stjepang",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.8"
|
||||
@@ -663,9 +737,9 @@ checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||
|
||||
[[package]]
|
||||
name = "rlimit"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d26e65e82a1e2628c5f209ec12f4508fa50e644bd2f264138e60129d61eae8"
|
||||
checksum = "49b02d62c38353a6fce45c25ca19783e25dd5f495ca681c674a4ee15aa4c1536"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@@ -720,27 +794,6 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
|
||||
[[package]]
|
||||
name = "smol"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "620cbb3c6e34da57d3a248cda0cd01cd5848164dc062e764e65d06fe3ea7aed5"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"blocking",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"scoped-tls",
|
||||
"slab",
|
||||
"socket2",
|
||||
"wepoll-sys-stjepang",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.12"
|
||||
@@ -761,9 +814,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.16"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
|
||||
checksum = "6cc388d94ffabf39b5ed5fadddc40147cb21e605f53db6f8f36a625d27489ac5"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
@@ -772,9 +825,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.9"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
|
||||
checksum = "5e2513111825077552a6751dfad9e11ce0fba07d7276a3943a037d7e93e64c5f"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
@@ -839,6 +892,12 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "vec-arena"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17dfb54bf57c9043f4616cb03dab30eff012cc26631b797d8354b916708db919"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
|
||||
+12
-5
@@ -10,15 +10,18 @@ license = "MIT"
|
||||
keywords = ["port", "scanning", "nmap"]
|
||||
categories = ["command-line-utilities"]
|
||||
readme="README.md"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
exclude = [
|
||||
".github/*",
|
||||
"pictures/*",
|
||||
"rustscan-debbuilder/*",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
colored = "2.0.0"
|
||||
structopt = "0.3.16"
|
||||
async-std = "1.6.2"
|
||||
structopt = "0.3.17"
|
||||
async-std = "1.6.3"
|
||||
futures = "0.3"
|
||||
rlimit = "0.3.0"
|
||||
rlimit = "0.4.0"
|
||||
shell-words = "1.0.0"
|
||||
log = "0.4.0"
|
||||
env_logger = "0.7.1"
|
||||
@@ -31,3 +34,7 @@ ansi_term = "0.12.1"
|
||||
[package.metadata.deb]
|
||||
depends = "$auto, nmap"
|
||||
section = "rust"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = 'abort'
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
FROM rust:alpine as builder
|
||||
RUN apk update && \
|
||||
apk add build-base && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
WORKDIR /usr/src/rustscan
|
||||
COPY . .
|
||||
RUN cargo install --path .
|
||||
|
||||
FROM alpine
|
||||
LABEL author="Hydragyrum <https://github.com/Hydragyrum>"
|
||||
RUN ulimit -n 100000 && \
|
||||
apk update && \
|
||||
apk add \
|
||||
nmap nmap-scripts wget \
|
||||
&& \
|
||||
rm -rf /var/cache/apk/*
|
||||
COPY --from=builder /usr/local/cargo/bin/rustscan /usr/local/bin/rustscan
|
||||
RUN addgroup -S rustscan && \
|
||||
adduser -S -G rustscan rustscan
|
||||
USER rustscan
|
||||
ENTRYPOINT ["/usr/local/bin/rustscan"]
|
||||
@@ -5,13 +5,13 @@
|
||||
<a href="https://github.com/RustScan/RustScan#-usage">Usage Guide</a>
|
||||
⬅️
|
||||
<br>
|
||||
<img src="pictures/rustscan.png">
|
||||
<img src="https://github.com/RustScan/RustScan/blob/master/pictures/rustscan.png?raw=true">
|
||||
</p>
|
||||
<p align="center">
|
||||
<u><b> Turns a 17 minutes Nmap scan into 19 seconds. </b></u><br> Find all open ports <b>fast</b> with RustScan, automatically pipe them into Nmap.
|
||||
</p>
|
||||
<p align="center">
|
||||
<img alt="AUR version" src="https://img.shields.io/aur/version/rustscan-bin">
|
||||
<img alt="AUR version" src="https://img.shields.io/aur/version/rustscan">
|
||||
<img src="https://img.shields.io/badge/Built%20with-Rust-Purple">
|
||||
<img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/w/brandonskerritt/rustscan">
|
||||
<img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/rustscan/rustscan/total?label=GitHub%20Downloads">
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
| <p align="center"><a href="https://hub.docker.com/r/cmnatic/rustscan">🐋 Docker (Recommended) </a></p> | <p align="center"><a href="https://github.com/RustScan/RustScan/releases">👩💻 Kali / Debian </p> | <p align="center"><a href="https://aur.archlinux.org/packages/rustscan/">🏗️ Arch </a></p> | <p align="center"><a href="https://crates.io/crates/rustscan">🔧 Cargo (Universal) </a></p> |
|
||||
| ---- | ---- | ---- | --- |
|
||||
| <p align="center"><img src="pictures/docker.png" /></p> | <p align="center"><img src="pictures/kali.png" /></p> | <p align="center"><img src="pictures/arch.png" /></p> | <p align="center"><img src="pictures/rust.png" /></p>
|
||||
| `docker pull cmnatic/rustscan:debian-buster` <p>[Usage](https://github.com/RustScan/RustScan#docker-whale) | [Read the install guide](https://github.com/brandonskerritt/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `cargo install rustscan`
|
||||
| <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/docker.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/kali.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/arch.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/rust.png?raw=true" /></p>
|
||||
| `docker pull rustscan/rustscan:alpine` <p>[Usage](https://github.com/RustScan/RustScan#docker-whale) | [Read the install guide](https://github.com/brandonskerritt/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `cargo install rustscan`
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Gif</th>
|
||||
<td><img src="pictures/with_rustscan.gif" alt="The guy she tells you not to worry about"></td>
|
||||
<td><img src="pictures/without_rustscan.gif" alt="You"></td>
|
||||
<td><img src="https://github.com/RustScan/RustScan/blob/master/pictures/with_rustscan.gif?raw=true" alt="The guy she tells you not to worry about"></td>
|
||||
<td><img src="https://github.com/RustScan/RustScan/blob/master/pictures/without_rustscan.gif?raw=true" alt="You"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
@@ -67,7 +67,7 @@ RustScans **only** job is to reduce the friction between finding open ports and
|
||||
|
||||
| Installation Guide | Documentation | Discord |
|
||||
| ------------------ | ------------- | ------- |
|
||||
| 📖 [Installation Guide](https://github.com/RustScan/RustScan#-full-installation-guide) | 📚 [Documentation](https://github.com/RustScan/RustScan/issues/89) | 🦜 [Discord](https://discord.gg/GFrQsGy)
|
||||
| 📖 [Installation Guide](https://github.com/RustScan/RustScan#-full-installation-guide) | 📚 [Documentation](https://rustscan.github.io/RustScan/) | 🦜 [Discord](https://discord.gg/GFrQsGy)
|
||||
|
||||
## 🙋 Table of Contents
|
||||
* 📖 [Installation Guide](https://github.com/RustScan/RustScan#-full-installation-guide)
|
||||
@@ -79,7 +79,7 @@ RustScans **only** job is to reduce the friction between finding open ports and
|
||||
# 🔭 Why RustScan?
|
||||
Why spend time running fast scans and manually copying the ports, or waiting for a 20 minute scan to finish when you can just do all 65k ports in less than a minute?
|
||||
|
||||

|
||||

|
||||
|
||||
**RustScan running in 8 seconds and finding all open ports out of 65k.**
|
||||
|
||||
@@ -122,22 +122,32 @@ Docker is the recommended way of installing RustScan. This is because:
|
||||
|
||||
To install Docker, [follow their guide](https://docs.docker.com/engine/install/).
|
||||
|
||||
**Once Docker is installed, run this command against the IP you want to target.**
|
||||
**Once Docker is installed, you can either build your own image using the `Dockerfile` (alpine) provided in the repo, or alternatively, use the published Docker image like below (most convenient)**
|
||||
|
||||
Please see our [DockerHub](https://hub.docker.com/repository/docker/rustscan/rustscan) for further info, however, note that we have two Docker images:
|
||||
```
|
||||
rustscan/rustscan:alpine
|
||||
|
||||
rustscan/rustscan:latest
|
||||
```
|
||||
We strongly recommend using the `alpine` tag, as this is the latest major - stable - release of RustScan. This READMDE uses the `alpine` image by default, however, note that the`latest` image is considered experimental.
|
||||
|
||||
#### To get started:
|
||||
|
||||
Simply run this command against the IP you want to target:
|
||||
|
||||
```
|
||||
docker run -it --rm --name rustscan cmnatic/rustscan:debian-buster rustscan 127.0.0.1
|
||||
docker run -it --rm --name rustscan rustscan/rustscan:alpine <rustscan arguments here> <ip address to scan>
|
||||
```
|
||||
|
||||
Note: this will scan the Docker's localhost, not your own.
|
||||
|
||||
This will download the Docker image.
|
||||
|
||||
Once done, you will no longer need to re-download the image (except when RustScan updates) and can use RustScan like a normal application.
|
||||
|
||||
You will have to run this command every time, so we suggest aliasing it to something memorable.
|
||||
|
||||
```
|
||||
alias rustscan='docker run -it --rm --name rustscan cmnatic/rustscan:debian-buster rustscan'
|
||||
alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:alpine <rustscan arguments here> <ip address to scan>'
|
||||
```
|
||||
|
||||
Then we can:
|
||||
@@ -146,6 +156,23 @@ Then we can:
|
||||
rustscan 127.0.0.1 -t 500 -b 1500 -- -A
|
||||
```
|
||||
|
||||
#### To build your own image:
|
||||
|
||||
Download the repo:
|
||||
```
|
||||
git clone https://github.com/RustScan/RustScan.git
|
||||
```
|
||||
|
||||
Ensure you navigate to the download location of the repo:
|
||||
```
|
||||
cd /path/to/download/RustScan
|
||||
```
|
||||
|
||||
Build away!
|
||||
```
|
||||
docker build -t <yourimagename> .
|
||||
```
|
||||
|
||||
## 🍺 HomeBrew
|
||||
|
||||
**Note for Mac users** Mac OS has a very, very small ulimit size. This will negatively impact RustScan by a significant amount. Please use the Docker container, or tell RustScan to up the ulimit size on every run.
|
||||
@@ -186,13 +213,12 @@ rustscan -h
|
||||
```
|
||||
|
||||
```
|
||||
rustscan 1.7.1
|
||||
Fast Port Scanner built in Rust. WARNING Do not use this program against sensitive infrastructure since the specified
|
||||
server may not be able to handle this many socket connections at once. - Discord https://discord.gg/GFrQsGy - GitHub
|
||||
https://github.com/RustScan/RustScan
|
||||
|
||||
USAGE:
|
||||
rustscan [FLAGS] [OPTIONS] <ips>... [-- <command>...]
|
||||
rustscan [FLAGS] [OPTIONS] <ips-or-hosts>... [-- <command>...]
|
||||
|
||||
FLAGS:
|
||||
-a, --accessible
|
||||
@@ -204,6 +230,8 @@ OPTIONS:
|
||||
-b, --batch-size <batch-size> The batch size for port scanning, it increases or slows the speed of scanning.
|
||||
Depends on the open file limit of your OS. If you do 65535 it will do every port
|
||||
at the same time. Although, your OS may not support this [default: 4500]
|
||||
-p, --ports <ports>... A list of comma separed ports to be scanned. Example: 80,443,8080.
|
||||
-r, --range <range> A range of ports with format start-end. Example: 1-1000
|
||||
--scan-order <scan-order> The order of scanning to be performed. The "serial" option will scan ports in
|
||||
ascending order while the "random" option will scan ports randomly [default:
|
||||
serial] [possible values: Serial, Random]
|
||||
@@ -211,11 +239,11 @@ OPTIONS:
|
||||
-u, --ulimit <ulimit> Automatically ups the ULIMIT with the value you provided
|
||||
|
||||
ARGS:
|
||||
<ips>... A list of comma separated IP addresses to be scanned
|
||||
<command>... The Nmap arguments to run. To use the argument -A, end RustScan's args with '-- -A'. Example:
|
||||
'rustscan -T 1500 127.0.0.1 -- -A -sC'. This command adds -Pn -vvv -p $PORTS automatically to
|
||||
nmap. For things like --script '(safe and vuln)' enclose it in quotations marks \"'(safe and
|
||||
vuln)'\"")
|
||||
<ips-or-hosts>... A list of comma separated IP addresses or hosts to be scanned
|
||||
<command>... The Nmap arguments to run. To use the argument -A, end RustScan's args with '-- -A'.
|
||||
Example: 'rustscan -t 1500 127.0.0.1 -- -A -sC'. This command adds -Pn -vvv -p $PORTS
|
||||
automatically to nmap. For things like --script '(safe and vuln)' enclose it in quotations
|
||||
marks \"'(safe and vuln)'\"")
|
||||
```
|
||||
|
||||
The format is `rustscan -b 500 -T 1500 192.168.0.1` to scan 192.168.0.1 with 500 batch size with a timeout of 1500ms. The timeout is how long RustScan waits for a response until it assumes the port is closed.
|
||||
@@ -240,7 +268,7 @@ You can also use both of these at the same time, to make it as slow or as fast a
|
||||
|
||||
**Please** do not use this tool against sensitive servers. It is designed mainly for Capture the Flag events, not real world servers with sensitive data.
|
||||
|
||||
## 🚨 Thread Paniced at Main: Too Many Open Files
|
||||
## 🚨 Thread Panicked at Main: Too Many Open Files
|
||||
This is the most common error found in RustScan.
|
||||
|
||||
The open file limit is how many open sockets you can have at any given time.
|
||||
@@ -353,7 +381,7 @@ Please read the [contributing.md file](contributing.md)
|
||||
|
||||
## Contributors ✨
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
@@ -373,7 +401,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/Atul9"><img src="https://avatars1.githubusercontent.com/u/3390330?v=4" width="100px;" alt=""/><br /><sub><b>Atul Bhosale</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=Atul9" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://tgotwig.me"><img src="https://avatars0.githubusercontent.com/u/30773779?v=4" width="100px;" alt=""/><br /><sub><b>Thomas Gotwig</b></sub></a><br /><a href="#platform-TGotwig" title="Packaging/porting to new platform">📦</a></td>
|
||||
<td align="center"><a href="https://github.com/remigourdon"><img src="https://avatars3.githubusercontent.com/u/2874133?v=4" width="100px;" alt=""/><br /><sub><b>Rémi Gourdon</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=remigourdon" title="Documentation">📖</a> <a href="https://github.com/RustScan/RustScan/commits?author=remigourdon" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://cmnatic.co.uk"><img src="https://avatars3.githubusercontent.com/u/4163116?v=4" width="100px;" alt=""/><br /><sub><b>Ben (CMNatic)</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=cmnatic" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/commits?author=cmnatic" title="Documentation">📖</a> <a href="#design-cmnatic" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/Ferryistaken"><img src="https://avatars3.githubusercontent.com/u/47927670?v=4" width="100px;" alt=""/><br /><sub><b>Alessandro Ferrari</b></sub></a><br /><a href="#content-Ferryistaken" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://github.com/Phenomite"><img src="https://avatars2.githubusercontent.com/u/8285537?v=4" width="100px;" alt=""/><br /><sub><b>Phenomite</b></sub></a><br /><a href="#content-Phenomite" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://supersandro.de/"><img src="https://avatars2.githubusercontent.com/u/7258858?v=4" width="100px;" alt=""/><br /><sub><b>Sandro</b></sub></a><br /><a href="#content-SuperSandro2000" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://swag.lgbt"><img src="https://avatars2.githubusercontent.com/u/25358963?v=4" width="100px;" alt=""/><br /><sub><b>Cass</b></sub></a><br /><a href="#platform-caass" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/RustScan/RustScan/commits?author=caass" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/issues?q=author%3Acaass" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
+1004
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -8,7 +8,7 @@ TL;DR if you abuse members of our community you will be **perma-banned** with no
|
||||
|
||||
RustScan has 2 major labels for GitHub issues you should look at:
|
||||
* Good First issue
|
||||
These are issues for newcomers to open source!
|
||||
These are issues for newcomers to open source!
|
||||
[https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22](https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
* Help wanted
|
||||
These are issues that aren't really for newcomers, but we could still do wiht help!
|
||||
@@ -16,7 +16,7 @@ These are issues that aren't really for newcomers, but we could still do wiht he
|
||||
|
||||
If you want to, solve the issue or comment on the issue for help.
|
||||
|
||||
The flow for contributing to open source software is:
|
||||
The [flow for contributing](https://guides.github.com/introduction/flow/) to open source software is:
|
||||
* Fork the repo
|
||||
* Make changes
|
||||
* Pull request to the repo
|
||||
|
||||
+156
-19
@@ -15,7 +15,8 @@ use rlimit::Resource;
|
||||
use rlimit::{getrlimit, setrlimit};
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
use std::str::FromStr;
|
||||
use std::{net::IpAddr, net::ToSocketAddrs, time::Duration};
|
||||
use structopt::{clap::arg_enum, StructOpt};
|
||||
|
||||
extern crate colorful;
|
||||
@@ -39,6 +40,35 @@ arg_enum! {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PortRange {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
fn parse_range(input: &str) -> Result<PortRange, String> {
|
||||
let range = input
|
||||
.split("-")
|
||||
.map(|x| x.parse::<u16>())
|
||||
.collect::<Result<Vec<u16>, std::num::ParseIntError>>();
|
||||
|
||||
if range.is_err() {
|
||||
return Err(String::from(
|
||||
"the range format must be 'start-end'. Example: 1-1000.",
|
||||
));
|
||||
}
|
||||
|
||||
match range.unwrap().as_slice() {
|
||||
[start, end] => Ok(PortRange {
|
||||
start: *start,
|
||||
end: *end,
|
||||
}),
|
||||
_ => Err(String::from(
|
||||
"the range format must be 'start-end'. Example: 1-1000.",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "rustscan", setting = structopt::clap::AppSettings::TrailingVarArg)]
|
||||
/// Fast Port Scanner built in Rust.
|
||||
@@ -47,9 +77,17 @@ arg_enum! {
|
||||
/// - Discord https://discord.gg/GFrQsGy
|
||||
/// - GitHub https://github.com/RustScan/RustScan
|
||||
struct Opts {
|
||||
/// A list of comma separated IP addresses to be scanned.
|
||||
#[structopt(use_delimiter = true, parse(try_from_str), required = true)]
|
||||
ips: Vec<IpAddr>,
|
||||
/// A list of comma separated IP addresses or hosts to be scanned.
|
||||
#[structopt(use_delimiter = true, required = true)]
|
||||
ips_or_hosts: Vec<String>,
|
||||
|
||||
/// A list of comma separed ports to be scanned. Example: 80,443,8080.
|
||||
#[structopt(short, long, use_delimiter = true)]
|
||||
ports: Option<Vec<u16>>,
|
||||
|
||||
/// A range of ports with format start-end. Example: 1-1000.
|
||||
#[structopt(short, long, conflicts_with = "ports", parse(try_from_str = parse_range))]
|
||||
range: Option<PortRange>,
|
||||
|
||||
///Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
|
||||
#[structopt(short, long)]
|
||||
@@ -82,7 +120,7 @@ struct Opts {
|
||||
|
||||
/// The Nmap arguments to run.
|
||||
/// To use the argument -A, end RustScan's args with '-- -A'.
|
||||
/// Example: 'rustscan -T 1500 127.0.0.1 -- -A -sC'.
|
||||
/// Example: 'rustscan -t 1500 127.0.0.1 -- -A -sC'.
|
||||
/// This command adds -Pn -vvv -p $PORTS automatically to nmap.
|
||||
/// For things like --script '(safe and vuln)' enclose it in quotations marks \"'(safe and vuln)'\"")
|
||||
#[structopt(last = true)]
|
||||
@@ -96,22 +134,37 @@ fn main() {
|
||||
env_logger::init();
|
||||
|
||||
info!("Starting up");
|
||||
let opts = Opts::from_args();
|
||||
let mut opts = Opts::from_args();
|
||||
|
||||
if opts.ports.is_none() && opts.range.is_none() {
|
||||
opts.range = Some(PortRange {
|
||||
start: LOWEST_PORT_NUMBER,
|
||||
end: TOP_PORT_NUMBER,
|
||||
});
|
||||
}
|
||||
|
||||
info!("Mains() `opts` arguments are {:?}", opts);
|
||||
|
||||
if !opts.quiet && !opts.accessible {
|
||||
print_opening();
|
||||
}
|
||||
|
||||
let ips: Vec<IpAddr> = parse_ips(&opts);
|
||||
|
||||
if ips.is_empty() {
|
||||
warning!("No IPs could be resolved, aborting scan.", false);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let ulimit: rlimit::rlim = adjust_ulimit_size(&opts);
|
||||
let batch_size: u16 = infer_batch_size(&opts, ulimit);
|
||||
|
||||
let scanner = Scanner::new(
|
||||
&opts.ips,
|
||||
&ips,
|
||||
batch_size,
|
||||
Duration::from_millis(opts.timeout.into()),
|
||||
opts.quiet,
|
||||
PortStrategy::pick(LOWEST_PORT_NUMBER, TOP_PORT_NUMBER, opts.scan_order),
|
||||
PortStrategy::pick(opts.range, opts.ports, opts.scan_order),
|
||||
);
|
||||
|
||||
let scan_result = block_on(scanner.run());
|
||||
@@ -124,7 +177,7 @@ fn main() {
|
||||
.push(socket.port());
|
||||
}
|
||||
|
||||
for ip in opts.ips {
|
||||
for ip in ips {
|
||||
if ports_per_ip.contains_key(&ip) {
|
||||
continue;
|
||||
}
|
||||
@@ -134,7 +187,7 @@ fn main() {
|
||||
|
||||
let x = format!("{} Looks like I didn't find any open ports for {:?}. This is usually caused by a high batch size.
|
||||
\n*I used {} batch size, consider lowering to {} with {} or a comfortable number for your system.
|
||||
\n Alternatively, increase the timeout if your ping is high. Rustscan -T 2000 for 2000 second timeout.\n",
|
||||
\n Alternatively, increase the timeout if your ping is high. Rustscan -t 2000 for 2000 milliseconds (2s) timeout.\n",
|
||||
"ERROR",
|
||||
ip,
|
||||
opts.batch_size,
|
||||
@@ -215,7 +268,6 @@ fn build_nmap_arguments<'a>(
|
||||
is_ipv6: bool,
|
||||
) -> Vec<&'a str> {
|
||||
let mut arguments: Vec<&str> = user_args.iter().map(AsRef::as_ref).collect();
|
||||
arguments.push("-A");
|
||||
arguments.push("-vvv");
|
||||
|
||||
if is_ipv6 {
|
||||
@@ -229,6 +281,25 @@ fn build_nmap_arguments<'a>(
|
||||
arguments
|
||||
}
|
||||
|
||||
fn parse_ips(opts: &Opts) -> Vec<IpAddr> {
|
||||
let mut ips: Vec<IpAddr> = Vec::new();
|
||||
|
||||
for ip_or_host in &opts.ips_or_hosts {
|
||||
match IpAddr::from_str(ip_or_host) {
|
||||
Ok(ip) => ips.push(ip),
|
||||
_ => match format!("{}:{}", &ip_or_host, 80).to_socket_addrs() {
|
||||
Ok(mut iter) => ips.push(iter.nth(0).unwrap().ip()),
|
||||
_ => {
|
||||
let failed_to_resolve = format!("Host {:?} could not be resolved.", ip_or_host);
|
||||
warning!(failed_to_resolve, opts.quiet);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
ips
|
||||
}
|
||||
|
||||
fn adjust_ulimit_size(opts: &Opts) -> rlimit::rlim {
|
||||
if opts.ulimit.is_some() {
|
||||
let limit: rlimit::rlim = opts.ulimit.unwrap();
|
||||
@@ -254,7 +325,7 @@ fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
|
||||
|
||||
// Adjust the batch size when the ulimit value is lower than the desired batch size
|
||||
if ulimit < batch_size {
|
||||
warning!("File limit is lower than default batch size. Consider upping with --ulimt. May cause harm to sensitive servers",
|
||||
warning!("File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers",
|
||||
opts.quiet
|
||||
);
|
||||
|
||||
@@ -289,13 +360,14 @@ fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{adjust_ulimit_size, infer_batch_size, print_opening, Opts, ScanOrder};
|
||||
use std::{net::IpAddr, str::FromStr};
|
||||
use crate::{adjust_ulimit_size, infer_batch_size, parse_ips, print_opening, Opts, ScanOrder};
|
||||
|
||||
#[test]
|
||||
fn batch_size_lowered() {
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
@@ -312,7 +384,9 @@ mod tests {
|
||||
#[test]
|
||||
fn batch_size_lowered_average_size() {
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
@@ -330,7 +404,9 @@ mod tests {
|
||||
// because ulimit and batch size are same size, batch size is lowered
|
||||
// to ULIMIT - 100
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
@@ -347,7 +423,9 @@ mod tests {
|
||||
fn batch_size_adjusted_2000() {
|
||||
// ulimit == batch_size
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
@@ -369,7 +447,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_high_ulimit_no_quiet_mode() {
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: false,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
@@ -383,4 +463,61 @@ mod tests {
|
||||
|
||||
assert!(1 == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_correct_ips_or_hosts() {
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned(), "google.com".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let ips = parse_ips(&opts);
|
||||
|
||||
assert_eq!(2, ips.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_correct_and_incorrect_ips_or_hosts() {
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned(), "im_wrong".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let ips = parse_ips(&opts);
|
||||
|
||||
assert_eq!(1, ips.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_incorrect_ips_or_hosts() {
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["im_wrong".to_owned(), "300.10.1.1".to_owned()],
|
||||
ports: None,
|
||||
range: None,
|
||||
quiet: true,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let ips = parse_ips(&opts);
|
||||
|
||||
assert_eq!(0, ips.len());
|
||||
}
|
||||
}
|
||||
+53
-10
@@ -1,5 +1,7 @@
|
||||
mod range_iterator;
|
||||
use super::ScanOrder;
|
||||
use super::{PortRange, ScanOrder};
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use range_iterator::RangeIterator;
|
||||
|
||||
/// Represents options of port scanning.
|
||||
@@ -7,20 +9,41 @@ use range_iterator::RangeIterator;
|
||||
/// Right now all these options involve ranges, but in the future
|
||||
/// it will also contain custom lists of ports.
|
||||
pub enum PortStrategy {
|
||||
Manual(Vec<u16>),
|
||||
Serial(SerialRange),
|
||||
Random(RandomRange),
|
||||
}
|
||||
|
||||
impl PortStrategy {
|
||||
pub fn pick(start: u16, end: u16, scan_type: ScanOrder) -> Self {
|
||||
match scan_type {
|
||||
ScanOrder::Serial => PortStrategy::Serial(SerialRange { start, end }),
|
||||
ScanOrder::Random => PortStrategy::Random(RandomRange { start, end }),
|
||||
pub fn pick(range: Option<PortRange>, ports: Option<Vec<u16>>, order: ScanOrder) -> Self {
|
||||
match order {
|
||||
ScanOrder::Serial if ports.is_none() => {
|
||||
let range = range.as_ref().unwrap();
|
||||
PortStrategy::Serial(SerialRange {
|
||||
start: range.start,
|
||||
end: range.end,
|
||||
})
|
||||
}
|
||||
ScanOrder::Random if ports.is_none() => {
|
||||
let range = range.as_ref().unwrap();
|
||||
PortStrategy::Random(RandomRange {
|
||||
start: range.start,
|
||||
end: range.end,
|
||||
})
|
||||
}
|
||||
ScanOrder::Serial => PortStrategy::Manual(ports.unwrap()),
|
||||
ScanOrder::Random => {
|
||||
let mut rng = thread_rng();
|
||||
let mut ports = ports.unwrap();
|
||||
ports.shuffle(&mut rng);
|
||||
PortStrategy::Manual(ports)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn order(&self) -> Vec<u16> {
|
||||
match self {
|
||||
PortStrategy::Manual(ports) => ports.to_vec(),
|
||||
PortStrategy::Serial(range) => range.generate(),
|
||||
PortStrategy::Random(range) => range.generate(),
|
||||
}
|
||||
@@ -71,18 +94,20 @@ impl RangeOrder for RandomRange {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PortStrategy;
|
||||
use crate::ScanOrder;
|
||||
use crate::{PortRange, ScanOrder};
|
||||
|
||||
#[test]
|
||||
fn serial_strategy() {
|
||||
let strategy = PortStrategy::pick(1, 100, ScanOrder::Serial);
|
||||
fn serial_strategy_with_range() {
|
||||
let range = PortRange { start: 1, end: 100 };
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Serial);
|
||||
let result = strategy.order();
|
||||
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
#[test]
|
||||
fn random_strategy() {
|
||||
let strategy = PortStrategy::pick(1, 100, ScanOrder::Random);
|
||||
fn random_strategy_with_range() {
|
||||
let range = PortRange { start: 1, end: 100 };
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
|
||||
let mut result = strategy.order();
|
||||
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
|
||||
assert_ne!(expected_range, result);
|
||||
@@ -90,4 +115,22 @@ mod tests {
|
||||
result.sort();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serial_strategy_with_ports() {
|
||||
let strategy = PortStrategy::pick(None, Some(vec![80, 443]), ScanOrder::Serial);
|
||||
let result = strategy.order();
|
||||
assert_eq!(vec![80, 443], result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_strategy_with_ports() {
|
||||
let strategy = PortStrategy::pick(None, Some((1..10).collect()), ScanOrder::Random);
|
||||
let mut result = strategy.order();
|
||||
let expected_range = (1..10).into_iter().collect::<Vec<u16>>();
|
||||
assert_ne!(expected_range, result);
|
||||
|
||||
result.sort();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
}
|
||||
Submodule
+1
Submodule src/rustscan_scripting_engine added at 13c3fabcac.
+38
-18
@@ -12,14 +12,14 @@ use std::{
|
||||
};
|
||||
|
||||
/// The class for the scanner
|
||||
/// Host is data type IpAddr and is the host address
|
||||
/// IP is data type IpAddr and is the IP address
|
||||
/// start & end is where the port scan starts and ends
|
||||
/// batch_size is how many ports at a time should be scanned
|
||||
/// Timeout is the time RustScan should wait before declaring a port closed. As datatype Duration.
|
||||
/// Quiet is whether or not RustScan should print things, or wait until the end to print only open ports.
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
pub struct Scanner {
|
||||
hosts: Vec<IpAddr>,
|
||||
ips: Vec<IpAddr>,
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
@@ -28,7 +28,7 @@ pub struct Scanner {
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(
|
||||
hosts: &[IpAddr],
|
||||
ips: &[IpAddr],
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
@@ -39,7 +39,7 @@ impl Scanner {
|
||||
timeout,
|
||||
quiet,
|
||||
port_strategy,
|
||||
hosts: hosts.iter().map(|host| host.to_owned()).collect(),
|
||||
ips: ips.iter().map(|ip| ip.to_owned()).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,10 +48,10 @@ impl Scanner {
|
||||
/// Returns all open ports as Vec<u16>
|
||||
pub async fn run(&self) -> Vec<SocketAddr> {
|
||||
let ports: Vec<u16> = self.port_strategy.order();
|
||||
let batch_per_host: usize = self.batch_size as usize / self.hosts.len();
|
||||
let batch_per_ip: usize = self.batch_size as usize / self.ips.len();
|
||||
let mut open_sockets: Vec<SocketAddr> = Vec::new();
|
||||
|
||||
for batch in ports.chunks(batch_per_host) {
|
||||
for batch in ports.chunks(batch_per_ip) {
|
||||
let mut sockets = self.scan_ports(batch).await;
|
||||
open_sockets.append(&mut sockets);
|
||||
}
|
||||
@@ -64,8 +64,8 @@ impl Scanner {
|
||||
async fn scan_ports(&self, ports: &[u16]) -> Vec<SocketAddr> {
|
||||
let mut ftrs = FuturesUnordered::new();
|
||||
for port in ports {
|
||||
for host in &self.hosts {
|
||||
ftrs.push(self.scan_socket(SocketAddr::new(*host, *port)));
|
||||
for ip in &self.ips {
|
||||
ftrs.push(self.scan_socket(SocketAddr::new(*ip, *port)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ impl Scanner {
|
||||
///
|
||||
/// self.scan_port(10:u16)
|
||||
///
|
||||
/// Note: `self` must contain `self.host`.
|
||||
/// Note: `self` must contain `self.ip`.
|
||||
async fn scan_socket(&self, socket: SocketAddr) -> io::Result<SocketAddr> {
|
||||
match self.connect(socket).await {
|
||||
Ok(x) => {
|
||||
@@ -119,9 +119,9 @@ impl Scanner {
|
||||
/// # Example
|
||||
///
|
||||
/// let port: u16 = 80
|
||||
/// // Host is an IpAddr type
|
||||
/// let host = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
/// let socket = SocketAddr::new(host, port);
|
||||
/// // ip is an IpAddr type
|
||||
/// let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
/// let socket = SocketAddr::new(ip, port);
|
||||
/// self.connect(socket)
|
||||
/// // returns Result which is either Ok(stream) for port is open, or Er for port is closed.
|
||||
/// // Timeout occurs after self.timeout seconds
|
||||
@@ -139,7 +139,7 @@ impl Scanner {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ScanOrder;
|
||||
use crate::{PortRange, ScanOrder};
|
||||
use async_std::task::block_on;
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
|
||||
@@ -147,7 +147,11 @@ mod tests {
|
||||
fn scanner_runs() {
|
||||
// Makes sure the program still runs and doesn't panic
|
||||
let addrs = vec!["127.0.0.1".parse::<IpAddr>().unwrap()];
|
||||
let strategy = PortStrategy::pick(1, 1_000, ScanOrder::Random);
|
||||
let range = PortRange {
|
||||
start: 1,
|
||||
end: 1_000,
|
||||
};
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
|
||||
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
|
||||
@@ -157,7 +161,11 @@ mod tests {
|
||||
fn ipv6_scanner_runs() {
|
||||
// Makes sure the program still runs and doesn't panic
|
||||
let addrs = vec!["::1".parse::<IpAddr>().unwrap()];
|
||||
let strategy = PortStrategy::pick(1, 1_000, ScanOrder::Random);
|
||||
let range = PortRange {
|
||||
start: 1,
|
||||
end: 1_000,
|
||||
};
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
|
||||
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
|
||||
@@ -166,7 +174,11 @@ mod tests {
|
||||
#[test]
|
||||
fn quad_zero_scanner_runs() {
|
||||
let addrs = vec!["0.0.0.0".parse::<IpAddr>().unwrap()];
|
||||
let strategy = PortStrategy::pick(1, 1_000, ScanOrder::Random);
|
||||
let range = PortRange {
|
||||
start: 1,
|
||||
end: 1_000,
|
||||
};
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
|
||||
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
@@ -174,7 +186,11 @@ mod tests {
|
||||
#[test]
|
||||
fn google_dns_runs() {
|
||||
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
|
||||
let strategy = PortStrategy::pick(400, 445, ScanOrder::Random);
|
||||
let range = PortRange {
|
||||
start: 400,
|
||||
end: 445,
|
||||
};
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
|
||||
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
@@ -185,7 +201,11 @@ mod tests {
|
||||
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
|
||||
|
||||
// mac should have this automatically scaled down
|
||||
let strategy = PortStrategy::pick(400, 600, ScanOrder::Random);
|
||||
let range = PortRange {
|
||||
start: 400,
|
||||
end: 600,
|
||||
};
|
||||
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
|
||||
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
|
||||
Reference in new issue
Block a user