mirror of
https://github.com/Astatin3/rust-scan.git
synced 2026-06-09 00:28:06 -06:00
308 lines
14 KiB
Rust
308 lines
14 KiB
Rust
use std::{
|
|
cmp::min,
|
|
env,
|
|
net::IpAddr,
|
|
time::{Duration, Instant},
|
|
};
|
|
|
|
use parse_ip_range::parse_ip_targets;
|
|
use untitled::{
|
|
database::ResultDatabase, online_scan, parse_ip_range, port_scan::tcp_scan, query,
|
|
service_scan::service_scan::scan_services,
|
|
};
|
|
|
|
const BATCH_SIZE: usize = 4096;
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let args: Vec<String> = env::args().collect();
|
|
let database = ResultDatabase::new("ping_result_database");
|
|
|
|
if args.len() <= 1 {
|
|
println!("You must specify a command!");
|
|
print_help(None);
|
|
return Ok(());
|
|
}
|
|
|
|
match args[1].to_lowercase().as_str() {
|
|
"scan" => {
|
|
if args.len() != 4 {
|
|
println!("Invalid Usage!");
|
|
print_help(Some(args[1].as_str()));
|
|
return Ok(());
|
|
}
|
|
let _ = scan(database, args[2].clone(), args[3].clone());
|
|
}
|
|
// "search" => {
|
|
// if args.len() != 4 {
|
|
// println!("Invalid Usage!");
|
|
// print_help(Some(args[1].as_str()));
|
|
// return Ok(());
|
|
// }
|
|
// search(database, args[2].to_string(), args[3].to_string());
|
|
// }
|
|
"help" => {
|
|
if args.len() != 3 {
|
|
print_help(None);
|
|
return Ok(());
|
|
}
|
|
print_help(Some(args[2].as_str()));
|
|
}
|
|
"search" => {
|
|
let start = Instant::now();
|
|
if let Ok(query) = query::search(args[2..].join(" ")) {
|
|
let results = database.search(query);
|
|
if let Ok(results) = results {
|
|
let len = results.len();
|
|
for result in results {
|
|
println!("{}", result.to_string());
|
|
}
|
|
println!("{} results in {}ms", len, start.elapsed().as_millis());
|
|
}
|
|
}
|
|
}
|
|
_ => {
|
|
println!("Invalid command!");
|
|
print_help(None);
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
const PORTS: [i32; 1000] = [
|
|
25565, 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, 65000, 65129, 65389,
|
|
];
|
|
|
|
fn scan(
|
|
database: ResultDatabase,
|
|
search_type: String,
|
|
arg: String,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
// Set default targets or use command line input
|
|
let targets = arg;
|
|
|
|
// Parse the targets into IP addresses
|
|
let hosts = parse_ip_targets(&targets)?;
|
|
|
|
match search_type.as_str() {
|
|
"ping" => {
|
|
let length = hosts.len();
|
|
|
|
let up_hosts: Vec<IpAddr> = online_scan::ping_scanner::ping_scan(hosts).unwrap();
|
|
println!("Finished! {} Scanned, {} Up", length, up_hosts.len());
|
|
let _ = database.add_ping_results(&up_hosts);
|
|
}
|
|
"tcp" => {
|
|
let chunks = hosts.chunks(BATCH_SIZE);
|
|
let num_chunks = chunks.len();
|
|
for (i, hosts) in chunks.enumerate() {
|
|
let hosts = hosts.to_vec();
|
|
let length = hosts.len();
|
|
|
|
println!("Scanning chunk {}/{} ({} hosts)", i + 1, num_chunks, length);
|
|
|
|
let up_hosts: Vec<IpAddr> = online_scan::ping_scanner::ping_scan(hosts).unwrap();
|
|
println!(
|
|
"Finished Pinging! {} Scanned, {} Up",
|
|
length,
|
|
up_hosts.len()
|
|
);
|
|
let _ = database.add_ping_results(&up_hosts);
|
|
|
|
let tcp_results =
|
|
tcp_scan::tcp_scan(up_hosts, PORTS.to_vec(), Duration::from_secs(3));
|
|
println!("Saving Data...");
|
|
let _ = database.add_tcp_results(&tcp_results);
|
|
}
|
|
}
|
|
"service" => {
|
|
let chunks = hosts.chunks(BATCH_SIZE);
|
|
let num_chunks = chunks.len();
|
|
for (i, hosts) in chunks.enumerate() {
|
|
let hosts = hosts.to_vec();
|
|
let length = hosts.len();
|
|
|
|
println!("Scanning chunk {}/{} ({} hosts)", i + 1, num_chunks, length);
|
|
|
|
let up_hosts: Vec<IpAddr> = online_scan::ping_scanner::ping_scan(hosts).unwrap();
|
|
let up_len = up_hosts.len();
|
|
println!(
|
|
"Finished Pinging! {} Scanned, {} Up",
|
|
length,
|
|
up_hosts.len()
|
|
);
|
|
let _ = database.add_ping_results(&up_hosts);
|
|
|
|
let tcp_results =
|
|
tcp_scan::tcp_scan(up_hosts, PORTS.to_vec(), Duration::from_secs(3));
|
|
println!("Finished port scan");
|
|
let _ = database.add_tcp_results(&tcp_results);
|
|
|
|
let service_results =
|
|
scan_services(tcp_results, min(50, up_len), Duration::from_secs(1));
|
|
println!("Finished service scan");
|
|
let _ = database.add_service_results(&service_results);
|
|
}
|
|
}
|
|
_ => {
|
|
println!("Invalid search type!");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// fn search(database: ResultDatabase, search_type: String, arg: String) {
|
|
// match search_type.as_str() {
|
|
// "host" => {
|
|
// let row = database.get_row_by_host(&arg);
|
|
// if let Some(row) = row {
|
|
// println!("{}", row.to_string());
|
|
// } else {
|
|
// println!("Could not find host by argument {}", arg.as_str());
|
|
// }
|
|
// }
|
|
|
|
// "port" => {
|
|
// let rows = database.get_rows_by_port(&arg);
|
|
|
|
// for row in rows {
|
|
// println!("{}", row.to_string());
|
|
// }
|
|
// }
|
|
|
|
// "service" => {
|
|
// let rows = database.get_rows_by_service(&arg);
|
|
|
|
// for row in rows {
|
|
// println!("{}", row.to_string());
|
|
// }
|
|
// }
|
|
// _ => {
|
|
// println!("Invalid search type!");
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
fn print_help(arg: Option<&str>) {
|
|
println!(
|
|
"{}",
|
|
match arg {
|
|
None => {
|
|
"rust-scan help menu
|
|
Commands:
|
|
scan <type> <hosts> - scan a block of addresses and check for online using icmp echo
|
|
search <arguments> - Search database
|
|
help (command) - Print help"
|
|
}
|
|
Some("scan") => {
|
|
"Usage scan (type) <addresses>
|
|
|
|
Example: scan ping 127.0.0.0/8
|
|
Example: scan 12.34.0.0-12.34.56.78,127.0.0.1
|
|
|
|
scan a block of addresses using diffrent methods
|
|
|
|
- scan ping <addresses>
|
|
Scan a block of addresses and check if their online
|
|
|
|
- scan tcp <addresses>
|
|
Scan a block of addresses and check if their online, then scan and check what ports are open
|
|
|
|
- scan service <addresses>
|
|
Scan a block of addresses and check if their online, then scan to check what ports are open, then scan to check what services are running and record responses
|
|
|
|
- scan <addresses>
|
|
Same as scan service"
|
|
}
|
|
|
|
Some("search") => {
|
|
"Usage: search <arguments>
|
|
Example: search ssh:raspbian
|
|
Example: search port:80,443 http-nginx https-nginx
|
|
Example: search port-8081 https:favicon
|
|
Example: search google
|
|
Example: search port=22,80,443
|
|
|
|
The format of the search is a list of tags that include the service or port followed by an equator, or a plain text search
|
|
|
|
There are four types of equators
|
|
|
|
\":\" or \"+\" - If the result contains an item
|
|
\"-\" - If the result does not contain an item
|
|
\"=\" - If the result is exactly equal to an item
|
|
\"!=\" - If the result is exactly not equal to an item
|
|
|
|
"
|
|
}
|
|
Some(_) => {
|
|
print_help(None);
|
|
"Invalid Command!"
|
|
}
|
|
}
|
|
);
|
|
}
|