1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
package com.it_jaros.jscanner;
import java.time.Duration;
import java.util.BitSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
public class App {
private static Thread shutdownHook;
private static final CountDownLatch shutdownLatch = new CountDownLatch(1);
private static final int shutdownTimeoutInMillis = 10000;
public static void main(String[] args) {
try {
run(args);
} catch (Exception e) {
System.out.printf("ERROR: %s", e.getMessage());
}
}
private static void run(String[] args) throws Exception {
ScanOptions options = parseOptions(args);
if (options == null) return;
try (Scanner scanner = new Scanner(options)) {
Scan scan = Scan.create(options);
addShutdownHook(scanner, options);
printScanResults(scanner.runScan(scan), scan.getPeakConcurrentConnects(), options.showFilteredPorts());
} finally {
shutdownLatch.countDown();
removeShutdownHook();
}
}
private static ScanOptions parseOptions(String[] args) {
CliParser cliParser = new CliParser();
try {
return cliParser.parseArgs(args);
} catch (IllegalArgumentException e) {
System.out.printf("Error while parsing arguments: %s", e.getMessage());
System.out.println();
}
cliParser.usageAndExit(1);
return null;
}
private static void printScanResults(List<ScanResult> result, int max, boolean showFilteredPorts) {
printStats(max);
result.forEach((ScanResult r) -> printPortsResults(r, showFilteredPorts));
}
private static void printStats(int max) {
System.out.println("--------------------");
System.out.println("Stats:");
System.out.println("Peak concurrent connects: " + max);
System.out.println("--------------------");
}
private static void printPortsResults(ScanResult result, boolean showFilteredPorts) {
if (result.openPorts().isEmpty() && (!showFilteredPorts || result.filteredPorts().isEmpty())) {
return;
}
System.out.println(result.host());
if (!result.openPorts().isEmpty()) {
System.out.printf("\t (%d) open:\t%s%n", result.openPorts().cardinality(), map(result.openPorts(), result.bannerRecognition()));
}
if (showFilteredPorts && !result.filteredPorts().isEmpty()) {
System.out.printf("\t (%d) filtered:\t%s%n", result.filteredPorts().cardinality(), map(result.filteredPorts()));
}
System.out.println();
}
private static String map(BitSet ports) {
return ports.stream().mapToObj(String::valueOf).collect(Collectors.joining(","));
}
private static String map(BitSet ports, java.util.HashMap<Integer, ServiceType> bannerRecognition) {
return ports.stream().mapToObj(port -> {
ServiceType serviceType = bannerRecognition.getOrDefault(port, ServiceType.UNKNOWN);
if (serviceType == ServiceType.UNKNOWN) {
return String.valueOf(port);
}
return port + "/" + serviceType.name().toLowerCase();
}).collect(Collectors.joining(","));
}
/**
* Notice user that the signal was received
* Start shutdown of scanner
*
* @param scanner
*/
private static void addShutdownHook(Scanner scanner, ScanOptions options) {
shutdownHook = new Thread(() -> {
System.err.printf("%nCtrl-C received. Shutting down... Waiting for timeout of %d seconds%n", shutdownTimeoutInMillis / 1000);
shutdown(scanner);
});
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
/**
* Try to gracefully shutdown scanner
* and wait
*
* @param scanner
*/
private static void shutdown(Scanner scanner) {
try {
scanner.cancel();
scanner.awaitTermination(Duration.ofMillis(shutdownTimeoutInMillis));
shutdownLatch.await(shutdownTimeoutInMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (TimeoutException e) {
// Time ran out
}
}
private static void removeShutdownHook() {
if (shutdownHook == null) {
return;
}
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ignored) {
// JVM is already shutting down
}
}
}
|