Compare commits

..
Author SHA1 Message Date
Brandon 7a73299c63 Merging with master 2020-09-07 02:21:16 +01:00
Bee 88e1f88f50 Merge branch 'master' into bee-add-without-nmap 2020-09-07 02:17:27 +01:00
Brandon 00394ec58b Updated code of conduct links and fixed tests 2020-09-07 02:14:40 +01:00
Brandon e669cff99f added no nmap mode 2020-09-07 02:02:42 +01:00
Brandon 87de96c3c4 Merge pull request #185 from RustScan/ba-add-config-file
Add configuration file
2020-08-30 14:00:07 +01:00
Bernardo Chaves 8e21f3bf8c Add configuration file
This configuration file will be read from the home directory of the
user. Options set within this file will have priority over arguments
from the command line unless the `--no-config` option is passed to the
program.
2020-08-29 18:01:44 -04:00
Brandon 4019d1ff3a Merge pull request #182 from RustScan/all-contributors/add-tim77
docs: add tim77 as a contributor
2020-08-29 12:15:07 +01:00
Brandon c004bd0527 Merge pull request #181 from tim77/tim77-patch-1
Add Fedora/CentOS installation instructions
2020-08-29 11:53:44 +01:00
allcontributors[bot] cdc5bbd924 docs: update .all-contributorsrc [skip ci] 2020-08-29 10:53:35 +00:00
allcontributors[bot] f41213047a docs: update README.md [skip ci] 2020-08-29 10:53:34 +00:00
Artem Polishchuk 2315ef2417 Add Fedora/CentOS installation instructions 2020-08-28 23:33:42 +03:00
Brandon cb87d5b9ce Update README.md 2020-08-28 16:14:10 +01:00
Brandon 92800678cd Merge branch 'master' of github.com:brandonskerritt/RustScan into master 2020-08-28 15:59:05 +01:00
Brandon 8e76a71a4c updated logo 2020-08-28 15:58:42 +01:00
Brandon 07fdea8471 Merge pull request #176 from niklasmohrin/improve-readme
README.md tweaks
2020-08-28 13:50:38 +01:00
Niklas Mohrin 8670bcc35f Move "rustscan -h" and output together 2020-08-28 14:43:50 +02:00
Niklas Mohrin fbba9d16ca Mark code blocks as bash commands in README 2020-08-28 14:43:50 +02:00
Niklas Mohrin 309d1ad660 Remove argument placeholders in docker alias 2020-08-28 14:43:47 +02:00
Brandon ed48161bea added travis token 2020-08-28 11:22:23 +01:00
Brandon f0d1aa2b9a Merge pull request #180 from RustScan/all-contributors/add-SuperSandro2000
docs: add SuperSandro2000 as a contributor
2020-08-28 11:12:35 +01:00
Brandon ac93feddb5 Merge pull request #178 from SuperSandro2000/optimize-docker
Optimize Dockerfile
2020-08-28 11:12:17 +01:00
allcontributors[bot] 1280fa1b47 docs: update .all-contributorsrc [skip ci] 2020-08-28 10:12:08 +00:00
Brandon 6e731aaf93 Merge branch 'master' into optimize-docker 2020-08-28 11:12:08 +01:00
allcontributors[bot] 9230165f8f docs: update README.md [skip ci] 2020-08-28 10:12:07 +00:00
Brandon 818c80041b Merge pull request #177 from RustScan/all-contributors/add-niklasmohrin
docs: add niklasmohrin as a contributor
2020-08-28 11:11:38 +01:00
allcontributors[bot] bce955212a docs: update .all-contributorsrc [skip ci] 2020-08-28 10:11:34 +00:00
allcontributors[bot] 41e0e8905f docs: update README.md [skip ci] 2020-08-28 10:11:33 +00:00
Sandro Jäckel 85f1699724 Prevent cache bustages 2020-08-28 01:31:54 +02:00
Sandro Jäckel bafd0141df Pin Alpine 3.12 to prevent breakages in the future 2020-08-28 01:31:26 +02:00
Sandro Jäckel aba0f3c38c Cleanup Dockerfile 2020-08-28 01:31:08 +02:00
allcontributors[bot] 9e161d4f79 docs: update .all-contributorsrc [skip ci] 2020-08-27 23:12:10 +00:00
allcontributors[bot] 731b4079cf docs: update README.md [skip ci] 2020-08-27 23:12:09 +00:00
Brandon b4edc6cca6 1.8.0 publish 2020-08-28 00:03:02 +01:00
Brandon 4a7cbd701b Merge pull request #175 from RustScan/all-contributors/add-caass
docs: add caass as a contributor
2020-08-27 20:39:46 +01:00
allcontributors[bot] f34ee8f5ef docs: update .all-contributorsrc [skip ci] 2020-08-27 19:36:22 +00:00
allcontributors[bot] 89c763789f docs: update README.md [skip ci] 2020-08-27 19:36:21 +00:00
Brandon 5c48f1173a Merge pull request #140 from remigourdon/docs-pages
Add Travis configuration to publish doc to GitHub pages
2020-08-27 14:02:46 +01:00
Brandon 8d8ca1d4a0 Merge branch 'master' into docs-pages 2020-08-27 14:01:29 +01:00
Brandon 8d8acd61e8 Merge pull request #173 from RustScan/bee-add-submodule
added submodule
2020-08-27 13:33:16 +01:00
Brandon 0ab3e53034 Merge branch 'master' into bee-add-submodule 2020-08-27 13:05:19 +01:00
Brandon 56493859cb added submodule 2020-08-27 12:36:56 +01:00
Brandon 2ef723ed96 Merge branch 'master' into docs-pages 2020-08-27 12:30:33 +01:00
Brandon e9288302ba Merge pull request #172 from RustScan/all-contributors/add-caass
docs: add caass as a contributor
2020-08-27 11:39:35 +01:00
remigourdon 8179511527 Add Travis configuration to publish doc to GitHub pages 2020-08-26 23:22:13 -04:00
allcontributors[bot] fbab4a4020 docs: update .all-contributorsrc [skip ci] 2020-08-26 23:22:13 -04:00
allcontributors[bot] b425d15a98 docs: update README.md [skip ci] 2020-08-26 23:22:13 -04:00
allcontributors[bot] fddda34465 docs: update .all-contributorsrc [skip ci] 2020-08-26 23:39:11 +00:00
allcontributors[bot] 125df4a2ed docs: update README.md [skip ci] 2020-08-26 23:39:10 +00:00
Brandon e670d11223 Merge pull request #170 from RustScan/all-contributors/add-SuperSandro2000
docs: add SuperSandro2000 as a contributor
2020-08-27 00:36:42 +01:00
Brandon 8453320586 Merge pull request #169 from SuperSandro2000/fix-timeout-arg
Convert -T to -t
2020-08-26 17:27:15 +01:00
allcontributors[bot] 99e9c834a9 docs: update .all-contributorsrc [skip ci] 2020-08-26 15:54:45 +00:00
allcontributors[bot] dfbce6a636 docs: update README.md [skip ci] 2020-08-26 15:54:44 +00:00
Sandro Jäckel 916be1e4a2 Convert -T to -t 2020-08-26 17:38:58 +02:00
Brandon 90b4328fb6 Merge pull request #167 from RustScan/all-contributors/add-Phenomite
docs: add Phenomite as a contributor
2020-08-26 16:08:25 +01:00
Brandon 76035d3379 Merge branch 'master' into all-contributors/add-Phenomite 2020-08-26 15:50:08 +01:00
Brandon 4de31ecede Merge pull request #163 from Phenomite/patch-1
2000 milliseconds not seconds
2020-08-26 15:47:50 +01:00
allcontributors[bot] ce9befaa1a docs: update .all-contributorsrc [skip ci] 2020-08-26 14:47:28 +00:00
Brandon 5f6457ed7e Merge branch 'master' into patch-1 2020-08-26 15:47:27 +01:00
allcontributors[bot] 12d3c91983 docs: update README.md [skip ci] 2020-08-26 14:47:27 +00:00
Brandon e0fd7a39dc Merge pull request #164 from RustScan/dependabot/cargo/structopt-0.3.17
Bump structopt from 0.3.16 to 0.3.17
2020-08-26 14:59:31 +01:00
Brandon ff0787e332 Merge branch 'master' into dependabot/cargo/structopt-0.3.17 2020-08-26 14:02:08 +01:00
Brandon 6ce6c0ce9e Merge pull request #166 from RustScan/all-contributors/add-Ferryistaken
docs: add Ferryistaken as a contributor
2020-08-26 14:01:48 +01:00
Brandon edf989ad5d Merge branch 'master' into all-contributors/add-Ferryistaken 2020-08-26 13:35:08 +01:00
Brandon 3fede4c6db Merge pull request #165 from Ferryistaken/fix-message
Fixed small typo in a warning message
2020-08-26 13:34:46 +01:00
allcontributors[bot] 75b310f227 docs: update .all-contributorsrc [skip ci] 2020-08-26 12:34:40 +00:00
allcontributors[bot] 72c6ef1f1d docs: update README.md [skip ci] 2020-08-26 12:34:39 +00:00
Ferry 83b23da32b Fixed small typo in a warning message 2020-08-26 11:00:54 +02:00
dependabot-preview[bot] 3886a07775 Bump structopt from 0.3.16 to 0.3.17
Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.16 to 0.3.17.
- [Release notes](https://github.com/TeXitoi/structopt/releases)
- [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.16...v0.3.17)

Signed-off-by: dependabot-preview[bot] <[email protected]>
2020-08-26 06:52:53 +00:00
Phenomite f5064d3d5c 2000 milliseconds not seconds 2020-08-25 18:42:59 -04:00
Brandon 22cbfc5826 Merge pull request #159 from RustScan/bee-add-nmap-ports
updated config file to feature nmap top 1k ports
2020-08-24 16:49:13 +01:00
Brandon a9d729300c Merge branch 'master' into bee-add-nmap-ports 2020-08-24 13:49:10 +01:00
Brandon 4f5dd20e85 Merge pull request #162 from RustScan/ba-reduce-binary-size
Reduce binary size from 2.4MB to 1.9MB
2020-08-24 12:48:45 +01:00
Bernardo Chaves 499ff66f36 Reduce binary size from 2.4MB to 1.9MB
By default, Cargo instructs compilation units to be compiled and optimized
in isolation. LTO instructs the linker to optimize at the link stage.
This can, for example, remove dead code and often times reduces binary size.

By default, when Rust code encounters a situation when it must call panic!(),
it unwinds the stack and produces a helpful backtrace. The unwinding code,
however, does require extra binary size. rustc can be instructed to abort
immediately rather than unwind, which removes the need for this extra unwinding code.

For more information see: https://github.com/johnthagen/min-sized-rust
2020-08-23 18:10:53 -04:00
Brandon 61b87243d9 Merge pull request #161 from RustScan/ba-refactor-port-strategy
Allow randomized order for manual ports
2020-08-22 22:27:37 +01:00
Bernardo Chaves e069991c8d Allow randomized order for manual ports
Before this change we would always scan manually specified ports in
sequential way, this is not the case anymore. This is an important
change since we are planning to introduce a config file with the top 1K
ports and we would like to scan those in a randomized way.
2020-08-21 13:09:41 -04:00
Brandon 85c1cbf445 Merge pull request #160 from RustScan/bee-remove-A
removed -A from nmap
2020-08-20 22:58:39 +01:00
Brandon 5551e64166 updated AUR package in readme 2020-08-20 00:40:41 +01:00
Brandon e0aa1423ad removed -A from nmap 2020-08-20 00:32:37 +01:00
Brandon e609b3617c updated config file to feature nmap top 1k ports 2020-08-20 00:05:45 +01:00
Brandon d0d8380296 Merge pull request #158 from RustScan/ba-add-port-and-range-options
Add --port and --range options
2020-08-19 16:26:39 +01:00
Brandon d66ad34f8c Merge branch 'master' into ba-add-port-and-range-options 2020-08-19 16:02:49 +01:00
Brandon 2670ec43df Merge pull request #156 from spenserblack/exclude-files
Exclude files
2020-08-19 00:05:59 +01:00
Bernardo Chaves 90d0b03ba7 Add --port and --range options
These options are mutually exclusive, this means that when a user
selects manual ports we will ignore ranges and vice-versa.

Manually specifying ports won't allow scan randomization for now.
2020-08-17 20:43:44 -04:00
Spenser Black 57eb3627b3 Use absolute image URLs instead of relative 2020-08-17 10:03:04 -04:00
Spenser Black 7e675b7557 Reduce crate size 2020-08-17 09:30:07 -04:00
Bernardo Araujo fdeaa05f23 Merge pull request #152 from RustScan/ba-add-host-resolution
Add host resolution
2020-08-16 18:35:40 -04:00
17 changed files with 2284 additions and 262 deletions

No files matched your search

+58
View File
@@ -115,6 +115,64 @@
"doc",
"design"
]
},
{
"login": "Ferryistaken",
"name": "Alessandro Ferrari",
"avatar_url": "https://avatars3.githubusercontent.com/u/47927670?v=4",
"profile": "https://github.com/Ferryistaken",
"contributions": [
"content"
]
},
{
"login": "Phenomite",
"name": "Phenomite",
"avatar_url": "https://avatars2.githubusercontent.com/u/8285537?v=4",
"profile": "https://github.com/Phenomite",
"contributions": [
"content"
]
},
{
"login": "SuperSandro2000",
"name": "Sandro",
"avatar_url": "https://avatars2.githubusercontent.com/u/7258858?v=4",
"profile": "https://supersandro.de/",
"contributions": [
"content",
"bug",
"code"
]
},
{
"login": "caass",
"name": "Cass",
"avatar_url": "https://avatars2.githubusercontent.com/u/25358963?v=4",
"profile": "https://swag.lgbt",
"contributions": [
"platform",
"code",
"bug"
]
},
{
"login": "niklasmohrin",
"name": "Niklas Mohrin",
"avatar_url": "https://avatars0.githubusercontent.com/u/47574893?v=4",
"profile": "https://github.com/niklasmohrin",
"contributions": [
"doc"
]
},
{
"login": "tim77",
"name": "Artem Polishchuk",
"avatar_url": "https://avatars0.githubusercontent.com/u/5614476?v=4",
"profile": "https://liberapay.com/Artem4/",
"contributions": [
"platform"
]
}
],
"contributorsPerLine": 7,
+2
View File
@@ -0,0 +1,2 @@
.git
Dockerfile
+3
View File
@@ -0,0 +1,3 @@
[submodule "src/rustscan_scripting_engine"]
path = src/rustscan_scripting_engine
url = https://github.com/RustScan/rustscan_scripting_engine
+23 -42
View File
@@ -1,56 +1,37 @@
language: rust
os:
- linux
- osx
# - windows
- linux
- osx
arch:
- amd64
- arm64
- amd64
- arm64
services:
- docker
- docker
before_install:
- rustup component add rustfmt
# cargo test
rust:
- stable
- beta
- 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
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
- chmod +x send.sh
- "./send.sh failure $WEBHOOK_URL"
after_success: |
if [ -n "${GITHUB_TOKEN}" ]; then
[ "${TRAVIS_BRANCH} " = master ] &&
[ "${TRAVIS_PULL_REQUEST}" = false ] &&
cargo doc &&
echo "<meta http-equiv=refresh content=0;url=rustscan/index.html>" > target/doc/index.html &&
sudo pip install ghp-import &&
ghp-import -n target/doc &&
git push -fq https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
fi
env:
global:
secure: Gf24LG7Hr3Q0drWyPrvISTL35Z57DxdS/wIOo7v+ZdauzY3Qjvv3Lh4TY//C4sdN0g1CLj4yjg7LQOqF4XRdh2Qah7JZPv/i2B5uz9nwjTsoRzmmMWML9VtfT1u53nSFqsNeXbvpmoNG9rfMXcoiyd+Lv+EgniHphDEBlXvS9n9KMcpOi1F2x7bsH0EK37wQYKMTpCCd5TPUPdZou7BJNiZS3ikRLpTRFF7uIN4gYtRH9kU5uBSphWgnJ6eBm2ItzZcUPOgrjAoF4RkmZAzGG4idDh1Qkf3No3nZwT3U5NSk8h7owtJ4oADlRgYqYKCB4YcC9cAKCJgDsyMlKKMkEyagvw1seFnBLCY3ljsW4EklpVEZ0rVqZOx4pTkIaxIxytLTC9pHmdDSnhdhFknOcVAQQWjg+nAZfD07QUeAqUdr0i/vxQoZitvbNY0znzEarycE1waKvwlkiB4gt385U1CBfYldydnOnRKkdtLNrCLClu13HU0djmSXMhojQJhTuNxTHtZAf5fKcWIWwkVbNZ5MNKYjQh4rKufqW3o1iHphB8dfAGsDEPv0RQMtVbu6H4+clCouLkFlxHOIrrOJ5SXQ8cIATPhnJR7y4cSDdRaN0DRLRjeLAIKlbOGBtNuFC+BftocaTY5qN42aKAMqQcT30ycfiLuRVJNiQJ5pkto=
+3 -3
View File
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at brandon@skerritt.blog. All
reported by contacting the project team at our discord via a private message to any of the owners. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
@@ -67,10 +67,10 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
This Code of Conduct is adapted from the Contributor Covenant homepage, version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
homepage: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
Generated
+74 -44
View File
@@ -41,9 +41,9 @@ checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]]
name = "async-channel"
version = "1.4.0"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43de69555a39d52918e2bc33a408d3c0a86c829b212d898f4ca25d21a6387478"
checksum = "59386c3aa61f4e14c4ddda1a6744c119b4bf278ec9f866d3c20bc5728ee0eb97"
dependencies = [
"concurrent-queue",
"event-listener",
@@ -85,9 +85,9 @@ dependencies = [
[[package]]
name = "async-mutex"
version = "1.1.5"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20e85981fc34e84cdff3fc2c9219189752633fdc538a06df8b5ac45b68a4f3a9"
checksum = "065de1ccf10280d0d75c2f3a71a970ee1007c85c51aa3e7deee1df100f1dfadb"
dependencies = [
"event-listener",
]
@@ -144,15 +144,15 @@ dependencies = [
[[package]]
name = "autocfg"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.11.0"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]]
name = "bitflags"
@@ -173,9 +173,9 @@ dependencies = [
[[package]]
name = "blocking"
version = "0.5.0"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76e94bf99b692f54c9d05f97454d3faf11134523fe5b180564a3fb6ed63bcc0a"
checksum = "ea5800d29218fea137b0880387e5948694a23c93fcdde157006966693a865c7c"
dependencies = [
"async-channel",
"atomic-waker",
@@ -198,9 +198,9 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
[[package]]
name = "cc"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"
[[package]]
name = "cfg-if"
@@ -210,9 +210,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "clap"
version = "2.33.2"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term 0.11.0",
"atty",
@@ -301,15 +301,15 @@ dependencies = [
[[package]]
name = "event-listener"
version = "2.3.2"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68082183f458867ce7cddea16d4df4443c1537112c0c09c450dedc09daf5c719"
checksum = "e1cd41440ae7e4734bbd42302f63eaba892afc93a3912dad84006247f0dedb0e"
[[package]]
name = "fastrand"
version = "1.3.3"
version = "1.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36a9cb09840f81cd211e435d00a4e487edd263dc3c8ff815c32dd76ad668ebed"
checksum = "5c85295147490b8fcf2ea3d104080a105a8b2c63f9c319e82c02d8e952388919"
[[package]]
name = "futures"
@@ -361,15 +361,15 @@ checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
[[package]]
name = "futures-lite"
version = "0.1.10"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe71459749b2e8e66fb95df721b22fa08661ad384a0c5b519e11d3893b4692a"
checksum = "97999970129b808f0ccba93211201d431fcc12d7e1ffae03a61b5cedd1a7ced2"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"memchr",
"parking 1.0.6",
"parking 2.0.0",
"pin-project-lite",
"waker-fn",
]
@@ -491,9 +491,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.74"
version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
[[package]]
name = "log"
@@ -533,9 +533,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.4.0"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
[[package]]
name = "parking"
@@ -583,21 +583,22 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "polling"
version = "0.1.3"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d83023eb990619815bb41b45625b02da62b00d0f24b0a08aae37697b3f6c94"
checksum = "53c5afb3e8bc82c2780a807374bda0fb8886904d8e9d51e6f4f3743fb1dd27fb"
dependencies = [
"cfg-if",
"libc",
"log",
"wepoll-sys-stjepang",
"winapi",
]
[[package]]
name = "ppv-lite86"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
[[package]]
name = "proc-macro-error"
@@ -708,9 +709,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_users"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall",
@@ -747,9 +748,9 @@ dependencies = [
[[package]]
name = "rust-argon2"
version = "0.7.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
dependencies = [
"base64",
"blake2b_simd",
@@ -759,7 +760,7 @@ dependencies = [
[[package]]
name = "rustscan"
version = "1.7.1"
version = "1.8.0"
dependencies = [
"ansi_term 0.12.1",
"async-std",
@@ -772,8 +773,11 @@ dependencies = [
"log",
"rand",
"rlimit",
"serde",
"serde_derive",
"shell-words",
"structopt",
"toml",
]
[[package]]
@@ -782,6 +786,23 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "serde"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
[[package]]
name = "serde_derive"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "shell-words"
version = "1.0.0"
@@ -814,9 +835,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
checksum = "6cc388d94ffabf39b5ed5fadddc40147cb21e605f53db6f8f36a625d27489ac5"
dependencies = [
"clap",
"lazy_static",
@@ -825,9 +846,9 @@ dependencies = [
[[package]]
name = "structopt-derive"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
checksum = "5e2513111825077552a6751dfad9e11ce0fba07d7276a3943a037d7e93e64c5f"
dependencies = [
"heck",
"proc-macro-error",
@@ -838,9 +859,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.38"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9"
dependencies = [
"proc-macro2",
"quote",
@@ -874,6 +895,15 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "toml"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
dependencies = [
"serde",
]
[[package]]
name = "unicode-segmentation"
version = "1.6.0"
@@ -894,9 +924,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "vec-arena"
version = "0.5.0"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17dfb54bf57c9043f4616cb03dab30eff012cc26631b797d8354b916708db919"
checksum = "8cb18268690309760d59ee1a9b21132c126ba384f374c59a94db4bc03adeb561"
[[package]]
name = "vec_map"
@@ -912,9 +942,9 @@ checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "waker-fn"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "wasi"
+14 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "rustscan"
version = "1.7.1"
version = "1.8.0"
authors = ["Bee <[email protected]>"]
edition = "2018"
description = "Faster Nmap Scanning with Rust"
@@ -10,12 +10,15 @@ license = "MIT"
keywords = ["port", "scanning", "nmap"]
categories = ["command-line-utilities"]
readme="README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
exclude = [
".github/*",
"pictures/*",
"rustscan-debbuilder/*",
]
[dependencies]
colored = "2.0.0"
structopt = "0.3.16"
structopt = "0.3.17"
async-std = "1.6.3"
futures = "0.3"
rlimit = "0.4.0"
@@ -27,7 +30,14 @@ gcd = "2.0.1"
rand = "0.7.3"
colorful = "0.2.1"
ansi_term = "0.12.1"
toml = "0.5.6"
serde = "1.0.115"
serde_derive = "1.0.115"
[package.metadata.deb]
depends = "$auto, nmap"
section = "rust"
[profile.release]
lto = true
panic = 'abort'
+7 -13
View File
@@ -1,22 +1,16 @@
FROM rust:alpine as builder
RUN apk update && \
apk add build-base && \
rm -rf /var/cache/apk/*
RUN apk add --no-cache build-base
WORKDIR /usr/src/rustscan
COPY . .
RUN cargo install --path .
FROM alpine
FROM alpine:3.12
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
adduser -S -G rustscan rustscan && \
ulimit -n 100000 && \
apk add --no-cache nmap nmap-scripts wget
COPY --from=builder /usr/local/cargo/bin/rustscan /usr/local/bin/rustscan
USER rustscan
ENTRYPOINT ["/usr/local/bin/rustscan"]
ENTRYPOINT [ "/usr/local/bin/rustscan" ]
+134 -71
View File
@@ -5,13 +5,13 @@
<a href="https://github.com/RustScan/RustScan#-usage">Usage Guide</a>
⬅️
<br>
<img src="pictures/rustscan.png">
<img src="pictures/rustscan.png" height=400px width=400px>
</p>
<p align="center">
<u><b> Turns a 17 minutes Nmap scan into 19 seconds. </b></u><br> Find all open ports <b>fast</b> with RustScan, automatically pipe them into Nmap.
</p>
<p align="center">
<img alt="AUR version" src="https://img.shields.io/aur/version/rustscan-bin">
<img alt="AUR version" src="https://img.shields.io/aur/version/rustscan">
<img src="https://img.shields.io/badge/Built%20with-Rust-Purple">
<img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/w/brandonskerritt/rustscan">
<img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/rustscan/rustscan/total?label=GitHub%20Downloads">
@@ -21,14 +21,15 @@
</p>
<hr>
| <p align="center"><a href="https://hub.docker.com/r/cmnatic/rustscan">🐋 Docker (Recommended) </a></p> | <p align="center"><a href="https://github.com/RustScan/RustScan/releases">👩‍💻 Kali / Debian </p> | <p align="center"><a href="https://aur.archlinux.org/packages/rustscan/">🏗️ Arch </a></p> | <p align="center"><a href="https://crates.io/crates/rustscan">🔧 Cargo (Universal) </a></p> |
| ---- | ---- | ---- | --- |
| <p align="center"><img src="pictures/docker.png" /></p> | <p align="center"><img src="pictures/kali.png" /></p> | <p align="center"><img src="pictures/arch.png" /></p> | <p align="center"><img src="pictures/rust.png" /></p>
| `docker pull 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`
| <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="https://github.com/RustScan/RustScan/blob/master/pictures/docker.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/kali.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/arch.png?raw=true" /></p> | <p align="center"><img src="https://github.com/RustScan/RustScan/blob/master/pictures/rust.png?raw=true" /></p> |
| `docker pull rustscan/rustscan:alpine` <p>[Usage](https://github.com/RustScan/RustScan#docker-whale) | [Read the install guide](https://github.com/brandonskerritt/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `cargo install rustscan` |
<hr>
# 🤔 What is this?
1. Find ports quickly using Rustscan (**3 seconds at its fastest**).
2. Automatically runs `nmap` on those ports.
3. ???
@@ -42,8 +43,8 @@
</tr>
<tr>
<th>Gif</th>
<td><img src="pictures/with_rustscan.gif" alt="The guy she tells you not to worry about"></td>
<td><img src="pictures/without_rustscan.gif" alt="You"></td>
<td><img src="https://github.com/RustScan/RustScan/blob/master/pictures/with_rustscan.gif?raw=true" alt="The guy she tells you not to worry about"></td>
<td><img src="https://github.com/RustScan/RustScan/blob/master/pictures/without_rustscan.gif?raw=true" alt="You"></td>
</tr>
<tr>
<th>Time</th>
@@ -57,29 +58,32 @@
RustScans **only** job is to reduce the friction between finding open ports and inputting them into nmap.
# ✨ Features
* Scans all 65k ports in **8 seconds** (on 10k batch size).
* 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
- Scans all 65k ports in **8 seconds** (on 10k batch size).
- 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)
| Installation Guide | Documentation | Discord |
| -------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------- |
| 📖 [Installation Guide](https://github.com/RustScan/RustScan#-full-installation-guide) | 📚 [Documentation](https://rustscan.github.io/RustScan/) | 🦜 [Discord](https://discord.gg/GFrQsGy) |
## 🙋 Table of Contents
* 📖 [Installation Guide](https://github.com/RustScan/RustScan#-full-installation-guide)
* 🐋 [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)
- 📖 [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?
![gif](pictures/8seconds.gif)
![gif](https://github.com/RustScan/RustScan/blob/master/pictures/8seconds.gif?raw=true)
**RustScan running in 8 seconds and finding all open ports out of 65k.**
@@ -87,11 +91,12 @@ Why spend time running fast scans and manually copying the ports, or waiting for
| **Name** | RustScan | Nmap | Masscan |
| ------------------------------------------------------------------------------------------ | -------- | ---- | ------- |
| Fast | ✅ | ❌ | ✅ |
| Actually useful | ❌ | ✅ | ❌ |
| Realises it's not useful, and pipes the only useful data into the only useful port scanner | ✅ | ❌ | ❌ |
| Fast | ✅ | ❌ | ✅ |
| Actually useful | ❌ | ✅ | ❌ |
| Realises it's not useful, and pipes the only useful data into the only useful port scanner | ✅ | ❌ | ❌ |
# 📖 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).
The easiest way to install RustScan is to use one of the packages provided for your system, such as HomeBrew or Yay for Arch Linux.
@@ -115,28 +120,31 @@ 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.
- 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:
```
```bash
docker run -it --rm --name rustscan rustscan/rustscan:alpine <rustscan arguments here> <ip address to scan>
```
@@ -146,30 +154,33 @@ Once done, you will no longer need to re-download the image (except when RustSca
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>'
```bash
alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:alpine'
```
Then we can:
```
```bash
rustscan 127.0.0.1 -t 500 -b 1500 -- -A
```
#### To build your own image:
Download the repo:
```
```bash
git clone https://github.com/RustScan/RustScan.git
```
Ensure you navigate to the download location of the repo:
```
```bash
cd /path/to/download/RustScan
```
Build away!
```
```bash
docker build -t <yourimagename> .
```
@@ -179,13 +190,13 @@ docker build -t <yourimagename> .
Tap the brew:
```
```bash
brew tap brandonskerritt/rustscan
```
Install it:
```
```bash
brew install rustscan
```
@@ -198,39 +209,41 @@ brew install 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)
- [OpenSuse](https://software.opensuse.org/package/rustscan?search_term=rustscan)
- [Fedora/CentOS](https://copr.fedorainfracloud.org/coprs/atim/rustscan/)
[![Packaging status](https://repology.org/badge/vertical-allrepos/rustscan.svg)](https://repology.org/project/rustscan/versions)
# 🤸 Usage
```
rustscan -h
```
```console
$ rustscan -h
```
rustscan 1.7.1
Fast Port Scanner built in Rust. WARNING Do not use this program against sensitive infrastructure since the specified
server may not be able to handle this many socket connections at once. - Discord https://discord.gg/GFrQsGy - GitHub
https://github.com/RustScan/RustScan
USAGE:
rustscan [FLAGS] [OPTIONS] <ips>... [-- <command>...]
rustscan [FLAGS] [OPTIONS] [ips-or-hosts]... [-- <command>...]
FLAGS:
-a, --accessible
-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
--accessible Accessible mode. Turns off features which negatively affect screen readers
-h, --help Prints help information
-i, --ignore-config Whether to ignore the configuration file or not
-q, --quiet Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file
-V, --version Prints version information
OPTIONS:
-b, --batch-size <batch-size> The batch size for port scanning, it increases or slows the speed of scanning.
Depends on the open file limit of your OS. If you do 65535 it will do every port
at the same time. Although, your OS may not support this [default: 4500]
-p, --ports <ports>... A list of comma separed ports to be scanned. Example: 80,443,8080
-r, --range <range> A range of ports with format start-end. Example: 1-1000
--scan-order <scan-order> The order of scanning to be performed. The "serial" option will scan ports in
ascending order while the "random" option will scan ports randomly [default:
serial] [possible values: Serial, Random]
@@ -238,11 +251,11 @@ OPTIONS:
-u, --ulimit <ulimit> Automatically ups the ULIMIT with the value you provided
ARGS:
<ips>... A list of comma separated IP addresses to be scanned
<command>... The Nmap arguments to run. To use the argument -A, end RustScan's args with '-- -A'. Example:
'rustscan -T 1500 127.0.0.1 -- -A -sC'. This command adds -Pn -vvv -p $PORTS automatically to
nmap. For things like --script '(safe and vuln)' enclose it in quotations marks \"'(safe and
vuln)'\"")
<ips-or-hosts>... A list of comma separated IP addresses or hosts to be scanned
<command>... The Nmap arguments to run. To use the argument -A, end RustScan's args with '-- -A'.
Example: 'rustscan -T 1500 127.0.0.1 -- -A -sC'. This command adds -Pn -vvv -p $PORTS
automatically to nmap. For things like --script '(safe and vuln)' enclose it in quotations
marks \"'(safe and vuln)'\"")
```
The format is `rustscan -b 500 -T 1500 192.168.0.1` to scan 192.168.0.1 with 500 batch size with a timeout of 1500ms. The timeout is how long RustScan waits for a response until it assumes the port is closed.
@@ -251,6 +264,37 @@ The batch size determines how fast RustScan is. Set it to 65k, and it will scan
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.
## Configuration file
This binary accepts a configuration file that is read from the home directory of the user. It follows the TOML format
and accepts the following fields:
- `ips_or_hosts`
- `ports`
- `range`
- `scan_order`
- `command`
- `accessible`
- `quiet`
- `batch-size`
- `timeout`
- `ulimit`
### Format example
```toml
ips_or_hosts = ["127.0.0.1", "192.168.0.1", "www.google.com"]
command = ["-A"]
ports = [80, 443, 8080]
range = { start = 1, end = 10 }
quiet = false
accessible = true
scan_order = "Serial"
batch_size = 1000
timeout = 1000
ulimit = 1000
```
## ⚠️ WARNING
This program, by default, scans 5000 ports at a time (5000 per second).
@@ -258,16 +302,18 @@ 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.
There are 2 ways to deal with this;
1. Decrease batch size
`rustscan -b 10` will run 10 port scans for 1 second, and then another 10 for 1 second and so on.
`rustscan -b 10` will run 10 port scans for 1 second, and then another 10 for 1 second and so on.
2. Increase timeout
`rustscan -T 5000` will mean RustScan waits 5 seconds until it scans the next ports.
`rustscan -T 5000` will mean RustScan waits 5 seconds until it scans the next ports.
You can also use both of these at the same time, to make it as slow or as fast as you want. A fun favourite is 65535 batch size with 1 second timeout. Theoretically, this scans all 65535 ports in 1 second.
**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 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.
@@ -279,6 +325,7 @@ RustScan does not automatically create defaults (other than 5000) like Nmap does
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
2. Increase open file limit
@@ -286,7 +333,7 @@ Decreasing batch size slows down the program, so as long as it isn't too drastic
Run these 3 commands:
```
```bash
ulimit -a
ulimit -Hn
ulimit -Sn
@@ -300,7 +347,7 @@ Increasing the open file limit increases speed, but poses danger. Although, **op
To open more, set the ulimit to a higher number:
```
```bash
ulimit -n 5000
```
@@ -320,6 +367,7 @@ The best way is to use it on a host computer, in Docker, or in a VM that isn't W
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.
## 🔌 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`.
@@ -327,13 +375,14 @@ RustScan automatically runs `nmap -vvv -p $PORTS $IP`. To make it run `-A`, exec
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
- Batch size
This increases speed, by allowing us to process more at once. Something experimental I am working on is changing the open file limit. You can do this manually with `ulimit -n 70000` and then running rustscan with `-b 65535`. This _should_ scan all 65535 ports at the exact same time. But this is extremely experimental.
For non-experimental speed increases, slowly increase the batch size until it no longer gets open ports, or it breaks.
* Accuracy (and some speed)
- Accuracy (and some speed)
To increase accuracy, the easiest way is to increase the timeout. The default is 1.5 seconds, by setting it to 4 seconds (4000) we are telling RustScan "if we do not hear back from a port in 4 seconds, assume it is closed".
@@ -350,19 +399,21 @@ Before contributing, read our [code of conduct](https://github.com/RustScan/Rust
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)
- 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
- Fork the repo
- Make changes
- Pull request to the repo
And then comment on the issue that you've done.
@@ -373,14 +424,17 @@ If you have any feature suggestions or bugs, leave a GitHub issue. We welcome an
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! :)
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)
## Contributors ✨
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-17-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -403,11 +457,20 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="https://tgotwig.me"><img src="https://avatars0.githubusercontent.com/u/30773779?v=4" width="100px;" alt=""/><br /><sub><b>Thomas Gotwig</b></sub></a><br /><a href="#platform-TGotwig" title="Packaging/porting to new platform">📦</a></td>
<td align="center"><a href="https://github.com/remigourdon"><img src="https://avatars3.githubusercontent.com/u/2874133?v=4" width="100px;" alt=""/><br /><sub><b>Rémi Gourdon</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=remigourdon" title="Documentation">📖</a> <a href="https://github.com/RustScan/RustScan/commits?author=remigourdon" title="Code">💻</a></td>
<td align="center"><a href="https://cmnatic.co.uk"><img src="https://avatars3.githubusercontent.com/u/4163116?v=4" width="100px;" alt=""/><br /><sub><b>Ben (CMNatic)</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=cmnatic" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/commits?author=cmnatic" title="Documentation">📖</a> <a href="#design-cmnatic" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/Ferryistaken"><img src="https://avatars3.githubusercontent.com/u/47927670?v=4" width="100px;" alt=""/><br /><sub><b>Alessandro Ferrari</b></sub></a><br /><a href="#content-Ferryistaken" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/Phenomite"><img src="https://avatars2.githubusercontent.com/u/8285537?v=4" width="100px;" alt=""/><br /><sub><b>Phenomite</b></sub></a><br /><a href="#content-Phenomite" title="Content">🖋</a></td>
<td align="center"><a href="https://supersandro.de/"><img src="https://avatars2.githubusercontent.com/u/7258858?v=4" width="100px;" alt=""/><br /><sub><b>Sandro</b></sub></a><br /><a href="#content-SuperSandro2000" title="Content">🖋</a> <a href="https://github.com/RustScan/RustScan/issues?q=author%3ASuperSandro2000" title="Bug reports">🐛</a> <a href="https://github.com/RustScan/RustScan/commits?author=SuperSandro2000" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://swag.lgbt"><img src="https://avatars2.githubusercontent.com/u/25358963?v=4" width="100px;" alt=""/><br /><sub><b>Cass</b></sub></a><br /><a href="#platform-caass" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/RustScan/RustScan/commits?author=caass" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/issues?q=author%3Acaass" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://github.com/niklasmohrin"><img src="https://avatars0.githubusercontent.com/u/47574893?v=4" width="100px;" alt=""/><br /><sub><b>Niklas Mohrin</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=niklasmohrin" title="Documentation">📖</a></td>
<td align="center"><a href="https://liberapay.com/Artem4/"><img src="https://avatars0.githubusercontent.com/u/5614476?v=4" width="100px;" alt=""/><br /><sub><b>Artem Polishchuk</b></sub></a><br /><a href="#platform-tim77" title="Packaging/porting to new platform">📦</a></td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
+1004
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 29 KiB

+359
View File
@@ -0,0 +1,359 @@
use serde_derive::Deserialize;
use std::fs;
use structopt::{clap::arg_enum, StructOpt};
const LOWEST_PORT_NUMBER: u16 = 1;
const TOP_PORT_NUMBER: u16 = 65535;
arg_enum! {
/// Represents the strategy in which the port scanning will run.
/// - Serial will run from start to end, for example 1 to 1_000.
/// - Random will randomize the order in which ports will be scanned.
#[derive(Deserialize, Debug, StructOpt, Clone, PartialEq)]
pub enum ScanOrder {
Serial,
Random,
}
}
/// Represents the range of ports to be scanned.
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct PortRange {
pub start: u16,
pub end: u16,
}
fn parse_range(input: &str) -> Result<PortRange, String> {
let range = input
.split("-")
.map(|x| x.parse::<u16>())
.collect::<Result<Vec<u16>, std::num::ParseIntError>>();
if range.is_err() {
return Err(String::from(
"the range format must be 'start-end'. Example: 1-1000.",
));
}
match range.unwrap().as_slice() {
[start, end] => Ok(PortRange {
start: *start,
end: *end,
}),
_ => Err(String::from(
"the range format must be 'start-end'. Example: 1-1000.",
)),
}
}
#[derive(StructOpt, Debug)]
#[structopt(name = "rustscan", setting = structopt::clap::AppSettings::TrailingVarArg)]
/// Fast Port Scanner built in Rust.
/// 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
pub struct Opts {
/// A list of comma separated IP addresses or hosts to be scanned.
#[structopt(use_delimiter = true)]
pub ips_or_hosts: Vec<String>,
/// A list of comma separed ports to be scanned. Example: 80,443,8080.
#[structopt(short, long, use_delimiter = true)]
pub ports: Option<Vec<u16>>,
/// A range of ports with format start-end. Example: 1-1000.
#[structopt(short, long, conflicts_with = "ports", parse(try_from_str = parse_range))]
pub range: Option<PortRange>,
/// Whether to ignore the configuration file or not.
#[structopt(short, long)]
pub no_config: bool,
/// Quiet mode. Only output the ports. No Nmap. Useful for grep or outputting to a file.
#[structopt(short, long)]
pub quiet: bool,
/// Accessible mode. Turns off features which negatively affect screen readers.
#[structopt(long)]
pub accessible: bool,
/// Turns off Nmap.
#[structopt(long)]
pub no_nmap: 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")]
pub batch_size: u16,
/// The timeout in milliseconds before a port is assumed to be closed.
#[structopt(short, long, default_value = "1500")]
pub timeout: u32,
/// Automatically ups the ULIMIT with the value you provided.
#[structopt(short, long)]
pub 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")]
pub 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)]
pub command: Vec<String>,
}
impl Opts {
pub fn read() -> Self {
let mut opts = Opts::from_args();
if opts.ports.is_none() && opts.range.is_none() {
opts.range = Some(PortRange {
start: LOWEST_PORT_NUMBER,
end: TOP_PORT_NUMBER,
});
}
opts
}
/// Reads the command line arguments into an Opts struct and merge
/// values found within the user configuration file.
pub fn merge(&mut self, config: &Config) {
if !self.no_config {
self.merge_required(&config);
self.merge_optional(&config);
}
}
fn merge_required(&mut self, config: &Config) {
macro_rules! merge_required {
($($field: ident),+) => {
$(
if let Some(e) = &config.$field {
self.$field = e.clone();
}
)+
}
}
merge_required!(
ips_or_hosts,
quiet,
accessible,
batch_size,
timeout,
scan_order,
command
);
}
fn merge_optional(&mut self, config: &Config) {
macro_rules! merge_optional {
($($field: ident),+) => {
$(
if config.$field.is_some() {
self.$field = config.$field.clone();
}
)+
}
}
merge_optional!(ports, range, ulimit);
}
}
/// Struct used to deserialize the options specified within our config file.
/// These will be further merged with our command line arguments in order to
/// generate the final Opts struct.
#[derive(Debug, Deserialize)]
pub struct Config {
ips_or_hosts: Option<Vec<String>>,
ports: Option<Vec<u16>>,
range: Option<PortRange>,
quiet: Option<bool>,
accessible: Option<bool>,
batch_size: Option<u16>,
timeout: Option<u32>,
no_nmap: Option<bool>,
ulimit: Option<rlimit::rlim>,
scan_order: Option<ScanOrder>,
command: Option<Vec<String>>,
}
impl Config {
/// Reads the configuration file with TOML format and parses it into a
/// Config struct.
///
/// # Format
///
/// ips_or_hosts = ["127.0.0.1", "127.0.0.1"]
/// ports = [80, 443, 8080]
/// quiet = true
/// scan_order: "Serial"
///
pub fn read() -> Self {
let path = match dirs::home_dir() {
Some(mut path) => {
path.push(".rustscan.toml");
path
}
None => panic!("Could not infer config file path."),
};
let contents = match fs::read_to_string(&path) {
Ok(content) => content,
Err(_) => {
println!("Could not find configation file at {:?}", &path);
String::new()
}
};
let config: Config = match toml::from_str(&contents) {
Ok(config) => config,
Err(e) => {
println!("Found {} in configuration file.\nAborting scan.\n", e);
std::process::exit(1);
}
};
config
}
}
#[cfg(test)]
mod tests {
use super::{Config, Opts, PortRange, ScanOrder};
#[test]
fn opts_no_merge_when_config_is_ignored() {
let mut opts = Opts {
ips_or_hosts: vec![],
ports: None,
range: None,
quiet: false,
batch_size: 0,
timeout: 0,
ulimit: None,
command: vec![],
accessible: false,
no_nmap: false,
scan_order: ScanOrder::Serial,
no_config: true,
};
let config = Config {
ips_or_hosts: Some(vec!["127.0.0.1".to_owned()]),
ports: None,
range: None,
quiet: Some(true),
batch_size: Some(25_000),
timeout: Some(1_000),
ulimit: None,
no_nmap: Some(false),
command: Some(vec!["-A".to_owned()]),
accessible: Some(true),
scan_order: Some(ScanOrder::Random),
};
opts.merge(&config);
assert_eq!(opts.ips_or_hosts, vec![] as Vec<String>);
assert_eq!(opts.quiet, false);
assert_eq!(opts.accessible, false);
assert_eq!(opts.timeout, 0);
assert_eq!(opts.command, vec![] as Vec<String>);
assert_eq!(opts.scan_order, ScanOrder::Serial);
}
#[test]
fn opts_merge_required_arguments() {
let mut opts = Opts {
ips_or_hosts: vec![],
ports: None,
range: None,
quiet: false,
batch_size: 0,
timeout: 0,
ulimit: None,
command: vec![],
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
};
let config = Config {
ips_or_hosts: Some(vec!["127.0.0.1".to_owned()]),
ports: None,
no_nmap: Some(false),
range: None,
quiet: Some(true),
batch_size: Some(25_000),
timeout: Some(1_000),
ulimit: None,
command: Some(vec!["-A".to_owned()]),
accessible: Some(true),
scan_order: Some(ScanOrder::Random),
};
opts.merge_required(&config);
assert_eq!(opts.ips_or_hosts, config.ips_or_hosts.unwrap());
assert_eq!(opts.quiet, config.quiet.unwrap());
assert_eq!(opts.timeout, config.timeout.unwrap());
assert_eq!(opts.command, config.command.unwrap());
assert_eq!(opts.accessible, config.accessible.unwrap());
assert_eq!(opts.scan_order, config.scan_order.unwrap());
}
#[test]
fn opts_merge_optional_arguments() {
let mut opts = Opts {
ips_or_hosts: vec![],
ports: None,
range: None,
quiet: false,
batch_size: 0,
timeout: 0,
ulimit: None,
command: vec![],
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
};
let config = Config {
ips_or_hosts: None,
ports: Some(vec![80, 403]),
range: Some(PortRange {
start: 1,
end: 1_000,
}),
quiet: None,
batch_size: None,
timeout: None,
no_nmap: Some(false),
ulimit: Some(1_000),
command: None,
accessible: None,
scan_order: None,
};
opts.merge_optional(&config);
assert_eq!(opts.ports, config.ports);
assert_eq!(opts.range, config.range);
assert_eq!(opts.ulimit, config.ulimit);
}
}
+47 -69
View File
@@ -2,6 +2,9 @@ extern crate shell_words;
mod tui;
mod input;
use input::{Config, Opts, PortRange, ScanOrder};
mod scanner;
use scanner::Scanner;
@@ -13,17 +16,16 @@ use colorful::Colorful;
use futures::executor::block_on;
use rlimit::Resource;
use rlimit::{getrlimit, setrlimit};
use std::collections::HashMap;
use std::net::ToSocketAddrs;
use std::process::Command;
use std::str::FromStr;
use std::{net::IpAddr, net::ToSocketAddrs, time::Duration};
use structopt::{clap::arg_enum, StructOpt};
use std::{net::IpAddr, time::Duration};
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
@@ -32,73 +34,18 @@ 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() {
env_logger::init();
info!("Starting up");
let opts = Opts::from_args();
info!("Mains() `opts` arguments are {:?}", opts);
let mut opts: Opts = Opts::read();
let config = Config::read();
opts.merge(&config);
dbg!(&opts);
info!("Main() `opts` arguments are {:?}", opts);
if !opts.quiet && !opts.accessible {
print_opening();
@@ -119,7 +66,7 @@ fn main() {
batch_size,
Duration::from_millis(opts.timeout.into()),
opts.quiet,
PortStrategy::pick(LOWEST_PORT_NUMBER, TOP_PORT_NUMBER, opts.scan_order),
PortStrategy::pick(opts.range, opts.ports, opts.scan_order),
);
let scan_result = block_on(scanner.run());
@@ -142,7 +89,7 @@ fn main() {
let x = format!("{} Looks like I didn't find any open ports for {:?}. This is usually caused by a high batch size.
\n*I used {} batch size, consider lowering to {} with {} or a comfortable number for your system.
\n Alternatively, increase the timeout if your ping is high. Rustscan -t 2000 for 2000 second timeout.\n",
\n Alternatively, increase the timeout if your ping is high. Rustscan -t 2000 for 2000 milliseconds (2s) timeout.\n",
"ERROR",
ip,
opts.batch_size,
@@ -223,7 +170,6 @@ fn build_nmap_arguments<'a>(
is_ipv6: bool,
) -> Vec<&'a str> {
let mut arguments: Vec<&str> = user_args.iter().map(AsRef::as_ref).collect();
arguments.push("-A");
arguments.push("-vvv");
if is_ipv6 {
@@ -281,7 +227,7 @@ fn infer_batch_size(opts: &Opts, ulimit: rlimit::rlim) -> u16 {
// Adjust the batch size when the ulimit value is lower than the desired batch size
if ulimit < batch_size {
warning!("File limit is lower than default batch size. Consider upping with --ulimt. May cause harm to sensitive servers",
warning!("File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers",
opts.quiet
);
@@ -322,6 +268,8 @@ mod tests {
fn batch_size_lowered() {
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
@@ -329,6 +277,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let batch_size = infer_batch_size(&opts, 120);
@@ -339,6 +289,8 @@ mod tests {
fn batch_size_lowered_average_size() {
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
@@ -346,6 +298,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let batch_size = infer_batch_size(&opts, 9_000);
@@ -357,6 +311,8 @@ mod tests {
// to ULIMIT - 100
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
@@ -364,6 +320,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let batch_size = infer_batch_size(&opts, 5_000);
@@ -374,6 +332,8 @@ mod tests {
// ulimit == batch_size
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
@@ -381,6 +341,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let batch_size = adjust_ulimit_size(&opts);
@@ -396,6 +358,8 @@ mod tests {
fn test_high_ulimit_no_quiet_mode() {
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned()],
ports: None,
range: None,
quiet: false,
batch_size: 10,
timeout: 1_000,
@@ -403,6 +367,8 @@ mod tests {
command: Vec::new(),
accessible: true,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
infer_batch_size(&opts, 1_000_000);
@@ -414,6 +380,8 @@ mod tests {
fn parse_correct_ips_or_hosts() {
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned(), "google.com".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 10,
timeout: 1_000,
@@ -421,6 +389,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let ips = parse_ips(&opts);
@@ -431,6 +401,8 @@ mod tests {
fn parse_correct_and_incorrect_ips_or_hosts() {
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned(), "im_wrong".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 10,
timeout: 1_000,
@@ -438,6 +410,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let ips = parse_ips(&opts);
@@ -448,6 +422,8 @@ mod tests {
fn parse_incorrect_ips_or_hosts() {
let opts = Opts {
ips_or_hosts: vec!["im_wrong".to_owned(), "300.10.1.1".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 10,
timeout: 1_000,
@@ -455,6 +431,8 @@ mod tests {
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_config: false,
no_nmap: false,
};
let ips = parse_ips(&opts);
+53 -10
View File
@@ -1,5 +1,7 @@
mod range_iterator;
use super::ScanOrder;
use super::{PortRange, ScanOrder};
use rand::seq::SliceRandom;
use rand::thread_rng;
use range_iterator::RangeIterator;
/// Represents options of port scanning.
@@ -7,20 +9,41 @@ use range_iterator::RangeIterator;
/// Right now all these options involve ranges, but in the future
/// it will also contain custom lists of ports.
pub enum PortStrategy {
Manual(Vec<u16>),
Serial(SerialRange),
Random(RandomRange),
}
impl PortStrategy {
pub fn pick(start: u16, end: u16, scan_type: ScanOrder) -> Self {
match scan_type {
ScanOrder::Serial => PortStrategy::Serial(SerialRange { start, end }),
ScanOrder::Random => PortStrategy::Random(RandomRange { start, end }),
pub fn pick(range: Option<PortRange>, ports: Option<Vec<u16>>, order: ScanOrder) -> Self {
match order {
ScanOrder::Serial if ports.is_none() => {
let range = range.as_ref().unwrap();
PortStrategy::Serial(SerialRange {
start: range.start,
end: range.end,
})
}
ScanOrder::Random if ports.is_none() => {
let range = range.as_ref().unwrap();
PortStrategy::Random(RandomRange {
start: range.start,
end: range.end,
})
}
ScanOrder::Serial => PortStrategy::Manual(ports.unwrap()),
ScanOrder::Random => {
let mut rng = thread_rng();
let mut ports = ports.unwrap();
ports.shuffle(&mut rng);
PortStrategy::Manual(ports)
}
}
}
pub fn order(&self) -> Vec<u16> {
match self {
PortStrategy::Manual(ports) => ports.to_vec(),
PortStrategy::Serial(range) => range.generate(),
PortStrategy::Random(range) => range.generate(),
}
@@ -71,18 +94,20 @@ impl RangeOrder for RandomRange {
#[cfg(test)]
mod tests {
use super::PortStrategy;
use crate::ScanOrder;
use crate::{PortRange, ScanOrder};
#[test]
fn serial_strategy() {
let strategy = PortStrategy::pick(1, 100, ScanOrder::Serial);
fn serial_strategy_with_range() {
let range = PortRange { start: 1, end: 100 };
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Serial);
let result = strategy.order();
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
assert_eq!(expected_range, result);
}
#[test]
fn random_strategy() {
let strategy = PortStrategy::pick(1, 100, ScanOrder::Random);
fn random_strategy_with_range() {
let range = PortRange { start: 1, end: 100 };
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
let mut result = strategy.order();
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
assert_ne!(expected_range, result);
@@ -90,4 +115,22 @@ mod tests {
result.sort();
assert_eq!(expected_range, result);
}
#[test]
fn serial_strategy_with_ports() {
let strategy = PortStrategy::pick(None, Some(vec![80, 443]), ScanOrder::Serial);
let result = strategy.order();
assert_eq!(vec![80, 443], result);
}
#[test]
fn random_strategy_with_ports() {
let strategy = PortStrategy::pick(None, Some((1..10).collect()), ScanOrder::Random);
let mut result = strategy.order();
let expected_range = (1..10).into_iter().collect::<Vec<u16>>();
assert_ne!(expected_range, result);
result.sort();
assert_eq!(expected_range, result);
}
}
+476
View File
@@ -0,0 +1,476 @@
extern crate shell_words;
mod tui;
mod input;
use input::{Config, Opts, PortRange, ScanOrder};
mod scanner;
use scanner::Scanner;
mod port_strategy;
use port_strategy::PortStrategy;
use colorful::Color;
use colorful::Colorful;
use futures::executor::block_on;
use rlimit::Resource;
use rlimit::{getrlimit, setrlimit};
use std::collections::HashMap;
use std::net::ToSocketAddrs;
use std::process::Command;
use std::str::FromStr;
use std::{net::IpAddr, time::Duration};
extern crate colorful;
extern crate dirs;
// 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;
#[cfg(not(tarpaulin_include))]
/// Faster Nmap scanning with Rust
/// If you're looking for the actual scanning, check out the module Scanner
fn main() {
env_logger::init();
let mut opts: Opts = Opts::read();
let config = Config::read();
opts.merge(&config);
dbg!(&opts);
info!("Main() `opts` arguments are {:?}", opts);
if !opts.quiet && !opts.accessible {
print_opening();
}
let ips: Vec<IpAddr> = parse_ips(&opts);
if ips.is_empty() {
warning!("No IPs could be resolved, aborting scan.", false);
std::process::exit(1);
}
let ulimit: rlimit::rlim = adjust_ulimit_size(&opts);
let batch_size: u16 = infer_batch_size(&opts, ulimit);
let scanner = Scanner::new(
&ips,
batch_size,
Duration::from_millis(opts.timeout.into()),
opts.quiet,
PortStrategy::pick(opts.range, opts.ports, 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 milliseconds (2s) 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();
// 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;
} else if opts.no_nmap {
continue;
} else {
detail!("Starting Nmap", opts.quiet);
}
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("-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 --ulimit. 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()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
ignore_config: false,
no_nmap: false,
no_config: false,
};
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()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
ignore_config: false,
no_nmap: false,
no_config: false,
};
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()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
no_nmap: false,
scan_order: ScanOrder::Serial,
no_config: false,
ignore_config: false,
ignore_config: false,
no_config: false,
};
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()],
ports: None,
range: None,
quiet: true,
batch_size: 50_000,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
ignore_config: false,
no_nmap: false,
no_config: false,
};
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()],
ports: None,
range: None,
quiet: false,
batch_size: 10,
timeout: 1_000,
ulimit: None,
command: Vec::new(),
accessible: true,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
ignore_config: false,
no_nmap: false,
no_config: false,
};
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()],
ports: None,
range: None,
quiet: true,
batch_size: 10,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
ignore_config: false,
no_nmap: false,
no_config: false,
};
let ips = parse_ips(&opts);
assert_eq!(2, ips.len());
}
#[test]
fn parse_correct_and_incorrect_ips_or_hosts() {
let opts = Opts {
ips_or_hosts: vec!["127.0.0.1".to_owned(), "im_wrong".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 10,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
ignore_config: false,
no_nmap: false,
no_config: false,
};
let ips = parse_ips(&opts);
assert_eq!(1, ips.len());
}
#[test]
fn parse_incorrect_ips_or_hosts() {
let opts = Opts {
ips_or_hosts: vec!["im_wrong".to_owned(), "300.10.1.1".to_owned()],
ports: None,
range: None,
quiet: true,
batch_size: 10,
timeout: 1_000,
ulimit: Some(2_000),
command: Vec::new(),
accessible: false,
scan_order: ScanOrder::Serial,
no_nmap: false,
no_config: false,
ignore_config: false,
};
let ips = parse_ips(&opts);
ignore_config: false,
no_nmap: false,
no_config: false,
};
let ips = parse_ips(&opts);
assert_eq!(0, ips.len());
}
}
+26 -6
View File
@@ -139,7 +139,7 @@ impl Scanner {
#[cfg(test)]
mod tests {
use super::*;
use crate::ScanOrder;
use crate::{PortRange, ScanOrder};
use async_std::task::block_on;
use std::{net::IpAddr, time::Duration};
@@ -147,7 +147,11 @@ mod tests {
fn scanner_runs() {
// Makes sure the program still runs and doesn't panic
let addrs = vec!["127.0.0.1".parse::<IpAddr>().unwrap()];
let strategy = PortStrategy::pick(1, 1_000, ScanOrder::Random);
let range = PortRange {
start: 1,
end: 1_000,
};
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
block_on(scanner.run());
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
@@ -157,7 +161,11 @@ mod tests {
fn ipv6_scanner_runs() {
// Makes sure the program still runs and doesn't panic
let addrs = vec!["::1".parse::<IpAddr>().unwrap()];
let strategy = PortStrategy::pick(1, 1_000, ScanOrder::Random);
let range = PortRange {
start: 1,
end: 1_000,
};
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
block_on(scanner.run());
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
@@ -166,7 +174,11 @@ mod tests {
#[test]
fn quad_zero_scanner_runs() {
let addrs = vec!["0.0.0.0".parse::<IpAddr>().unwrap()];
let strategy = PortStrategy::pick(1, 1_000, ScanOrder::Random);
let range = PortRange {
start: 1,
end: 1_000,
};
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
block_on(scanner.run());
assert_eq!(1, 1);
@@ -174,7 +186,11 @@ mod tests {
#[test]
fn google_dns_runs() {
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
let strategy = PortStrategy::pick(400, 445, ScanOrder::Random);
let range = PortRange {
start: 400,
end: 445,
};
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
block_on(scanner.run());
assert_eq!(1, 1);
@@ -185,7 +201,11 @@ mod tests {
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
// mac should have this automatically scaled down
let strategy = PortStrategy::pick(400, 600, ScanOrder::Random);
let range = PortRange {
start: 400,
end: 600,
};
let strategy = PortStrategy::pick(Some(range), None, ScanOrder::Random);
let scanner = Scanner::new(&addrs, 10, Duration::from_millis(100), true, strategy);
block_on(scanner.run());
assert_eq!(1, 1);