mirror of
https://github.com/bee-san/RustScan.git
synced 2026-11-07 09:46:04 -10:00
Compare commits
145
Commits
ipv6-support
...
1.7.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
751c4daff6 | ||
|
|
f6214cfb27 | ||
|
|
a92eb80365 | ||
|
|
aeab4fb68c | ||
|
|
9ab15c9d8b | ||
|
|
7146c23ed9 | ||
|
|
f37f2d8f9d | ||
|
|
5a3a4d1c0c | ||
|
|
33e7cd44b6 | ||
|
|
8288856949 | ||
|
|
c3b96e262d | ||
|
|
a54868000e | ||
|
|
8f4acdf99a | ||
|
|
c637042906 | ||
|
|
766164588c | ||
|
|
b2be83c04a | ||
|
|
a3654b68eb | ||
|
|
1873a92951 | ||
|
|
c7a422b962 | ||
|
|
0eec9233bd | ||
|
|
0f18bb49a3 | ||
|
|
e546608ff8 | ||
|
|
a7d1952b72 | ||
|
|
67726cc490 | ||
|
|
d5d39cacd3 | ||
|
|
52cbbeeac6 | ||
|
|
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 | ||
|
|
ef893fdcb8 | ||
|
|
7ad7e34abc | ||
|
|
e41393b4ad | ||
|
|
4785b75f9f |
No files matched your search
+17
-1
@@ -66,11 +66,27 @@
|
||||
"bug",
|
||||
"maintenance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Atul9",
|
||||
"name": "Atul Bhosale",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/3390330?v=4",
|
||||
"profile": "https://github.com/Atul9",
|
||||
"contributions": [
|
||||
"doc"
|
||||
"login": "royharoush",
|
||||
"name": "royharoush",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/8113056?v=4",
|
||||
"profile": "https://github.com/royharoush",
|
||||
"contributions": [
|
||||
"ideas",
|
||||
"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
|
||||
@@ -45,4 +45,11 @@ jobs:
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
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
+221
-66
@@ -19,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",
|
||||
@@ -81,12 +102,29 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "0.4.7"
|
||||
@@ -127,11 +165,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",
|
||||
@@ -142,9 +180,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",
|
||||
@@ -152,14 +190,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"
|
||||
@@ -171,6 +221,26 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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"
|
||||
@@ -186,9 +256,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.2.1"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829694371bd7bbc6aee17c4ff624aad8bf9f4dc06c6f9f6071eaa08c89530d10"
|
||||
checksum = "68082183f458867ce7cddea16d4df4443c1537112c0c09c450dedc09daf5c719"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
@@ -246,9 +316,9 @@ 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",
|
||||
@@ -306,6 +376,23 @@ 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"
|
||||
@@ -335,9 +422,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.42"
|
||||
version = "0.3.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
|
||||
checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -359,9 +446,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"
|
||||
@@ -402,18 +489,18 @@ checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.22"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17"
|
||||
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",
|
||||
@@ -433,10 +520,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.3"
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880"
|
||||
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",
|
||||
@@ -447,22 +540,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn-mid",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.16"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
|
||||
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
@@ -494,12 +585,64 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.9"
|
||||
@@ -529,14 +672,31 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[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",
|
||||
"colored",
|
||||
"colorful",
|
||||
"dirs",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"gcd",
|
||||
"log",
|
||||
"rand",
|
||||
"rlimit",
|
||||
"shell-words",
|
||||
"structopt",
|
||||
@@ -601,9 +761,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.15"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c"
|
||||
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
@@ -612,9 +772,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.8"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118"
|
||||
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
@@ -625,26 +785,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.35"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
|
||||
checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn-mid"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.0"
|
||||
@@ -709,10 +858,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",
|
||||
@@ -720,9 +875,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",
|
||||
@@ -735,9 +890,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",
|
||||
@@ -747,9 +902,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",
|
||||
@@ -757,9 +912,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",
|
||||
@@ -770,15 +925,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",
|
||||
|
||||
+11
-6
@@ -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,15 +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"
|
||||
structopt = "0.3.15"
|
||||
colored = "2.0.0"
|
||||
structopt = "0.3.16"
|
||||
async-std = "1.6.2"
|
||||
futures = "0.3"
|
||||
rlimit = "0.3.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"
|
||||
@@ -1,6 +1,6 @@
|
||||
<p align="center">
|
||||
➡️
|
||||
<a href="https://discord.gg/r38pna">Discord</a> |
|
||||
<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>
|
||||
⬅️
|
||||
@@ -17,20 +17,19 @@
|
||||
<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">
|
||||
<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` | `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 cmnatic/rustscan:debian-buster` <p>[Usage](https://github.com/RustScan/RustScan#docker-whale) | [Read the install guide](https://github.com/brandonskerritt/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `cargo install rustscan`
|
||||
|
||||
<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!
|
||||
@@ -53,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.
|
||||
|
||||
@@ -62,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?
|
||||
@@ -78,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).
|
||||
|
||||
@@ -115,19 +112,44 @@ 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!
|
||||
## Docker :whale:
|
||||
|
||||
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/`
|
||||
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, run this command against the IP you want to target.**
|
||||
|
||||
```
|
||||
docker run -it --rm --name rustscan cmnatic/rustscan:debian-buster rustscan 127.0.0.1
|
||||
```
|
||||
|
||||
Note: this will scan the Docker's localhost, not your own.
|
||||
|
||||
This will download the Docker image.
|
||||
|
||||
Once done, you will no longer need to re-download the image (except when RustScan updates) and can use RustScan like a normal application.
|
||||
|
||||
You will have to run this command every time, so we suggest aliasing it to something memorable.
|
||||
|
||||
```
|
||||
alias rustscan='docker run -it --rm --name rustscan cmnatic/rustscan:debian-buster rustscan'
|
||||
```
|
||||
|
||||
Then we can:
|
||||
|
||||
```
|
||||
rustscan 127.0.0.1 -t 500 -b 1500 -- -A
|
||||
```
|
||||
|
||||
## 🍺 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:
|
||||
|
||||
```
|
||||
@@ -148,6 +170,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
|
||||
|
||||
```
|
||||
@@ -277,16 +308,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)):
|
||||
@@ -296,12 +359,14 @@ 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="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/brandonskerritt/RustScan/issues?q=author%3Aimlonghao" title="Bug reports">🐛</a> <a href="#maintenance-imlonghao" title="Maintenance">🚧</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/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="Documentation">📖</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>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
Rust room
|
||||
|
||||
# what is rust?
|
||||
* speed
|
||||
* saftey
|
||||
* cargo (pip but for rust)
|
||||
* Links to the rust book (the documentation for rust is literally an ebook)
|
||||
|
||||
# Toolings
|
||||
|
||||
|
||||
# Introduction
|
||||
* if statements
|
||||
* functions
|
||||
* variables
|
||||
* loops
|
||||
|
||||
Some basic questions like "how would u make variable x, how would u make a function named x" and so on
|
||||
|
||||
# Expressions
|
||||
* rust return statements (they're super weird)
|
||||
* What is an expression?
|
||||
|
||||
# Results object
|
||||
If something can fail in Rust, you **HAVE** to deal with the exception.
|
||||
|
||||
FOr example
|
||||
|
||||
```python3
|
||||
# python
|
||||
f = open("file.txt", 'r')
|
||||
```
|
||||
|
||||
But in Rust, you **cannot** open a file unless you write an exception for if that file does not exist.
|
||||
|
||||
In Rust, everything that can fail returns a <return> object. This means that you're never going to encounter an unexpected "file not found" or similar, because everything is accounted for.
|
||||
|
||||
# Borrow checker
|
||||
Variables not in scope are killed. In Python, I think you can do:
|
||||
|
||||
```
|
||||
if y = 6:
|
||||
x = 3
|
||||
else:
|
||||
x = 9
|
||||
```
|
||||
|
||||
But in Rust, the borrow checker will kill X the second the if is over. You cannot create variables inside a scope and use them out fo the scope.
|
||||
|
||||
You can however, do this
|
||||
|
||||
```
|
||||
let x = if y == 6 {3} else {9}
|
||||
```
|
||||
|
||||
This is a security feature, the borrow checker stops you from doing silly things with variables -- everything is either in scope or it's killed off.
|
||||
|
||||
# Multi-threading
|
||||
* Rayon
|
||||
* Turning a for loop into multi-threaded with one word (into_iter -> into_para_iter)
|
||||
# Async
|
||||
* Basic async 101
|
||||
* Making a web server with async rust and how rust ensures saftey with async
|
||||
|
||||
|
||||
# Packaging
|
||||
* Packaging your rust app
|
||||
* Okay not security related but it's really cool it's just 1 command `rust publish`
|
||||
|
||||
## TODO
|
||||
* Rust has an official discord (like, the one the Rust team uses to organise their codebase and create new features). I can ask them for their fave blueteam features of Rust :)
|
||||
* Ask if I'm allowed to include a link to the official discord of Rust. They only have like 2 help channels, the rest of the channels are for organising new features / work on the language itself. It's really cool to be able to see the language evole in Discord, rather than whatever C++ or Python uses (mailing lists I think)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
+274
-158
@@ -1,16 +1,30 @@
|
||||
extern crate shell_words;
|
||||
|
||||
mod tui;
|
||||
|
||||
mod scanner;
|
||||
use scanner::Scanner;
|
||||
|
||||
use colored::*;
|
||||
use colorful::Color;
|
||||
use colorful::Colorful;
|
||||
use futures::executor::block_on;
|
||||
use rlimit::Resource;
|
||||
use rlimit::{getrlimit, setrlimit};
|
||||
use std::process::{exit, Command};
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
use structopt::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;
|
||||
|
||||
@@ -19,9 +33,12 @@ extern crate log;
|
||||
/// 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 {
|
||||
/// The IP address to scan
|
||||
ip: String,
|
||||
/// A list of comma separated IP addresses to be scanned.
|
||||
#[structopt(use_delimiter = true, parse(try_from_str), required = true)]
|
||||
ips: Vec<IpAddr>,
|
||||
|
||||
///Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
|
||||
#[structopt(short, long)]
|
||||
@@ -32,212 +49,311 @@ struct Opts {
|
||||
/// it will do every port at the same time. Although, your OS may not
|
||||
/// support this.
|
||||
#[structopt(short, long, default_value = "4500")]
|
||||
batch_size: u64,
|
||||
batch_size: u16,
|
||||
|
||||
/// The timeout in milliseconds before a port is assumed to be closed.
|
||||
#[structopt(short, long, default_value = "1500")]
|
||||
timeout: u64,
|
||||
timeout: u32,
|
||||
|
||||
/// Automatically ups the ULIMIT with the value you provided.
|
||||
#[structopt(short, long)]
|
||||
ulimit: Option<u64>,
|
||||
|
||||
/// IPv6 mode.
|
||||
#[structopt(short, long)]
|
||||
ipv6: bool,
|
||||
ulimit: Option<rlimit::rlim>,
|
||||
|
||||
/// 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.
|
||||
/// If you're looking for the actual scanning, check out the module Scanner
|
||||
fn main() {
|
||||
// logger
|
||||
env_logger::init();
|
||||
|
||||
info!("Starting up");
|
||||
let mut opts = Opts::from_args();
|
||||
let opts = Opts::from_args();
|
||||
info!("Mains() `opts` arguments are {:?}", opts);
|
||||
|
||||
let user_nmap_options = if opts.command.is_empty() {
|
||||
"-A -vvv".to_string()
|
||||
} else {
|
||||
opts.command.join(" ")
|
||||
};
|
||||
|
||||
if !opts.quiet {
|
||||
print_opening();
|
||||
}
|
||||
|
||||
// Updates ulimit when the argument is set
|
||||
let ulimit: rlimit::rlim = adjust_ulimit_size(&opts);
|
||||
let batch_size: u16 = infer_batch_size(&opts, ulimit);
|
||||
|
||||
// Automatically ups the ulimit
|
||||
if opts.ulimit.is_some() {
|
||||
let limit = opts.ulimit.unwrap();
|
||||
info!("Automatically upping ulimit");
|
||||
|
||||
if !opts.quiet {
|
||||
println!("Automatically upping ulimit to {}", limit);
|
||||
}
|
||||
|
||||
match setrlimit(Resource::NOFILE, limit, limit) {
|
||||
Ok(_) => {}
|
||||
Err(_) => println!("ERROR. Failed to set Ulimit."),
|
||||
}
|
||||
}
|
||||
|
||||
let (x, _) = getrlimit(Resource::NOFILE).unwrap();
|
||||
|
||||
// if maximum limit is lower than batch size
|
||||
// automatically re-adjust the batch size
|
||||
if x < opts.batch_size {
|
||||
if !opts.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());
|
||||
}
|
||||
|
||||
// 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 {
|
||||
opts.batch_size = 3000
|
||||
} else {
|
||||
opts.batch_size = x - 100u64
|
||||
}
|
||||
}
|
||||
// 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 > opts.batch_size.into() && (opts.ulimit.is_none()) {
|
||||
if !opts.quiet {
|
||||
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 - 1u64
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let addr = match opts.ip.parse::<IpAddr>() {
|
||||
Ok(res) => res,
|
||||
Err(_) => panic!("Could not parse IP Address"),
|
||||
};
|
||||
|
||||
// 65535 + 1 because of 0 indexing
|
||||
let scanner = Scanner::new(
|
||||
addr,
|
||||
1,
|
||||
65535,
|
||||
opts.batch_size.into(),
|
||||
&opts.ips,
|
||||
LOWEST_PORT_NUMBER,
|
||||
TOP_PORT_NUMBER,
|
||||
batch_size,
|
||||
Duration::from_millis(opts.timeout.into()),
|
||||
opts.quiet,
|
||||
);
|
||||
|
||||
let scan_result = block_on(scanner.run());
|
||||
let mut ports_per_ip = HashMap::new();
|
||||
|
||||
// prints ports and places them into nmap string
|
||||
let nmap_str_ports: Vec<String> = scan_result
|
||||
.into_iter()
|
||||
.map(|port| port.to_string())
|
||||
.collect();
|
||||
for socket in scan_result {
|
||||
ports_per_ip
|
||||
.entry(socket.ip())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(socket.port());
|
||||
}
|
||||
|
||||
// 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.
|
||||
for ip in opts.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.", "ERROR".red(),
|
||||
\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().green(),
|
||||
"'rustscan -b <batch_size> <ip address>'".green());
|
||||
(opts.batch_size / 2).to_string(),
|
||||
"'rustscan -b <batch_size> <ip address>'");
|
||||
warning!(x, opts.quiet);
|
||||
}
|
||||
|
||||
// Tells the user we are now switching to Nmap
|
||||
if !opts.quiet {
|
||||
println!("{}", "Starting nmap.".blue(),);
|
||||
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");
|
||||
}
|
||||
|
||||
// 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 opts.quiet {
|
||||
println!("{}", ports_str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let nmap_args = if !opts.ipv6 {
|
||||
format!(
|
||||
"{} {} {} {} {} {}",
|
||||
&user_nmap_options, "-vvv", "-Pn", "-p", &ports_str, opts.ip
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{} {} {} {} {} {} {}",
|
||||
&user_nmap_options, "-vvv", "-Pn", "-6", "-p", &ports_str, opts.ip
|
||||
)
|
||||
};
|
||||
|
||||
if !opts.quiet {
|
||||
println!("The Nmap command to be run is {}", &nmap_args);
|
||||
}
|
||||
let nmap_args = shell_words::split(&nmap_args).expect("failed to parse nmap arguments");
|
||||
|
||||
// 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 = "
|
||||
_____ _ _____
|
||||
| __ \\ | | / ____|
|
||||
| |__) | _ ___| |_| (___ ___ __ _ _ __
|
||||
| _ / | | / __| __|\\___ \\ / __/ _` | '_ \\
|
||||
| | \\ \\ |_| \\__ \\ |_ ____) | (_| (_| | | | |
|
||||
|_| \\_\\__,_|___/\\__|_____/ \\___\\__,_|_| |_|
|
||||
Faster nmap scanning with rust.";
|
||||
println!("{}\n", s.green());
|
||||
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 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 Ulimt with '--ulimt 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 super::Scanner;
|
||||
use async_std::task::block_on;
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
use crate::{adjust_ulimit_size, infer_batch_size, print_opening, Opts};
|
||||
use std::{net::IpAddr, str::FromStr};
|
||||
|
||||
#[test]
|
||||
fn does_it_run() {
|
||||
// Makes sure te program still runs and doesn't panic
|
||||
let addr = match "127.0.0.1".parse::<IpAddr>() {
|
||||
Ok(res) => res,
|
||||
Err(_) => panic!("Could not parse IP Address"),
|
||||
fn batch_size_lowered() {
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
};
|
||||
let scanner = Scanner::new(addr, 1, 65535, 1000, Duration::from_millis(10), true);
|
||||
let scan_result = block_on(scanner.run());
|
||||
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
|
||||
assert_eq!(1, 1);
|
||||
let batch_size = infer_batch_size(&opts, 120);
|
||||
|
||||
assert!(batch_size < 50_000);
|
||||
}
|
||||
fn does_it_run_ivp6() {
|
||||
// Makes sure te program still runs and doesn't panic
|
||||
let addr = match "::1".parse::<IpAddr>() {
|
||||
Ok(res) => res,
|
||||
Err(_) => panic!("Could not parse IP Address"),
|
||||
|
||||
#[test]
|
||||
fn batch_size_lowered_average_size() {
|
||||
let opts = Opts {
|
||||
ips: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
};
|
||||
let scanner = Scanner::new(addr, 1, 65535, 1000, Duration::from_millis(10), true);
|
||||
let scan_result = block_on(scanner.run());
|
||||
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
|
||||
assert_eq!(1, 1);
|
||||
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: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
};
|
||||
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: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
quiet: true,
|
||||
batch_size: 50_000,
|
||||
timeout: 1_000,
|
||||
ulimit: Some(2_000),
|
||||
command: Vec::new(),
|
||||
};
|
||||
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: vec![IpAddr::from_str("127.0.0.1").unwrap()],
|
||||
quiet: false,
|
||||
batch_size: 10,
|
||||
timeout: 1_000,
|
||||
ulimit: None,
|
||||
command: Vec::new(),
|
||||
};
|
||||
|
||||
infer_batch_size(&opts, 1_000_000);
|
||||
|
||||
assert!(1 == 1);
|
||||
}
|
||||
}
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
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
|
||||
/// Host is data type IpAddr and is the host 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.
|
||||
/// ipv6 is whether or not this scan is an ipv6 scan.
|
||||
pub struct Scanner {
|
||||
host: IpAddr,
|
||||
start: u16,
|
||||
end: u16,
|
||||
batch_size: u64,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(
|
||||
host: IpAddr,
|
||||
start: u16,
|
||||
end: u16,
|
||||
batch_size: u64,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
host: host.to_owned(),
|
||||
start,
|
||||
end,
|
||||
batch_size,
|
||||
timeout,
|
||||
quiet,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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<u16> {
|
||||
let ports: Vec<u16> = (self.start..self.end).collect();
|
||||
let mut open_ports: std::vec::Vec<u16> = Vec::new();
|
||||
// TODO change this to port size
|
||||
// to fix bug when we introduce custom port ranges
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/// Given a range of ports, scan them all.
|
||||
/// Returns a vector of open ports.
|
||||
async fn scan_range(&self, range: &[u16]) -> Vec<u16> {
|
||||
let mut ftrs = FuturesUnordered::new();
|
||||
for port in range {
|
||||
ftrs.push(self.scan_port(*port));
|
||||
}
|
||||
|
||||
let mut open_ports: Vec<u16> = Vec::new();
|
||||
while let Some(result) = ftrs.next().await {
|
||||
match result {
|
||||
Ok(port) => open_ports.push(port),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
open_ports
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// ```rust
|
||||
/// self.scan_port(10:u16)
|
||||
/// ```
|
||||
/// Note: `self` must contain `self.host`.
|
||||
async fn scan_port(&self, port: u16) -> io::Result<u16> {
|
||||
let addr = SocketAddr::new(self.host, port);
|
||||
// println!("{:?}", addr);
|
||||
match self.connect(addr).await {
|
||||
Ok(x) => {
|
||||
// match stream_result.shutdown(Shutdown::Both)
|
||||
info!("Shutting down stream");
|
||||
match x.shutdown(Shutdown::Both) {
|
||||
_ => {}
|
||||
}
|
||||
if !self.quiet {
|
||||
println!("Open {}", port.to_string().purple());
|
||||
}
|
||||
// if connection successful
|
||||
// shut down stream
|
||||
// return port
|
||||
Ok(port)
|
||||
}
|
||||
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
|
||||
/// ```rust
|
||||
/// let port: u16 = 80
|
||||
/// // Host is an IpAddr type
|
||||
/// let host = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
/// let addr = SocketAddr::new(host, port)
|
||||
/// self.connect(addr)
|
||||
/// // returns Result which is either Ok(stream) for port is open, or Er for port is closed.
|
||||
/// // Timesout after self.timeouts seconds
|
||||
/// ```
|
||||
async fn connect(&self, addr: SocketAddr) -> io::Result<TcpStream> {
|
||||
let stream =
|
||||
io::timeout(self.timeout, async move { TcpStream::connect(addr).await }).await?;
|
||||
info!("Returning okay from connect");
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn does_it_run() {
|
||||
// TODO run functions here
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
mod range_iterator;
|
||||
use range_iterator::RangeIterator;
|
||||
|
||||
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
|
||||
/// Host is data type IpAddr and is the host address
|
||||
/// start & end is where the port scan starts and ends
|
||||
/// batch_size is how many ports at a time should be scanned
|
||||
/// Timeout is the time RustScan should wait before declaring a port closed. As datatype Duration.
|
||||
/// Quiet is whether or not RustScan should print things, or wait until the end to print only open ports.
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
pub struct Scanner {
|
||||
hosts: Vec<IpAddr>,
|
||||
start: u16,
|
||||
end: u16,
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(
|
||||
hosts: &[IpAddr],
|
||||
start: u16,
|
||||
end: u16,
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
batch_size,
|
||||
timeout,
|
||||
quiet,
|
||||
hosts: hosts.iter().map(|host| host.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 range_iterator = RangeIterator::new(self.start.into(), self.end.into());
|
||||
let mut sockets: Vec<SocketAddr> = Vec::new();
|
||||
let mut open_sockets: Vec<SocketAddr> = Vec::new();
|
||||
|
||||
for port in range_iterator {
|
||||
for host in &self.hosts {
|
||||
sockets.push(SocketAddr::new(*host, port));
|
||||
}
|
||||
|
||||
if sockets.len() >= self.batch_size.into() {
|
||||
let mut results = self.scan_range(&sockets).await;
|
||||
open_sockets.append(&mut results);
|
||||
sockets = Vec::new();
|
||||
}
|
||||
}
|
||||
|
||||
// This will happen if we have a number of sockets remaining
|
||||
// that is lower than the batch size.
|
||||
if !sockets.is_empty() {
|
||||
let mut results = self.scan_range(&sockets).await;
|
||||
open_sockets.append(&mut results);
|
||||
}
|
||||
|
||||
open_sockets
|
||||
}
|
||||
|
||||
/// Given a slice of sockets, scan them all.
|
||||
/// Returns a vector of open sockets.
|
||||
async fn scan_range(&self, sockets: &[SocketAddr]) -> Vec<SocketAddr> {
|
||||
let mut ftrs = FuturesUnordered::new();
|
||||
for socket in sockets {
|
||||
ftrs.push(self.scan_socket(socket));
|
||||
}
|
||||
|
||||
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.host`.
|
||||
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
|
||||
/// // Host is an IpAddr type
|
||||
/// let host = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
/// let socket = SocketAddr::new(host, port);
|
||||
/// 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 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 scanner = Scanner::new(&addrs, 1, 1_000, 10, Duration::from_millis(100), true);
|
||||
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 scanner = Scanner::new(&addrs, 1, 1_000, 10, Duration::from_millis(100), false);
|
||||
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 scanner = Scanner::new(&addrs, 1, 1_000, 10, Duration::from_millis(500), true);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
#[test]
|
||||
fn google_dns_runs() {
|
||||
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
|
||||
let scanner = Scanner::new(&addrs, 400, 445, 10, Duration::from_millis(1_500), true);
|
||||
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 scanner = Scanner::new(&addrs, 400, 600, 10_000, Duration::from_millis(1500), true);
|
||||
block_on(scanner.run());
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
use gcd::Gcd;
|
||||
use rand::Rng;
|
||||
|
||||
pub struct RangeIterator {
|
||||
normalized_end: u32,
|
||||
normalized_first_pick: Option<u32>,
|
||||
normalized_pick: Option<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);
|
||||
|
||||
Self {
|
||||
normalized_end,
|
||||
step,
|
||||
normalized_first_pick: None,
|
||||
normalized_pick: None,
|
||||
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> {
|
||||
// Randomly choose a number within the range to be the first
|
||||
// and assign it as a pick.
|
||||
if self.normalized_first_pick.is_none() {
|
||||
let mut rng = rand::thread_rng();
|
||||
let normalized_first_pick = rng.gen_range(0, self.normalized_end);
|
||||
|
||||
self.normalized_first_pick = Some(normalized_first_pick);
|
||||
self.normalized_pick = Some(normalized_first_pick);
|
||||
return Some((self.actual_start + normalized_first_pick) as u16);
|
||||
}
|
||||
|
||||
let current_pick = self.normalized_pick.unwrap();
|
||||
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.unwrap() {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.normalized_pick = Some(next_pick);
|
||||
Some((self.actual_start + next_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
|
||||
}
|
||||
}
|
||||
+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