Skip to content

Commit 5859f13

Browse files
tooryxcopybara-github
authored andcommitted
Restructure the documentation about how to write a new detector.
PiperOrigin-RevId: 716694646 Change-Id: I670a533ed873c093e0cf9ab8807f7735d80b5990
1 parent 67781bd commit 5859f13

File tree

2 files changed

+179
-169
lines changed

2 files changed

+179
-169
lines changed

docs/howto/new-detector.md

+6-169
Original file line numberDiff line numberDiff line change
@@ -1,173 +1,10 @@
11
# Writing a Tsunami detector
22

3-
## Overview
3+
Welcome to the Tsunami community, we are thrilled that you want to contribute.
4+
This guide will help you get started with writing a Tsunami detector.
45

5-
Each Tsunami detector needs the following pieces which we will create in this
6-
tutorial:
6+
There are several ways to write a Tsunami detector:
77

8-
* A plugin name that is unique among all enabled Tsunami plugins.
9-
* A set of build rules for [Gradle](https://gradle.org/) (external build)
10-
* A `VulnDetector` that implements the vulnerability detection logic.
11-
* A `PluginBootstrapModule` that provides necessary Guice bindings for the
12-
detector.
13-
* An optional `CliOption` that captures all the supported command line flags
14-
for the detector.
15-
* An optional `ConfigProperties` that captures all the supported configuration
16-
for the detector.
17-
18-
## 1. Fork the examples
19-
20-
Tsunami provides a few example implementations of a `VulnDetector` plugin. The
21-
examples live in the
22-
[examples directory](https://github.com/google/tsunami-security-scanner-plugins/tree/master/examples)
23-
24-
* Update Java package names. The example `VulnDetector` plugin is defined
25-
under `com.google.tsunami.plugins.example` package. Refactor the package and
26-
class name according to your detector implementation.
27-
* Give a meaningful description to the Gradle build rule at `build.gradle`. We
28-
will work on the Gradle build rule later.
29-
* Rewrite the `README.md` file to have a good explanation of your
30-
`VulnDetector` plugin.
31-
32-
## 2. Putting the detector together
33-
34-
### 2.a - `PluginInfo` annotation
35-
36-
All Tsunami plugins must be annotated by the `PluginInfo` annotation. Otherwise
37-
it cannot be identified by Tsunami scanner at runtime. This annotation provides
38-
the general information about the plugin to the core scanner.
39-
40-
Following is an example usage of the `PluginInfo` annotation from our
41-
`WordPressInstallPageDetector`.
42-
43-
```java
44-
@PluginInfo(
45-
// VULN_DETECTION PluginType is required for a VulnDetector plugin.
46-
type = PluginType.VULN_DETECTION,
47-
// This gives a human readable name for your VulnDetector. Can be different
48-
// from your class name.
49-
name = "WordPressInstallPageDetector",
50-
// The current version of your plugin.
51-
version = "0.1",
52-
// A detailed description about what this plugin does.
53-
description =
54-
"This detector checks whether a WordPress install is unfinished. An unfinished WordPress"
55-
+ " installation exposes the /wp-admin/install.php page, which allows attacker to set"
56-
+ " the admin password and possibly compromise the system.",
57-
// The author of this plugin.
58-
author = "Tsunami Team ([email protected])",
59-
// The guice module that bootstraps this plugin.
60-
bootstrapModule = WordPressInstallPageDetectorBootstrapModule.class)
61-
```
62-
63-
### 2.b - Define the `VulnDetector` plugin
64-
65-
Each vulnerability detector plugin is an implementation of the `VulnDetector`
66-
interface. For this step we only explain the placeholder code, later you'll need
67-
to provide implementations for the class itself.
68-
69-
Following is an example placeholder code from the
70-
`WordPressInstallPageDetector`:
71-
72-
```java
73-
// ...
74-
// annotations
75-
// ...
76-
public final class WordPressInstallPageDetector implements VulnDetector {
77-
// See https://github.com/google/flogger for details.
78-
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
79-
80-
// Tsunami uses Guice (https://github.com/google/guice) to manage the
81-
// dependencies.
82-
@Inject
83-
WordPressInstallPageDetector(
84-
// Tsunami provides a UtcClock for production and FakeUtcClock for
85-
// testing purposes.
86-
@UtcClock Clock utcClock,
87-
// You can also inject other useful dependencies to your plugin code, e.g.
88-
// inject HttpClient if you need to interact with a web server.
89-
HttpClient httpClient) {
90-
}
91-
92-
// The entrypoint of the VulnDetector. We will explain this later.
93-
@Override
94-
public DetectionReportList detect(
95-
TargetInfo targetInfo, ImmutableList<NetworkService> matchedServices) {
96-
// implement me.
97-
}
98-
}
99-
```
100-
101-
### 2.c - Implement the main detection logic
102-
103-
The main logic of the detection is expected to happen in the `detect` method,
104-
which expects two arguments:
105-
106-
1. [The `TargetInfo` proto](https://github.com/google/tsunami-security-scanner/blob/master/proto/reconnaissance.proto).
107-
This proto contains information that were gathered during the fingerprinting
108-
and discovery phase.
109-
1. [The `NetworkService` list](https://github.com/google/tsunami-security-scanner/blob/master/proto/network_service.proto).
110-
This list contains all the identified network services that match the
111-
service filtering annotations.
112-
113-
The main detection logic usually iterates over all the elements of the
114-
`matchedServices` parameter and checks whether the `NetworkService` is
115-
vulnerable to the vulnerability your plugin checks for. If any service is
116-
vulnerable, you'll need to build a `DetectionReport` proto that explains the
117-
identified vulnerability.
118-
119-
Following is an example implementation from our `WordPressInstallPageDetector`:
120-
121-
```java
122-
@Override
123-
public DetectionReportList detect(
124-
TargetInfo targetInfo, ImmutableList<NetworkService> matchedServices) {
125-
return DetectionReportList.newBuilder()
126-
.addAllDetectionReports(
127-
matchedServices.stream()
128-
// The WordPressInstallPageDetector only works for web services.
129-
.filter(NetworkServiceUtils::isWebService)
130-
// Detection logic that checks whether a web service exposes
131-
// a wordpress installation page. Omitted here for simplicity.
132-
.filter(this::isServiceVulnerable)
133-
// Build a DetectionReport when the web service is vulnerable.
134-
.map(networkService -> buildDetectionReport(targetInfo, networkService))
135-
.collect(toImmutableList()))
136-
.build();
137-
}
138-
139-
private DetectionReport buildDetectionReport(
140-
TargetInfo scannedTarget, NetworkService vulnerableNetworkService) {
141-
return DetectionReport.newBuilder()
142-
.setTargetInfo(scannedTarget)
143-
.setNetworkService(vulnerableNetworkService)
144-
.setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli()))
145-
.setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED)
146-
.setVulnerability(
147-
Vulnerability.newBuilder()
148-
.setMainId(
149-
VulnerabilityId.newBuilder()
150-
.setPublisher("GOOGLE")
151-
.setValue("UNFINISHED_WORD_PRESS_INSTALLATION"))
152-
.setSeverity(Severity.CRITICAL)
153-
.setTitle("Unfinished WordPress Installation")
154-
.setDescription(
155-
"An unfinished WordPress installation exposes the /wp-admin/install.php page,"
156-
+ " which allows attacker to set the admin password and possibly"
157-
+ " compromise the system."))
158-
.build();
159-
}
160-
```
161-
162-
## 3. Preparing the `PluginBootstrapModule`
163-
164-
Each Tsunami plugin must have a companion `PluginBootstrapModule` that provides
165-
the required Guice bindings and registers the plugin to the core engine.
166-
167-
Creating a `PluginBootstrampModule` is rather simple if you only need to
168-
register the plugin. You only need to call `registerPlugin` within the
169-
`configurePlugin` method (e.g.
170-
[`ExampleVulnDetectorBootstrapModule`](https://github.com/google/tsunami-security-scanner-plugins/tree/master/examples/example_vuln_detector/src/main/java/com/google/tsunami/plugins/example/ExampleVulnDetectorBootstrapModule.java)).
171-
172-
A more complete example is the
173-
[GenericWeakCredentialDetectorBootstrapModule](https://github.com/google/tsunami-security-scanner-plugins/blob/master/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/GenericWeakCredentialDetectorBootstrapModule.java)
8+
* Using our custom configuration format (coming soon)
9+
* [Using Java]({{ site.baseurl }}/howto/new-detector/new-detector-java)
10+
* Using Python (not documented yet)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Writing a Tsunami detector (Java)
2+
3+
## Overview
4+
5+
Each Tsunami detector needs the following pieces which we will create in this
6+
tutorial:
7+
8+
* A plugin name that is unique among all enabled Tsunami plugins.
9+
* A set of build rules for [Gradle](https://gradle.org/) (external build)
10+
* A `VulnDetector` that implements the vulnerability detection logic.
11+
* A `PluginBootstrapModule` that provides necessary Guice bindings for the
12+
detector.
13+
* An optional `CliOption` that captures all the supported command line flags
14+
for the detector.
15+
* An optional `ConfigProperties` that captures all the supported configuration
16+
for the detector.
17+
18+
## 1. Fork the examples
19+
20+
Tsunami provides a few example implementations of a `VulnDetector` plugin. The
21+
examples live in the
22+
[examples directory](https://github.com/google/tsunami-security-scanner-plugins/tree/master/examples)
23+
24+
* Update Java package names. The example `VulnDetector` plugin is defined
25+
under `com.google.tsunami.plugins.example` package. Refactor the package and
26+
class name according to your detector implementation.
27+
* Give a meaningful description to the Gradle build rule at `build.gradle`. We
28+
will work on the Gradle build rule later.
29+
* Rewrite the `README.md` file to have a good explanation of your
30+
`VulnDetector` plugin.
31+
32+
## 2. Putting the detector together
33+
34+
### 2.a - `PluginInfo` annotation
35+
36+
All Tsunami plugins must be annotated by the `PluginInfo` annotation. Otherwise
37+
it cannot be identified by Tsunami scanner at runtime. This annotation provides
38+
the general information about the plugin to the core scanner.
39+
40+
Following is an example usage of the `PluginInfo` annotation from our
41+
`WordPressInstallPageDetector`.
42+
43+
```java
44+
@PluginInfo(
45+
// VULN_DETECTION PluginType is required for a VulnDetector plugin.
46+
type = PluginType.VULN_DETECTION,
47+
// This gives a human readable name for your VulnDetector. Can be different
48+
// from your class name.
49+
name = "WordPressInstallPageDetector",
50+
// The current version of your plugin.
51+
version = "0.1",
52+
// A detailed description about what this plugin does.
53+
description =
54+
"This detector checks whether a WordPress install is unfinished. An unfinished WordPress"
55+
+ " installation exposes the /wp-admin/install.php page, which allows attacker to set"
56+
+ " the admin password and possibly compromise the system.",
57+
// The author of this plugin.
58+
author = "Tsunami Team ([email protected])",
59+
// The guice module that bootstraps this plugin.
60+
bootstrapModule = WordPressInstallPageDetectorBootstrapModule.class)
61+
```
62+
63+
### 2.b - Define the `VulnDetector` plugin
64+
65+
Each vulnerability detector plugin is an implementation of the `VulnDetector`
66+
interface. For this step we only explain the placeholder code, later you'll need
67+
to provide implementations for the class itself.
68+
69+
Following is an example placeholder code from the
70+
`WordPressInstallPageDetector`:
71+
72+
```java
73+
// ...
74+
// annotations
75+
// ...
76+
public final class WordPressInstallPageDetector implements VulnDetector {
77+
// See https://github.com/google/flogger for details.
78+
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
79+
80+
// Tsunami uses Guice (https://github.com/google/guice) to manage the
81+
// dependencies.
82+
@Inject
83+
WordPressInstallPageDetector(
84+
// Tsunami provides a UtcClock for production and FakeUtcClock for
85+
// testing purposes.
86+
@UtcClock Clock utcClock,
87+
// You can also inject other useful dependencies to your plugin code, e.g.
88+
// inject HttpClient if you need to interact with a web server.
89+
HttpClient httpClient) {
90+
}
91+
92+
// The entrypoint of the VulnDetector. We will explain this later.
93+
@Override
94+
public DetectionReportList detect(
95+
TargetInfo targetInfo, ImmutableList<NetworkService> matchedServices) {
96+
// implement me.
97+
}
98+
}
99+
```
100+
101+
### 2.c - Implement the main detection logic
102+
103+
The main logic of the detection is expected to happen in the `detect` method,
104+
which expects two arguments:
105+
106+
1. [The `TargetInfo` proto](https://github.com/google/tsunami-security-scanner/blob/master/proto/reconnaissance.proto).
107+
This proto contains information that were gathered during the fingerprinting
108+
and discovery phase.
109+
1. [The `NetworkService` list](https://github.com/google/tsunami-security-scanner/blob/master/proto/network_service.proto).
110+
This list contains all the identified network services that match the
111+
service filtering annotations.
112+
113+
The main detection logic usually iterates over all the elements of the
114+
`matchedServices` parameter and checks whether the `NetworkService` is
115+
vulnerable to the vulnerability your plugin checks for. If any service is
116+
vulnerable, you'll need to build a `DetectionReport` proto that explains the
117+
identified vulnerability.
118+
119+
Following is an example implementation from our `WordPressInstallPageDetector`:
120+
121+
```java
122+
@Override
123+
public DetectionReportList detect(
124+
TargetInfo targetInfo, ImmutableList<NetworkService> matchedServices) {
125+
return DetectionReportList.newBuilder()
126+
.addAllDetectionReports(
127+
matchedServices.stream()
128+
// The WordPressInstallPageDetector only works for web services.
129+
.filter(NetworkServiceUtils::isWebService)
130+
// Detection logic that checks whether a web service exposes
131+
// a wordpress installation page. Omitted here for simplicity.
132+
.filter(this::isServiceVulnerable)
133+
// Build a DetectionReport when the web service is vulnerable.
134+
.map(networkService -> buildDetectionReport(targetInfo, networkService))
135+
.collect(toImmutableList()))
136+
.build();
137+
}
138+
139+
private DetectionReport buildDetectionReport(
140+
TargetInfo scannedTarget, NetworkService vulnerableNetworkService) {
141+
return DetectionReport.newBuilder()
142+
.setTargetInfo(scannedTarget)
143+
.setNetworkService(vulnerableNetworkService)
144+
.setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli()))
145+
.setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED)
146+
.setVulnerability(
147+
Vulnerability.newBuilder()
148+
.setMainId(
149+
VulnerabilityId.newBuilder()
150+
.setPublisher("GOOGLE")
151+
.setValue("UNFINISHED_WORD_PRESS_INSTALLATION"))
152+
.setSeverity(Severity.CRITICAL)
153+
.setTitle("Unfinished WordPress Installation")
154+
.setDescription(
155+
"An unfinished WordPress installation exposes the /wp-admin/install.php page,"
156+
+ " which allows attacker to set the admin password and possibly"
157+
+ " compromise the system."))
158+
.build();
159+
}
160+
```
161+
162+
## 3. Preparing the `PluginBootstrapModule`
163+
164+
Each Tsunami plugin must have a companion `PluginBootstrapModule` that provides
165+
the required Guice bindings and registers the plugin to the core engine.
166+
167+
Creating a `PluginBootstrampModule` is rather simple if you only need to
168+
register the plugin. You only need to call `registerPlugin` within the
169+
`configurePlugin` method (e.g.
170+
[`ExampleVulnDetectorBootstrapModule`](https://github.com/google/tsunami-security-scanner-plugins/tree/master/examples/example_vuln_detector/src/main/java/com/google/tsunami/plugins/example/ExampleVulnDetectorBootstrapModule.java)).
171+
172+
A more complete example is the
173+
[GenericWeakCredentialDetectorBootstrapModule](https://github.com/google/tsunami-security-scanner-plugins/blob/master/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/GenericWeakCredentialDetectorBootstrapModule.java)

0 commit comments

Comments
 (0)