Skip to content

Commit 7279fbd

Browse files
committed
Strict KEX 対応 (CVE-2023-48795)
とりあえず Strict KEX のネゴシエーションとシーケンス番号のリセットに対応。
1 parent 809e59d commit 7279fbd

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

Diff for: ttssh2/ttxssh/kex.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ void SSH2_update_kex_myproposal(PTInstVar pvar)
146146
// キー再作成の場合には、接続時に pvar->settings から組み立てられた myproposal を書き換える。
147147
// pvar->settings が 接続時に myproposal を作成したときの値から変わっていない保証がない。
148148
// 再度組み立てるのではなく既存の myproposal を書き換えることにした。
149-
int pos = strlen(myproposal[PROPOSAL_KEX_ALGS]) - strlen(",ext-info-c");
150-
if (strcmp(myproposal[PROPOSAL_KEX_ALGS] + pos, ",ext-info-c") == 0) {
149+
int pos = strlen(myproposal[PROPOSAL_KEX_ALGS]) - strlen(",ext-info-c,kex-strict-c-v00@openssh.com");
150+
if (strcmp(myproposal[PROPOSAL_KEX_ALGS] + pos, ",ext-info-c,kex-strict-c-v00@openssh.com") == 0) {
151151
myproposal[PROPOSAL_KEX_ALGS][pos] = '\0';
152152
}
153153
}
@@ -163,8 +163,8 @@ void SSH2_update_kex_myproposal(PTInstVar pvar)
163163
strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
164164
}
165165

166-
// RFC 8308 Extension Negotiation
167-
strncat_s(buf, sizeof(buf), "ext-info-c", _TRUNCATE);
166+
// Enables RFC 8308 Extension Negotiation & Strict KEX mode (for CVE-2023-48795)
167+
strncat_s(buf, sizeof(buf), "ext-info-c,kex-strict-c-v00@openssh.com", _TRUNCATE);
168168

169169
myproposal[PROPOSAL_KEX_ALGS] = buf;
170170
}

Diff for: ttssh2/ttxssh/ssh.c

+17-1
Original file line numberDiff line numberDiff line change
@@ -2997,6 +2997,7 @@ void SSH_init(PTInstVar pvar)
29972997
pvar->use_subsystem = FALSE;
29982998
pvar->nosession = FALSE;
29992999
pvar->server_sig_algs = NULL;
3000+
pvar->server_strict_kex = FALSE;
30003001

30013002
}
30023003

@@ -4813,7 +4814,7 @@ static BOOL handle_SSH2_kexinit(PTInstVar pvar)
48134814
if (pvar->kex_status == KEX_FLAG_KEXDONE) {
48144815
pvar->kex_status = KEX_FLAG_REKEYING;
48154816

4816-
// キー再作成時は myproposal から ",ext-info-c" を削除する
4817+
// キー再作成時は myproposal から ",ext-info-c,kex-strict-c-v00@openssh.com" を削除する
48174818
// 更新するのは KEX のみでよい
48184819
SSH2_update_kex_myproposal(pvar);
48194820

@@ -4878,6 +4879,13 @@ static BOOL handle_SSH2_kexinit(PTInstVar pvar)
48784879
goto error;
48794880
}
48804881

4882+
// サーバー側がStrict KEXに対応しているかの確認
4883+
choose_SSH2_proposal(buf, "kex-strict-s-v00@openssh.com", tmp, sizeof(tmp));
4884+
if (tmp[0] != '\0') {
4885+
pvar->server_strict_kex = TRUE;
4886+
logprintf(LOG_LEVEL_INFO, "Server supports strict kex. Strict kex will be enabled.");
4887+
}
4888+
48814889
// ホスト鍵アルゴリズム
48824890
switch (get_namelist_from_payload(pvar, buf, sizeof(buf), &size)) {
48834891
case GetPayloadError:
@@ -5644,6 +5652,10 @@ static void ssh2_send_newkeys(PTInstVar pvar)
56445652

56455653
pvar->kex_status |= KEX_FLAG_NEWKEYS_SENT;
56465654

5655+
if (pvar->server_strict_kex) {
5656+
pvar->ssh_state.sender_sequence_number = 0;
5657+
}
5658+
56475659
// SSH2_MSG_NEWKEYS を既に受け取っていたらKEXは完了。次の処理に移る。
56485660
if (pvar->kex_status & KEX_FLAG_NEWKEYS_RECEIVED) {
56495661
if ((pvar->kex_status & KEX_FLAG_REKEYING)) {
@@ -6238,6 +6250,10 @@ static BOOL handle_SSH2_newkeys(PTInstVar pvar)
62386250
pvar->ssh2_keys[MODE_IN].comp.enabled = 1;
62396251
enable_recv_compression(pvar);
62406252

6253+
if (pvar->server_strict_kex) {
6254+
pvar->ssh_state.receiver_sequence_number = 0;
6255+
}
6256+
62416257
SSH2_dispatch_add_message(SSH2_MSG_EXT_INFO);
62426258

62436259
// SSH2_MSG_NEWKEYS を既に送っていたらKEXは完了。次の処理に移る。

Diff for: ttssh2/ttxssh/ttxssh.h

+1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ typedef struct _TInstVar {
363363
} recv;
364364

365365
char *server_sig_algs;
366+
BOOL server_strict_kex;
366367

367368
char UIMsg[MAX_UIMSG];
368369
} TInstVar;

0 commit comments

Comments
 (0)