mirror of
https://github.com/bee-san/RustScan.git
synced 2026-11-08 01:08:27 -10:00
Compare commits
236
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fbf39f0cc | ||
|
|
14b6ea928d | ||
|
|
9452b1f922 | ||
|
|
ed12888e81 | ||
|
|
f68abcb955 | ||
|
|
4c91e8fb40 | ||
|
|
1d3e831066 | ||
|
|
ff6b1c40db | ||
|
|
5573d91a7b | ||
|
|
a8e56eec4b | ||
|
|
fb75c9d332 | ||
|
|
581ec27cb5 | ||
|
|
9673c8807d | ||
|
|
78818d6bc7 | ||
|
|
d0ff597be6 | ||
|
|
516ebe367a | ||
|
|
1e9660e4ff | ||
|
|
7b4dda5a19 | ||
|
|
a20b71191d | ||
|
|
18c5dd69e5 | ||
|
|
090264ac26 | ||
|
|
702681606f | ||
|
|
c58ac613c9 | ||
|
|
44b53fb877 | ||
|
|
99e72e4a16 | ||
|
|
e02073bd97 | ||
|
|
59bb72426d | ||
|
|
f48590c238 | ||
|
|
a3eb548ae9 | ||
|
|
050a8baf48 | ||
|
|
9b893dbf71 | ||
|
|
8245ccf31e | ||
|
|
301a656006 | ||
|
|
1639aadc54 | ||
|
|
c66bb50508 | ||
|
|
b490eb08be | ||
|
|
990e92dcbf | ||
|
|
883e89fe5e | ||
|
|
1b15cc2f71 | ||
|
|
18b574f6bb | ||
|
|
3fafee42b9 | ||
|
|
8b21dfd9a2 | ||
|
|
2f16729c54 | ||
|
|
785c2a4de1 | ||
|
|
80cc97bf83 | ||
|
|
7a825dae41 | ||
|
|
751c4daff6 | ||
|
|
f6214cfb27 | ||
|
|
a92eb80365 | ||
|
|
aeab4fb68c | ||
|
|
9ab15c9d8b | ||
|
|
7146c23ed9 | ||
|
|
f37f2d8f9d | ||
|
|
5a3a4d1c0c | ||
|
|
33e7cd44b6 | ||
|
|
8288856949 | ||
|
|
c3b96e262d | ||
|
|
a54868000e | ||
|
|
8f4acdf99a | ||
|
|
c637042906 | ||
|
|
766164588c | ||
|
|
b2be83c04a | ||
|
|
a3654b68eb | ||
|
|
1873a92951 | ||
|
|
c7a422b962 | ||
|
|
0eec9233bd | ||
|
|
0f18bb49a3 | ||
|
|
8b363571f1 | ||
|
|
e546608ff8 | ||
|
|
a7d1952b72 | ||
|
|
0fa11f6e51 | ||
|
|
d423f34e7a | ||
|
|
67726cc490 | ||
|
|
d5d39cacd3 | ||
|
|
52cbbeeac6 | ||
|
|
e17f9d0bb1 | ||
|
|
3329428766 | ||
|
|
23c049413b | ||
|
|
9858406271 | ||
|
|
6abb3737ec | ||
|
|
65b9cb1659 | ||
|
|
d2684baead | ||
|
|
5a40bc4182 | ||
|
|
f03f15a6d0 | ||
|
|
5f95b34250 | ||
|
|
4bca6ce337 | ||
|
|
9740d54912 | ||
|
|
f577cd23bd | ||
|
|
f16d704c86 | ||
|
|
e5368a31db | ||
|
|
01c2580672 | ||
|
|
200382a731 | ||
|
|
6a000762a5 | ||
|
|
e9b21338ef | ||
|
|
bd436221ca | ||
|
|
5d16af21f1 | ||
|
|
e331789598 | ||
|
|
bf56b10ff4 | ||
|
|
719c38bd32 | ||
|
|
a08fe2456d | ||
|
|
db1831c4b8 | ||
|
|
74e2ff026a | ||
|
|
897c1c4091 | ||
|
|
a9340bb622 | ||
|
|
9caed66265 | ||
|
|
eae6342255 | ||
|
|
328156c613 | ||
|
|
f53f6123bf | ||
|
|
7044174933 | ||
|
|
1ede04d539 | ||
|
|
e56456e779 | ||
|
|
484cf023d7 | ||
|
|
98763d43e0 | ||
|
|
a81c409ed4 | ||
|
|
c0f63e0534 | ||
|
|
137f8669fe | ||
|
|
c658b0ea70 | ||
|
|
1d68c842d9 | ||
|
|
6568203f46 | ||
|
|
0cfe82eb5d | ||
|
|
53512039d1 | ||
|
|
7b392f0d6d | ||
|
|
bf67019079 | ||
|
|
da27b17485 | ||
|
|
a528d41ac6 | ||
|
|
7686c25d0d | ||
|
|
9cf4177faa | ||
|
|
647b97b52c | ||
|
|
1b8b0b4478 | ||
|
|
c6dedc317a | ||
|
|
654488cbbc | ||
|
|
81701d4243 | ||
|
|
97eac2aa33 | ||
|
|
76ee4666b8 | ||
|
|
7e48f125dc | ||
|
|
56482fd8ff | ||
|
|
5e41472814 | ||
|
|
d99c811e93 | ||
|
|
ec003e4557 | ||
|
|
50ca069f20 | ||
|
|
9d2318ab9c | ||
|
|
9c7916f92a | ||
|
|
6d053ad199 | ||
|
|
7dedfb5fed | ||
|
|
748ad43db0 | ||
|
|
75523d03cb | ||
|
|
328226838e | ||
|
|
f78b114486 | ||
|
|
7bb1f7860b | ||
|
|
2fd63fa1f3 | ||
|
|
89047f4b26 | ||
|
|
f659b8dd3d | ||
|
|
6ab1c526cc | ||
|
|
b2eac63130 | ||
|
|
cdb55261b2 | ||
|
|
fb666f46bb | ||
|
|
96659dcd89 | ||
|
|
b4f9d9d228 | ||
|
|
30ab9523a2 | ||
|
|
ff2eea2015 | ||
|
|
aef842c2e3 | ||
|
|
2f9a54e2ba | ||
|
|
dfb451aacc | ||
|
|
0cd37b4ffe | ||
|
|
0c01dc0f17 | ||
|
|
b52a990ad0 | ||
|
|
1c88f98132 | ||
|
|
c8404781dc | ||
|
|
6617b2178b | ||
|
|
e2395f8ddc | ||
|
|
6ab43bf213 | ||
|
|
da3629cc7b | ||
|
|
af344becbc | ||
|
|
85b7f9fe7a | ||
|
|
9d1d064e71 | ||
|
|
343563818f | ||
|
|
bc77814d59 | ||
|
|
42b72ea114 | ||
|
|
d73c66482e | ||
|
|
b850868265 | ||
|
|
c77e45d478 | ||
|
|
82e3128641 | ||
|
|
679d1a787d | ||
|
|
813b6753c8 | ||
|
|
51df49836b | ||
|
|
2df98016c9 | ||
|
|
deb8bb3216 | ||
|
|
6ce8fe1afd | ||
|
|
8aa9a44949 | ||
|
|
416602dd02 | ||
|
|
a2e7125e03 | ||
|
|
10acad243c | ||
|
|
5d69339cc7 | ||
|
|
d8fd12694c | ||
|
|
7d4084d06c | ||
|
|
365be75689 | ||
|
|
5ea316c5db | ||
|
|
b363529045 | ||
|
|
ed378f7fc8 | ||
|
|
aa3c591016 | ||
|
|
ef893fdcb8 | ||
|
|
b78a8ad0af | ||
|
|
7ad7e34abc | ||
|
|
e41393b4ad | ||
|
|
6d72037974 | ||
|
|
66486b2467 | ||
|
|
4b085d97f2 | ||
|
|
4785b75f9f | ||
|
|
3951c25dff | ||
|
|
071c437206 | ||
|
|
7d351f2025 | ||
|
|
8ce14c5690 | ||
|
|
6cf71a1529 | ||
|
|
50c74d63cf | ||
|
|
c1f9be150f | ||
|
|
0a13100185 | ||
|
|
b67aa40eae | ||
|
|
fb3c7c4ce2 | ||
|
|
4d4ef5ac51 | ||
|
|
022cc8725a | ||
|
|
e12a12fd04 | ||
|
|
999634cf9b | ||
|
|
c45f4d1b86 | ||
|
|
3f4c0c32cc | ||
|
|
a3a4cf9587 | ||
|
|
e17ec84867 | ||
|
|
0fbdda51d2 | ||
|
|
4de017250d | ||
|
|
08cbf08beb | ||
|
|
e5c51c3980 | ||
|
|
757653a30b | ||
|
|
c5d02c31f1 | ||
|
|
6906177ec2 | ||
|
|
276e0d193c | ||
|
|
965d3d780c | ||
|
|
67d34b5036 |
No files matched your search
+60
-1
@@ -56,11 +56,70 @@
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "imlonghao",
|
||||
"name": "imlonghao",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/4951333?v=4",
|
||||
"profile": "https://imlonghao.com",
|
||||
"contributions": [
|
||||
"bug",
|
||||
"maintenance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "royharoush",
|
||||
"name": "royharoush",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/8113056?v=4",
|
||||
"profile": "https://github.com/royharoush",
|
||||
"contributions": [
|
||||
"ideas",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Atul9",
|
||||
"name": "Atul Bhosale",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/3390330?v=4",
|
||||
"profile": "https://github.com/Atul9",
|
||||
"contributions": [
|
||||
"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",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2874133?v=4",
|
||||
"profile": "https://github.com/remigourdon",
|
||||
"contributions": [
|
||||
"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"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "RustScan",
|
||||
"projectOwner": "brandonskerritt",
|
||||
"projectOwner": "RustScan",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
todo:
|
||||
keyword: "TODO"
|
||||
keyword: "// TODO"
|
||||
@@ -0,0 +1,10 @@
|
||||
name: Check Markdown links
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
markdown-link-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
@@ -30,3 +30,26 @@ jobs:
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
|
||||
fmt:
|
||||
name: Rustfmt
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- run: rustup component add rustfmt
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
links:
|
||||
name: markdown-link-check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Check Markdown links
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
# Run everyday at 9:00 AM (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07)
|
||||
- cron: "0 9 * * *"
|
||||
|
||||
jobs:
|
||||
markdown-link-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
with:
|
||||
use-quiet-mode: 'yes'
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
language: rust
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
# - windows
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- rustup component add rustfmt
|
||||
|
||||
# cargo test
|
||||
rust:
|
||||
- stable
|
||||
- beta
|
||||
jobs:
|
||||
fast_finish: true
|
||||
|
||||
# Cargo fmt
|
||||
script:
|
||||
- cargo build
|
||||
- cargo test
|
||||
- cargo fmt -- --check
|
||||
|
||||
# automatic deployment to cargo on release
|
||||
# deploy:
|
||||
|
||||
# provider: releases
|
||||
# api_key: "GITHUB OAUTH TOKEN"
|
||||
# file: "FILE TO UPLOAD"
|
||||
# skip_cleanup: true
|
||||
# on:
|
||||
# tags: true
|
||||
|
||||
# after_success:
|
||||
# - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
|
||||
# - chmod +x send.sh
|
||||
# - ./send.sh success $WEBHOOK_URL
|
||||
|
||||
# only deploy on master branch
|
||||
# on:
|
||||
# branch: master
|
||||
# provider: cargo
|
||||
# token: $crates
|
||||
|
||||
|
||||
after_failure:
|
||||
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
|
||||
- chmod +x send.sh
|
||||
- ./send.sh failure $WEBHOOK_URL
|
||||
Generated
+470
-83
@@ -1,5 +1,14 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
@@ -10,10 +19,31 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.1.1"
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee81ba99bee79f3c8ae114ae4baa7eaa326f63447cf2ec65e4393618b63f8770"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43de69555a39d52918e2bc33a408d3c0a86c829b212d898f4ca25d21a6387478"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener",
|
||||
@@ -21,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",
|
||||
@@ -39,7 +116,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
"smol",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
@@ -72,6 +148,12 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
@@ -79,16 +161,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "0.4.7"
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2468ff7bf85066b4a3678fede6fe66db31846d753ff0adfbfab2c6a6e81612b"
|
||||
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76e94bf99b692f54c9d05f97454d3faf11134523fe5b180564a3fb6ed63bcc0a"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"atomic-waker",
|
||||
"futures-lite",
|
||||
"once_cell",
|
||||
"parking",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
@@ -118,11 +210,11 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.1"
|
||||
version = "2.33.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||
checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"ansi_term 0.11.0",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
@@ -133,9 +225,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "1.9.3"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
|
||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
@@ -143,14 +235,26 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "1.1.2"
|
||||
name = "colorful"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1582139bb74d97ef232c30bc236646017db06f13ee7cc01fa24c9e55640f86d4"
|
||||
checksum = "0bca1619ff57dd7a56b58a8e25ef4199f123e78e503fe1653410350a1b98ae65"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
|
||||
dependencies = [
|
||||
"cache-padded",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
@@ -163,10 +267,43 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.2.1"
|
||||
name = "dirs"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829694371bd7bbc6aee17c4ff624aad8bf9f4dc06c6f9f6071eaa08c89530d10"
|
||||
checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68082183f458867ce7cddea16d4df4443c1537112c0c09c450dedc09daf5c719"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
@@ -224,15 +361,15 @@ checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cc8771bd1bb4c7be3c5f072a1d5e18086ef220f100a0a4efece41076e87b9f2"
|
||||
checksum = "bbe71459749b2e8e66fb95df721b22fa08661ad384a0c5b519e11d3893b4692a"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
"parking",
|
||||
"parking 1.0.6",
|
||||
"pin-project-lite",
|
||||
"waker-fn",
|
||||
]
|
||||
@@ -284,6 +421,32 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcd"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c7cd301bf2ab11ae4e5bdfd79c221d97a25e46c089144a62ee9d09cb32d2b92"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.15"
|
||||
@@ -294,10 +457,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.42"
|
||||
name = "humantime"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
|
||||
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||
dependencies = [
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -319,9 +491,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.73"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
|
||||
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@@ -338,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"
|
||||
@@ -361,19 +544,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.22"
|
||||
name = "parking"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17"
|
||||
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "0.4.22"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7"
|
||||
checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -393,10 +582,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.16"
|
||||
name = "polling"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
|
||||
checksum = "b6d83023eb990619815bb41b45625b02da62b00d0f24b0a08aae37697b3f6c94"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wepoll-sys-stjepang",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
@@ -413,6 +644,12 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
@@ -422,6 +659,47 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
@@ -429,24 +707,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "rlimit"
|
||||
version = "0.3.0"
|
||||
name = "redox_users"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d26e65e82a1e2628c5f209ec12f4508fa50e644bd2f264138e60129d61eae8"
|
||||
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||
|
||||
[[package]]
|
||||
name = "rlimit"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b02d62c38353a6fce45c25ca19783e25dd5f495ca681c674a4ee15aa4c1536"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustscan"
|
||||
version = "1.2.0"
|
||||
name = "rust-argon2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustscan"
|
||||
version = "1.7.1"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"async-std",
|
||||
"clap",
|
||||
"colored",
|
||||
"colorful",
|
||||
"dirs",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"gcd",
|
||||
"log",
|
||||
"rand",
|
||||
"rlimit",
|
||||
"shell-words",
|
||||
"structopt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -455,33 +782,18 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "shell-words"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fa3938c99da4914afedd13bf3d79bcb6c277d1b2c398d23257a304d9e1b074"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
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"
|
||||
@@ -501,16 +813,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.35"
|
||||
name = "structopt"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
|
||||
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
@@ -520,6 +865,21 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
@@ -532,12 +892,24 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.0.0"
|
||||
@@ -545,10 +917,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.65"
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -556,9 +934,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.65"
|
||||
version = "0.2.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
|
||||
checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@@ -571,9 +949,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.15"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41ad6e4e8b2b7f8c90b6e09a9b590ea15cb0d1dbe28502b5a405cd95d1981671"
|
||||
checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@@ -583,9 +961,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.65"
|
||||
version = "0.2.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
|
||||
checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -593,9 +971,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.65"
|
||||
version = "0.2.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
|
||||
checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -606,15 +984,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.65"
|
||||
version = "0.2.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
|
||||
checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.42"
|
||||
version = "0.3.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
|
||||
checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -645,6 +1023,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
||||
+16
-8
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "rustscan"
|
||||
version = "1.2.0"
|
||||
version = "1.7.1"
|
||||
authors = ["Bee <[email protected]>"]
|
||||
edition = "2018"
|
||||
description = "Faster Nmap Scanning with Rust"
|
||||
homepage = "https://github.com/brandonskerritt/rustscan"
|
||||
repository = "https://github.com/brandonskerritt/rustscan"
|
||||
homepage = "https://github.com/rustscan/rustscan"
|
||||
repository = "https://github.com/rustscan/rustscan"
|
||||
license = "MIT"
|
||||
keywords = ["port", "scanning", "nmap"]
|
||||
categories = ["command-line-utilities"]
|
||||
@@ -14,12 +14,20 @@ readme="README.md"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
colored = "1.9.3"
|
||||
clap = "2.33.0"
|
||||
async-std = "1.6.2"
|
||||
colored = "2.0.0"
|
||||
structopt = "0.3.16"
|
||||
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"
|
||||
dirs = "3.0.1"
|
||||
gcd = "2.0.1"
|
||||
rand = "0.7.3"
|
||||
colorful = "0.2.1"
|
||||
ansi_term = "0.12.1"
|
||||
|
||||
[package.metadata.deb]
|
||||
depends = "$auto, nmap"
|
||||
|
||||
section = "rust"
|
||||
+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"]
|
||||
@@ -0,0 +1,21 @@
|
||||
install:
|
||||
cargo install cross
|
||||
|
||||
build:
|
||||
make build-linux
|
||||
make build-mac
|
||||
|
||||
make shasum
|
||||
|
||||
build-linux:
|
||||
@echo 'Building for Linux... 🐧'
|
||||
cross build --release --target=x86_64-unknown-linux-musl
|
||||
mkdir -p target/release-archives && tar -czf target/release-archives/rustscan-linux.tar.gz target/x86_64-unknown-linux-musl/release/rustscan
|
||||
|
||||
build-mac:
|
||||
@echo 'Building for MacOS... 🍏'
|
||||
cross build --release --target=x86_64-apple-darwin
|
||||
mkdir -p target/release-archives && tar -czf target/release-archives/rustscan-mac.tar.gz target/x86_64-apple-darwin/release/rustscan
|
||||
|
||||
shasum:
|
||||
shasum -a 256 target/release-archives/rustscan-*.tar.gz
|
||||
@@ -1,24 +1,35 @@
|
||||
<p align="center">
|
||||
<img src="pictures/rustscan.png"><br>
|
||||
<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.
|
||||
➡️
|
||||
<a href="https://discord.gg/GFrQsGy">Discord</a> |
|
||||
<a href="https://github.com/RustScan/RustScan#-full-installation-guide">Installation Guide</a> |
|
||||
<a href="https://github.com/RustScan/RustScan#-usage">Usage Guide</a>
|
||||
⬅️
|
||||
<br>
|
||||
<img src="pictures/rustscan.png">
|
||||
</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 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">
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/d/rustscan?label=Cargo%20Downloads">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/736614461313515576">
|
||||
<img alt="Actions" src="https://github.com/RustScan/RustScan/workflows/Continuous%20integration/badge.svg?branch=master">
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
|
||||
| <p align="center"><a href="https://crates.io/crates/rustscan">🔧 Cargo (Universal) </a></p> | <p align="center"><a href="https://crates.io/crates/rust_scan"> Arch </a></p> | <p align="center"><a href="https://crates.io/crates/rust_scan"> HomeBrew </a></p> | <p align="center"><a href="https://crates.io/crates/rust_scan"> Kali / Debian </p> |
|
||||
| <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/rust.png" /></p> | <p align="center"><img src="pictures/arch.png" /></p> | <p align="center"><img src="pictures/apple.png" /></p> | <p align="center"><img src="pictures/kali.png" /></p> |
|
||||
| `cargo install rustscan` | `yay -S rustscan-bin` | `brew tap brandonskerritt/rustscan && brew install rustscan` | [Read the install guide](https://github.com/brandonskerritt/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) |
|
||||
| <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 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>
|
||||
|
||||
# 🤔 What is this?
|
||||
1. Find ports quickly using Rustscan (**8 seconds at its fastest**).
|
||||
1. Find ports quickly using Rustscan (**3 seconds at its fastest**).
|
||||
2. Automatically runs `nmap` on those ports.
|
||||
3. ???
|
||||
4. Profit!
|
||||
@@ -41,7 +52,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<sub><b>Note</b> This is an older gif. RustScan's current top speed is 8 seconds for all 65k ports. This gif is 26 seconds.</sub><br>
|
||||
<sub><b>Note</b> This is an older gif. RustScan's current top speed is 3 seconds for all 65k ports. This gif is 26 seconds.</sub><br>
|
||||
|
||||
RustScans **only** job is to reduce the friction between finding open ports and inputting them into nmap.
|
||||
|
||||
@@ -50,6 +61,20 @@ RustScans **only** job is to reduce the friction between finding open ports and
|
||||
* Saves you time by automatically piping it into Nmap. No more manual copying and pasting!
|
||||
* Does one thing and does it well. **Only** purpose is to improve Nmap, not replace it!
|
||||
* Let's you choose what Nmap commands to run, or uses the default.
|
||||
* IPv6 Support
|
||||
|
||||
## ‼️ Important Links
|
||||
|
||||
| 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)
|
||||
|
||||
## 🙋 Table of Contents
|
||||
* 📖 [Installation Guide](https://github.com/RustScan/RustScan#-full-installation-guide)
|
||||
* 🐋 [Docker Usage](https://github.com/RustScan/RustScan#docker-whale)
|
||||
* 🦜 [Discord](https://discord.gg/GFrQsGy)
|
||||
* 🤸 [Usage](https://github.com/RustScan/RustScan#-usage)
|
||||
* 🎪 [Community](https://github.com/RustScan/RustScan#-community)
|
||||
|
||||
# 🔭 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?
|
||||
@@ -66,22 +91,6 @@ Why spend time running fast scans and manually copying the ports, or waiting for
|
||||
| Actually useful | ❌ | ✅ | ❌ |
|
||||
| Realises it's not useful, and pipes the only useful data into the only useful port scanner | ✅ | ❌ | ❌ |
|
||||
|
||||
|
||||
## 🙋 FAQ
|
||||
> I think this would be a great port scanner on its own without Nmap!
|
||||
|
||||
No. If you want a fast port scanner, use Masscan.
|
||||
> I have this great idea for a script to get information on ports / hosts
|
||||
|
||||
Great. Contribute it to Nmap! :D
|
||||
> Not everyone has nmap installed....
|
||||
|
||||
If you're a pentester, then yes, you have Nmap installed.
|
||||
|
||||
> I want to contribute!
|
||||
|
||||
Great! I'd love some help with this. Read the [contributing.md file](contributing.md) file for more information!
|
||||
|
||||
# 📖 Full Installation Guide
|
||||
**You need Nmap**. If you have Kali Linux or Parrot OS installed, you already have Nmap. If not, [follow the nmap install guide](https://nmap.org/download.html).
|
||||
|
||||
@@ -89,29 +98,85 @@ The easiest way to install RustScan is to use one of the packages provided for y
|
||||
|
||||
The most universal way is to use `cargo`, Rust's built in package manager (think Pip but for Rust). [Follow this guide to installing Rust & Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html).
|
||||
|
||||
If you face any issues at all, please leave a GitHub issue. I have only tested this on Linux, so there may be issues for Mac OS or Windows.
|
||||
If you face any issues at all, please leave a GitHub issue. I have only tested this on Linux, so there may be issues for Mac OS or Windows.
|
||||
|
||||
Note: sometimes Rust doesn't add Cargo to the path. Please see [this issue](https://github.com/rust-lang/rustup/issues/2436) for how to fix that.
|
||||
|
||||
## 🖥️ Debian / Kali
|
||||
|
||||
Download the .deb file from the releases page:
|
||||
|
||||
[https://github.com/brandonskerritt/RustScan/releases](https://github.com/brandonskerritt/RustScan/releases)
|
||||
Run the commpand `dpkg -i` on the file. Note: sometimes you can double click the file to achieve the same result.
|
||||
|
||||
### 🥧 .deb file not working?
|
||||
The .deb file only works on AMD64 CPUs. If yours is different (such as a Raspberry Pi) or the .deb file doesn't work, it is easy to build the .deb file yourself.
|
||||
**Note**: It is easier to install Rust and install via Cargo, then it is to build the .deb file. But this is just in case!
|
||||
Run the commpand `dpkg -i` on the file.
|
||||
|
||||
1. Install Rust You can do this with `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` which I took from the Rust website https://www.rust-lang.org/tools/install
|
||||
2. `cargo install rustscan` if you want the easiest method possible. Otherwise, to build the .deb file `cargo install cargo-deb`
|
||||
3. Git clone this repo `git clone https://github.com/brandonskerritt/RustScan`
|
||||
4. cd RustScan (into the git cloned repo) `cd RustScan`
|
||||
5. Run `cargo deb`
|
||||
6. Your .deb file is now located in `target/releases/Debian/`
|
||||
Note: sometimes you can double click the file to achieve the same result.
|
||||
|
||||
## Docker :whale:
|
||||
|
||||
Docker is the recommended way of installing RustScan. This is because:
|
||||
* It has a high open file descriptor limit, which is one of the [main problems](https://github.com/RustScan/RustScan/issues/40) with RustScan. Now you don't have to fiddle around trying to understand your OS.
|
||||
* It works on all systems, regardless of OS. Even Windows, which we don't officially support.
|
||||
* The Docker image uses the latest build from Cargo, our main source-of-truth package. This means that you will always be using the latest version.
|
||||
* No need to install Rust, Cargo, or Nmap.
|
||||
|
||||
To install Docker, [follow their guide](https://docs.docker.com/engine/install/).
|
||||
|
||||
**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 rustscan/rustscan:alpine <rustscan arguments here> <ip address to scan>
|
||||
```
|
||||
|
||||
Note: this will scan the Docker's localhost, not your own.
|
||||
|
||||
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 rustscan/rustscan:alpine <rustscan arguments here> <ip address to scan>'
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Tap the brew:
|
||||
|
||||
```
|
||||
@@ -132,6 +197,15 @@ brew install rustscan
|
||||
4. The binary is located at `target/release/rustscan`
|
||||
5. Symlink to the binary or something. Whatever you want!
|
||||
|
||||
## 🦊 Community Distributions
|
||||
Here are all of RustScan's community distributions.
|
||||
|
||||
If you maintain a community distribution and want it listed here, leave an issue / pull request / Discord message or however you want to let us know.
|
||||
|
||||
* [OpenSuse](https://software.opensuse.org/package/rustscan?search_term=rustscan)
|
||||
|
||||
[](https://repology.org/project/rustscan/versions)
|
||||
|
||||
# 🤸 Usage
|
||||
|
||||
```
|
||||
@@ -139,43 +213,47 @@ rustscan -h
|
||||
```
|
||||
|
||||
```
|
||||
RustScan 1.2.0
|
||||
Bee https://github.com/brandonskerritt
|
||||
Fast Port Scanner built in Rust
|
||||
WARNING Do not use this program against sensitive infrastructure. The specified server may not be able to handle this
|
||||
many socket connections at once.
|
||||
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] <ip> [command]...
|
||||
rustscan [FLAGS] [OPTIONS] <ips>... [-- <command>...]
|
||||
|
||||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
-q, --quiet Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
|
||||
-V, --version Prints version information
|
||||
-a, --accessible
|
||||
-h, --help Prints help information
|
||||
-q, --quiet Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file
|
||||
-V, --version Prints version information
|
||||
|
||||
OPTIONS:
|
||||
-T, --timeout <T> The timeout before a port is assumed to be close. In MS. [default: 1500]
|
||||
-b, --batch <b> Increases speed of scanning. The batch size for port scanning. Depends on your open file limit
|
||||
of OS. If you do 65535 it will do every port at the same time. Although, your OS may not
|
||||
support this. [default: 4500]
|
||||
-u, --ulimit <u> Automatically ups the ULIMIT with the value you provided.
|
||||
-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]
|
||||
--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]
|
||||
-t, --timeout <timeout> The timeout in milliseconds before a port is assumed to be closed [default: 1500]
|
||||
-u, --ulimit <ulimit> Automatically ups the ULIMIT with the value you provided
|
||||
|
||||
ARGS:
|
||||
<ip> The IP address to scan
|
||||
<command>... The Nmap arguments to run. To use the argument -A, end RustScan's args with '-- -A'. To run
|
||||
EXAMPLE: 'rustscan -T 1500 127.0.0.1 -- -A -sC'. This argument auto runs nmap {your commands}
|
||||
-vvv -p $PORTS
|
||||
<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)'\"")
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
The batch size determines how fast RustScan is. Set it to 65k, and it will scan all 65k ports at the same time. This means at at 65k batch size, RustScan will take TIMEOUT long to scan all ports. Essentially, if timeout is 1000ms, **RustScan can scan in 1 second**.
|
||||
The batch size determines how fast RustScan is. Set it to 65k, and it will scan all 65k ports at the same time. This means at at 65k batch size, RustScan will take TIMEOUT long to scan all ports. Essentially, if timeout is 1000ms, **RustScan can scan in 1 second**.
|
||||
|
||||
Your operating system may not support this, but it is worth it to play around and see where your open file limit is. Shortly I will be releasing a dockerised version with a much larger open file limit, so this will be possible.
|
||||
|
||||
## ⚠️ WARNING
|
||||
|
||||
This program, by default, scans 5000 ports at a time (5000 per second).
|
||||
This program, by default, scans 5000 ports at a time (5000 per second).
|
||||
|
||||
This may cause damage to a server, or may make it incredibly obvious you are scanning the server.
|
||||
|
||||
@@ -189,7 +267,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.
|
||||
@@ -198,7 +276,7 @@ This limit changes from OS to OS.
|
||||
|
||||
RustScan does not automatically create defaults (other than 5000) like Nmap does with their -T1, -T2 system.
|
||||
|
||||
By figuring out for yourself the optimal batch size, you will know that RustScan is the most optimised port scanner for your system.
|
||||
By figuring out for yourself the optimal batch size, you will know that RustScan is the most optimised port scanner for your system.
|
||||
|
||||
There are 2 things you can do:
|
||||
1. Decrease batch size
|
||||
@@ -227,16 +305,16 @@ ulimit -n 5000
|
||||
```
|
||||
|
||||
**Mac OS**
|
||||
Mac OS has, from what I can tell, a naturally very low open file descriptor limit. The limit for Ubuntu is 8800. The limit for Mac OS is 255!
|
||||
Mac OS has, from what I can tell, a naturally very low open file descriptor limit. The limit for Ubuntu is 8800. The limit for Mac OS is 255!
|
||||
|
||||
In this case, I would say it is safe to increase the open file limit. As most Linux based OS' have limits in the thousands.
|
||||
In this case, I would say it is safe to increase the open file limit. As most Linux based OS' have limits in the thousands.
|
||||
|
||||
Although, if this breaks anything, please don't blame me.
|
||||
Although, if this breaks anything, please don't blame me.
|
||||
|
||||
**Windows Subsystem for Linux**
|
||||
Windows Subsystem for Linux does not support ulimt (see issue #39).
|
||||
Windows Subsystem for Linux does not support ulimit (see issue #39).
|
||||
|
||||
The best way is to use it on a host computer, in Docker, or in a VM that isn't WSL.
|
||||
The best way is to use it on a host computer, in Docker, or in a VM that isn't WSL.
|
||||
|
||||
**Automatic Ulimit updating**
|
||||
We are currently working on automatic Ulimit updating. If it is too high, it will lower itself. If it is too low, it will suggest a higher Ulimit. Watch [this issue](https://github.com/brandonskerritt/RustScan/issues/25) for more.
|
||||
@@ -244,9 +322,9 @@ We are currently working on automatic Ulimit updating. If it is too high, it wil
|
||||
## 🔌 Nmap Custom Flags
|
||||
To run your own nmap commands, end the RustScan command with `-- -A` where `--` indicates "end of RustScan flags, please do not parse anything further" and any flags after that will be entered into nmap.
|
||||
|
||||
RustScan automatically runs `nmap -vvv -p $PORTS $IP`. To make it run `-A`, execute the command `rustscan 127.0.0.1 -- -A`.
|
||||
RustScan automatically runs `nmap -vvv -p $PORTS $IP`. To make it run `-A`, execute the command `rustscan 127.0.0.1 -- -A`.
|
||||
|
||||
**Note**: due to how Nmap behaves, sometimes you cannot SIGINT ctrl+c to end the scan and it acts like it is running in the background, but printing to STD::OUT. There is nothing I can do about this, unless I create a TTY shell for the sole purpose of running Nmap. Sorry 😓 I'll try to fix in an upcoming release. If any Rust experts want to help, please do!
|
||||
If you want to run commands such as `--script (vuln and safe)`, you will need to enclose it in quotations like so `--script '"(vuln and safe) or default"'`.
|
||||
|
||||
## 🎯 Increasing speed / accuracy
|
||||
* Batch size
|
||||
@@ -261,16 +339,48 @@ To increase accuracy, the easiest way is to increase the timeout. The default is
|
||||
|
||||
Decreasing accuracy gives some speed bonus, but my testing found that batch size dramatically changed the speed whereas timeout did, but not so much.
|
||||
|
||||
# 🎪 Contributing
|
||||
# 🎪 Community
|
||||
|
||||
Howdy Space Cow-Person 🤠🌌
|
||||
|
||||
RustScan is always looking for contributors. Whether that's spelling mistakes or major changes, your help is **wanted** and welcomed here.
|
||||
|
||||
Before contributing, read our [code of conduct](https://github.com/RustScan/RustScan/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
TL;DR if you abuse members of our community you will be **perma-banned** 🤗
|
||||
|
||||
RustScan has 2 major labels for GitHub issues you should look at:
|
||||
* Good First issue
|
||||
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!
|
||||
[https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+label%3A%22help+wanted%22](https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+label%3A%22help+wanted%22)
|
||||
|
||||
If you want to, solve the issue or comment on the issue for help.
|
||||
|
||||
The flow for contributing to open source software is:
|
||||
* Fork the repo
|
||||
* Make changes
|
||||
* Pull request to the repo
|
||||
|
||||
And then comment on the issue that you've done.
|
||||
|
||||
RustScan also has some `// TODO`'s in the codebase, which are meant more for the core team but we wouldn't say no to help with these issues.
|
||||
|
||||
If you have any feature suggestions or bugs, leave a GitHub issue. We welcome any and all support :D
|
||||
|
||||
We communicate over Discord. [Click here](https://discord.gg/GFrQsGy) to join our Discord community!
|
||||
|
||||
## Rewarding you
|
||||
I cannot pay you :-( But, I can place your GitHub profile on the README under `#Contributors` as a thank you! :)
|
||||
|
||||
|
||||
Please read the [contributing.md file](contributing.md)
|
||||
|
||||
# 💻 Other Hacking Projects By This Author
|
||||
## 🧮 Ciphey
|
||||
Ciphey is an automated decryption tool using artifical intelligence & natural language processing.
|
||||
[Check it out here!](https://github.com/ciphey/ciphey)
|
||||
## 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)):
|
||||
@@ -280,11 +390,19 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://skerritt.blog"><img src="https://avatars3.githubusercontent.com/u/10378052?v=4" width="100px;" alt=""/><br /><sub><b>Brandon</b></sub></a><br /><a href="#infra-brandonskerritt" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/brandonskerritt/RustScan/commits?author=brandonskerritt" title="Tests">⚠️</a> <a href="https://github.com/brandonskerritt/RustScan/commits?author=brandonskerritt" title="Code">💻</a> <a href="#design-brandonskerritt" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://sakiir.ovh"><img src="https://avatars1.githubusercontent.com/u/9950578?v=4" width="100px;" alt=""/><br /><sub><b>SakiiR</b></sub></a><br /><a href="https://github.com/brandonskerritt/RustScan/commits?author=SakiiR" title="Code">💻</a> <a href="https://github.com/brandonskerritt/RustScan/issues?q=author%3ASakiiR" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://skerritt.blog"><img src="https://avatars3.githubusercontent.com/u/10378052?v=4" width="100px;" alt=""/><br /><sub><b>Brandon</b></sub></a><br /><a href="#infra-brandonskerritt" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/RustScan/RustScan/commits?author=brandonskerritt" title="Tests">⚠️</a> <a href="https://github.com/RustScan/RustScan/commits?author=brandonskerritt" title="Code">💻</a> <a href="#design-brandonskerritt" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://sakiir.ovh"><img src="https://avatars1.githubusercontent.com/u/9950578?v=4" width="100px;" alt=""/><br /><sub><b>SakiiR</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=SakiiR" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/issues?q=author%3ASakiiR" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://github.com/smackhack"><img src="https://avatars2.githubusercontent.com/u/48143394?v=4" width="100px;" alt=""/><br /><sub><b>smackhack</b></sub></a><br /><a href="#ideas-smackhack" title="Ideas, Planning, & Feedback">🤔</a> <a href="#example-smackhack" title="Examples">💡</a></td>
|
||||
<td align="center"><a href="http://bernardoamc.github.io/"><img src="https://avatars0.githubusercontent.com/u/428984?v=4" width="100px;" alt=""/><br /><sub><b>Bernardo Araujo</b></sub></a><br /><a href="https://github.com/brandonskerritt/RustScan/commits?author=bernardoamc" title="Code">💻</a> <a href="https://github.com/brandonskerritt/RustScan/issues?q=author%3Abernardoamc" title="Bug reports">🐛</a> <a href="#design-bernardoamc" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/Isona"><img src="https://avatars2.githubusercontent.com/u/11759523?v=4" width="100px;" alt=""/><br /><sub><b>Izzy Whistlecroft</b></sub></a><br /><a href="https://github.com/brandonskerritt/RustScan/issues?q=author%3AIsona" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="http://bernardoamc.github.io/"><img src="https://avatars0.githubusercontent.com/u/428984?v=4" width="100px;" alt=""/><br /><sub><b>Bernardo Araujo</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=bernardoamc" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/issues?q=author%3Abernardoamc" title="Bug reports">🐛</a> <a href="#design-bernardoamc" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/Isona"><img src="https://avatars2.githubusercontent.com/u/11759523?v=4" width="100px;" alt=""/><br /><sub><b>Izzy Whistlecroft</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/issues?q=author%3AIsona" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://imlonghao.com"><img src="https://avatars1.githubusercontent.com/u/4951333?v=4" width="100px;" alt=""/><br /><sub><b>imlonghao</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/issues?q=author%3Aimlonghao" title="Bug reports">🐛</a> <a href="#maintenance-imlonghao" title="Maintenance">🚧</a></td>
|
||||
<td align="center"><a href="https://github.com/royharoush"><img src="https://avatars3.githubusercontent.com/u/8113056?v=4" width="100px;" alt=""/><br /><sub><b>royharoush</b></sub></a><br /><a href="#ideas-royharoush" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-royharoush" title="Design">🎨</a></td>
|
||||
</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>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
+29
-4
@@ -1,6 +1,31 @@
|
||||
This is my first Rust project! As such, I expect there are many, many bugs involved or things that can be sped up.
|
||||
Howdy Space Cow-Person 🤠🌌
|
||||
|
||||
If you're looking to get involved, we make use of Good First Issues / Help Wanted tags. Click this link to see all the issues we could use help with!
|
||||
[https://github.com/brandonskerritt/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22](https://github.com/brandonskerritt/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
RustScan is always looking for contributors. Whether that's spelling mistakes or major changes, your help is **wanted** and welcomed here.
|
||||
|
||||
Please leave issues / pull requests, I'd love to learn more about this amazing language :)
|
||||
Before contributing, read our [code of conduct](https://github.com/RustScan/RustScan/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
TL;DR if you abuse members of our community you will be **perma-banned** with no chance to get unbanned. No warnings either. 🤗
|
||||
|
||||
RustScan has 2 major labels for GitHub issues you should look at:
|
||||
* Good First issue
|
||||
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!
|
||||
[https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+label%3A%22help+wanted%22](https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+label%3A%22help+wanted%22)
|
||||
|
||||
If you want to, solve the issue or comment on the issue for help.
|
||||
|
||||
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
|
||||
|
||||
And then comment on the issue that you've done.
|
||||
|
||||
RustScan also has some `// TODO`'s in the codebase, which are meant more for the core team but we wouldn't say no to help with these issues.
|
||||
|
||||
If you have any feature suggestions or bugs, leave a GitHub issue. We welcome any and all support :D
|
||||
|
||||
## Rewarding you
|
||||
I cannot pay you :-( But, I can place your GitHub profile on the README under `#Contributors` as a thank you! :)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
+444
-188
@@ -1,207 +1,463 @@
|
||||
extern crate shell_words;
|
||||
|
||||
mod tui;
|
||||
|
||||
mod scanner;
|
||||
use scanner::Scanner;
|
||||
|
||||
use clap::{App, Arg, AppSettings};
|
||||
use colored::*;
|
||||
use std::time::Duration;
|
||||
use std::process::{exit, Command};
|
||||
use std::convert::TryInto;
|
||||
mod port_strategy;
|
||||
use port_strategy::PortStrategy;
|
||||
|
||||
use colorful::Color;
|
||||
use colorful::Colorful;
|
||||
use futures::executor::block_on;
|
||||
use rlimit::Resource;
|
||||
use rlimit::{setrlimit, getrlimit};
|
||||
use rlimit::{getrlimit, setrlimit};
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::{net::IpAddr, net::ToSocketAddrs, time::Duration};
|
||||
use structopt::{clap::arg_enum, StructOpt};
|
||||
|
||||
extern crate colorful;
|
||||
extern crate dirs;
|
||||
|
||||
const LOWEST_PORT_NUMBER: u16 = 1;
|
||||
const TOP_PORT_NUMBER: u16 = 65535;
|
||||
// Average value for Ubuntu
|
||||
const DEFAULT_FILE_DESCRIPTORS_LIMIT: rlimit::rlim = 8000;
|
||||
// Safest batch size based on experimentation
|
||||
const AVERAGE_BATCH_SIZE: rlimit::rlim = 3000;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
arg_enum! {
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum ScanOrder {
|
||||
Serial,
|
||||
Random,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "rustscan", setting = structopt::clap::AppSettings::TrailingVarArg)]
|
||||
/// 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
|
||||
struct Opts {
|
||||
/// A list of comma separated IP addresses or hosts to be scanned.
|
||||
#[structopt(use_delimiter = true, required = true)]
|
||||
ips_or_hosts: Vec<String>,
|
||||
|
||||
///Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
|
||||
#[structopt(short, long)]
|
||||
quiet: bool,
|
||||
|
||||
//Accessible mode. Turns off features which negatively affect screen readers.
|
||||
#[structopt(short, long)]
|
||||
accessible: bool,
|
||||
|
||||
/// 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.
|
||||
#[structopt(short, long, default_value = "4500")]
|
||||
batch_size: u16,
|
||||
|
||||
/// The timeout in milliseconds before a port is assumed to be closed.
|
||||
#[structopt(short, long, default_value = "1500")]
|
||||
timeout: u32,
|
||||
|
||||
/// Automatically ups the ULIMIT with the value you provided.
|
||||
#[structopt(short, long)]
|
||||
ulimit: Option<rlimit::rlim>,
|
||||
|
||||
/// The order of scanning to be performed. The "serial" option will
|
||||
/// scan ports in ascending order while the "random" option will scan
|
||||
/// ports randomly.
|
||||
#[structopt(long, possible_values = &ScanOrder::variants(), case_insensitive = true, default_value = "serial")]
|
||||
scan_order: ScanOrder,
|
||||
|
||||
/// 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)'\"")
|
||||
#[structopt(last = true)]
|
||||
command: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
/// Faster Nmap scanning with Rust
|
||||
/// If you're looking for the actual scanning, check out the module Scanner
|
||||
fn main() {
|
||||
let matches = App::new("RustScan")
|
||||
.author("Bee https://github.com/brandonskerritt")
|
||||
.about("Fast Port Scanner built in Rust\nWARNING Do not use this program against sensitive infrastructure. The specified server may not be able to handle this many socket connections at once.")
|
||||
.version("1.2.0")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
env_logger::init();
|
||||
|
||||
// IP address is a required argument
|
||||
.arg(Arg::with_name("ip")
|
||||
.required(true)
|
||||
.index(1)
|
||||
.long("ip-address")
|
||||
.help("The IP address to scan"))
|
||||
.arg(Arg::with_name("b")
|
||||
.short("b")
|
||||
.long("batch")
|
||||
.takes_value(true)
|
||||
.default_value("4500")
|
||||
.help("Increases speed of scanning. The batch size for port scanning. Depends on your open file limit of OS. If you do 65535 it will do every port at the same time. Although, your OS may not support this."))
|
||||
.arg(Arg::with_name("T")
|
||||
.short("T")
|
||||
.long("timeout")
|
||||
.takes_value(true)
|
||||
.default_value("1500")
|
||||
.help("The timeout before a port is assumed to be close. In MS."))
|
||||
.arg(Arg::with_name("q")
|
||||
.short("-q")
|
||||
.long("quiet")
|
||||
.takes_value(false)
|
||||
.help("Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file."))
|
||||
.arg(Arg::with_name("u")
|
||||
.short("u")
|
||||
.long("ulimit")
|
||||
.help("Automatically ups the ULIMIT with the value you provided.")
|
||||
.takes_value(true))
|
||||
.arg(
|
||||
Arg::with_name("command")
|
||||
.help("The Nmap arguments to run. To use the argument -A, end RustScan's args with '-- -A'. To run EXAMPLE: 'rustscan -T 1500 127.0.0.1 -- -A -sC'. This argument auto runs nmap {your commands} -vvv -p $PORTS ")
|
||||
.takes_value(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.get_matches();
|
||||
info!("Starting up");
|
||||
let opts = Opts::from_args();
|
||||
info!("Mains() `opts` arguments are {:?}", opts);
|
||||
|
||||
|
||||
let ip = matches.value_of("ip").unwrap_or("None");
|
||||
let ulimit_arg = matches.value_of("u").unwrap_or("None");
|
||||
let quiet = if matches.is_present("q") { true } else { false };
|
||||
let command_matches= matches.values_of("command");
|
||||
let command_run: String = match command_matches {
|
||||
// We use the user supplied args
|
||||
Some(_x) => {
|
||||
// TODO x is the same as below, use that instead
|
||||
matches.values_of("command").unwrap().collect::<Vec<_>>().join(" ")
|
||||
}
|
||||
// we default
|
||||
None => "-A -vvv".to_string()
|
||||
|
||||
};
|
||||
|
||||
let mut batch_size: u64 = matches
|
||||
.value_of("b")
|
||||
.unwrap_or("None")
|
||||
.parse::<u64>()
|
||||
.unwrap();
|
||||
|
||||
if !quiet {
|
||||
if !opts.quiet && !opts.accessible {
|
||||
print_opening();
|
||||
}
|
||||
|
||||
// checks ulimit
|
||||
let ips: Vec<IpAddr> = parse_ips(&opts);
|
||||
|
||||
// change ulimit size
|
||||
if !(ulimit_arg == "None") {
|
||||
let limit = ulimit_arg.parse::<u64>().unwrap();
|
||||
if !quiet{
|
||||
println!("Automatically upping ulimit to {}", ulimit_arg);
|
||||
}
|
||||
let uresult = setrlimit(Resource::NOFILE, limit, limit);
|
||||
|
||||
match uresult {
|
||||
Ok(_) => {}
|
||||
Err(_) => {println!("ERROR. Failed to set Ulimit.")}
|
||||
}
|
||||
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 (x, _) = getrlimit(Resource::NOFILE).unwrap();
|
||||
|
||||
// if maximum limit is lower than batch size
|
||||
// automatically re-adjust the batch size
|
||||
if x < batch_size.into() {
|
||||
if !quiet{
|
||||
println!("{}", "WARNING: Your file description limit is lower than selected batch size. Please considering upping this (how to is on the README). NOTE: this may be dangerous and may cause harm to sensitive servers. Automatically reducing Batch Size to match your limit, this process isn't harmful but reduces speed.".red());
|
||||
// TODO this is a joke please fix
|
||||
|
||||
// if the OS supports high file limits like 8000
|
||||
// but the user selected a batch size higher than this
|
||||
// reduce to a lower number
|
||||
// basically, ubuntu is 8000
|
||||
// but i can only get it to work on < 5k in testing
|
||||
// 5k is default, so 3000 seems safe
|
||||
if x > 8000{
|
||||
batch_size = 3000
|
||||
}
|
||||
else {
|
||||
let ten: u64 = 100;
|
||||
batch_size = x - ten;
|
||||
}
|
||||
}
|
||||
}
|
||||
// else if the ulimit is higher than batch size
|
||||
// tell the user they can increase batch size
|
||||
// if the user set ulimit arg they probably know what they are doing so don't print this
|
||||
else if x + 2 > batch_size.into() && (ulimit_arg == "None"){
|
||||
if !quiet{
|
||||
// TODO this is a joke please fix
|
||||
let one: u64 = 1;
|
||||
println!("Your file description limit is higher than the batch size. You can potentially increase the speed by increasing the batch size, but this may cause harm to sensitive servers. Your limit is {}, try batch size {}.", x, x - one);
|
||||
}
|
||||
}
|
||||
// the user has asked to automatically up the ulimit
|
||||
|
||||
// gets timeout
|
||||
let duration_timeout =
|
||||
matches
|
||||
.value_of("T")
|
||||
.unwrap_or("None")
|
||||
.parse::<u64>()
|
||||
.unwrap();
|
||||
|
||||
// 65535 + 1 because of 0 indexing
|
||||
let scanner = Scanner::new(ip, 1, 65536, batch_size.try_into().unwrap(), Duration::from_millis(duration_timeout), quiet);
|
||||
let scan_result = block_on(scanner.run());
|
||||
|
||||
// prints ports and places them into nmap string
|
||||
let nmap_str_ports: Vec<String> = scan_result.into_iter().map(|port| port.to_string()).collect();
|
||||
|
||||
// if no ports are found, suggest running with less
|
||||
if nmap_str_ports.is_empty() {
|
||||
panic!("{} Looks like I didn't find any open ports. This is usually caused by a high batch size.
|
||||
\n*I used {} threads, consider lowering to {} with {} or a comfortable number lfor your system.
|
||||
\n Alternatively, increase the timeout if your ping is high. Rustscan -T 2000 for 2000 second timeout.", "ERROR".red(), batch_size, (batch_size / 2).to_string().green(), "'rustscan -b <batch_size> <ip address>'".green());
|
||||
}
|
||||
|
||||
// Tells the user we are now switching to Nmap
|
||||
if !quiet{
|
||||
println!(
|
||||
"{}",
|
||||
"Starting nmap.".blue(),
|
||||
);
|
||||
}
|
||||
|
||||
// nmap port style is 80,443. Comma seperated with no spaces.
|
||||
let ports_str = nmap_str_ports.join(",");
|
||||
|
||||
// if quiet mode is on, return ports and exit
|
||||
if quiet{
|
||||
println!("{:?}", ports_str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let string_format = format!("{} {} {} {} {} {}", command_run, "-Pn", "-vvv", "-p", &ports_str, ip);
|
||||
if !quiet{
|
||||
println!("The Nmap command to be run is {}", string_format);
|
||||
}
|
||||
let command_list = string_format.split_whitespace();
|
||||
let vec = command_list.collect::<Vec<&str>>();
|
||||
|
||||
// Runs the nmap command and spawns it as a process.
|
||||
let mut child = Command::new("nmap")
|
||||
.args(&vec)
|
||||
.spawn()
|
||||
.expect("failed to execute nmap process");
|
||||
|
||||
child.wait().expect("failed to wait on nmap process");
|
||||
}
|
||||
|
||||
fn print_opening() {
|
||||
let s = "
|
||||
_____ _ _____
|
||||
| __ \\ | | / ____|
|
||||
| |__) | _ ___| |_| (___ ___ __ _ _ __
|
||||
| _ / | | / __| __|\\___ \\ / __/ _` | '_ \\
|
||||
| | \\ \\ |_| \\__ \\ |_ ____) | (_| (_| | | | |
|
||||
|_| \\_\\__,_|___/\\__|_____/ \\___\\__,_|_| |_|
|
||||
Faster nmap scanning with rust.";
|
||||
println!(
|
||||
"{} \n {} \n {}",
|
||||
s.green(),
|
||||
"Automated Decryption Tool - https://github.com/ciphey/ciphey".green(),
|
||||
"Creator https://github.com/brandonskerritt".green()
|
||||
let scanner = Scanner::new(
|
||||
&ips,
|
||||
batch_size,
|
||||
Duration::from_millis(opts.timeout.into()),
|
||||
opts.quiet,
|
||||
PortStrategy::pick(LOWEST_PORT_NUMBER, TOP_PORT_NUMBER, opts.scan_order),
|
||||
);
|
||||
|
||||
let scan_result = block_on(scanner.run());
|
||||
let mut ports_per_ip = HashMap::new();
|
||||
|
||||
for socket in scan_result {
|
||||
ports_per_ip
|
||||
.entry(socket.ip())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(socket.port());
|
||||
}
|
||||
|
||||
for ip in ips {
|
||||
if ports_per_ip.contains_key(&ip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we got here it means the IP was not found within the HashMap, this
|
||||
// means the scan couldn't find any open ports for it.
|
||||
|
||||
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",
|
||||
"ERROR",
|
||||
ip,
|
||||
opts.batch_size,
|
||||
(opts.batch_size / 2).to_string(),
|
||||
"'rustscan -b <batch_size> <ip address>'");
|
||||
warning!(x, opts.quiet);
|
||||
}
|
||||
|
||||
for (ip, ports) in ports_per_ip.iter_mut() {
|
||||
let nmap_str_ports: Vec<String> = ports.into_iter().map(|port| port.to_string()).collect();
|
||||
|
||||
detail!("Starting Nmap", opts.quiet);
|
||||
|
||||
// nmap port style is 80,443. Comma separated with no spaces.
|
||||
let ports_str = nmap_str_ports.join(",");
|
||||
|
||||
// if quiet mode is on nmap should not be spawned
|
||||
if opts.quiet {
|
||||
println!("{}", ports_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
let addr = ip.to_string();
|
||||
let user_nmap_args =
|
||||
shell_words::split(&opts.command.join(" ")).expect("failed to parse nmap arguments");
|
||||
let nmap_args = build_nmap_arguments(&addr, &ports_str, &user_nmap_args, ip.is_ipv6());
|
||||
|
||||
output!(format!(
|
||||
"The Nmap command to be run is nmap {}\n",
|
||||
&nmap_args.join(" ")
|
||||
));
|
||||
|
||||
// Runs the nmap command and spawns it as a process.
|
||||
let mut child = Command::new("nmap")
|
||||
.args(&nmap_args)
|
||||
.spawn()
|
||||
.expect("failed to execute nmap process");
|
||||
|
||||
child.wait().expect("failed to wait on nmap process");
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the opening title of RustScan
|
||||
fn print_opening() {
|
||||
info!("Printing opening");
|
||||
let s = r#".----. .-. .-. .----..---. .----. .---. .--. .-. .-.
|
||||
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
|
||||
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
|
||||
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
|
||||
Faster Nmap scanning with Rust."#;
|
||||
println!("{}", s.gradient(Color::Green).bold());
|
||||
let info = r#"________________________________________
|
||||
: https://discord.gg/GFrQsGy :
|
||||
: https://github.com/RustScan/RustScan :
|
||||
--------------------------------------"#;
|
||||
println!("{}", info.gradient(Color::Yellow).bold());
|
||||
funny_opening!();
|
||||
|
||||
let config_path = match dirs::config_dir() {
|
||||
Some(mut path) => {
|
||||
path.push("rustscan");
|
||||
path.push("config.toml");
|
||||
path
|
||||
}
|
||||
None => panic!("Couldn't find config dir."),
|
||||
};
|
||||
|
||||
detail!(format!(
|
||||
"{} {:?}",
|
||||
"The config file is expected to be at", config_path
|
||||
));
|
||||
}
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn build_nmap_arguments<'a>(
|
||||
addr: &'a str,
|
||||
ports: &'a str,
|
||||
user_args: &'a Vec<String>,
|
||||
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 {
|
||||
arguments.push("-6");
|
||||
}
|
||||
|
||||
arguments.push("-p");
|
||||
arguments.push(ports);
|
||||
arguments.push(addr);
|
||||
|
||||
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();
|
||||
|
||||
match setrlimit(Resource::NOFILE, limit, limit) {
|
||||
Ok(_) => {
|
||||
detail!(
|
||||
format!("Automatically increasing ulimit value to {}.", limit),
|
||||
opts.quiet
|
||||
);
|
||||
}
|
||||
Err(_) => println!("{}", "ERROR. Failed to set ulimit value."),
|
||||
}
|
||||
}
|
||||
|
||||
let (rlim, _) = getrlimit(Resource::NOFILE).unwrap();
|
||||
|
||||
rlim
|
||||
}
|
||||
|
||||
fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
|
||||
let mut batch_size: rlimit::rlim = opts.batch_size.into();
|
||||
|
||||
// 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",
|
||||
opts.quiet
|
||||
);
|
||||
|
||||
// When the OS supports high file limits like 8000, but the user
|
||||
// selected a batch size higher than this we should reduce it to
|
||||
// a lower number.
|
||||
if ulimit < AVERAGE_BATCH_SIZE {
|
||||
// ulimit is smaller than aveage batch size
|
||||
// user must have very small ulimit
|
||||
// decrease batch size to half of ulimit
|
||||
warning!("Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'. ");
|
||||
info!("Halving batch_size because ulimit is smaller than average batch size");
|
||||
batch_size = ulimit / 2
|
||||
} else if ulimit > DEFAULT_FILE_DESCRIPTORS_LIMIT {
|
||||
info!("Batch size is now average batch size");
|
||||
batch_size = AVERAGE_BATCH_SIZE
|
||||
} else {
|
||||
batch_size = ulimit - 100
|
||||
}
|
||||
}
|
||||
// When the ulimit is higher than the batch size let the user know that the
|
||||
// batch size can be increased unless they specified the ulimit themselves.
|
||||
else if ulimit + 2 > batch_size && (opts.ulimit.is_none()) {
|
||||
detail!(format!(
|
||||
"File limit higher than batch size. Can increase speed by increasing batch size '-b {}'.",
|
||||
ulimit - 100
|
||||
), opts.quiet);
|
||||
}
|
||||
|
||||
batch_size as u16
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{adjust_ulimit_size, infer_batch_size, parse_ips, print_opening, Opts, ScanOrder};
|
||||
|
||||
#[test]
|
||||
fn batch_size_lowered() {
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 120);
|
||||
|
||||
assert!(batch_size < 50_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_size_lowered_average_size() {
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 9_000);
|
||||
|
||||
assert!(batch_size == 3_000);
|
||||
}
|
||||
#[test]
|
||||
fn batch_size_equals_ulimit_lowered() {
|
||||
// because ulimit and batch size are same size, batch size is lowered
|
||||
// to ULIMIT - 100
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 5_000);
|
||||
|
||||
assert!(batch_size == 4_900);
|
||||
}
|
||||
#[test]
|
||||
fn batch_size_adjusted_2000() {
|
||||
// ulimit == batch_size
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
accessible: false,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
let batch_size = adjust_ulimit_size(&opts);
|
||||
|
||||
assert!(batch_size == 2_000);
|
||||
}
|
||||
#[test]
|
||||
fn test_print_opening_no_panic() {
|
||||
// print opening should not panic
|
||||
print_opening();
|
||||
assert!(1 == 1);
|
||||
}
|
||||
#[test]
|
||||
fn test_high_ulimit_no_quiet_mode() {
|
||||
let opts = Opts {
|
||||
ips_or_hosts: vec!["127.0.0.1".to_owned()],
|
||||
quiet: false,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: None,
|
||||
command: Vec::new(),
|
||||
accessible: true,
|
||||
scan_order: ScanOrder::Serial,
|
||||
};
|
||||
|
||||
infer_batch_size(&opts, 1_000_000);
|
||||
|
||||
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()],
|
||||
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()],
|
||||
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()],
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
mod range_iterator;
|
||||
use super::ScanOrder;
|
||||
use range_iterator::RangeIterator;
|
||||
|
||||
/// Represents options of port scanning.
|
||||
///
|
||||
/// Right now all these options involve ranges, but in the future
|
||||
/// it will also contain custom lists of ports.
|
||||
pub enum PortStrategy {
|
||||
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 order(&self) -> Vec<u16> {
|
||||
match self {
|
||||
PortStrategy::Serial(range) => range.generate(),
|
||||
PortStrategy::Random(range) => range.generate(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait associated with a port strategy. Each PortStrategy must be able
|
||||
/// to generate an order for future port scanning.
|
||||
trait RangeOrder {
|
||||
fn generate(&self) -> Vec<u16>;
|
||||
}
|
||||
|
||||
/// As the name implies SerialRange will always generate a vector in
|
||||
/// ascending order.
|
||||
pub struct SerialRange {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
impl RangeOrder for SerialRange {
|
||||
fn generate(&self) -> Vec<u16> {
|
||||
(self.start..self.end).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// As the name implies RandomRange will always generate a vector with
|
||||
/// a random order. This vector is built following the LCG algorithm.
|
||||
pub struct RandomRange {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
impl RangeOrder for RandomRange {
|
||||
// Right now using RangeIterator and generating a range + shuffling the
|
||||
// vector is pretty much the same. The advantages of it will come once
|
||||
// we have to generate different ranges for different IPs without storing
|
||||
// actual vectors.
|
||||
//
|
||||
// Another benefit of RangeIterator is that it always generate a range with
|
||||
// a certain distance between the items in the Array. The chances of having
|
||||
// port numbers close to each other are pretty slim due to the way the
|
||||
// algorithm works.
|
||||
fn generate(&self) -> Vec<u16> {
|
||||
RangeIterator::new(self.start.into(), self.end.into()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PortStrategy;
|
||||
use crate::ScanOrder;
|
||||
|
||||
#[test]
|
||||
fn serial_strategy() {
|
||||
let strategy = PortStrategy::pick(1, 100, 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);
|
||||
let mut result = strategy.order();
|
||||
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
|
||||
assert_ne!(expected_range, result);
|
||||
|
||||
result.sort();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
use gcd::Gcd;
|
||||
use rand::Rng;
|
||||
|
||||
pub struct RangeIterator {
|
||||
active: bool,
|
||||
normalized_end: u32,
|
||||
normalized_first_pick: u32,
|
||||
normalized_pick: u32,
|
||||
actual_start: u32,
|
||||
step: u32,
|
||||
}
|
||||
|
||||
/// An iterator that follows the `Linear Congruential Generator` algorithm.
|
||||
///
|
||||
/// For more information: https://en.wikipedia.org/wiki/Linear_congruential_generator
|
||||
impl RangeIterator {
|
||||
/// Receives the the start and end of a range and normalize
|
||||
/// these values before selecting a coprime for the end of the range
|
||||
/// which will server as the step for the algorithm.
|
||||
///
|
||||
/// For example, the range `1000-2500` will be normalized to `0-1500`
|
||||
/// before going through the algorithm.
|
||||
pub fn new(start: u32, end: u32) -> Self {
|
||||
let normalized_end = end - start;
|
||||
let step = pick_random_coprime(normalized_end);
|
||||
|
||||
// Randomly choose a number within the range to be the first
|
||||
// and assign it as a pick.
|
||||
let mut rng = rand::thread_rng();
|
||||
let normalized_first_pick = rng.gen_range(0, normalized_end);
|
||||
|
||||
Self {
|
||||
active: true,
|
||||
normalized_end,
|
||||
step,
|
||||
normalized_first_pick,
|
||||
normalized_pick: normalized_first_pick,
|
||||
actual_start: start,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for RangeIterator {
|
||||
type Item = u16;
|
||||
|
||||
// The next step is always bound by the formula: N+1 = (N + STEP) % TOP_OF_THE_RANGE
|
||||
// It will only stop once we generate a number equal to the first generated number.
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if !self.active {
|
||||
return None;
|
||||
}
|
||||
|
||||
let current_pick = self.normalized_pick;
|
||||
let next_pick = (current_pick + self.step) % self.normalized_end;
|
||||
|
||||
// If the next pick is equal to the first pick this means that
|
||||
// we have iterated through the entire range.
|
||||
if next_pick == self.normalized_first_pick {
|
||||
self.active = false;
|
||||
}
|
||||
|
||||
self.normalized_pick = next_pick;
|
||||
Some((self.actual_start + current_pick) as u16)
|
||||
}
|
||||
}
|
||||
|
||||
/// The probability that two random integers are coprime to one another
|
||||
/// works out to be around 61%, given that we can safely pick a random
|
||||
/// number and test it. Just in case we are having a bad day and we cannot
|
||||
/// pick a coprime number after 10 tries we just return "end - 1" which
|
||||
/// is guaranteed to be a coprime, but won't provide ideal randomization.
|
||||
///
|
||||
/// We pick between "lower_range" and "upper_range" since values too close to
|
||||
/// the boundaries, which in these case are the "start" and "end" arguments
|
||||
/// would also provide non-ideal randomization as discussed on the paragraph
|
||||
/// above.
|
||||
fn pick_random_coprime(end: u32) -> u32 {
|
||||
let range_boundary = end / 4;
|
||||
let lower_range = range_boundary;
|
||||
let upper_range = end - range_boundary;
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut candidate = rng.gen_range(lower_range, upper_range);
|
||||
|
||||
for _ in 0..10 {
|
||||
if end.gcd(candidate) == 1 {
|
||||
return candidate;
|
||||
} else {
|
||||
candidate = rng.gen_range(lower_range, upper_range);
|
||||
}
|
||||
}
|
||||
|
||||
end - 1
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::RangeIterator;
|
||||
|
||||
#[test]
|
||||
fn range_iterator_iterates_through_the_entire_range() {
|
||||
let result = generate_sorted_range(1, 10);
|
||||
let expected_range = (1..10).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1, 100);
|
||||
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1, 1000);
|
||||
let expected_range = (1..1000).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1, 65_535);
|
||||
let expected_range = (1..65_535).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1000, 2000);
|
||||
let expected_range = (1000..2000).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
|
||||
fn generate_sorted_range(start: u32, end: u32) -> Vec<u16> {
|
||||
let range = RangeIterator::new(start, end);
|
||||
let mut result = range.into_iter().collect::<Vec<u16>>();
|
||||
result.sort();
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
use async_std::io;
|
||||
use async_std::net::TcpStream;
|
||||
use colored::*;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
net::{SocketAddr, Shutdown},
|
||||
io::ErrorKind,
|
||||
};
|
||||
use async_std::prelude::*;
|
||||
use futures::stream::FuturesUnordered;
|
||||
|
||||
pub struct Scanner {
|
||||
host: String,
|
||||
start: u64,
|
||||
end: u64,
|
||||
batch_size: u64,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(host: &str, start: u64, end: u64, batch_size: u64, timeout: Duration, quiet: bool) -> Self {
|
||||
Self {
|
||||
host: host.to_owned(),
|
||||
start,
|
||||
end,
|
||||
batch_size,
|
||||
timeout,
|
||||
quiet
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(&self) -> Vec<u64> {
|
||||
let ports: Vec<u64> = (self.start..self.end).collect();
|
||||
let mut open_ports: std::vec::Vec<u64> = Vec::new();
|
||||
|
||||
for range in ports.chunks(self.batch_size as usize) {
|
||||
let mut ports = self.scan_range(range).await;
|
||||
open_ports.append(&mut ports);
|
||||
}
|
||||
|
||||
open_ports
|
||||
}
|
||||
|
||||
async fn scan_range(&self, range: &[u64]) -> Vec<u64> {
|
||||
let mut ftrs = FuturesUnordered::new();
|
||||
|
||||
for port in range {
|
||||
ftrs.push(self.scan_port(port));
|
||||
}
|
||||
|
||||
let mut open_ports: Vec<u64> = Vec::new();
|
||||
while let Some(result) = ftrs.next().await {
|
||||
match result {
|
||||
Ok(port) => open_ports.push(port),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
open_ports
|
||||
}
|
||||
|
||||
async fn scan_port(&self, port: &u64) -> io::Result<u64> {
|
||||
let addr = format!("{}:{}", self.host , port);
|
||||
|
||||
match addr.parse() {
|
||||
Ok(sock_addr) => match self.connect(sock_addr).await {
|
||||
Ok(stream_result) => {
|
||||
match stream_result.shutdown(Shutdown::Both) {
|
||||
_ => {}
|
||||
}
|
||||
if !self.quiet {
|
||||
println!("Open {}", port.to_string().purple());
|
||||
}
|
||||
|
||||
Ok(*port)
|
||||
}
|
||||
Err(e) => match e.kind() {
|
||||
ErrorKind::Other => {
|
||||
eprintln!("{:?}", e); // in case we get too many open files
|
||||
panic!("Too many open files. Please reduce batch size. The default is 5000. Try -b 2500.");
|
||||
}
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, e.to_string())),
|
||||
},
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Unable to convert to socket address {:?}", e);
|
||||
panic!("Unable to convert to socket address");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn connect(&self, addr: SocketAddr) -> io::Result<TcpStream> {
|
||||
let stream = io::timeout(self.timeout, async move { TcpStream::connect(addr).await }).await?;
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
use super::PortStrategy;
|
||||
|
||||
use async_std::io;
|
||||
use async_std::net::TcpStream;
|
||||
use async_std::prelude::*;
|
||||
use colored::*;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
io::ErrorKind,
|
||||
net::{IpAddr, Shutdown, SocketAddr},
|
||||
};
|
||||
|
||||
/// The class for the scanner
|
||||
/// 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 {
|
||||
ips: Vec<IpAddr>,
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
port_strategy: PortStrategy,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(
|
||||
ips: &[IpAddr],
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
port_strategy: PortStrategy,
|
||||
) -> Self {
|
||||
Self {
|
||||
batch_size,
|
||||
timeout,
|
||||
quiet,
|
||||
port_strategy,
|
||||
ips: ips.iter().map(|ip| ip.to_owned()).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs scan_range with chunk sizes
|
||||
/// If you want to run RustScan normally, this is the entry point used
|
||||
/// 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_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_ip) {
|
||||
let mut sockets = self.scan_ports(batch).await;
|
||||
open_sockets.append(&mut sockets);
|
||||
}
|
||||
|
||||
open_sockets
|
||||
}
|
||||
|
||||
/// Given a slice of sockets, scan them all.
|
||||
/// Returns a vector of open sockets.
|
||||
async fn scan_ports(&self, ports: &[u16]) -> Vec<SocketAddr> {
|
||||
let mut ftrs = FuturesUnordered::new();
|
||||
for port in ports {
|
||||
for ip in &self.ips {
|
||||
ftrs.push(self.scan_socket(SocketAddr::new(*ip, *port)));
|
||||
}
|
||||
}
|
||||
|
||||
let mut open_sockets: Vec<SocketAddr> = Vec::new();
|
||||
while let Some(result) = ftrs.next().await {
|
||||
match result {
|
||||
Ok(socket) => open_sockets.push(socket),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
open_sockets
|
||||
}
|
||||
|
||||
/// Given a port, scan it.
|
||||
/// Turns the address into a SocketAddr
|
||||
/// Deals with the <result> type
|
||||
/// If it experiences error ErrorKind::Other then too many files are open and it Panics!
|
||||
/// ese any other error, it returns the error in Result as a string
|
||||
/// If no errors occur, it returns the port number in Result to signify the port is open.
|
||||
/// This function mainly deals with the logic of Results handling.
|
||||
/// # Example
|
||||
///
|
||||
/// self.scan_port(10:u16)
|
||||
///
|
||||
/// Note: `self` must contain `self.ip`.
|
||||
async fn scan_socket(&self, socket: SocketAddr) -> io::Result<SocketAddr> {
|
||||
match self.connect(socket).await {
|
||||
Ok(x) => {
|
||||
// match stream_result.shutdown(Shutdown::Both)
|
||||
info!("Shutting down stream");
|
||||
match x.shutdown(Shutdown::Both) {
|
||||
_ => {}
|
||||
}
|
||||
if !self.quiet {
|
||||
println!("Open {}", socket.to_string().purple());
|
||||
}
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
Err(e) => match e.kind() {
|
||||
ErrorKind::Other => {
|
||||
panic!("Too many open files. Please reduce batch size. The default is 5000. Try -b 2500.");
|
||||
}
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, e.to_string())),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs the connection to the socket with timeout
|
||||
/// # Example
|
||||
///
|
||||
/// let port: u16 = 80
|
||||
/// // 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
|
||||
///
|
||||
async fn connect(&self, socket: SocketAddr) -> io::Result<TcpStream> {
|
||||
let stream = io::timeout(
|
||||
self.timeout,
|
||||
async move { TcpStream::connect(socket).await },
|
||||
)
|
||||
.await?;
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ScanOrder;
|
||||
use async_std::task::block_on;
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
|
||||
#[test]
|
||||
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 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!
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
#[test]
|
||||
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 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!
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
#[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 scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
#[test]
|
||||
fn google_dns_runs() {
|
||||
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
|
||||
let strategy = PortStrategy::pick(400, 445, ScanOrder::Random);
|
||||
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
#[test]
|
||||
fn infer_ulimit_lowering_no_panic() {
|
||||
// Test behaviour on MacOS where ulimit is not automatically lowered
|
||||
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 scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/// Terminal User Interface Module for RustScan
|
||||
/// Defines macros to use
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warning {
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::Red;
|
||||
println!("{} {}", Red.bold().paint("[!]"), $name);
|
||||
};
|
||||
// quiet mode
|
||||
($name:expr, $quiet:expr) => {
|
||||
use ansi_term::Colour::Red;
|
||||
if !$quiet {
|
||||
println!("{} {}", Red.bold().paint("[!]"), $name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! detail {
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::Blue;
|
||||
println!("{} {}", Blue.bold().paint("[~]"), $name);
|
||||
};
|
||||
($name:expr, $quiet:expr) => {
|
||||
use ansi_term::Colour::Blue;
|
||||
if !$quiet {
|
||||
println!("{} {}", Blue.bold().paint("[~]"), $name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! output {
|
||||
($name:expr, $quiet:expr) => {
|
||||
use ansi_term::Colour::RGB;
|
||||
if !$quiet {
|
||||
println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
}
|
||||
};
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::RGB;
|
||||
println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! funny_opening {
|
||||
// prints a funny quote / opening
|
||||
() => {
|
||||
use rand::seq::SliceRandom;
|
||||
let quotes = vec![
|
||||
"Nmap? More like slowmap.🐢",
|
||||
"🌍HACK THE PLANET🌍",
|
||||
"Real hackers hack time ⌛",
|
||||
"Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan",
|
||||
"😵 https://admin.tryhackme.com",
|
||||
];
|
||||
let random_quote = quotes.choose(&mut rand::thread_rng()).unwrap();
|
||||
|
||||
println!("{}\n", random_quote);
|
||||
// println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user