13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
+
16
17
package com .google .tsunami .plugins .detectors .cves .cve202422476 ;
17
18
18
19
import static com .google .common .truth .Truth .assertThat ;
19
20
import static com .google .common .truth .extensions .proto .ProtoTruth .assertThat ;
20
- import static com .google .tsunami .common .data .NetworkEndpointUtils .forHostname ;
21
21
import static com .google .tsunami .common .data .NetworkEndpointUtils .forHostnameAndPort ;
22
22
23
23
import com .google .common .collect .ImmutableList ;
24
24
import com .google .inject .Guice ;
25
25
import com .google .protobuf .util .Timestamps ;
26
26
import com .google .tsunami .common .net .http .HttpClientModule ;
27
- import com .google .tsunami .common .net .http .HttpStatus ;
28
27
import com .google .tsunami .common .time .testing .FakeUtcClock ;
29
28
import com .google .tsunami .common .time .testing .FakeUtcClockModule ;
30
29
import com .google .tsunami .plugin .payload .testing .FakePayloadGeneratorModule ;
34
33
import com .google .tsunami .proto .DetectionStatus ;
35
34
import com .google .tsunami .proto .NetworkService ;
36
35
import com .google .tsunami .proto .Severity ;
37
- import com .google .tsunami .proto .Software ;
38
36
import com .google .tsunami .proto .TargetInfo ;
39
- import com .google .tsunami .proto .TransportProtocol ;
40
37
import com .google .tsunami .proto .Vulnerability ;
41
38
import com .google .tsunami .proto .VulnerabilityId ;
42
39
import java .io .IOException ;
43
40
import java .time .Instant ;
44
41
import javax .inject .Inject ;
42
+ import okhttp3 .mockwebserver .Dispatcher ;
45
43
import okhttp3 .mockwebserver .MockResponse ;
46
44
import okhttp3 .mockwebserver .MockWebServer ;
45
+ import okhttp3 .mockwebserver .RecordedRequest ;
47
46
import org .junit .After ;
48
47
import org .junit .Before ;
49
48
import org .junit .Test ;
@@ -57,7 +56,7 @@ public class Cve202422476VulnDetectorTest {
57
56
FakeUtcClock .create ().setNow (Instant .parse ("2022-05-23T00:00:00.00Z" ));
58
57
private MockWebServer mockWebServer ;
59
58
private MockWebServer mockCallbackServer ;
60
- private NetworkService service ;
59
+ private NetworkService targetNetworkService ;
61
60
private TargetInfo targetInfo ;
62
61
63
62
@ Inject private Cve202422476VulnDetector detector ;
@@ -74,20 +73,6 @@ public void setUp() throws IOException {
74
73
FakePayloadGeneratorModule .builder ().setCallbackServer (mockCallbackServer ).build (),
75
74
new Cve202422476DetectorBootstrapModule ())
76
75
.injectMembers (this );
77
-
78
- service =
79
- NetworkService .newBuilder ()
80
- .setNetworkEndpoint (
81
- forHostnameAndPort (mockWebServer .getHostName (), mockWebServer .getPort ()))
82
- .setTransportProtocol (TransportProtocol .TCP )
83
- .setSoftware (Software .newBuilder ().setName ("http" ))
84
- .setServiceName ("http" )
85
- .build ();
86
-
87
- targetInfo =
88
- TargetInfo .newBuilder ()
89
- .addNetworkEndpoints (forHostname (mockWebServer .getHostName ()))
90
- .build ();
91
76
}
92
77
93
78
@ After
@@ -99,21 +84,16 @@ public void tearDown() throws IOException {
99
84
@ Test
100
85
public void detect_whenVulnerable_returnsVulnerability () throws IOException {
101
86
// It is a blind RCE, body is not important. This is a part of a valid response.
102
- mockWebServer .enqueue (
103
- new MockResponse ()
104
- .setResponseCode (200 )
105
- .setBody (
106
- "{\" status\" :\" successfully\" ,\" task_id\" :\" 065d95dd70524cb2baa743def3ff7036\" ,\" msg\" :\" Task"
107
- + " submitted successfully\" }" ));
108
-
87
+ startMockWebServer (true );
109
88
mockCallbackServer .enqueue (PayloadTestHelper .generateMockSuccessfulCallbackResponse ());
110
- DetectionReportList detectionReports = detector .detect (targetInfo , ImmutableList .of (service ));
89
+ DetectionReportList detectionReports =
90
+ detector .detect (targetInfo , ImmutableList .of (targetNetworkService ));
111
91
112
92
assertThat (detectionReports .getDetectionReportsList ())
113
93
.containsExactly (
114
94
DetectionReport .newBuilder ()
115
95
.setTargetInfo (targetInfo )
116
- .setNetworkService (service )
96
+ .setNetworkService (targetNetworkService )
117
97
.setDetectionTimestamp (
118
98
Timestamps .fromMillis (Instant .now (fakeUtcClock ).toEpochMilli ()))
119
99
.setDetectionStatus (DetectionStatus .VULNERABILITY_VERIFIED )
@@ -138,17 +118,63 @@ public void detect_whenVulnerable_returnsVulnerability() throws IOException {
138
118
+ " result, attackers can manipulate this parameter to remotely"
139
119
+ " execute arbitrary commands." ))
140
120
.build ());
141
- assertThat (mockWebServer .getRequestCount ()).isEqualTo (1 );
121
+ assertThat (mockWebServer .getRequestCount ()).isEqualTo (2 );
142
122
assertThat (mockCallbackServer .getRequestCount ()).isEqualTo (1 );
143
123
}
144
124
145
125
@ Test
146
126
public void detect_ifNotVulnerable_doesNotReportVuln () throws IOException {
147
- mockWebServer .enqueue (
148
- new MockResponse ().setResponseCode (HttpStatus .OK .code ()).setBody ("Hello world!" ));
127
+ startMockWebServer (false );
149
128
150
- DetectionReportList detectionReports = detector .detect (targetInfo , ImmutableList .of (service ));
129
+ DetectionReportList detectionReports =
130
+ detector .detect (targetInfo , ImmutableList .of (targetNetworkService ));
151
131
assertThat (detectionReports .getDetectionReportsList ()).isEmpty ();
152
- assertThat (mockWebServer .getRequestCount ()).isEqualTo (1 );
132
+ assertThat (mockWebServer .getRequestCount ()).isEqualTo (2 );
133
+ }
134
+
135
+ private void startMockWebServer (boolean isVulnerableServer ) throws IOException {
136
+ final Dispatcher dispatcher =
137
+ new Dispatcher () {
138
+
139
+ @ Override
140
+ public MockResponse dispatch (RecordedRequest request ) {
141
+ switch (request .getPath ()) {
142
+ case "/" :
143
+ return new MockResponse ()
144
+ .setResponseCode (200 )
145
+ .setBody ("{\" message\" :\" Welcome to Neural Solution!\" }" );
146
+ case "/task/submit/" :
147
+ if (isVulnerableServer ) {
148
+ return new MockResponse ()
149
+ .setResponseCode (200 )
150
+ .setBody (
151
+ "{\" status\" :\" successfully\" ,\" task_id\" :\" 065d95dd70524cb2baa743def3ff7036\" ,\" msg\" :\" Task"
152
+ + " submitted successfully\" }" );
153
+ } else {
154
+ return new MockResponse ()
155
+ .setResponseCode (422 )
156
+ .setBody ("{\" detail\" :\" Invalid task\" }" );
157
+ }
158
+ default :
159
+ return new MockResponse ()
160
+ .setResponseCode (404 )
161
+ .setBody ("{\" detail\" :\" Not Found\" }" );
162
+ }
163
+ }
164
+ };
165
+ mockWebServer .setDispatcher (dispatcher );
166
+ mockWebServer .start ();
167
+ mockWebServer .url ("/" );
168
+ targetNetworkService =
169
+ NetworkService .newBuilder ()
170
+ .setNetworkEndpoint (
171
+ forHostnameAndPort (mockWebServer .getHostName (), mockWebServer .getPort ()))
172
+ .addSupportedHttpMethods ("POST" )
173
+ .addSupportedHttpMethods ("GET" )
174
+ .build ();
175
+ targetInfo =
176
+ TargetInfo .newBuilder ()
177
+ .addNetworkEndpoints (targetNetworkService .getNetworkEndpoint ())
178
+ .build ();
153
179
}
154
180
}
0 commit comments