]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ssh: disable inspection in encrypted phase
authorVictor Julien <victor@inliniac.net>
Sat, 1 Mar 2014 17:11:19 +0000 (18:11 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 3 Mar 2014 16:34:57 +0000 (17:34 +0100)
When both sides of the session have completed the encryption setup,
flag the stream to disable detection.

src/app-layer-ssh.c

index 8205c4709ae7a15307e487f348c2c8bf7cf6289c..8f85a57c507a0f9ad3dd5924eb2aa546452fb3c4 100644 (file)
@@ -316,18 +316,6 @@ again:
         }
     }
 
-#if 0
-    if (state->cli_hdr.msg_code == SSH_MSG_NEWKEYS) {
-        /* We are not going to inspect any packet more
-         * as the data is now encrypted */
-        SCLogDebug("SSH parser done (the rest of the communication is encrypted)");
-        pstate->flags |= APP_LAYER_PARSER_DONE;
-        pstate->flags |= APP_LAYER_PARSER_NO_INSPECTION;
-        pstate->flags |= APP_LAYER_PARSER_NO_REASSEMBLY;
-        pstate->parse_field = 1;
-        SCReturnInt(1);
-    }
-#endif
     SCReturnInt(0);
 }
 
@@ -406,6 +394,13 @@ static int SSHParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
     SshHeader *ssh_header = &ssh_state->cli_hdr;
 
     int r = SSHParseData(ssh_state, ssh_header, input, input_len);
+
+    if (ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE &&
+        ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE) {
+        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION);
+        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY);
+    }
+
     SCReturnInt(r);
 }
 
@@ -417,6 +412,13 @@ static int SSHParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
     SshHeader *ssh_header = &ssh_state->srv_hdr;
 
     int r = SSHParseData(ssh_state, ssh_header, input, input_len);
+
+    if (ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE &&
+        ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE) {
+        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION);
+        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY);
+    }
+
     SCReturnInt(r);
 }
 
@@ -1856,6 +1858,109 @@ end:
     return result;
 }
 
+/** \test 2 directional test */
+static int SSHParserTest18(void) {
+    int result = 0;
+    Flow f;
+
+    uint8_t server1[] = "SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu3\r\n";
+    uint32_t serverlen1 = sizeof(server1) - 1;
+
+    uint8_t sshbuf1[] = "SSH-";
+    uint32_t sshlen1 = sizeof(sshbuf1) - 1;
+    uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n";
+    uint32_t sshlen2 = sizeof(sshbuf2) - 1;
+
+    uint8_t server2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 };
+    uint32_t serverlen2 = sizeof(server2) - 1;
+
+    uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 };
+    uint32_t sshlen3 = sizeof(sshbuf3);
+
+
+    TcpSession ssn;
+    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+    memset(&f, 0, sizeof(f));
+    memset(&ssn, 0, sizeof(ssn));
+    f.protoctx = (void *)&ssn;
+
+    StreamTcpInitConfig(TRUE);
+
+    SCMutexLock(&f.m);
+    int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, server1, serverlen1);
+    if (r != 0) {
+        printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    SCMutexLock(&f.m);
+    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1);
+    if (r != 0) {
+        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    SCMutexLock(&f.m);
+    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2);
+    if (r != 0) {
+        printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    SCMutexLock(&f.m);
+    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, server2, serverlen2);
+    if (r != 0) {
+        printf("toclient chunk 2 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    SCMutexLock(&f.m);
+    r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3);
+    if (r != 0) {
+        printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    SshState *ssh_state = f.alstate;
+    if (ssh_state == NULL) {
+        printf("no ssh state: ");
+        goto end;
+    }
+
+    if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) {
+        printf("Didn't detect the msg code of new keys (ciphered data starts): ");
+        goto end;
+    }
+
+    if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) {
+        printf("Didn't detect the msg code of new keys (ciphered data starts): ");
+        goto end;
+    }
+
+    if (!(AppLayerParserStateIssetFlag(f.alparser, APP_LAYER_PARSER_NO_INSPECTION))) {
+        printf("detection not disabled: ");
+        goto end;
+    }
+
+    result = 1;
+end:
+    if (alp_tctx != NULL)
+        AppLayerParserThreadCtxFree(alp_tctx);
+    StreamTcpFreeConfig(TRUE);
+    return result;
+}
+
 #endif /* UNITTESTS */
 
 void SSHParserRegisterTests(void) {
@@ -1877,6 +1982,7 @@ void SSHParserRegisterTests(void) {
     UtRegisterTest("SSHParserTest15", SSHParserTest15, 1);
     UtRegisterTest("SSHParserTest16", SSHParserTest16, 1);
     UtRegisterTest("SSHParserTest17", SSHParserTest17, 1);
+    UtRegisterTest("SSHParserTest18", SSHParserTest18, 1);
 #endif /* UNITTESTS */
 }