Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08904c0bf2 | ||
|
|
bc5b2eea7e | ||
|
|
bda392c9a7 | ||
|
|
3836480486 | ||
|
|
2291ba73d2 | ||
|
|
e0af8a306a | ||
|
|
cb0f4f7a92 | ||
|
|
402bea4b06 | ||
|
|
f44dda0360 | ||
|
|
965a173032 | ||
|
|
d95cae6677 | ||
|
|
2f92d5583a | ||
|
|
8d8da79640 | ||
|
|
e5b4a2f443 | ||
|
|
a0b877729e | ||
|
|
743fa1cad6 | ||
|
|
a0561d4728 | ||
|
|
b2a1bd2e7a | ||
|
|
87de96c3c4 | ||
|
|
8e21f3bf8c | ||
|
|
4019d1ff3a | ||
|
|
c004bd0527 | ||
|
|
cdc5bbd924 | ||
|
|
f41213047a | ||
|
|
2315ef2417 | ||
|
|
cb87d5b9ce | ||
|
|
92800678cd | ||
|
|
8e76a71a4c | ||
|
|
07fdea8471 | ||
|
|
8670bcc35f | ||
|
|
fbba9d16ca | ||
|
|
309d1ad660 | ||
|
|
ed48161bea | ||
|
|
f0d1aa2b9a | ||
|
|
ac93feddb5 | ||
|
|
1280fa1b47 | ||
|
|
6e731aaf93 | ||
|
|
9230165f8f | ||
|
|
818c80041b | ||
|
|
bce955212a | ||
|
|
41e0e8905f | ||
|
|
85f1699724 | ||
|
|
bafd0141df | ||
|
|
aba0f3c38c | ||
|
|
9e161d4f79 | ||
|
|
731b4079cf | ||
|
|
b4edc6cca6 | ||
|
|
4a7cbd701b | ||
|
|
f34ee8f5ef | ||
|
|
89c763789f | ||
|
|
5c48f1173a | ||
|
|
8d8ca1d4a0 | ||
|
|
8d8acd61e8 | ||
|
|
0ab3e53034 | ||
|
|
56493859cb | ||
|
|
2ef723ed96 | ||
|
|
e9288302ba | ||
|
|
8179511527 | ||
|
|
fbab4a4020 | ||
|
|
b425d15a98 | ||
|
|
fddda34465 | ||
|
|
125df4a2ed | ||
|
|
e670d11223 | ||
|
|
8453320586 | ||
|
|
99e9c834a9 | ||
|
|
dfbce6a636 | ||
|
|
916be1e4a2 | ||
|
|
90b4328fb6 | ||
|
|
76035d3379 | ||
|
|
4de31ecede | ||
|
|
ce9befaa1a | ||
|
|
5f6457ed7e | ||
|
|
12d3c91983 | ||
|
|
e0fd7a39dc | ||
|
|
ff0787e332 | ||
|
|
6ce6c0ce9e | ||
|
|
edf989ad5d | ||
|
|
3fede4c6db | ||
|
|
75b310f227 | ||
|
|
72c6ef1f1d | ||
|
|
83b23da32b | ||
|
|
3886a07775 | ||
|
|
f5064d3d5c | ||
|
|
22cbfc5826 | ||
|
|
a9d729300c | ||
|
|
4f5dd20e85 | ||
|
|
499ff66f36 | ||
|
|
61b87243d9 | ||
|
|
e069991c8d | ||
|
|
85c1cbf445 | ||
|
|
5551e64166 | ||
|
|
e0aa1423ad | ||
|
|
e609b3617c | ||
|
|
d0d8380296 | ||
|
|
d66ad34f8c | ||
|
|
2670ec43df | ||
|
|
90d0b03ba7 | ||
|
|
57eb3627b3 | ||
|
|
7e675b7557 | ||
|
|
fdeaa05f23 | ||
|
|
9fbf39f0cc | ||
|
|
14b6ea928d | ||
|
|
9452b1f922 | ||
|
|
ed12888e81 | ||
|
|
f68abcb955 | ||
|
|
4c91e8fb40 | ||
|
|
1d3e831066 | ||
|
|
ff6b1c40db | ||
|
|
5573d91a7b | ||
|
|
a8e56eec4b | ||
|
|
fb75c9d332 | ||
|
|
581ec27cb5 | ||
|
|
9673c8807d | ||
|
|
78818d6bc7 | ||
|
|
d0ff597be6 | ||
|
|
516ebe367a | ||
|
|
1e9660e4ff | ||
|
|
7b4dda5a19 | ||
|
|
a20b71191d | ||
|
|
18c5dd69e5 | ||
|
|
090264ac26 | ||
|
|
702681606f | ||
|
|
c58ac613c9 | ||
|
|
44b53fb877 | ||
|
|
99e72e4a16 | ||
|
|
e02073bd97 | ||
|
|
59bb72426d | ||
|
|
f48590c238 | ||
|
|
a3eb548ae9 | ||
|
|
050a8baf48 | ||
|
|
9b893dbf71 | ||
|
|
8245ccf31e | ||
|
|
301a656006 | ||
|
|
1639aadc54 | ||
|
|
c66bb50508 | ||
|
|
b490eb08be | ||
|
|
990e92dcbf | ||
|
|
883e89fe5e | ||
|
|
1b15cc2f71 | ||
|
|
18b574f6bb | ||
|
|
3fafee42b9 | ||
|
|
8b21dfd9a2 | ||
|
|
2f16729c54 | ||
|
|
785c2a4de1 | ||
|
|
80cc97bf83 | ||
|
|
7a825dae41 | ||
|
|
751c4daff6 | ||
|
|
f6214cfb27 | ||
|
|
a92eb80365 | ||
|
|
aeab4fb68c | ||
|
|
9ab15c9d8b | ||
|
|
7146c23ed9 | ||
|
|
f37f2d8f9d | ||
|
|
5a3a4d1c0c | ||
|
|
33e7cd44b6 | ||
|
|
8288856949 | ||
|
|
c3b96e262d | ||
|
|
a54868000e | ||
|
|
8f4acdf99a | ||
|
|
c637042906 | ||
|
|
766164588c | ||
|
|
b2be83c04a | ||
|
|
a3654b68eb | ||
|
|
1873a92951 | ||
|
|
c7a422b962 | ||
|
|
0eec9233bd | ||
|
|
0f18bb49a3 | ||
|
|
8b363571f1 | ||
|
|
e546608ff8 | ||
|
|
a7d1952b72 | ||
|
|
0fa11f6e51 | ||
|
|
d423f34e7a | ||
|
|
67726cc490 | ||
|
|
d5d39cacd3 | ||
|
|
52cbbeeac6 | ||
|
|
e17f9d0bb1 | ||
|
|
3329428766 | ||
|
|
23c049413b | ||
|
|
9858406271 | ||
|
|
6abb3737ec | ||
|
|
65b9cb1659 | ||
|
|
d2684baead | ||
|
|
5a40bc4182 | ||
|
|
f03f15a6d0 | ||
|
|
5f95b34250 | ||
|
|
4bca6ce337 | ||
|
|
9740d54912 | ||
|
|
f577cd23bd | ||
|
|
f16d704c86 | ||
|
|
e5368a31db | ||
|
|
01c2580672 | ||
|
|
200382a731 | ||
|
|
6a000762a5 | ||
|
|
e9b21338ef | ||
|
|
bd436221ca | ||
|
|
5d16af21f1 | ||
|
|
e331789598 | ||
|
|
bf56b10ff4 | ||
|
|
719c38bd32 | ||
|
|
a08fe2456d | ||
|
|
db1831c4b8 | ||
|
|
74e2ff026a | ||
|
|
897c1c4091 | ||
|
|
a9340bb622 | ||
|
|
9caed66265 | ||
|
|
eae6342255 | ||
|
|
328156c613 | ||
|
|
f53f6123bf | ||
|
|
7044174933 | ||
|
|
1ede04d539 | ||
|
|
e56456e779 | ||
|
|
484cf023d7 | ||
|
|
98763d43e0 | ||
|
|
a81c409ed4 | ||
|
|
c0f63e0534 | ||
|
|
137f8669fe | ||
|
|
c658b0ea70 | ||
|
|
1d68c842d9 | ||
|
|
6568203f46 | ||
|
|
0cfe82eb5d | ||
|
|
53512039d1 | ||
|
|
7b392f0d6d | ||
|
|
bf67019079 | ||
|
|
da27b17485 | ||
|
|
a528d41ac6 | ||
|
|
7686c25d0d | ||
|
|
9cf4177faa | ||
|
|
647b97b52c | ||
|
|
1b8b0b4478 | ||
|
|
c6dedc317a | ||
|
|
654488cbbc | ||
|
|
81701d4243 | ||
|
|
97eac2aa33 | ||
|
|
76ee4666b8 | ||
|
|
7e48f125dc | ||
|
|
56482fd8ff | ||
|
|
5e41472814 | ||
|
|
d99c811e93 | ||
|
|
ec003e4557 | ||
|
|
50ca069f20 | ||
|
|
9d2318ab9c | ||
|
|
9c7916f92a | ||
|
|
6d053ad199 | ||
|
|
7dedfb5fed | ||
|
|
748ad43db0 | ||
|
|
75523d03cb | ||
|
|
328226838e | ||
|
|
f78b114486 | ||
|
|
7bb1f7860b | ||
|
|
2fd63fa1f3 | ||
|
|
89047f4b26 | ||
|
|
f659b8dd3d | ||
|
|
6ab1c526cc | ||
|
|
b2eac63130 | ||
|
|
cdb55261b2 | ||
|
|
fb666f46bb | ||
|
|
96659dcd89 | ||
|
|
b4f9d9d228 | ||
|
|
30ab9523a2 | ||
|
|
ff2eea2015 | ||
|
|
aef842c2e3 | ||
|
|
2f9a54e2ba | ||
|
|
dfb451aacc | ||
|
|
0cd37b4ffe | ||
|
|
0c01dc0f17 | ||
|
|
b52a990ad0 | ||
|
|
1c88f98132 | ||
|
|
c8404781dc | ||
|
|
6617b2178b | ||
|
|
e2395f8ddc | ||
|
|
6ab43bf213 | ||
|
|
da3629cc7b | ||
|
|
af344becbc | ||
|
|
85b7f9fe7a | ||
|
|
9d1d064e71 | ||
|
|
343563818f | ||
|
|
bc77814d59 | ||
|
|
42b72ea114 | ||
|
|
d73c66482e | ||
|
|
b850868265 | ||
|
|
c77e45d478 | ||
|
|
82e3128641 | ||
|
|
679d1a787d | ||
|
|
813b6753c8 | ||
|
|
51df49836b | ||
|
|
2df98016c9 | ||
|
|
deb8bb3216 | ||
|
|
6ce8fe1afd | ||
|
|
8aa9a44949 | ||
|
|
416602dd02 | ||
|
|
a2e7125e03 | ||
|
|
10acad243c | ||
|
|
5d69339cc7 | ||
|
|
d8fd12694c | ||
|
|
7d4084d06c | ||
|
|
365be75689 | ||
|
|
5ea316c5db | ||
|
|
b363529045 | ||
|
|
ed378f7fc8 | ||
|
|
aa3c591016 | ||
|
|
ef893fdcb8 | ||
|
|
b78a8ad0af | ||
|
|
7ad7e34abc | ||
|
|
e41393b4ad | ||
|
|
6d72037974 | ||
|
|
66486b2467 | ||
|
|
4b085d97f2 | ||
|
|
4785b75f9f | ||
|
|
3951c25dff | ||
|
|
071c437206 | ||
|
|
7d351f2025 | ||
|
|
8ce14c5690 | ||
|
|
6cf71a1529 | ||
|
|
50c74d63cf | ||
|
|
c1f9be150f | ||
|
|
0a13100185 | ||
|
|
b67aa40eae | ||
|
|
fb3c7c4ce2 | ||
|
|
4d4ef5ac51 | ||
|
|
022cc8725a | ||
|
|
e12a12fd04 | ||
|
|
999634cf9b | ||
|
|
c45f4d1b86 | ||
|
|
3f4c0c32cc | ||
|
|
a3a4cf9587 | ||
|
|
e17ec84867 | ||
|
|
0fbdda51d2 | ||
|
|
4de017250d | ||
|
|
08cbf08beb | ||
|
|
e5c51c3980 | ||
|
|
757653a30b | ||
|
|
c5d02c31f1 | ||
|
|
6906177ec2 | ||
|
|
276e0d193c | ||
|
|
965d3d780c | ||
|
|
67d34b5036 | ||
|
|
542fa36650 | ||
|
|
cf56da5aaf | ||
|
|
4f36218ffe | ||
|
|
65f7db7a07 | ||
|
|
9645c58760 | ||
|
|
7e8771fc3b | ||
|
|
37ef19f798 | ||
|
|
f57bd6f395 | ||
|
|
661f9f4774 | ||
|
|
8d1075127f | ||
|
|
5e382948b6 | ||
|
|
da325a94ac | ||
|
|
f1741f376c | ||
|
|
756ec0a8a5 | ||
|
|
bfe8e775cf | ||
|
|
9e4f5855aa | ||
|
|
8c9e5b57a3 | ||
|
|
d2ad8ab756 | ||
|
|
6ac61a40ae | ||
|
|
ea2a13b021 | ||
|
|
b8fc25c76b | ||
|
|
9894942b24 | ||
|
|
83d544ca9f | ||
|
|
fd0ea4ddce | ||
|
|
8ce275e240 | ||
|
|
0affe5ec0f | ||
|
|
4d67440865 | ||
|
|
ed3276c3a8 | ||
|
|
2218e00783 | ||
|
|
0b2972460b | ||
|
|
9cc9d02eb7 | ||
|
|
803d9c4508 | ||
|
|
41b3f31cfd | ||
|
|
12d4954815 | ||
|
|
26df0b9877 | ||
|
|
26be07b7cd | ||
|
|
4ec0b73b5c | ||
|
|
15786dea5c | ||
|
|
d9c4134657 | ||
|
|
b633df020f | ||
|
|
44fb76da7f | ||
|
|
b609f40bd2 | ||
|
|
bc1a33b327 | ||
|
|
4b29527051 | ||
|
|
fa4ee5d750 | ||
|
|
74677c5f4d | ||
|
|
6c2c845812 | ||
|
|
b2c3dfa7e3 | ||
|
|
028799e5cd | ||
|
|
a86959158d | ||
|
|
6b941ce10f | ||
|
|
64acfd1f00 | ||
|
|
27d1e84b95 | ||
|
|
f13cebce4b | ||
|
|
ae46a75253 | ||
|
|
8641021134 | ||
|
|
b5d43dd23a | ||
|
|
b39c907b1a | ||
|
|
237afacb44 | ||
|
|
9e10d07a53 | ||
|
|
79e716cff7 | ||
|
|
fa5b081602 | ||
|
|
226d2d4686 | ||
|
|
18eb55f1a4 | ||
|
|
5d1318c52a | ||
|
|
574cd3fee3 | ||
|
|
ffca404263 | ||
|
|
1d958bbb89 | ||
|
|
1e404d8c3d | ||
|
|
3c57d384d7 | ||
|
|
834b6a4110 | ||
|
|
d579b827b8 | ||
|
|
6f76265a73 | ||
|
|
bf76e91c55 | ||
|
|
6e8647dac8 | ||
|
|
5b58677134 | ||
|
|
ad6b0045e4 | ||
|
|
281202402e | ||
|
|
d820de0d7f | ||
|
|
c2bb178d6a | ||
|
|
4dd58a6efa | ||
|
|
81e82e6fc8 | ||
|
|
a6561fb96a | ||
|
|
553baf91bb | ||
|
|
fa337fbe33 | ||
|
|
bd0af601bf | ||
|
|
c9b43a6de5 | ||
|
|
1a66b08de3 | ||
|
|
96052b1531 | ||
|
|
2757f12c9a | ||
|
|
2675b2b21e | ||
|
|
33ebc299af | ||
|
|
fb6e18382d | ||
|
|
a200911d3c | ||
|
|
d7b30a0310 | ||
|
|
3dc0611b38 | ||
|
|
9cdd249417 | ||
|
|
a5422f59d1 | ||
|
|
eaba3ba877 | ||
|
|
938265e16a | ||
|
|
b77a7675d9 | ||
|
|
73ee2f3c16 | ||
|
|
71b7d1fe6d | ||
|
|
03f93374e4 | ||
|
|
43d476ffb1 | ||
|
|
2cea1f1a10 | ||
|
|
c64ea36883 | ||
|
|
bf0220030e | ||
|
|
7d8d3b20a3 | ||
|
|
beefebc6c9 | ||
|
|
dbc7a24227 | ||
|
|
2597fd5f77 | ||
|
|
fdfef51492 | ||
|
|
8d4516b395 | ||
|
|
c7f921e7ec | ||
|
|
3ff83a20cf | ||
|
|
80cdc653b3 | ||
|
|
63d01c570f | ||
|
|
79ebd810da | ||
|
|
b78da984e6 | ||
|
|
a298cff510 | ||
|
|
4360cff06a | ||
|
|
e21803a0d8 | ||
|
|
cb99d7549e | ||
|
|
c3fb26c0e2 | ||
|
|
2fc5b316d9 | ||
|
|
6fa284cc71 | ||
|
|
09491bf4d3 | ||
|
|
c99a4d8ffe | ||
|
|
e0d1fbb860 | ||
|
|
f330b7b3e6 | ||
|
|
617e77e428 | ||
|
|
a86b6ffbae | ||
|
|
22abe4ddda | ||
|
|
80d066abfd | ||
|
|
88fba17fc5 | ||
|
|
b7874574ec | ||
|
|
548d76591b | ||
|
|
2fedb1ccf8 | ||
|
|
a5fbdd9441 | ||
|
|
176ec018d5 | ||
|
|
d0b71449d0 | ||
|
|
fb93c454b1 | ||
|
|
accc28b82f | ||
|
|
55fb5a5547 |
No files matched your search
@@ -0,0 +1,12 @@
|
||||
pkgbase = rustscan-bin
|
||||
pkgdesc = Faster Nmap Scanning with Rust
|
||||
pkgver = 1.1.0
|
||||
pkgrel = 1
|
||||
url = https://github.com/brandonskerritt/rustscan
|
||||
arch = x86_64
|
||||
license = MIT
|
||||
depends = rustup
|
||||
provides = rustscan
|
||||
|
||||
pkgname = rustscan-bin
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"commit": false,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "brandonskerritt",
|
||||
"name": "Brandon",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/10378052?v=4",
|
||||
"profile": "https://skerritt.blog",
|
||||
"contributions": [
|
||||
"infra",
|
||||
"test",
|
||||
"code",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "SakiiR",
|
||||
"name": "SakiiR",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/9950578?v=4",
|
||||
"profile": "https://sakiir.ovh",
|
||||
"contributions": [
|
||||
"code",
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "smackhack",
|
||||
"name": "smackhack",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/48143394?v=4",
|
||||
"profile": "https://github.com/smackhack",
|
||||
"contributions": [
|
||||
"ideas",
|
||||
"example"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "bernardoamc",
|
||||
"name": "Bernardo Araujo",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/428984?v=4",
|
||||
"profile": "http://bernardoamc.github.io/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"bug",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Isona",
|
||||
"name": "Izzy Whistlecroft",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/11759523?v=4",
|
||||
"profile": "https://github.com/Isona",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "imlonghao",
|
||||
"name": "imlonghao",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/4951333?v=4",
|
||||
"profile": "https://imlonghao.com",
|
||||
"contributions": [
|
||||
"bug",
|
||||
"maintenance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "royharoush",
|
||||
"name": "royharoush",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/8113056?v=4",
|
||||
"profile": "https://github.com/royharoush",
|
||||
"contributions": [
|
||||
"ideas",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Atul9",
|
||||
"name": "Atul Bhosale",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/3390330?v=4",
|
||||
"profile": "https://github.com/Atul9",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TGotwig",
|
||||
"name": "Thomas Gotwig",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/30773779?v=4",
|
||||
"profile": "https://tgotwig.me",
|
||||
"contributions": [
|
||||
"platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "remigourdon",
|
||||
"name": "Rémi Gourdon",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2874133?v=4",
|
||||
"profile": "https://github.com/remigourdon",
|
||||
"contributions": [
|
||||
"doc",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cmnatic",
|
||||
"name": "Ben (CMNatic)",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/4163116?v=4",
|
||||
"profile": "https://cmnatic.co.uk",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "buermarc",
|
||||
"name": "buermarc",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/44375277?v=4",
|
||||
"profile": "https://github.com/buermarc",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "RustScan",
|
||||
"projectOwner": "RustScan",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
.git
|
||||
Dockerfile
|
||||
@@ -0,0 +1,4 @@
|
||||
github: bee-san
|
||||
patreon: brandonskerritt
|
||||
ko_fi: hacker
|
||||
custom: ["https://monzo.me/bee", "https://paypal.me/brandonskerritt"]
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,2 @@
|
||||
todo:
|
||||
keyword: "// TODO"
|
||||
@@ -0,0 +1,4 @@
|
||||
template: |
|
||||
## What’s Changed
|
||||
|
||||
$CHANGES
|
||||
@@ -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
|
||||
@@ -0,0 +1,55 @@
|
||||
on: [push, pull_request]
|
||||
|
||||
name: Continuous integration
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
|
||||
test:
|
||||
name: Test Suite
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
|
||||
fmt:
|
||||
name: Rustfmt
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- run: rustup component add rustfmt
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
links:
|
||||
name: markdown-link-check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Check Markdown links
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
# Run everyday at 9:00 AM (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07)
|
||||
- cron: "0 9 * * *"
|
||||
|
||||
jobs:
|
||||
markdown-link-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
with:
|
||||
use-quiet-mode: 'yes'
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
@@ -13,3 +12,34 @@ Cargo.lock
|
||||
#Added by cargo
|
||||
|
||||
/target
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/rust,archlinuxpackages
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,archlinuxpackages
|
||||
|
||||
### ArchLinuxPackages ###
|
||||
*.tar
|
||||
*.tar.*
|
||||
*.jar
|
||||
*.exe
|
||||
*.msi
|
||||
*.zip
|
||||
*.tgz
|
||||
*.log
|
||||
*.log.*
|
||||
*.sig
|
||||
|
||||
pkg/
|
||||
|
||||
### Rust ###
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/rust,archlinuxpackages
|
||||
*.deb
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "src/rustscan_scripting_engine"]
|
||||
path = src/rustscan_scripting_engine
|
||||
url = https://github.com/RustScan/rustscan_scripting_engine
|
||||
@@ -0,0 +1,37 @@
|
||||
language: rust
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- rustup component add rustfmt
|
||||
rust:
|
||||
- stable
|
||||
- beta
|
||||
jobs:
|
||||
fast_finish: true
|
||||
script:
|
||||
- cargo build
|
||||
- cargo test
|
||||
- cargo fmt -- --check
|
||||
after_failure:
|
||||
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
|
||||
- chmod +x send.sh
|
||||
- "./send.sh failure $WEBHOOK_URL"
|
||||
after_success: |
|
||||
if [ -n "${GITHUB_TOKEN}" ]; then
|
||||
[ "${TRAVIS_BRANCH} " = master ] &&
|
||||
[ "${TRAVIS_PULL_REQUEST}" = false ] &&
|
||||
cargo doc &&
|
||||
echo "<meta http-equiv=refresh content=0;url=rustscan/index.html>" > target/doc/index.html &&
|
||||
sudo pip install ghp-import &&
|
||||
ghp-import -n target/doc &&
|
||||
git push -fq https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
||||
fi
|
||||
env:
|
||||
global:
|
||||
secure: Gf24LG7Hr3Q0drWyPrvISTL35Z57DxdS/wIOo7v+ZdauzY3Qjvv3Lh4TY//C4sdN0g1CLj4yjg7LQOqF4XRdh2Qah7JZPv/i2B5uz9nwjTsoRzmmMWML9VtfT1u53nSFqsNeXbvpmoNG9rfMXcoiyd+Lv+EgniHphDEBlXvS9n9KMcpOi1F2x7bsH0EK37wQYKMTpCCd5TPUPdZou7BJNiZS3ikRLpTRFF7uIN4gYtRH9kU5uBSphWgnJ6eBm2ItzZcUPOgrjAoF4RkmZAzGG4idDh1Qkf3No3nZwT3U5NSk8h7owtJ4oADlRgYqYKCB4YcC9cAKCJgDsyMlKKMkEyagvw1seFnBLCY3ljsW4EklpVEZ0rVqZOx4pTkIaxIxytLTC9pHmdDSnhdhFknOcVAQQWjg+nAZfD07QUeAqUdr0i/vxQoZitvbNY0znzEarycE1waKvwlkiB4gt385U1CBfYldydnOnRKkdtLNrCLClu13HU0djmSXMhojQJhTuNxTHtZAf5fKcWIWwkVbNZ5MNKYjQh4rKufqW3o1iHphB8dfAGsDEPv0RQMtVbu6H4+clCouLkFlxHOIrrOJ5SXQ8cIATPhnJR7y4cSDdRaN0DRLRjeLAIKlbOGBtNuFC+BftocaTY5qN42aKAMqQcT30ycfiLuRVJNiQJ5pkto=
|
||||
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
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 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.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
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
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
@@ -1,19 +1,44 @@
|
||||
[package]
|
||||
name = "rust_scan"
|
||||
version = "1.0.0"
|
||||
name = "rustscan"
|
||||
version = "1.8.0"
|
||||
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"]
|
||||
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 = "1.9.3"
|
||||
clap = "2.33.0"
|
||||
rayon = "1.3.1"
|
||||
colored = "2.0.0"
|
||||
structopt = "0.3.17"
|
||||
async-std = "1.6.3"
|
||||
futures = "0.3"
|
||||
rlimit = "0.4.0"
|
||||
shell-words = "1.0.0"
|
||||
log = "0.4.0"
|
||||
env_logger = "0.7.1"
|
||||
dirs = "3.0.1"
|
||||
gcd = "2.0.1"
|
||||
rand = "0.7.3"
|
||||
colorful = "0.2.1"
|
||||
ansi_term = "0.12.1"
|
||||
toml = "0.5.6"
|
||||
serde = "1.0.115"
|
||||
serde_derive = "1.0.115"
|
||||
cidr-utils = "0.5.0"
|
||||
|
||||
[package.metadata.deb]
|
||||
depends = "$auto, nmap"
|
||||
section = "rust"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = 'abort'
|
||||
@@ -0,0 +1,16 @@
|
||||
FROM rust:alpine as builder
|
||||
RUN apk add --no-cache build-base
|
||||
|
||||
WORKDIR /usr/src/rustscan
|
||||
COPY . .
|
||||
RUN cargo install --path .
|
||||
|
||||
FROM alpine:3.12
|
||||
LABEL author="Hydragyrum <https://github.com/Hydragyrum>"
|
||||
RUN addgroup -S 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" ]
|
||||
@@ -1,21 +1,674 @@
|
||||
MIT License
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (c) 2020 Brandon
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Preamble
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,21 @@
|
||||
install:
|
||||
cargo install cross
|
||||
|
||||
build:
|
||||
make build-linux
|
||||
make build-mac
|
||||
|
||||
make shasum
|
||||
|
||||
build-linux:
|
||||
@echo 'Building for Linux... 🐧'
|
||||
cross build --release --target=x86_64-unknown-linux-musl
|
||||
mkdir -p target/release-archives && tar -czf target/release-archives/rustscan-linux.tar.gz target/x86_64-unknown-linux-musl/release/rustscan
|
||||
|
||||
build-mac:
|
||||
@echo 'Building for MacOS... 🍏'
|
||||
cross build --release --target=x86_64-apple-darwin
|
||||
mkdir -p target/release-archives && tar -czf target/release-archives/rustscan-mac.tar.gz target/x86_64-apple-darwin/release/rustscan
|
||||
|
||||
shasum:
|
||||
shasum -a 256 target/release-archives/rustscan-*.tar.gz
|
||||
@@ -1,16 +0,0 @@
|
||||
# Maintainer: Bee <[email protected]>
|
||||
pkgname=RustScan-bin
|
||||
pkgver=0.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Faster Nmap Scanning with Rust"
|
||||
url="https://github.com/brandonskerritt/rustscan"
|
||||
license=("GNU")
|
||||
arch=("x86_64")
|
||||
provides=("RustScan")
|
||||
options=("strip")
|
||||
source=("https://github.com/brandonskerritt/rustscan/releases/download/v$pkgver/RustScan-$pkgver-x86_64.tar.gz")
|
||||
sha256sums=("0ab268ae43a79cad6e9f75b650629208061590b3311780d55b8a03d35a8d90b0")
|
||||
|
||||
package() {
|
||||
install -Dm755 RustScan -t "$pkgdir/usr/bin/"
|
||||
}
|
||||
@@ -1,82 +1,153 @@
|
||||
<p align="center">
|
||||
<img src="pictures/rustscan.png"><br>
|
||||
Find all open ports <b>fast</b> with Rustscan, automatically pipe them into Nmap. Built with Rust.
|
||||
➡️
|
||||
<a href="https://discord.gg/GFrQsGy">Discord</a> |
|
||||
<a href="https://github.com/RustScan/RustScan#-full-installation-guide">Installation Guide</a> |
|
||||
<a href="https://github.com/RustScan/RustScan#-usage">Usage Guide</a>
|
||||
⬅️
|
||||
<br>
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/d/rust_scan">
|
||||
<img src="pictures/rustscan.png" height=400px width=400px>
|
||||
</p>
|
||||
<p align="center">
|
||||
<u><b> 👽 The Modern Day Port Scanner 👽
|
||||
</p>
|
||||
<p align="center">
|
||||
<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 All Releases" src="https://img.shields.io/github/downloads/rustscan/rustscan/total?label=GitHub%20Downloads">
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/d/rustscan?label=Cargo%20Downloads">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/736614461313515576">
|
||||
<img alt="Actions" src="https://github.com/RustScan/RustScan/workflows/Continuous%20integration/badge.svg?branch=master">
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
| <p align="center"><a href="https://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/Rustscan/RustScan/blob/master/README.md#%EF%B8%8F-debian--kali) | `yay -S rustscan` | `cargo install rustscan` |
|
||||
|
||||
| <p align="center"><a href="https://crates.io/crates/rust_scan">🔧 Cargo (Universal) </a></p> | <p align="center"><a href="https://pypi.org/project/ciphey"> Arch </a></p> | <p align="center"><a href="https://pypi.org/project/ciphey"> HomeBrew </a></p> | <p align="center"><a href="https://pypi.org/project/ciphey"> Kali / Debian </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 rust_scan` | `yay rustscan` | `brew install rustscan` | `dpkg -i rustscan.deb` |
|
||||
|
||||
**Note**: You must have Nmap installed.
|
||||
<hr>
|
||||
|
||||
# TODO
|
||||
* debian package
|
||||
* terminal gifs
|
||||
|
||||
# 🤔 What is this?
|
||||
If you are a competitive CTF player and often find yourself running masscan / a basic nmap scan before running a more comprehensive scan, this tool is for you.
|
||||
1. Find ports quickly using Rustscan (**27 seconds on average**).
|
||||
2. Automatically runs `nmap -A -sV -p $ports -vvv` on those ports.
|
||||
3. Profit???
|
||||
|
||||
[ GIFS HERE ]
|
||||
RustScan is the port scanner for the modern world. Built with speed & you in mind.
|
||||
|
||||

|
||||
|
||||
Rustscans **only** job is to reduce the friction between finding open ports and inputting them into nmap.
|
||||
|
||||
# ✨ Features
|
||||
* Scans all 64k ports in 27 seconds (on 1k threads).
|
||||
* 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!
|
||||
|
||||
- Scans all 65k ports in **3 seconds** (max speed) **or as slow as you'd like**
|
||||
- Saves you time by automatically piping it into Nmap. No more manual copying and pasting!
|
||||
- Adaptive Learning System. The scanner learns how _you_ use it and improves itself over time.
|
||||
- Intuitive Scripting Engine support. Write scripts in Python!
|
||||
- IPv6, CIDR, top ports, multiple IP scanning, host resolution, and more!
|
||||
|
||||
## ‼️ Important Links
|
||||
|
||||
| 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) |
|
||||
|
||||
|
||||
# 🔭 Why RustScan?
|
||||
|
||||
## 🔬 Without RustScan
|
||||
* Gif here comparison
|
||||
RustScan is a port scanner built for the modern day world. Initially created to aid in CTFs, but now expanded to real world usage.
|
||||
|
||||
## 📊 RustScan vs Nmap vs MassScan
|
||||
One of RustScan's most popular features is the Nmap extension. Quickly scan ports with RustScan, run Nmap on the found ports.
|
||||
|
||||
| **Name** | RustScan | Nmap | Masscan |
|
||||
| ------------------------------------------------------------------------------------------ | -------- | ---- | ------- |
|
||||
| Fast | ✅ | ❌ | ✅ |
|
||||
| Actually useful | ❌ | ✅ | ❌ |
|
||||
| Realises it's not useful, and pipes the only useful data into the only useful port scanner | ✅ | ❌ | ❌ |
|
||||
**RustScan running in 8 seconds and finding all open ports out of 65k.**
|
||||
|
||||

|
||||
|
||||
# Packages
|
||||
|
||||
[](https://repology.org/project/rustscan/versions)
|
||||
|
||||
|
||||
## 🙋 FAQ
|
||||
> I think this would be a great port scanner on its own without Nmap!
|
||||
# 🎪 Community
|
||||
|
||||
No. If you want a fast port scanner, use Masscan.
|
||||
> I have this great idea for a script to get information on ports / hosts
|
||||
Howdy Space Cow-Person 🤠🌌
|
||||
|
||||
Great. Contribute it to Nmap! :D
|
||||
> Not everyone has nmap installed....
|
||||
RustScan is always looking for contributors. Whether that's spelling mistakes or major changes, your help is **wanted** and welcomed here.
|
||||
|
||||
If you're a pentester, then yes, you have Nmap installed.
|
||||
Before contributing, read our [code of conduct](https://github.com/RustScan/RustScan/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
> I want to contribute!
|
||||
TL;DR if you abuse members of our community you will be **perma-banned** 🤗
|
||||
|
||||
Great! I'd love some help with this. Read the [contributing.md file](contributing.md) file for more information!
|
||||
RustScan has 2 major labels for GitHub issues you should look at:
|
||||
|
||||
# 📖 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).
|
||||
- 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)
|
||||
|
||||
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.
|
||||
If you want to, solve the issue or comment on the issue for help.
|
||||
|
||||
The most universal way is to use `cargo`, Rust's built in package manager (think Pip but for Rust). [Follow this guide to installing Rust & Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html).
|
||||
The flow for contributing to open source software is:
|
||||
|
||||
If you face any issues at all, please leave a GitHub issue. I have only tested this on Linux, so there may be issues for Mac OS or Windows.
|
||||
- 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! :)
|
||||
|
||||
# 🎪 Contributing
|
||||
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-)
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- 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/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/RustScan/RustScan/commits?author=bernardoamc" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/issues?q=author%3Abernardoamc" title="Bug reports">🐛</a> <a href="#design-bernardoamc" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://github.com/Isona"><img src="https://avatars2.githubusercontent.com/u/11759523?v=4" width="100px;" alt=""/><br /><sub><b>Izzy Whistlecroft</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/issues?q=author%3AIsona" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://imlonghao.com"><img src="https://avatars1.githubusercontent.com/u/4951333?v=4" width="100px;" alt=""/><br /><sub><b>imlonghao</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/issues?q=author%3Aimlonghao" title="Bug reports">🐛</a> <a href="#maintenance-imlonghao" title="Maintenance">🚧</a></td>
|
||||
<td align="center"><a href="https://github.com/royharoush"><img src="https://avatars3.githubusercontent.com/u/8113056?v=4" width="100px;" alt=""/><br /><sub><b>royharoush</b></sub></a><br /><a href="#ideas-royharoush" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-royharoush" title="Design">🎨</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/Atul9"><img src="https://avatars1.githubusercontent.com/u/3390330?v=4" width="100px;" alt=""/><br /><sub><b>Atul Bhosale</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=Atul9" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://tgotwig.me"><img src="https://avatars0.githubusercontent.com/u/30773779?v=4" width="100px;" alt=""/><br /><sub><b>Thomas Gotwig</b></sub></a><br /><a href="#platform-TGotwig" title="Packaging/porting to new platform">📦</a></td>
|
||||
<td align="center"><a href="https://github.com/remigourdon"><img src="https://avatars3.githubusercontent.com/u/2874133?v=4" width="100px;" alt=""/><br /><sub><b>Rémi Gourdon</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=remigourdon" title="Documentation">📖</a> <a href="https://github.com/RustScan/RustScan/commits?author=remigourdon" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://cmnatic.co.uk"><img src="https://avatars3.githubusercontent.com/u/4163116?v=4" width="100px;" alt=""/><br /><sub><b>Ben (CMNatic)</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=cmnatic" title="Code">💻</a> <a href="https://github.com/RustScan/RustScan/commits?author=cmnatic" title="Documentation">📖</a> <a href="#design-cmnatic" title="Design">🎨</a></td>
|
||||
<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>
|
||||
<td align="center"><a href="https://github.com/buermarc"><img src="https://avatars2.githubusercontent.com/u/44375277?v=4" width="100px;" alt=""/><br /><sub><b>buermarc</b></sub></a><br /><a href="https://github.com/RustScan/RustScan/commits?author=buermarc" title="Code">💻</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!
|
||||
@@ -1,8 +1,31 @@
|
||||
This is my first Rust project! As such, I expect there are many, many bugs involved or things that can be sped up.
|
||||
Howdy Space Cow-Person 🤠🌌
|
||||
|
||||
In particular, here is my roadmap:
|
||||
* Tokio async
|
||||
* Better UX
|
||||
* Optimised code
|
||||
RustScan is always looking for contributors. Whether that's spelling mistakes or major changes, your help is **wanted** and welcomed here.
|
||||
|
||||
Please leave issues / pull requests, I'd love to learn more about this amazing language :)
|
||||
Before contributing, read our [code of conduct](https://github.com/RustScan/RustScan/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
TL;DR if you abuse members of our community you will be **perma-banned** with no chance to get unbanned. No warnings either. 🤗
|
||||
|
||||
RustScan has 2 major labels for GitHub issues you should look at:
|
||||
* Good First issue
|
||||
These are issues for newcomers to open source!
|
||||
[https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22](https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
* Help wanted
|
||||
These are issues that aren't really for newcomers, but we could still do wiht help!
|
||||
[https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+label%3A%22help+wanted%22](https://github.com/RustScan/RustScan/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+label%3A%22help+wanted%22)
|
||||
|
||||
If you want to, solve the issue or comment on the issue for help.
|
||||
|
||||
The [flow for contributing](https://guides.github.com/introduction/flow/) to open source software is:
|
||||
* Fork the repo
|
||||
* Make changes
|
||||
* Pull request to the repo
|
||||
|
||||
And then comment on the issue that you've done.
|
||||
|
||||
RustScan also has some `// TODO`'s in the codebase, which are meant more for the core team but we wouldn't say no to help with these issues.
|
||||
|
||||
If you have any feature suggestions or bugs, leave a GitHub issue. We welcome any and all support :D
|
||||
|
||||
## Rewarding you
|
||||
I cannot pay you :-( But, I can place your GitHub profile on the README under `#Contributors` as a thank you! :)
|
||||
@@ -1,72 +0,0 @@
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <set>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
auto timeout = std::chrono::milliseconds{500};
|
||||
auto inter = std::chrono::microseconds{5};
|
||||
|
||||
boost::asio::io_context io_ctx;
|
||||
boost::asio::thread_pool threads;
|
||||
|
||||
// Max out fds
|
||||
::rlimit rl;
|
||||
::getrlimit(RLIMIT_NOFILE, &rl);
|
||||
rl.rlim_cur = rl.rlim_max;
|
||||
::setrlimit(RLIMIT_NOFILE, &rl);
|
||||
|
||||
std::vector<bool> open(65536, false);
|
||||
std::vector<std::atomic<bool>> done(65536);
|
||||
std::vector<boost::asio::ip::tcp::socket> socks;
|
||||
socks.reserve(65536);
|
||||
|
||||
auto target_ip = boost::asio::ip::make_address("45.33.32.156");
|
||||
|
||||
std::set top_ports{1,3,4,6,7,9,13,17,19,20,21,22,23,24,25,26,30,32,33,37,42,43,49,53,70,79,80,81,82,83,84,85,88,89,90,99,100,106,109,110,111,113,119,125,135,139,143,144,146,161,163,179,199,211,212,222,254,255,256,259,264,280,301,306,311,340,366,389,406,407,416,417,425,427,443,444,445,458,464,465,481,497,500,512,513,514,515,524,541,543,544,545,548,554,555,563,587,593,616,617,625,631,636,646,648,666,667,668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800,801,808,843,873,880,888,898,900,901,902,903,911,912,981,987,990,992,993,995,999,1000,1001,1002,1007,1009,1010,1011,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1102,1104,1105,1106,1107,1108,1110,1111,1112,1113,1114,1117,1119,1121,1122,1123,1124,1126,1130,1131,1132,1137,1138,1141,1145,1147,1148,1149,1151,1152,1154,1163,1164,1165,1166,1169,1174,1175,1183,1185,1186,1187,1192,1198,1199,1201,1213,1216,1217,1218,1233,1234,1236,1244,1247,1248,1259,1271,1272,1277,1287,1296,1300,1301,1309,1310,1311,1322,1328,1334,1352,1417,1433,1434,1443,1455,1461,1494,1500,1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687,1688,1700,1717,1718,1719,1720,1721,1723,1755,1761,1782,1783,1801,1805,1812,1839,1840,1862,1863,1864,1875,1900,1914,1935,1947,1971,1972,1974,1984,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013,2020,2021,2022,2030,2033,2034,2035,2038,2040,2041,2042,2043,2045,2046,2047,2048,2049,2065,2068,2099,2100,2103,2105,2106,2107,2111,2119,2121,2126,2135,2144,2160,2161,2170,2179,2190,2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381,2382,2383,2393,2394,2399,2401,2492,2500,2522,2525,2557,2601,2602,2604,2605,2607,2608,2638,2701,2702,2710,2717,2718,2725,2800,2809,2811,2869,2875,2909,2910,2920,2967,2968,2998,3000,3001,3003,3005,3006,3007,3011,3013,3017,3030,3031,3052,3071,3077,3128,3168,3211,3221,3260,3261,3268,3269,3283,3300,3301,3306,3322,3323,3324,3325,3333,3351,3367,3369,3370,3371,3372,3389,3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689,3690,3703,3737,3766,3784,3800,3801,3809,3814,3826,3827,3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000,4001,4002,4003,4004,4005,4006,4045,4111,4125,4126,4129,4224,4242,4279,4321,4343,4443,4444,4445,4446,4449,4550,4567,4662,4848,4899,4900,4998,5000,5001,5002,5003,5004,5009,5030,5033,5050,5051,5054,5060,5061,5080,5087,5100,5101,5102,5120,5190,5200,5214,5221,5222,5225,5226,5269,5280,5298,5357,5405,5414,5431,5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678,5679,5718,5730,5800,5801,5802,5810,5811,5815,5822,5825,5850,5859,5862,5877,5900,5901,5902,5903,5904,5906,5907,5910,5911,5915,5922,5925,5950,5952,5959,5960,5961,5962,5963,5987,5988,5989,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6009,6025,6059,6100,6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565,6566,6567,6580,6646,6666,6667,6668,6669,6689,6692,6699,6779,6788,6789,6792,6839,6881,6901,6969,7000,7001,7002,7004,7007,7019,7025,7070,7100,7103,7106,7200,7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777,7778,7800,7911,7920,7921,7937,7938,7999,8000,8001,8002,8007,8008,8009,8010,8011,8021,8022,8031,8042,8045,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8093,8099,8100,8180,8181,8192,8193,8194,8200,8222,8254,8290,8291,8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651,8652,8654,8701,8800,8873,8888,8899,8994,9000,9001,9002,9003,9009,9010,9011,9040,9050,9071,9080,9081,9090,9091,9099,9100,9101,9102,9103,9110,9111,9200,9207,9220,9290,9415,9418,9485,9500,9502,9503,9535,9575,9593,9594,9595,9618,9666,9876,9877,9878,9898,9900,9917,9929,9943,9944,9968,9998,9999,10000,10001,10002,10003,10004,10009,10010,10012,10024,10025,10082,10180,10215,10243,10566,10616,10617,10621,10626,10628,10629,10778,11110,11111,11967,12000,12174,12265,12345,13456,13722,13782,13783,14000,14238,14441,14442,15000,15002,15003,15004,15660,15742,16000,16001,16012,16016,16018,16080,16113,16992,16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221,20222,20828,21571,22939,23502,24444,24800,25734,25735,26214,27000,27352,27353,27355,27356,27715,28201,30000,30718,30951,31038,31337,32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779,32780,32781,32782,32783,32784,32785,33354,33899,34571,34572,34573,35500,38292,40193,40911,41511,42510,44176,44442,44443,44501,45100,48080,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49163,49165,49167,49175,49176,49400,49999,50000,50001,50002,50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055,55056,55555,55600,56737,56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65Line truncated
|
||||
for (uint16_t port = 1; port != 0; ++port) {
|
||||
if (!top_ports.count(port))
|
||||
done[port] = true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
for (uint16_t port = 1; port != 0; ++port) {
|
||||
if (done[port])
|
||||
continue;
|
||||
socks.emplace_back(io_ctx);
|
||||
auto& sock = socks.back();
|
||||
sock.async_connect(boost::asio::ip::tcp::endpoint{target_ip, port},
|
||||
[&open, &done, port](boost::system::error_code err) {
|
||||
|
||||
if (!err || err.value() == boost::asio::error::connection_refused)
|
||||
// Check to see if some bastard thread has broken our stuff
|
||||
if (!done[port].exchange(true))
|
||||
open[port] = !err.failed();
|
||||
});
|
||||
|
||||
if (port % 128) {
|
||||
boost::asio::post(threads, [&]() {
|
||||
io_ctx.run();
|
||||
});
|
||||
std::this_thread::sleep_for(inter);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
io_ctx.run_for(timeout);
|
||||
io_ctx.stop();
|
||||
|
||||
for (uint16_t i = 1; i != 0; ++i)
|
||||
if (open[i])
|
||||
std::cout << i << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,157 @@
|
||||
# The configurations that used for the recording, feel free to edit them
|
||||
config:
|
||||
|
||||
# Specify a command to be executed
|
||||
# like `/bin/bash -l`, `ls`, or any other commands
|
||||
# the default is bash for Linux
|
||||
# or powershell.exe for Windows
|
||||
command: zsh
|
||||
|
||||
# Specify the current working directory path
|
||||
# the default is the current working directory path
|
||||
cwd: /home/bee/Documents/RustScan
|
||||
|
||||
# Export additional ENV variables
|
||||
env:
|
||||
recording: true
|
||||
|
||||
# Explicitly set the number of columns
|
||||
# or use `auto` to take the current
|
||||
# number of columns of your shell
|
||||
cols: 105
|
||||
|
||||
# Explicitly set the number of rows
|
||||
# or use `auto` to take the current
|
||||
# number of rows of your shell
|
||||
rows: 34
|
||||
|
||||
# Amount of times to repeat GIF
|
||||
# If value is -1, play once
|
||||
# If value is 0, loop indefinitely
|
||||
# If value is a positive number, loop n times
|
||||
repeat: 0
|
||||
|
||||
# Quality
|
||||
# 1 - 100
|
||||
quality: 100
|
||||
|
||||
# Delay between frames in ms
|
||||
# If the value is `auto` use the actual recording delays
|
||||
frameDelay: auto
|
||||
|
||||
# Maximum delay between frames in ms
|
||||
# Ignored if the `frameDelay` isn't set to `auto`
|
||||
# Set to `auto` to prevent limiting the max idle time
|
||||
maxIdleTime: auto
|
||||
|
||||
# The surrounding frame box
|
||||
# The `type` can be null, window, floating, or solid`
|
||||
# To hide the title use the value null
|
||||
# Don't forget to add a backgroundColor style with a null as type
|
||||
frameBox:
|
||||
type: floating
|
||||
title: Terminalizer
|
||||
style:
|
||||
border: 0px black solid
|
||||
# boxShadow: none
|
||||
# margin: 0px
|
||||
|
||||
# Add a watermark image to the rendered gif
|
||||
# You need to specify an absolute path for
|
||||
# the image on your machine or a URL, and you can also
|
||||
# add your own CSS styles
|
||||
watermark:
|
||||
imagePath: null
|
||||
style:
|
||||
position: absolute
|
||||
right: 15px
|
||||
bottom: 15px
|
||||
width: 100px
|
||||
opacity: 0.9
|
||||
|
||||
# Cursor style can be one of
|
||||
# `block`, `underline`, or `bar`
|
||||
cursorStyle: block
|
||||
|
||||
# Font family
|
||||
# You can use any font that is installed on your machine
|
||||
# in CSS-like syntax
|
||||
fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace"
|
||||
|
||||
# The size of the font
|
||||
fontSize: 12
|
||||
|
||||
# The height of lines
|
||||
lineHeight: 1
|
||||
|
||||
# The spacing between letters
|
||||
letterSpacing: 0
|
||||
|
||||
# Theme
|
||||
theme:
|
||||
background: "transparent"
|
||||
foreground: "#afafaf"
|
||||
cursor: "#c7c7c7"
|
||||
black: "#232628"
|
||||
red: "#fc4384"
|
||||
green: "#b3e33b"
|
||||
yellow: "#ffa727"
|
||||
blue: "#75dff2"
|
||||
magenta: "#ae89fe"
|
||||
cyan: "#708387"
|
||||
white: "#d5d5d0"
|
||||
brightBlack: "#626566"
|
||||
brightRed: "#ff7fac"
|
||||
brightGreen: "#c8ed71"
|
||||
brightYellow: "#ebdf86"
|
||||
brightBlue: "#75dff2"
|
||||
brightMagenta: "#ae89fe"
|
||||
brightCyan: "#b1c6ca"
|
||||
brightWhite: "#f9f9f4"
|
||||
|
||||
# Records, feel free to edit them
|
||||
records:
|
||||
- delay: 815
|
||||
content: "\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;..ents/RustScan\a"
|
||||
- delay: 178
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m asyncMaster\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [$!?]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[32m➜ \e[0m\e[32m\e[39m\e[1m\e[0m\e[K\e[?1h\e=\e[?2004h"
|
||||
- delay: 406
|
||||
content: "\e[32mc\e[39m\e[90margo build --release && ./target/release/rustscan 127.0.0.1\e[39m\e[59D"
|
||||
- delay: 137
|
||||
content: "\b\e[1m\e[31mc\e[1m\e[31ma\e[0m\e[39m"
|
||||
- delay: 72
|
||||
content: "\b\b\e[1m\e[31mc\e[1m\e[31ma\e[1m\e[31mr\e[0m\e[39m"
|
||||
- delay: 203
|
||||
content: "\b\b\b\e[0m\e[32mc\e[0m\e[32ma\e[0m\e[32mr\e[32mg\e[32mo\e[39m\e[39m \e[39mb\e[39mu\e[39mi\e[39ml\e[39md\e[39m \e[39m-\e[39m-\e[39mr\e[39me\e[39ml\e[39me\e[39ma\e[39ms\e[39me\e[39m \e[39m&\e[39m&\e[39m \e[32m.\e[32m/\e[32mt\e[32ma\e[32mr\e[32mg\e[32me\e[32mt\e[32m/\e[32mr\e[32me\e[32ml\e[32me\e[32ma\e[32ms\e[32me\e[32m/\e[32mr\e[32mu\e[32ms\e[32mt\e[32ms\e[32mc\e[32ma\e[32mn\e[39m\e[39m \e[39m1\e[39m2\e[39m7\e[39m.\e[39m0\e[39m.\e[39m0\e[39m.\e[39m1"
|
||||
- delay: 145
|
||||
content: "\e[?1l\e>"
|
||||
- delay: 7
|
||||
content: "\e[?2004l\r\r\n\e]2;cargo\a"
|
||||
- delay: 37
|
||||
content: "\e[0m\e[0m\e[1m\e[36m Building\e[0m [====================================================> ] 87/92: futures-executor, smol \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [======================================================> ] 89/92: futures, async-std \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [======================================================> ] 90/92: async-std \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [=======================================================> ] 91/92: rustscan(bin) \r\e[K\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:193:13\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m192\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m panic!(\"Unable to convert to socket address\");\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m----------------------------------------------\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12many code following this expression is unreachable\e[0m\r\n\e[0m\e[1m\e[38;5;12m193\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m Err(io::Error::new(io::ErrorKind::Other, e.to_string()))\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\e[0m\e[0m \e[0m\e[0m\e[1m\e[33munreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m= \e[0m\e[0m\e[1mnote\e[0m\e[0m: `#[warn(unreachable_code)]` on by default\e[0m\r\n\r\n\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unused variable: `x`\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:57:14\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m57\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m Some(x) => {\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[33m^\e[0m\e[0m \e[0m\e[0m\e[1m\e[33mhelp: if this is intentional, prefix it with an underscore: `_x`\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m= \e[0m\e[0m\e[1mnote\e[0m\e[0m: `#[warn(unused_variables)]` on by default\e[0m\r\n\r\n\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: 2 warnings emitted\e[0m\r\n\r\n\e[0m\e[0m\e[1m\e[32m Finished\e[0m release [optimized] target(s) in 0.03s\r\n\e[32m\r\n _____ _ _____ \r\n | __ \\ | | / ____| \r\n | |__) | _ ___| |_| (___ ___ __ _ _ __ \r\n | _ / | | / __| __|\\___ \\ / __/ _` | '_ \\ \r\n | | \\ \\ |_| \\__ \\ |_ ____) | (_| (_| | | | |\r\n |_| \\_\\__,_|___/\\__|_____/ \\___\\__,_|_| |_|\r\n Faster nmap scanning with rust.\e[0m \r\n \e[31mAutomated Decryption Tool - https://github.com/ciphey/ciphey\e[0m \r\n \e[32mCreator https://github.com/brandonskerritt\e[0m\r\n"
|
||||
- delay: 326
|
||||
content: "Open \e[35m53\e[0m\r\nOpen \e[35m631\e[0m\r\n"
|
||||
- delay: 6
|
||||
content: "Open \e[35m1716\e[0m\r\n"
|
||||
- delay: 1138
|
||||
content: "Open \e[35m46624\e[0m\r\n"
|
||||
- delay: 156
|
||||
content: "Open \e[35m52880\e[0m\r\n"
|
||||
- delay: 146
|
||||
content: "\e[34mStarting nmap.\e[0m\r\n\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;..ents/RustScan\a"
|
||||
- delay: 9
|
||||
content: "Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-22 22:12 BST\r\n"
|
||||
- delay: 153
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m asyncMaster\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [$!?]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[32m➜ \e[0m\e[32m\e[39m\e[1m\e[0m\e[K\e[?1h\e=\e[?2004h"
|
||||
- delay: 119
|
||||
content: "NSE: Loaded 151 scripts for scanning.\r\nNSE: Script Pre-scanning.\r\nNSE: Starting runlevel 1 (of 3) scan.\r\nInitiating NSE at 22:12\r\nCompleted NSE at 22:12, 0.00s elapsed\r\nNSE: Starting runlevel 2 (of 3) scan.\r\nInitiating NSE at 22:12\r\nCompleted NSE at 22:12, 0.00s elapsed\r\nNSE: Starting runlevel 3 (of 3) scan.\r\nInitiating NSE at 22:12\r\nCompleted NSE at 22:12, 0.00s elapsed\r\n"
|
||||
- delay: 21
|
||||
content: "Initiating Ping Scan at 22:12\r\nScanning 127.0.0.1 [2 ports]\r\nCompleted Ping Scan at 22:12, 0.00s elapsed (1 total hosts)\r\nInitiating Connect Scan at 22:12\r\nScanning localhost (127.0.0.1) [5 ports]\r\nDiscovered open port 53/tcp on 127.0.0.1\r\nDiscovered open port 46624/tcp on 127.0.0.1\r\nDiscovered open port 1716/tcp on 127.0.0.1\r\nDiscovered open port 631/tcp on 127.0.0.1\r\nCompleted Connect Scan at 22:12, 0.00s elapsed (5 total ports)\r\n"
|
||||
- delay: 52
|
||||
content: "Initiating Service scan at 22:12\r\nScanning 4 services on localhost (127.0.0.1)\r\n"
|
||||
- delay: 105
|
||||
content: "\e[?2004l\r\r\n\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;..ents/RustScan\a"
|
||||
- delay: 158
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m asyncMaster\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [$!?]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[31m➜ \e[0m\e[31m\e[39m\e[1m\e[0m\e[K\e[?1h\e=\e[?2004h"
|
||||
- delay: 1332
|
||||
content: "\e[?2004l\r\r\n"
|
||||
|
After Width: | Height: | Size: 228 KiB |
@@ -0,0 +1,143 @@
|
||||
# The configurations that used for the recording, feel free to edit them
|
||||
config:
|
||||
|
||||
# Specify a command to be executed
|
||||
# like `/bin/bash -l`, `ls`, or any other commands
|
||||
# the default is bash for Linux
|
||||
# or powershell.exe for Windows
|
||||
command: zsh
|
||||
|
||||
# Specify the current working directory path
|
||||
# the default is the current working directory path
|
||||
cwd: /home/bee/Documents/RustScan
|
||||
|
||||
# Export additional ENV variables
|
||||
env:
|
||||
recording: true
|
||||
|
||||
# Explicitly set the number of columns
|
||||
# or use `auto` to take the current
|
||||
# number of columns of your shell
|
||||
cols: 235
|
||||
|
||||
# Explicitly set the number of rows
|
||||
# or use `auto` to take the current
|
||||
# number of rows of your shell
|
||||
rows: 31
|
||||
|
||||
# Amount of times to repeat GIF
|
||||
# If value is -1, play once
|
||||
# If value is 0, loop indefinitely
|
||||
# If value is a positive number, loop n times
|
||||
repeat: 0
|
||||
|
||||
# Quality
|
||||
# 1 - 100
|
||||
quality: 100
|
||||
|
||||
# Delay between frames in ms
|
||||
# If the value is `auto` use the actual recording delays
|
||||
frameDelay: auto
|
||||
|
||||
# Maximum delay between frames in ms
|
||||
# Ignored if the `frameDelay` isn't set to `auto`
|
||||
# Set to `auto` to prevent limiting the max idle time
|
||||
maxIdleTime: auto
|
||||
|
||||
# The surrounding frame box
|
||||
# The `type` can be null, window, floating, or solid`
|
||||
# To hide the title use the value null
|
||||
# Don't forget to add a backgroundColor style with a null as type
|
||||
frameBox:
|
||||
type: floating
|
||||
title: Terminalizer
|
||||
style:
|
||||
border: 0px black solid
|
||||
# boxShadow: none
|
||||
# margin: 0px
|
||||
|
||||
# Add a watermark image to the rendered gif
|
||||
# You need to specify an absolute path for
|
||||
# the image on your machine or a URL, and you can also
|
||||
# add your own CSS styles
|
||||
watermark:
|
||||
imagePath: null
|
||||
style:
|
||||
position: absolute
|
||||
right: 15px
|
||||
bottom: 15px
|
||||
width: 100px
|
||||
opacity: 0.9
|
||||
|
||||
# Cursor style can be one of
|
||||
# `block`, `underline`, or `bar`
|
||||
cursorStyle: block
|
||||
|
||||
# Font family
|
||||
# You can use any font that is installed on your machine
|
||||
# in CSS-like syntax
|
||||
fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace"
|
||||
|
||||
# The size of the font
|
||||
fontSize: 12
|
||||
|
||||
# The height of lines
|
||||
lineHeight: 1
|
||||
|
||||
# The spacing between letters
|
||||
letterSpacing: 0
|
||||
|
||||
# Theme
|
||||
theme:
|
||||
background: "transparent"
|
||||
foreground: "#afafaf"
|
||||
cursor: "#c7c7c7"
|
||||
black: "#232628"
|
||||
red: "#fc4384"
|
||||
green: "#b3e33b"
|
||||
yellow: "#ffa727"
|
||||
blue: "#75dff2"
|
||||
magenta: "#ae89fe"
|
||||
cyan: "#708387"
|
||||
white: "#d5d5d0"
|
||||
brightBlack: "#626566"
|
||||
brightRed: "#ff7fac"
|
||||
brightGreen: "#c8ed71"
|
||||
brightYellow: "#ebdf86"
|
||||
brightBlue: "#75dff2"
|
||||
brightMagenta: "#ae89fe"
|
||||
brightCyan: "#b1c6ca"
|
||||
brightWhite: "#f9f9f4"
|
||||
|
||||
# Records, feel free to edit them
|
||||
records:
|
||||
- delay: 818
|
||||
content: "\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;bee@beehive: ~/Documents/RustScan\a\e]1;..ents/RustScan\a"
|
||||
- delay: 187
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m master\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [⇡$!?]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[32m➜ \e[0m\e[32m\e[39m\e[1m\e[0m\e[K\e[?1h\e=\e[?2004h"
|
||||
- delay: 432
|
||||
content: "\e[32mc\e[39m\e[90margo build --release && ./target/release/rustscan 8.8.8.8\e[39m\e[57D"
|
||||
- delay: 106
|
||||
content: "\b\e[1m\e[31mc\e[1m\e[31ma\e[0m\e[39m"
|
||||
- delay: 115
|
||||
content: "\b\b\e[1m\e[31mc\e[1m\e[31ma\e[1m\e[31mr\e[0m\e[39m"
|
||||
- delay: 178
|
||||
content: "\b\b\b\e[0m\e[32mc\e[0m\e[32ma\e[0m\e[32mr\e[32mg\e[32mo\e[39m\e[39m \e[39mb\e[39mu\e[39mi\e[39ml\e[39md\e[39m \e[39m-\e[39m-\e[39mr\e[39me\e[39ml\e[39me\e[39ma\e[39ms\e[39me\e[39m \e[39m&\e[39m&\e[39m \e[32m.\e[32m/\e[32mt\e[32ma\e[32mr\e[32mg\e[32me\e[32mt\e[32m/\e[32mr\e[32me\e[32ml\e[32me\e[32ma\e[32ms\e[32me\e[32m/\e[32mr\e[32mu\e[32ms\e[32mt\e[32ms\e[32mc\e[32ma\e[32mn\e[39m\e[39m \e[39m8\e[39m.\e[39m8\e[39m.\e[39m8\e[39m.\e[39m8"
|
||||
- delay: 143
|
||||
content: "\e[?1l\e>"
|
||||
- delay: 8
|
||||
content: "\e[?2004l\r\r\n\e]2;cargo build --release && ./target/release/rustscan 8.8.8.8\a\e]1;cargo\a"
|
||||
- delay: 40
|
||||
content: "\e[0m\e[0m\e[1m\e[36m Building\e[0m [=================================================> ] 82/92: proc-macro-nested(build), rayon-core \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [==================================================> ] 83/92: rayon, proc-macro-nested(build) \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [===================================================> ] 84/92: proc-macro-nested(build) \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [===================================================> ] 85/92: proc-macro-nested \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [====================================================> ] 86/92: futures-util \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [====================================================> ] 87/92: smol, futures-executor \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [======================================================> ] 89/92: async-std, futures \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [======================================================> ] 90/92: async-std \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [=======================================================> ] 91/92: rustscan(bin) \r\e[K\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unused import: `Command`\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:5:26\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m5\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0muse std::process::{exit, Command};\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[33m^^^^^^^\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m= \e[0m\e[0m\e[1mnote\e[0m\e[0m: `#[warn(unused_imports)]` on by default\e[0m\r\n\r\n\e[0m\e[0m\e[1m\e[36m Building\e[0m [=======================================================> ] 91/92: rustscan(bin) \r\e[K\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:181:21\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m180\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m panic!(\"Too many open files. Please reduce batch size.\");\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m---------------------------------------------------------\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12many code following this expression is unreachable\e[0m\r\n\e[0m\e[1m\e[38;5;12m181\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m Err(e)\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[33m^^^^^^\e[0m\e[0m \e[0m\e[0m\e[1m\e[33munreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m= \e[0m\e[0m\e[1mnote\e[0m\e[0m: `#[warn(unreachable_code)]` on by default\e[0m\r\n\r\n\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:189:13\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m188\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m panic!(\"Unable to convert to socket address\");\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m----------------------------------------------\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12many code following this expression is unreachable\e[0m\r\n\e[0m\e[1m\e[38;5;12m189\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m Err(io::Error::new(io::ErrorKind::Other, e.to_string()))\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \Line truncated
|
||||
- delay: 368
|
||||
content: "Open \e[35m53\e[0m\r\n"
|
||||
- delay: 37
|
||||
content: "Open \e[35m853\e[0m\r\n"
|
||||
- delay: 849
|
||||
content: "Open \e[35m443\e[0m\r\n"
|
||||
- delay: 6605
|
||||
content: "\e[34mStarting nmap.\e[0m\r\n\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;bee@beehive: ~/Documents/RustScan\a\e]1;..ents/RustScan\a"
|
||||
- delay: 175
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m master\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [⇡$!?]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mtook \e[0m\e[1m\e[33m8s\e[0m\e[33m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[31m➜ \e[0m\e[31m\e[39m\e[1m\e[0m\e[K\e[?1h\e=\e[?2004h"
|
||||
- delay: 554
|
||||
content: "\e[?2004l\r\r\n"
|
||||
@@ -0,0 +1,167 @@
|
||||
# The configurations that used for the recording, feel free to edit them
|
||||
config:
|
||||
|
||||
# Specify a command to be executed
|
||||
# like `/bin/bash -l`, `ls`, or any other commands
|
||||
# the default is bash for Linux
|
||||
# or powershell.exe for Windows
|
||||
command: zsh
|
||||
|
||||
# Specify the current working directory path
|
||||
# the default is the current working directory path
|
||||
cwd: /home/bee/Documents/RustScan
|
||||
|
||||
# Export additional ENV variables
|
||||
env:
|
||||
recording: true
|
||||
|
||||
# Explicitly set the number of columns
|
||||
# or use `auto` to take the current
|
||||
# number of columns of your shell
|
||||
cols: 108
|
||||
|
||||
# Explicitly set the number of rows
|
||||
# or use `auto` to take the current
|
||||
# number of rows of your shell
|
||||
rows: 45
|
||||
|
||||
# Amount of times to repeat GIF
|
||||
# If value is -1, play once
|
||||
# If value is 0, loop indefinitely
|
||||
# If value is a positive number, loop n times
|
||||
repeat: 0
|
||||
|
||||
# Quality
|
||||
# 1 - 100
|
||||
quality: 100
|
||||
|
||||
# Delay between frames in ms
|
||||
# If the value is `auto` use the actual recording delays
|
||||
frameDelay: auto
|
||||
|
||||
# Maximum delay between frames in ms
|
||||
# Ignored if the `frameDelay` isn't set to `auto`
|
||||
# Set to `auto` to prevent limiting the max idle time
|
||||
maxIdleTime: auto
|
||||
|
||||
# The surrounding frame box
|
||||
# The `type` can be null, window, floating, or solid`
|
||||
# To hide the title use the value null
|
||||
# Don't forget to add a backgroundColor style with a null as type
|
||||
frameBox:
|
||||
type: floating
|
||||
title: Terminalizer
|
||||
style:
|
||||
border: 0px black solid
|
||||
# boxShadow: none
|
||||
# margin: 0px
|
||||
|
||||
# Add a watermark image to the rendered gif
|
||||
# You need to specify an absolute path for
|
||||
# the image on your machine or a URL, and you can also
|
||||
# add your own CSS styles
|
||||
watermark:
|
||||
imagePath: null
|
||||
style:
|
||||
position: absolute
|
||||
right: 15px
|
||||
bottom: 15px
|
||||
width: 100px
|
||||
opacity: 0.9
|
||||
|
||||
# Cursor style can be one of
|
||||
# `block`, `underline`, or `bar`
|
||||
cursorStyle: block
|
||||
|
||||
# Font family
|
||||
# You can use any font that is installed on your machine
|
||||
# in CSS-like syntax
|
||||
fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace"
|
||||
|
||||
# The size of the font
|
||||
fontSize: 12
|
||||
|
||||
# The height of lines
|
||||
lineHeight: 1
|
||||
|
||||
# The spacing between letters
|
||||
letterSpacing: 0
|
||||
|
||||
# Theme
|
||||
theme:
|
||||
background: "transparent"
|
||||
foreground: "#afafaf"
|
||||
cursor: "#c7c7c7"
|
||||
black: "#232628"
|
||||
red: "#fc4384"
|
||||
green: "#b3e33b"
|
||||
yellow: "#ffa727"
|
||||
blue: "#75dff2"
|
||||
magenta: "#ae89fe"
|
||||
cyan: "#708387"
|
||||
white: "#d5d5d0"
|
||||
brightBlack: "#626566"
|
||||
brightRed: "#ff7fac"
|
||||
brightGreen: "#c8ed71"
|
||||
brightYellow: "#ebdf86"
|
||||
brightBlue: "#75dff2"
|
||||
brightMagenta: "#ae89fe"
|
||||
brightCyan: "#b1c6ca"
|
||||
brightWhite: "#f9f9f4"
|
||||
|
||||
# Records, feel free to edit them
|
||||
records:
|
||||
- delay: 895
|
||||
content: "No protocol specified\r\nCan't open display :0\r\n"
|
||||
- delay: 253
|
||||
content: "\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;bee@beehive: ~/Documents/RustScan\a\e]1;..ents/RustScan\a"
|
||||
- delay: 29
|
||||
content: c
|
||||
- delay: 131
|
||||
content: a
|
||||
- delay: 29
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m asyncMaster\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [$!]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[32m➜ \e[0m\e[32m\e[39m\e[1m\e[0m\e[K\e[?1h\e[?2004hc"
|
||||
- delay: 5
|
||||
content: "\b\e[1m\e[31mc\e[1m\e[31ma\e[0m\e[39m\e[90mrgo build --release && ./target/release/rustscan 127.0.0.1\e[39m\e[58D"
|
||||
- delay: 719
|
||||
content: "\b\b\e[1m\e[31mc\e[1m\e[31ma\e[1m\e[31mr\e[0m\e[39m"
|
||||
- delay: 697
|
||||
content: "\b\b\b\e[1m\e[31mc\e[1m\e[31ma\e[0m\e[39m\e[0m\e[90mr\b"
|
||||
- delay: 172
|
||||
content: "\b\b\e[0m\e[32mc\e[39m\e[0m\e[90md\e[90m \e[90mR\e[90mu\e[90ms\e[90mt\e[90mS\e[90mc\e[90ma\e[90mn\e[39m\e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[59D"
|
||||
- delay: 174
|
||||
content: "\b\e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[39m \e[11D"
|
||||
- delay: 2955
|
||||
content: "\e[32mc\e[39m\e[90md RustScan\e[39m\e[10D"
|
||||
- delay: 111
|
||||
content: "\b\e[1m\e[31mc\e[1m\e[31ma\e[0m\e[39m\e[90mr\e[90mg\e[90mo\e[90m \e[90mb\e[90mu\e[90mi\e[90ml\e[90md\e[90m --release && ./target/release/rustscan 127.0.0.1\e[39m\e[58D"
|
||||
- delay: 99
|
||||
content: "\b\b\e[1m\e[31mc\e[1m\e[31ma\e[1m\e[31mr\e[0m\e[39m"
|
||||
- delay: 192
|
||||
content: "\b\b\b\e[0m\e[32mc\e[0m\e[32ma\e[0m\e[32mr\e[32mg\e[32mo\e[39m\e[39m \e[39mb\e[39mu\e[39mi\e[39ml\e[39md\e[39m \e[39m-\e[39m-\e[39mr\e[39me\e[39ml\e[39me\e[39ma\e[39ms\e[39me\e[39m \e[39m&\e[39m&\e[39m \e[32m.\e[32m/\e[32mt\e[32ma\e[32mr\e[32mg\e[32me\e[32mt\e[32m/\e[32mr\e[32me\e[32ml\e[32me\e[32ma\e[32ms\e[32me\e[32m/\e[32mr\e[32mu\e[32ms\e[32mt\e[32ms\e[32mc\e[32ma\e[32mn\e[39m\e[39m \e[39m1\e[39m2\e[39m7\e[39m.\e[39m0\e[39m.\e[39m0\e[39m.\e[39m1"
|
||||
- delay: 217
|
||||
content: "\e[?1l\e[?2004l\r\r\n\e]2;cargo build --release && ./target/release/rustscan 127.0.0.1\a\e]1;cargo\a"
|
||||
- delay: 38
|
||||
content: "\e[0m\e[0m\e[1m\e[36m Building\e[0m [ ] 0/92: autocfg \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [==========================================> ] 70/92: crossbeam-utils(build.r...\r\e[0m\e[0m\e[1m\e[36m Building\e[0m [==========================================> ] 71/92: crossbeam-utils(build.r...\r\e[0m\e[0m\e[1m\e[36m Building\e[0m [============================================> ] 73/92: crossbeam-utils(build),...\r\e[0m\e[0m\e[1m\e[36m Building\e[0m [=============================================> ] 75/92: crossbeam-utils, quote \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [==============================================> ] 76/92: crossbeam-epoch, crossb...\r\e[0m\e[0m\e[1m\e[36m Building\e[0m [===============================================> ] 78/92: crossbeam-deque, quote \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [=================================================> ] 81/92: rayon, syn \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [===================================================> ] 85/92: pin-project \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [====================================================> ] 86/92: futures-util \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [=====================================================> ] 88/92: async-std, futures-exec...\r\e[0m\e[0m\e[1m\e[36m Building\e[0m [======================================================> ] 89/92: futures-executor \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [======================================================> ] 90/92: futures \r\e[0m\e[0m\e[1m\e[36m Building\e[0m [=======================================================> ] 91/92: rustscan(bin) \r\e[K\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:193:13\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m192\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m panic!(\"Unable to convert to socket address\");\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m----------------------------------------------\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12many code following this expression is unreachable\e[0m\r\n\e[0m\e[1m\e[38;5;12m193\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m Err(io::Error::new(io::ErrorKind::Other, e.to_string()))\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\e[0m\e[0m \e[0m\e[0m\e[1m\e[33munreachable expression\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m= \e[0m\e[0m\e[1mnote\e[0m\e[0m: `#[warn(unreachable_code)]` on by default\e[0m\r\n\r\n\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: unused variable: `x`\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m--> \e[0m\e[0msrc/main.rs:57:14\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m\e[1m\e[38;5;12m57\e[0m\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m Some(x) => {\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m| \e[0m\e[0m \e[0m\e[0m\e[1m\e[33m^\e[0m\e[0m \e[0m\e[0m\e[1m\e[33mhelp: if this is intentional, prefix it with an underscore: `_x`\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m|\e[0m\r\n\e[0m \e[0m\e[0m\e[1m\e[38;5;12m= \e[0m\e[0m\e[1mnote\e[0m\e[0m: `#[warn(unused_variables)]` on by default\e[0m\r\n\r\n\e[0m\e[1m\e[33mwarning\e[0m\e[0m\e[1m: 2 warnings emitted\e[0m\r\n\r\n\e[0m\e[0m\e[1m\e[32m Finished\e[0m release [optimized] target(s) in 0.03s\r\n\e[32m\r\n _____ _ _____ \r\n | __ \\ | | / ____| \r\n | |__) | _ ___| |_| (___ ___ __ _ _ __ \r\n | _ / | | / __| __|\\___ \\ / __/ _` | '_ \\ \r\n | | \\ \\ |_| \\__ \\ |_ ____) | (_| (_| | | | |\r\n |_| \\_\\__,_|___/\\__|_____/ \\___\\__,_|_| |_|\r\n Faster nmap scanning with rust.\e[0m \r\n \e[31mAutomated Decryption Tool - https://github.com/ciphey/ciphey\e[0m \r\n \e[32mCreator https://github.com/brandonskerritt\e[0m\r\n"
|
||||
- delay: 309
|
||||
content: "Open \e[35m53\e[0m\r\nOpen \e[35m631\e[0m\r\n"
|
||||
- delay: 1132
|
||||
content: "Open \e[35m46624\e[0m\r\n"
|
||||
- delay: 136
|
||||
content: "Open \e[35m51934\e[0m\r\n"
|
||||
- delay: 159
|
||||
content: "\e[34mStarting nmap.\e[0m\r\n\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;bee@beehive: ~/Documents/RustScan\a\e]1;..ents/RustScan\aStarting Nmap 7.80 ( https://nmap.org ) at 2020-07-22 22:09 BST\r\n"
|
||||
- delay: 156
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m asyncMaster\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [$!]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mtook \e[0m\e[1m\e[33m2s\e[0m\e[33m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[32m➜ \e[0m\e[32m\e[39m\e[1m\e[0m\e[K\e[?1h\e[?2004h"
|
||||
- delay: 75
|
||||
content: "NSE: Loaded 151 scripts for scanning.\r\nNSE: Script Pre-scanning.\r\nNSE: Starting runlevel 1 (of 3) scan.\r\nInitiating NSE at 22:09\r\nCompleted NSE at 22:09, 0.00s elapsed\r\nNSE: Starting runlevel 2 (of 3) scan.\r\nInitiating NSE at 22:09\r\nCompleted NSE at 22:09, 0.00s elapsed\r\nNSE: Starting runlevel 3 (of 3) scan.\r\nInitiating NSE at 22:09\r\nCompleted NSE at 22:09, 0.00s elapsed\r\n"
|
||||
- delay: 21
|
||||
content: "Initiating Ping Scan at 22:09\r\nScanning 127.0.0.1 [2 ports]\r\nCompleted Ping Scan at 22:09, 0.00s elapsed (1 total hosts)\r\nInitiating Connect Scan at 22:09\r\nScanning localhost (127.0.0.1) [4 ports]\r\nDiscovered open port 53/tcp on 127.0.0.1\r\nDiscovered open port 631/tcp on 127.0.0.1\r\nDiscovered open port 46624/tcp on 127.0.0.1\r\nCompleted Connect Scan at 22:09, 0.00s elapsed (4 total ports)\r\n"
|
||||
- delay: 55
|
||||
content: "Initiating Service scan at 22:09\r\nScanning 3 services on localhost (127.0.0.1)\r\n"
|
||||
- delay: 42
|
||||
content: "\e[?2004l\r\r\n\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;bee@beehive: ~/Documents/RustScan\a\e]1;..ents/RustScan\a"
|
||||
- delay: 168
|
||||
content: "\r\e[0m\e[27m\e[24m\e[J\r\n\e[1m\e[0m\e[1m\e[36mRustScan\e[0m\e[36m\e[39m\e[1m \e[0m\e[1mon \e[0m\e[1m\e[37m\e[1m\e[37m\e[0m\e[37m\e[1m\e[37m\e[35m asyncMaster\e[0m\e[35m\e[39m\e[1m\e[0m\e[1m\e[0m\e[1m\e[31m [$!]\e[0m\e[31m\e[39m\e[1m\e[0m\e[0m\e[39m\e[1m \e[0m\e[1mis \e[0m\e[1m\e[31m\U0001F4E6 vrustscan:1.0.1\e[0m\e[31m\e[39m\e[1m \e[0m\e[1mvia \e[0m\e[1m\e[31m\U0001D5E5 v1.45.0\e[0m\e[31m\e[39m\e[1m \e[0m\r\n\e[1m\e[0m\e[1m\e[31m➜ \e[0m\e[31m\e[39m\e[1m\e[0m\e[K\e[?1h\e[?2004h"
|
||||
- delay: 403
|
||||
content: "\e[?2004l\r\r\n"
|
||||
|
After Width: | Height: | Size: 340 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 878 KiB |
|
After Width: | Height: | Size: 374 KiB |
@@ -1,13 +0,0 @@
|
||||
# Generated by makepkg 5.2.1
|
||||
# using fakeroot version 1.24
|
||||
pkgname = RustScan-bin
|
||||
pkgbase = RustScan-bin
|
||||
pkgver = 0.1.0-1
|
||||
pkgdesc = Faster Nmap Scanning with Rust
|
||||
url = https://github.com/brandonskerritt/rustscan
|
||||
builddate = 1594732664
|
||||
packager = Unknown Packager
|
||||
size = 911768
|
||||
arch = x86_64
|
||||
license = GNU
|
||||
provides = RustScan
|
||||
@@ -0,0 +1,20 @@
|
||||
FROM rust:latest
|
||||
|
||||
RUN git clone https://github.com/brandonskerritt/RustScan
|
||||
WORKDIR "/RustScan"
|
||||
RUN git pull --force
|
||||
RUN cargo install cargo-deb
|
||||
|
||||
RUN apt update -y && apt upgrade -y
|
||||
RUN apt install libc6-dev-i386 -y
|
||||
RUN git clone --depth=1 https://github.com/raspberrypi/tools /raspberrypi-tools
|
||||
ENV PATH=/raspberrypi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/:$PATH
|
||||
ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
|
||||
RUN mkdir /root/.cargo
|
||||
RUN echo "[target.arm-unknown-linux-gnueabihf]" >> /root/.cargo/config
|
||||
RUN echo "strip = { path = \"arm-linux-gnueabihf-strip\" }" >> /root/.cargo/config
|
||||
RUN echo "objcopy = { path = \"arm-linux-gnueabihf-objcopy\" }" >> /root/.cargo/config
|
||||
|
||||
COPY ./entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd /RustScan
|
||||
git pull --force
|
||||
|
||||
#amd64
|
||||
cargo deb
|
||||
|
||||
#arm64
|
||||
rustup target add arm-unknown-linux-gnueabihf
|
||||
cargo deb --target=arm-unknown-linux-gnueabihf
|
||||
|
||||
#i386
|
||||
rustup target add i686-unknown-linux-gnu
|
||||
cargo deb --target=i686-unknown-linux-gnu
|
||||
|
||||
find target/ -name \*.deb -exec cp {} /debs \;
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
docker build -t rustscan-builder . || exit
|
||||
|
||||
# This creates a volume which binds your currentdirectory/debs to
|
||||
# the location where the deb files get spat out in the container.
|
||||
# You don't need to worry about it. Just chmod +x run.sh && ./run.sh and
|
||||
# you'll get yer .deb file in a few minutes. It runs faster after you've used it the first time.
|
||||
docker run -v "$(pwd)/debs:/debs" rustscan-builder
|
||||
@@ -1 +0,0 @@
|
||||
/home/bee/Documents/RustScan/RustScan-0.1.0-x86_64.tar.gz
|
||||
@@ -0,0 +1,368 @@
|
||||
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 CIDRs, IPs, or hosts to be scanned.
|
||||
#[structopt(use_delimiter = true)]
|
||||
pub addresses: 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!(addresses, 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 {
|
||||
addresses: 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
|
||||
///
|
||||
/// addresses = ["127.0.0.1", "127.0.0.1"]
|
||||
/// ports = [80, 443, 8080]
|
||||
/// quiet = true
|
||||
/// scan_order: "Serial"
|
||||
///
|
||||
pub fn read() -> Self {
|
||||
let mut paths = Vec::new();
|
||||
paths.push(match dirs::home_dir() {
|
||||
Some(mut path) => {
|
||||
path.push(".rustscan.toml");
|
||||
path
|
||||
}
|
||||
None => panic!("Could not infer config file path."),
|
||||
});
|
||||
|
||||
paths.push(match dirs::config_dir() {
|
||||
Some(mut path) => {
|
||||
path.push("rustscan");
|
||||
path.push("config.toml");
|
||||
path
|
||||
}
|
||||
None => panic!("Could not infer config file path."),
|
||||
});
|
||||
|
||||
let mut contents: Option<String> = None;
|
||||
for path in paths.iter().rev() {
|
||||
contents = match fs::read_to_string(path) {
|
||||
Ok(content) => {
|
||||
contents = Some(content);
|
||||
break;
|
||||
}
|
||||
Err(_) => None,
|
||||
};
|
||||
}
|
||||
|
||||
if contents.is_none() {
|
||||
contents = Some(String::new());
|
||||
}
|
||||
|
||||
let config: Config = match toml::from_str(&contents.unwrap()) {
|
||||
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 {
|
||||
addresses: 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 {
|
||||
addresses: 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.addresses, 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 {
|
||||
addresses: 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 {
|
||||
addresses: 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.addresses, config.addresses.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 {
|
||||
addresses: 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 {
|
||||
addresses: 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);
|
||||
}
|
||||
}
|
||||
@@ -1,134 +1,473 @@
|
||||
use colored::*;
|
||||
use clap::{App, Arg};
|
||||
use std::{str::FromStr, net::{IpAddr, TcpStream, SocketAddr}};
|
||||
use rayon::prelude::*;
|
||||
use std::time::Duration;
|
||||
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 cidr_utils::cidr::IpCidr;
|
||||
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::{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() {
|
||||
// NMAP top 1k ports
|
||||
// let NMAP_1000 = vec!(1,3,4,6,7,9,13,17,19,20,21,22,23,24,25,26,30,32,33,37,42,43,49,53,70,79,80,81,82,83,84,85,88,89,90,99,100,106,109,110,111,113,119,125,135,139,143,144,146,161,163,179,199,211,212,222,254,255,256,259,264,280,301,306,311,340,366,389,406,407,416,417,425,427,443,444,445,458,464,465,481,497,500,512,513,514,515,524,541,543,544,545,548,554,555,563,587,593,616,617,625,631,636,646,648,666,667,668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800,801,808,843,873,880,888,898,900,901,902,903,911,912,981,987,990,992,993,995,999,1000,1001,1002,1007,1009,1010,1011,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1102,1104,1105,1106,1107,1108,1110,1111,1112,1113,1114,1117,1119,1121,1122,1123,1124,1126,1130,1131,1132,1137,1138,1141,1145,1147,1148,1149,1151,1152,1154,1163,1164,1165,1166,1169,1174,1175,1183,1185,1186,1187,1192,1198,1199,1201,1213,1216,1217,1218,1233,1234,1236,1244,1247,1248,1259,1271,1272,1277,1287,1296,1300,1301,1309,1310,1311,1322,1328,1334,1352,1417,1433,1434,1443,1455,1461,1494,1500,1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687,1688,1700,1717,1718,1719,1720,1721,1723,1755,1761,1782,1783,1801,1805,1812,1839,1840,1862,1863,1864,1875,1900,1914,1935,1947,1971,1972,1974,1984,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013,2020,2021,2022,2030,2033,2034,2035,2038,2040,2041,2042,2043,2045,2046,2047,2048,2049,2065,2068,2099,2100,2103,2105,2106,2107,2111,2119,2121,2126,2135,2144,2160,2161,2170,2179,2190,2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381,2382,2383,2393,2394,2399,2401,2492,2500,2522,2525,2557,2601,2602,2604,2605,2607,2608,2638,2701,2702,2710,2717,2718,2725,2800,2809,2811,2869,2875,2909,2910,2920,2967,2968,2998,3000,3001,3003,3005,3006,3007,3011,3013,3017,3030,3031,3052,3071,3077,3128,3168,3211,3221,3260,3261,3268,3269,3283,3300,3301,3306,3322,3323,3324,3325,3333,3351,3367,3369,3370,3371,3372,3389,3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689,3690,3703,3737,3766,3784,3800,3801,3809,3814,3826,3827,3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000,4001,4002,4003,4004,4005,4006,4045,4111,4125,4126,4129,4224,4242,4279,4321,4343,4443,4444,4445,4446,4449,4550,4567,4662,4848,4899,4900,4998,5000,5001,5002,5003,5004,5009,5030,5033,5050,5051,5054,5060,5061,5080,5087,5100,5101,5102,5120,5190,5200,5214,5221,5222,5225,5226,5269,5280,5298,5357,5405,5414,5431,5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678,5679,5718,5730,5800,5801,5802,5810,5811,5815,5822,5825,5850,5859,5862,5877,5900,5901,5902,5903,5904,5906,5907,5910,5911,5915,5922,5925,5950,5952,5959,5960,5961,5962,5963,5987,5988,5989,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6009,6025,6059,6100,6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565,6566,6567,6580,6646,6666,6667,6668,6669,6689,6692,6699,6779,6788,6789,6792,6839,6881,6901,6969,7000,7001,7002,7004,7007,7019,7025,7070,7100,7103,7106,7200,7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777,7778,7800,7911,7920,7921,7937,7938,7999,8000,8001,8002,8007,8008,8009,8010,8011,8021,8022,8031,8042,8045,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8093,8099,8100,8180,8181,8192,8193,8194,8200,8222,8254,8290,8291,8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651,8652,8654,8701,8800,8873,8888,8899,8994,9000,9001,9002,9003,9009,9010,9011,9040,9050,9071,9080,9081,9090,9091,9099,9100,9101,9102,9103,9110,9111,9200,9207,9220,9290,9415,9418,9485,9500,9502,9503,9535,9575,9593,9594,9595,9618,9666,9876,9877,9878,9898,9900,9917,9929,9943,9944,9968,9998,9999,10000,10001,10002,10003,10004,10009,10010,10012,10024,10025,10082,10180,10215,10243,10566,10616,10617,10621,10626,10628,10629,10778,11110,11111,11967,12000,12174,12265,12345,13456,13722,13782,13783,14000,14238,14441,14442,15000,15002,15003,15004,15660,15742,16000,16001,16012,16016,16018,16080,16113,16992,16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221,20222,20828,21571,22939,23502,24444,24800,25734,25735,26214,27000,27352,27353,27355,27356,27715,28201,30000,30718,30951,31038,31337,32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779,32780,32781,32782,32783,32784,32785,33354,33899,34571,34572,34573,35500,38292,40193,40911,41511,42510,44176,44442,44443,44501,45100,48080,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49163,49165,49167,49175,49176,49400,49999,50000,50001,50002,50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055,55056,55555,55600,56737,56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,6
Line truncated
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("RustScan")
|
||||
.author("Bee https://github.com/brandonskerritt")
|
||||
.about("Fast Port Scanner built in Rust")
|
||||
.version("0.01")
|
||||
// IP address is a required argument
|
||||
.arg(Arg::with_name("i")
|
||||
.required(true)
|
||||
.index(1)
|
||||
.long("ip-address")
|
||||
.help("The IP address to scan"))
|
||||
.arg(Arg::with_name("t")
|
||||
.short("t")
|
||||
.long("threads")
|
||||
.takes_value(true)
|
||||
.default_value("1000")
|
||||
.help("How many threads do you want to use? Default 1000"))
|
||||
.arg(Arg::with_name("T")
|
||||
.short("T")
|
||||
.long("timeout")
|
||||
.takes_value(true)
|
||||
.default_value("250")
|
||||
.help("The timeout before a port is assumed to be close. Default 250, but can go up to 1000."))
|
||||
/*.arg(Arg::with_name("n")
|
||||
.short("n")
|
||||
.long("nmap-1000")
|
||||
.takes_value(true)
|
||||
.help("Use the nmap top 1k ports"))*/
|
||||
.get_matches();
|
||||
let mut opts: Opts = Opts::read();
|
||||
let config = Config::read();
|
||||
opts.merge(&config);
|
||||
dbg!(&opts);
|
||||
|
||||
print_opening();
|
||||
info!("Main() `opts` arguments are {:?}", opts);
|
||||
|
||||
let ip = matches.value_of("i").unwrap_or("None");
|
||||
let threads_str: &str = matches.value_of("t").unwrap_or("None");
|
||||
// let nmap_arg = matches.value_of("n").unwrap_or("None");
|
||||
let threads: usize = threads_str.parse::<usize>().unwrap();
|
||||
// gets timeout duration
|
||||
let duration_timeout= Duration::from_millis(matches.value_of("T").unwrap_or("None").parse::<u64>().unwrap());
|
||||
// let ports = if !(nmap_arg == "None") { NMAP_1000.iter() } else {(1..65536)};
|
||||
|
||||
|
||||
// validates the IP address and turns it into an IpAddr type
|
||||
let addr = IpAddr::from_str(&ip)
|
||||
.expect("IPADDR must be a valid IPv4 or IPv6 address");
|
||||
if !opts.quiet && !opts.accessible {
|
||||
print_opening();
|
||||
}
|
||||
|
||||
let ips: Vec<IpAddr> = parse_addresses(&opts);
|
||||
|
||||
// increases thread pool
|
||||
rayon::ThreadPoolBuilder::new().num_threads(threads).build_global().unwrap();
|
||||
|
||||
// collect_into_vec is faster than into_vec
|
||||
let mut ports_full: Vec<bool> = vec![false; 65536];
|
||||
if ips.is_empty() {
|
||||
warning!("No IPs could be resolved, aborting scan.", false);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// performs the scan using rayon
|
||||
// 65535 + 1 because of 0 indexing
|
||||
// TODO let the user decide max port number
|
||||
(1..65536).into_par_iter()
|
||||
.map(|x: i32| scan(addr, x, duration_timeout))
|
||||
.collect_into_vec(&mut ports_full);
|
||||
let ulimit: rlimit::rlim = adjust_ulimit_size(&opts);
|
||||
let batch_size: u16 = infer_batch_size(&opts, ulimit);
|
||||
|
||||
// prints ports and places them into nmap string
|
||||
let mut nmap_str_ports = Vec::new();
|
||||
let scanner = Scanner::new(
|
||||
&ips,
|
||||
batch_size,
|
||||
Duration::from_millis(opts.timeout.into()),
|
||||
opts.quiet,
|
||||
PortStrategy::pick(opts.range, opts.ports, opts.scan_order),
|
||||
);
|
||||
|
||||
// makes vector of open ports
|
||||
for (i, item) in ports_full.iter().enumerate(){
|
||||
if item == &true{
|
||||
// appends it to port
|
||||
nmap_str_ports.push((i + 1).to_string());
|
||||
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 no ports are found, suggest running with less threads
|
||||
if nmap_str_ports.len() == 0{
|
||||
panic!("{} Looks like I didn't find any open ports. This is usually caused by too many threads. \n*I used {} threads, consider lowering to {} with {} or a comfortable number lfor your system. \n Alternatively, increase the timeout if your ping is high. Rustscan -T 1500 for 1.5 second timeout.", "ERROR".red(), threads_str, (threads / 2).to_string().green(), "'rustscan -t <thread_nums> <ip address>'".green());
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Tells the user we are now switching to Nmap
|
||||
println!("{} -A -p {:?} -vvv {}", "Starting nmap".blue(), nmap_str_ports, ip);
|
||||
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 seperated with no spaces.
|
||||
let ports_str = nmap_str_ports.join(",");
|
||||
detail!("Starting Nmap", opts.quiet);
|
||||
|
||||
// Runs the nmap command and spawns it as a process.
|
||||
/*Command::new("nmap")
|
||||
.arg("-A")
|
||||
.arg("-p")
|
||||
.arg(ports_str)
|
||||
.arg("-vvv")
|
||||
.arg(ip)
|
||||
// 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 process");*/
|
||||
}
|
||||
|
||||
fn scan(addr: IpAddr, port: i32, duration_timeout: Duration) -> bool {
|
||||
let string_list = vec![addr.to_string(), port.to_string()].join(":");
|
||||
let server: SocketAddr = string_list
|
||||
.parse()
|
||||
.expect("Unable to parse socket address");
|
||||
|
||||
match TcpStream::connect_timeout(&server,duration_timeout) {
|
||||
Ok(_) => {
|
||||
// Found open port, indicate progress
|
||||
println!("{} open", port.to_string().green());
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
Err(_) => {return false;}
|
||||
.expect("failed to execute nmap process");
|
||||
|
||||
child.wait().expect("failed to wait on nmap process");
|
||||
}
|
||||
}
|
||||
fn print_opening(){
|
||||
let s = "
|
||||
_____ _ _____
|
||||
| __ \\ | | / ____|
|
||||
| |__) | _ ___| |_| (___ ___ __ _ _ __
|
||||
| _ / | | / __| __|\\___ \\ / __/ _` | '_ \\
|
||||
| | \\ \\ |_| \\__ \\ |_ ____) | (_| (_| | | | |
|
||||
|_| \\_\\__,_|___/\\__|_____/ \\___\\__,_|_| |_|
|
||||
Faster nmap scanning with rust.";
|
||||
println!("{} \n {} \n {}", s.green(), "Automated Decryption Tool - https://github.com/ciphey/ciphey".red(),"Creator https://github.com/brandonskerritt".green());
|
||||
|
||||
|
||||
/// 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_addresses(opts: &Opts) -> Vec<IpAddr> {
|
||||
let mut ips: Vec<IpAddr> = Vec::new();
|
||||
|
||||
for ip_or_host in &opts.addresses {
|
||||
match IpCidr::from_str(ip_or_host) {
|
||||
Ok(cidr) => cidr.iter().for_each(|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_addresses, print_opening, Opts, ScanOrder,
|
||||
};
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
#[test]
|
||||
fn batch_size_lowered() {
|
||||
let opts = Opts {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: false,
|
||||
};
|
||||
let batch_size = infer_batch_size(&opts, 120);
|
||||
|
||||
assert!(batch_size < 50_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_size_lowered_average_size() {
|
||||
let opts = Opts {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: 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 {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: 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 {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: 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 {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: false,
|
||||
};
|
||||
|
||||
infer_batch_size(&opts, 1_000_000);
|
||||
|
||||
assert!(1 == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_correct_addresses() {
|
||||
let opts = Opts {
|
||||
addresses: vec!["127.0.0.1".to_owned(), "192.168.0.0/30".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_config: false,
|
||||
no_nmap: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
assert_eq!(
|
||||
ips,
|
||||
[
|
||||
Ipv4Addr::new(127, 0, 0, 1),
|
||||
Ipv4Addr::new(192, 168, 0, 0),
|
||||
Ipv4Addr::new(192, 168, 0, 1),
|
||||
Ipv4Addr::new(192, 168, 0, 2),
|
||||
Ipv4Addr::new(192, 168, 0, 3)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_correct_host_addresses() {
|
||||
let opts = Opts {
|
||||
addresses: vec!["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_config: false,
|
||||
no_nmap: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
assert_eq!(ips.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_correct_and_incorrect_addresses() {
|
||||
let opts = Opts {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
assert_eq!(ips, [Ipv4Addr::new(127, 0, 0, 1),]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_incorrect_addresses() {
|
||||
let opts = Opts {
|
||||
addresses: 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_config: false,
|
||||
no_nmap: false,
|
||||
};
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
assert_eq!(ips.is_empty(), true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
mod range_iterator;
|
||||
use super::{PortRange, ScanOrder};
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use range_iterator::RangeIterator;
|
||||
|
||||
/// Represents options of port scanning.
|
||||
///
|
||||
/// Right now all these options involve ranges, but in the future
|
||||
/// it will also contain custom lists of ports.
|
||||
pub enum PortStrategy {
|
||||
Manual(Vec<u16>),
|
||||
Serial(SerialRange),
|
||||
Random(RandomRange),
|
||||
}
|
||||
|
||||
impl PortStrategy {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait associated with a port strategy. Each PortStrategy must be able
|
||||
/// to generate an order for future port scanning.
|
||||
trait RangeOrder {
|
||||
fn generate(&self) -> Vec<u16>;
|
||||
}
|
||||
|
||||
/// As the name implies SerialRange will always generate a vector in
|
||||
/// ascending order.
|
||||
pub struct SerialRange {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
impl RangeOrder for SerialRange {
|
||||
fn generate(&self) -> Vec<u16> {
|
||||
(self.start..self.end).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// As the name implies RandomRange will always generate a vector with
|
||||
/// a random order. This vector is built following the LCG algorithm.
|
||||
pub struct RandomRange {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
impl RangeOrder for RandomRange {
|
||||
// Right now using RangeIterator and generating a range + shuffling the
|
||||
// vector is pretty much the same. The advantages of it will come once
|
||||
// we have to generate different ranges for different IPs without storing
|
||||
// actual vectors.
|
||||
//
|
||||
// Another benefit of RangeIterator is that it always generate a range with
|
||||
// a certain distance between the items in the Array. The chances of having
|
||||
// port numbers close to each other are pretty slim due to the way the
|
||||
// algorithm works.
|
||||
fn generate(&self) -> Vec<u16> {
|
||||
RangeIterator::new(self.start.into(), self.end.into()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PortStrategy;
|
||||
use crate::{PortRange, ScanOrder};
|
||||
|
||||
#[test]
|
||||
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_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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
use gcd::Gcd;
|
||||
use rand::Rng;
|
||||
|
||||
pub struct RangeIterator {
|
||||
active: bool,
|
||||
normalized_end: u32,
|
||||
normalized_first_pick: u32,
|
||||
normalized_pick: u32,
|
||||
actual_start: u32,
|
||||
step: u32,
|
||||
}
|
||||
|
||||
/// An iterator that follows the `Linear Congruential Generator` algorithm.
|
||||
///
|
||||
/// For more information: https://en.wikipedia.org/wiki/Linear_congruential_generator
|
||||
impl RangeIterator {
|
||||
/// Receives the the start and end of a range and normalize
|
||||
/// these values before selecting a coprime for the end of the range
|
||||
/// which will server as the step for the algorithm.
|
||||
///
|
||||
/// For example, the range `1000-2500` will be normalized to `0-1500`
|
||||
/// before going through the algorithm.
|
||||
pub fn new(start: u32, end: u32) -> Self {
|
||||
let normalized_end = end - start;
|
||||
let step = pick_random_coprime(normalized_end);
|
||||
|
||||
// Randomly choose a number within the range to be the first
|
||||
// and assign it as a pick.
|
||||
let mut rng = rand::thread_rng();
|
||||
let normalized_first_pick = rng.gen_range(0, normalized_end);
|
||||
|
||||
Self {
|
||||
active: true,
|
||||
normalized_end,
|
||||
step,
|
||||
normalized_first_pick,
|
||||
normalized_pick: normalized_first_pick,
|
||||
actual_start: start,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for RangeIterator {
|
||||
type Item = u16;
|
||||
|
||||
// The next step is always bound by the formula: N+1 = (N + STEP) % TOP_OF_THE_RANGE
|
||||
// It will only stop once we generate a number equal to the first generated number.
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if !self.active {
|
||||
return None;
|
||||
}
|
||||
|
||||
let current_pick = self.normalized_pick;
|
||||
let next_pick = (current_pick + self.step) % self.normalized_end;
|
||||
|
||||
// If the next pick is equal to the first pick this means that
|
||||
// we have iterated through the entire range.
|
||||
if next_pick == self.normalized_first_pick {
|
||||
self.active = false;
|
||||
}
|
||||
|
||||
self.normalized_pick = next_pick;
|
||||
Some((self.actual_start + current_pick) as u16)
|
||||
}
|
||||
}
|
||||
|
||||
/// The probability that two random integers are coprime to one another
|
||||
/// works out to be around 61%, given that we can safely pick a random
|
||||
/// number and test it. Just in case we are having a bad day and we cannot
|
||||
/// pick a coprime number after 10 tries we just return "end - 1" which
|
||||
/// is guaranteed to be a coprime, but won't provide ideal randomization.
|
||||
///
|
||||
/// We pick between "lower_range" and "upper_range" since values too close to
|
||||
/// the boundaries, which in these case are the "start" and "end" arguments
|
||||
/// would also provide non-ideal randomization as discussed on the paragraph
|
||||
/// above.
|
||||
fn pick_random_coprime(end: u32) -> u32 {
|
||||
let range_boundary = end / 4;
|
||||
let lower_range = range_boundary;
|
||||
let upper_range = end - range_boundary;
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut candidate = rng.gen_range(lower_range, upper_range);
|
||||
|
||||
for _ in 0..10 {
|
||||
if end.gcd(candidate) == 1 {
|
||||
return candidate;
|
||||
} else {
|
||||
candidate = rng.gen_range(lower_range, upper_range);
|
||||
}
|
||||
}
|
||||
|
||||
end - 1
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::RangeIterator;
|
||||
|
||||
#[test]
|
||||
fn range_iterator_iterates_through_the_entire_range() {
|
||||
let result = generate_sorted_range(1, 10);
|
||||
let expected_range = (1..10).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1, 100);
|
||||
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1, 1000);
|
||||
let expected_range = (1..1000).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1, 65_535);
|
||||
let expected_range = (1..65_535).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
|
||||
let result = generate_sorted_range(1000, 2000);
|
||||
let expected_range = (1000..2000).into_iter().collect::<Vec<u16>>();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
|
||||
fn generate_sorted_range(start: u32, end: u32) -> Vec<u16> {
|
||||
let range = RangeIterator::new(start, end);
|
||||
let mut result = range.into_iter().collect::<Vec<u16>>();
|
||||
result.sort();
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
use super::PortStrategy;
|
||||
|
||||
use async_std::io;
|
||||
use async_std::net::TcpStream;
|
||||
use async_std::prelude::*;
|
||||
use colored::*;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
io::ErrorKind,
|
||||
net::{IpAddr, Shutdown, SocketAddr},
|
||||
};
|
||||
|
||||
/// The class for the scanner
|
||||
/// IP is data type IpAddr and is the IP address
|
||||
/// start & end is where the port scan starts and ends
|
||||
/// batch_size is how many ports at a time should be scanned
|
||||
/// Timeout is the time RustScan should wait before declaring a port closed. As datatype Duration.
|
||||
/// Quiet is whether or not RustScan should print things, or wait until the end to print only open ports.
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
pub struct Scanner {
|
||||
ips: Vec<IpAddr>,
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
port_strategy: PortStrategy,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new(
|
||||
ips: &[IpAddr],
|
||||
batch_size: u16,
|
||||
timeout: Duration,
|
||||
quiet: bool,
|
||||
port_strategy: PortStrategy,
|
||||
) -> Self {
|
||||
Self {
|
||||
batch_size,
|
||||
timeout,
|
||||
quiet,
|
||||
port_strategy,
|
||||
ips: ips.iter().map(|ip| ip.to_owned()).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs scan_range with chunk sizes
|
||||
/// If you want to run RustScan normally, this is the entry point used
|
||||
/// Returns all open ports as Vec<u16>
|
||||
pub async fn run(&self) -> Vec<SocketAddr> {
|
||||
let ports: Vec<u16> = self.port_strategy.order();
|
||||
let batch_per_ip: usize = self.batch_size as usize / self.ips.len();
|
||||
let mut open_sockets: Vec<SocketAddr> = Vec::new();
|
||||
|
||||
for batch in ports.chunks(batch_per_ip) {
|
||||
let mut sockets = self.scan_ports(batch).await;
|
||||
open_sockets.append(&mut sockets);
|
||||
}
|
||||
|
||||
open_sockets
|
||||
}
|
||||
|
||||
/// Given a slice of sockets, scan them all.
|
||||
/// Returns a vector of open sockets.
|
||||
async fn scan_ports(&self, ports: &[u16]) -> Vec<SocketAddr> {
|
||||
let mut ftrs = FuturesUnordered::new();
|
||||
for port in ports {
|
||||
for ip in &self.ips {
|
||||
ftrs.push(self.scan_socket(SocketAddr::new(*ip, *port)));
|
||||
}
|
||||
}
|
||||
|
||||
let mut open_sockets: Vec<SocketAddr> = Vec::new();
|
||||
while let Some(result) = ftrs.next().await {
|
||||
match result {
|
||||
Ok(socket) => open_sockets.push(socket),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
open_sockets
|
||||
}
|
||||
|
||||
/// Given a port, scan it.
|
||||
/// Turns the address into a SocketAddr
|
||||
/// Deals with the <result> type
|
||||
/// If it experiences error ErrorKind::Other then too many files are open and it Panics!
|
||||
/// ese any other error, it returns the error in Result as a string
|
||||
/// If no errors occur, it returns the port number in Result to signify the port is open.
|
||||
/// This function mainly deals with the logic of Results handling.
|
||||
/// # Example
|
||||
///
|
||||
/// self.scan_port(10:u16)
|
||||
///
|
||||
/// Note: `self` must contain `self.ip`.
|
||||
async fn scan_socket(&self, socket: SocketAddr) -> io::Result<SocketAddr> {
|
||||
match self.connect(socket).await {
|
||||
Ok(x) => {
|
||||
// match stream_result.shutdown(Shutdown::Both)
|
||||
info!("Shutting down stream");
|
||||
match x.shutdown(Shutdown::Both) {
|
||||
_ => {}
|
||||
}
|
||||
if !self.quiet {
|
||||
println!("Open {}", socket.to_string().purple());
|
||||
}
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
Err(e) => match e.kind() {
|
||||
ErrorKind::Other => {
|
||||
panic!("Too many open files. Please reduce batch size. The default is 5000. Try -b 2500.");
|
||||
}
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, e.to_string())),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs the connection to the socket with timeout
|
||||
/// # Example
|
||||
///
|
||||
/// let port: u16 = 80
|
||||
/// // ip is an IpAddr type
|
||||
/// let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
/// let socket = SocketAddr::new(ip, port);
|
||||
/// self.connect(socket)
|
||||
/// // returns Result which is either Ok(stream) for port is open, or Er for port is closed.
|
||||
/// // Timeout occurs after self.timeout seconds
|
||||
///
|
||||
async fn connect(&self, socket: SocketAddr) -> io::Result<TcpStream> {
|
||||
let stream = io::timeout(
|
||||
self.timeout,
|
||||
async move { TcpStream::connect(socket).await },
|
||||
)
|
||||
.await?;
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{PortRange, ScanOrder};
|
||||
use async_std::task::block_on;
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
|
||||
#[test]
|
||||
fn scanner_runs() {
|
||||
// Makes sure the program still runs and doesn't panic
|
||||
let addrs = vec!["127.0.0.1".parse::<IpAddr>().unwrap()];
|
||||
let 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!
|
||||
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 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!
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
#[test]
|
||||
fn quad_zero_scanner_runs() {
|
||||
let addrs = vec!["0.0.0.0".parse::<IpAddr>().unwrap()];
|
||||
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);
|
||||
}
|
||||
#[test]
|
||||
fn google_dns_runs() {
|
||||
let addrs = vec!["8.8.8.8".parse::<IpAddr>().unwrap()];
|
||||
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);
|
||||
}
|
||||
#[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 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||