SlideShare une entreprise Scribd logo
1  sur  36
Télécharger pour lire hors ligne
SSH(Secure SHell)の勉強資料です。
SSHのパケットを復号することになり、その過程で調べたり作ったりしたものをサマった資料です。
● 使用ソフト
sshクライアント&サーバー libssh 0.8.6
復号 openssl 1.0.2q
間違っていたらコメントをお願いします。
SSHの勉強資料
Table of Contents
Table of Contents 1
SSH復号ツールを作ろう 3
1. デバッグ環境構築 3
1.1 libsshをビルド&インストール 3
1.2 sshクライアント 4
1.2.1 作成 4
1.2.2 ビルド 5
1.2.3 実行&トレース 5
1.3 sshサーバー 6
1.3.1 作成 6
1.3.2 ビルド 10
1.3.3 実行&トレース 10
1.4 libssh改造 10
1.4.1 処理の流れ 10
1.4.2 改造ソース 11
1.4.3 デバッグメモ 12
2. 復号プログラム作成 12
2.1 作成 12
2.2 ビルド 13
2.3 実行 13
2.3.1 パケット準備 13
2.3.2 復号プログラムの実行 14
2.4 考察 17
RFC編 18
SSH関連のRFCリスト 18
RFC 4251, The Secure Shell (SSH) Protocol Architecture 20
1. Introduction 20
4. Architecture 20
4.1. Host Keys 20
4.2. Extensibility 20
4.3. Policy Issues 21
4.4. Security Properties 21
5. Data Type Representations Used in the SSH Protocols 21
1
7. Message Numbers 22
RFC 4253, The Secure Shell (SSH) Transport Layer Protocol 23
1. Introduction 23
4. Connection Setup 23
4.1. Use over TCP/IP 23
6. Binary Packet Protocol 23
6.1. Maximum Packet Length 24
6.2. Compression 24
6.3. Encryption 24
6.4. Data Integrity 25
6.5. Key Exchange Methods 26
6.6. Public Key Algorithms 26
7. Key Exchange 27
7.1. Algorithm Negotiation 28
7.2. Output from Key Exchange 29
7.3. Taking Keys Into Use 30
8. Diffie-Hellman Key Exchange 30
9. Key Re-Exchange 31
10. Service Request 31
11. Additional Messages 32
11.1. Disconnection Message 32
11.2. Ignored Data Message 33
11.3. Debug Message 33
11.4. Reserved Messages 33
12. Summary of Message Numbers 34
RFC 4344, The Secure Shell (SSH) Transport Layer Encryption Modes 35
1. Introduction 35
3. Rekeying 35
3.1. First Rekeying Recommendation 35
3.2. Second Rekeying Recommendation 35
4. Encryption Modes 35
2
SSH復号ツールを作ろう
 まずRFCを読んで復号に必要な情報を特定する。
⇒Key, IV、アルゴリズムがわかればOK。圧縮ありの場合は圧縮アルゴリズムも。
 アルゴリズムによってはブロック番号、Counter、前の暗号化パケット等が必要になる。
 #圧縮アルゴリズムはマジックナンバー見ればわかる。
 詳細は​RFC編​の章を参照。
 libsshを修正して復号に必要な情報を出力する。
⇒libsshをデバッグして探す。
 詳細は​1. デバッグ環境構築​の章を参照。
 それらの情報と復号プログラムを使ってsshパケットを復号する。
⇒libsslで復号する。
 詳細は​2. 復号プログラム作成​の章を参照。
 以下はSSHのコネクションフロー。SSH_MSG_NEWKWYSのときにsrcdh.cでKey、IVが生成されるので主にそのあたりを見て
いく。
1. デバッグ環境構築
 libsshに修正が必要なのでlibsshのデバッグ環境を構築する。
1.1 libsshをビルド&インストール
 デバッグ用のオプション指定(-DCMAKE_BUILD_TYPE=Profiling、-DWITH_DEBUG_CRYPTO=ON)がポイント。
# wget https://git.libssh.org/projects/libssh.git/snapshot/libssh-0.8.6.zip
# unzip libssh-0.8.6.zip
# cd libssh-0.8.6
# mkdir build
# cmake ​-DCMAKE_BUILD_TYPE=Profiling​ ​-DWITH_DEBUG_CRYPTO=ON​ ..
# make
# make install
3
1.2 sshクライアント
1.2.1 作成
 GDBでデバッグする用のsshクライアントを作成する。
 localhost:2222のsshサーバーに接続して認証用のユーザー名、パスワードを送信してcatして切断する。
 catしているファイルは2,000byteのテキストファイル。
 詳細はlibsshのチュートリアルとAPIリファレンス参照。
 ​http://api.libssh.org/master/libssh_tutorial.html
/* sshc.c */
#define LIBSSH_STATIC 1
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
ssh_session session;
ssh_channel channel;
int port = 2222;
char userpass[] = "hasegawa";
char buffer[4096];
unsigned int nbytes;
const char *pcap_file="debug.client.pcap";
ssh_pcap_file pcap;
int state;
session = ssh_new();
system("tcpdump -i any -w sshc.pcap &");
system("sleep 3");
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
ssh_options_set(session, SSH_OPTIONS_PORT, &port);
ssh_options_set(session, SSH_OPTIONS_USER, userpass);
pcap=ssh_pcap_file_new();
ssh_pcap_file_open(pcap,pcap_file);
ssh_set_pcap_file(session,pcap);
ssh_connect(session);
ssh_userauth_password(session, NULL, userpass);
channel = ssh_channel_new(session);
ssh_channel_open_session(channel);
state = ssh_channel_request_exec(channel, "cat /hasegawa.txt");
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) {
fwrite(buffer, 1, nbytes, stdout);
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_channel_free(channel);
ssh_disconnect(session);
ssh_free(session);
ssh_pcap_file_free(pcap);
ssh_finalize();
system("sleep 3");
system("killall tcpdump");
return 0;
}
4
1.2.2 ビルド
# gcc -DLIBSSH_STATIC sshc.c -lssh -g -O0 -o sshc
1.2.3 実行&トレース
# gdb ./sshc
(gdb) b main
Breakpoint 1 at 0xb65: file sshc.c, line 6.
(gdb) r
Breakpoint 1, main () at sshc.c:6
6 int main() {
(gdb) s
9 int port = 2222;
(gdb)
10 char userpass[] = "hasegawa";
(gdb)
13 session = ssh_new();
(gdb)
ssh_new () at /root/libssh/libssh-0.8.6/src/session.c:60
 ちなみに「WITH_DEBUG_CRYPTO=ON」でlibsshをビルドすると、暗号化/復号のために必要なIV、Keyが表示される。
 暗号化アルゴリズム種別は出力されないので「libssh-0.8.6srcdh.c::ssh_generate_session_keys()」に手を入
れて表示する。
 実行例)クライアントのログ
 クライアントからサーバー方向の通信(暗号化)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無
し。
 サーバーからクライアント方向の通信(復号)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無
し。
Encrypt IV:
3b:1a:a7:66:20:a3:3b:de:71:ed:9c:3d:d3:25:39:44:bd:62:66:f0:cb:b5:e3:37:80:e5:db:47:fb:04:87
:02
Decrypt IV:
6e:57:fd:ee:d4:5e:dc:d0:9c:64:44:61:3b:5f:ef:a5:8b:da:35:e7:ed:6d:c8:14:38:d1:eb:ce:19:1b:d2
:eb
Encryption key:
d8:8f:39:02:4c:cc:46:43:6d:9e:b9:3e:13:21:ed:f9:e4:af:56:87:5d:5c:40:2c:42:85:09:a4:f6:ab:cc
:67
Decryption key:
ad:d0:6b:d0:12:17:0e:73:e3:40:90:e7:ec:05:57:3e:ea:98:bc:f9:cd:3e:9d:1b:bf:a2:d1:4d:e2:d3:a5
:98
Encryption MAC:
0f:b4:ae:91:af:af:e7:55:69:49:dd:0f:93:34:53:73:c6:ca:e4:31:08:a1:d3:48:9f:e3:4d:8e:c1:80:f0
:50
Decryption MAC:
19:9e:2c:da:33:ee:90:84:3d:31:8d:31:67:c8:d7:bd:e4:2d:36:77:54:bb:f6:1f:23:d3:03:a4:f1:44:bf
:39
Encrypt: aes256-ctr
Decryption: aes256-ctr
do_compress_out: 0
do_compress_in: 0
5
1.3 sshサーバー
1.3.1 作成
 GDBでデバッグする用のsshサーバーを作成する。
 localhost:2222でリッスン、クライアントをパスワード認証してコマンドの結果を返す。
 詳細はlibsshのチュートリアルとAPIリファレンス参照。
 ​http://api.libssh.org/master/libssh_tutorial.html
/* sshs.c */
#include <libssh/callbacks.h>
#include <libssh/server.h>
#include <poll.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <stdio.h>
#define BUF_SIZE 4096
/* A userdata struct for channel. */
struct channel_data_struct {
pid_t pid;
socket_t pty_master;
socket_t pty_slave;
socket_t child_stdin;
socket_t child_stdout;
socket_t child_stderr;
ssh_event event;
struct winsize *winsize;
};
/* A userdata struct for session. */
struct session_data_struct {
ssh_channel channel;
int auth_attempts;
int authenticated;
};
static int exec_request(ssh_session session, ssh_channel channel,
const char *command, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
int in[2], out[2], err[2];
pipe(in);
pipe(out);
pipe(err);
if((cdata->pid = fork()) == 0) {
close(in[1]);
close(out[0]);
close(err[0]);
dup2(in[0], STDIN_FILENO);
dup2(out[1], STDOUT_FILENO);
dup2(err[1], STDERR_FILENO);
close(in[0]);
close(out[1]);
close(err[1]);
execl("/bin/sh", "sh", "-c", command, NULL);
exit(0);
}
close(in[0]);
6
close(out[1]);
close(err[1]);
cdata->child_stdin = in[1];
cdata->child_stdout = out[0];
cdata->child_stderr = err[0];
return SSH_OK;
}
static int auth_password(ssh_session session, const char *user,
const char *pass, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
if (strcmp(user, "hasegawa") == 0 && strcmp(pass, "hasegawa") == 0) {
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
sdata->auth_attempts++;
return SSH_AUTH_DENIED;
}
static ssh_channel channel_open(ssh_session session, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
sdata->channel = ssh_channel_new(session);
return sdata->channel;
}
static int process_stdout(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
if (n > 0) {
ssh_channel_write(channel, buf, n);
}
}
return n;
}
static int process_stderr(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
if (n > 0) {
ssh_channel_write_stderr(channel, buf, n);
}
}
return n;
}
static void handle_session(ssh_event event, ssh_session session) {
int n, rc;
struct winsize wsize = {
.ws_row = 0,
.ws_col = 0,
.ws_xpixel = 0,
7
.ws_ypixel = 0
};
struct channel_data_struct cdata = {
.pid = 0,
.pty_master = -1,
.pty_slave = -1,
.child_stdin = -1,
.child_stdout = -1,
.child_stderr = -1,
.event = NULL,
.winsize = &wsize
};
struct session_data_struct sdata = {
.channel = NULL,
.auth_attempts = 0,
.authenticated = 0
};
struct ssh_channel_callbacks_struct channel_cb = {
.userdata = &cdata,
.channel_exec_request_function = exec_request,
};
struct ssh_server_callbacks_struct server_cb = {
.userdata = &sdata,
.auth_password_function = auth_password,
.channel_open_request_session_function = channel_open,
};
ssh_callbacks_init(&server_cb);
ssh_callbacks_init(&channel_cb);
ssh_set_server_callbacks(session, &server_cb);
ssh_handle_key_exchange(session);
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
ssh_event_add_session(event, session);
n = 0;
while (sdata.authenticated == 0 || sdata.channel == NULL) {
ssh_event_dopoll(event, 100);
n++;
}
ssh_set_channel_callbacks(sdata.channel, &channel_cb);
do {
ssh_event_dopoll(event, -1);
if (cdata.event != NULL || cdata.pid == 0) {
continue;
}
cdata.event = event;
if (cdata.child_stdout != -1) {
ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout,
sdata.channel);
}
if (cdata.child_stderr != -1) {
ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr,
sdata.channel);
}
} while(ssh_channel_is_open(sdata.channel) &&
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
close(cdata.pty_master);
close(cdata.child_stdin);
8
close(cdata.child_stdout);
close(cdata.child_stderr);
ssh_event_remove_fd(event, cdata.child_stdout);
ssh_event_remove_fd(event, cdata.child_stderr);
if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) {
rc = WEXITSTATUS(rc);
ssh_channel_request_send_exit_status(sdata.channel, rc);
} else if (cdata.pid > 0) {
kill(cdata.pid, SIGKILL);
}
ssh_channel_send_eof(sdata.channel);
ssh_channel_close(sdata.channel);
for (n = 0; n < 50 && (ssh_get_status(session) & (SSH_CLOSED | SSH_CLOSED_ERROR)) == 0;
n++) {
ssh_event_dopoll(event, 100);
}
}
int main(int argc, char **argv) {
ssh_bind sshbind;
ssh_session session;
ssh_event event;
int port = 2222;
const char *pcap_file="debug.server.pcap";
ssh_pcap_file pcap;
ssh_init();
sshbind = ssh_bind_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port);
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, "ssh_host_rsa_key");
ssh_bind_listen(sshbind);
while (1) {
session = ssh_new();
pcap = ssh_pcap_file_new();
ssh_pcap_file_open(pcap, pcap_file);
ssh_set_pcap_file(session, pcap);
ssh_bind_accept(sshbind, session);
if(fork() == 0) {
ssh_bind_free(sshbind);
event = ssh_event_new();
handle_session(event, session);
ssh_event_free(event);
ssh_disconnect(session);
ssh_free(session);
ssh_pcap_file_free(pcap);
exit(0);
}
ssh_disconnect(session);
ssh_free(session);
}
ssh_bind_free(sshbind);
ssh_finalize();
return 0;
}
 Host認証用のRSA keyを生成する。
#ssh-keygen -t rsa -b 2048 -f ssh_host_rsa_key -N ''
9
1.3.2 ビルド
gcc -DLIBSSH_STATIC -DWOTH_PCAP sshs.c -lssh -g -O0 -o sshs
1.3.3 実行&トレース
 実行例)サーバーのログ
 サーバーからクライアント方向の通信(暗号化)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無
し。
 クライアントからサーバー方向の通信(復号)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無
し。
 暗号化/復号のKey、IVがクライアントの例を逆になっている。
Encrypt IV:
6e:57:fd:ee:d4:5e:dc:d0:9c:64:44:61:3b:5f:ef:a5:8b:da:35:e7:ed:6d:c8:14:38:d1:eb:ce:19:1b:d2
:eb
Decrypt IV:
3b:1a:a7:66:20:a3:3b:de:71:ed:9c:3d:d3:25:39:44:bd:62:66:f0:cb:b5:e3:37:80:e5:db:47:fb:04:87
:02
Encryption key:
ad:d0:6b:d0:12:17:0e:73:e3:40:90:e7:ec:05:57:3e:ea:98:bc:f9:cd:3e:9d:1b:bf:a2:d1:4d:e2:d3:a5
:98
Decryption key:
d8:8f:39:02:4c:cc:46:43:6d:9e:b9:3e:13:21:ed:f9:e4:af:56:87:5d:5c:40:2c:42:85:09:a4:f6:ab:cc
:67
Encryption MAC:
19:9e:2c:da:33:ee:90:84:3d:31:8d:31:67:c8:d7:bd:e4:2d:36:77:54:bb:f6:1f:23:d3:03:a4:f1:44:bf
:39
Decryption MAC:
0f:b4:ae:91:af:af:e7:55:69:49:dd:0f:93:34:53:73:c6:ca:e4:31:08:a1:d3:48:9f:e3:4d:8e:c1:80:f0
:50
Encrypt: aes256-ctr
Decryption: aes256-ctr
do_compress_out: 0
do_compress_in: 0
1.4 libssh改造
 SSH_MSG_NEWKEYSを受信し、Shared secret K、 Exchange hash HからKey、IVを生成する箇所にそれらをダンプす
る処理を追加する。
1.4.1 処理の流れ
処理内容 ソース
①Key, IVを生成、設定 srcpacket_cb.c::SSH_PACKET_CALLBACK(ssh_packet_newkeys)
SSH_MSG_NEWKEYS受信時のコールバック。主に以下の処理を実行する。
srcdh.c::ssh_generate_session_keys(ssh_session session)
Shared secret K、 Exchange hash HからKey、IVを生成。
両方向のIV、Key、MACをssh_crypto_structにセット。
srcpacket_cb.c::SSH_PACKET_CALLBACK(ssh_packet_newkeys)
set_decrypt_key()、set_encrypt_key()でKey、IVを設定
10
②受信パケットの復号 srcpacket_crypt.c::ssh_packet_decrypt()
受信したパケットを復号する。アルゴリズム毎に復号関数は異なる。
srclibcrypto.c::struct ssh_ciphertab[]
アルゴリズム定義の構造体。名前、暗号化/復号の関数等が設定される。
(例)AES-256-CTRの場合は下記。
.name = "aes256-ctr",
.blocksize = 16,
.ciphertype = SSH_AES256_CTR,
.keysize = 256,
.set_encrypt_key = evp_cipher_set_encrypt_key,
.set_decrypt_key = evp_cipher_set_decrypt_key,
.encrypt = evp_cipher_encrypt,
.decrypt = evp_cipher_decrypt,
.cleanup = evp_cipher_cleanup
1.4.2 改造ソース
 改造内容は下記。①のKey、IVを生成後に値をダンプする。
diff src/dh.c src/dh_org.c
1159,1198d1158
< {
< const char *filename_C[]= {"/EIV_C", "/DIV_C", "/EKEY_C", "/DKEY_C"};
< const char *filename_S[]= {"/EIV_S", "/DIV_S", "/EKEY_S", "/DKEY_S"};
< const char *ALGO_file_C="/ALGO_C";
< const char *ALGO_file_S="/ALGO_S";
< FILE *fp;
<
< for(int i=0; i<4; i++) {
< if(session->client)
< fp = fopen(filename_C[i], "wb");
< else
< fp = fopen(filename_S[i], "wb");
< switch(i) {
< case 0:
< fwrite ((const void *)crypto->encryptIV, crypto->digest_len, 1, fp);
< break;
< case 1:
< fwrite ((const void *)crypto->decryptIV, crypto->digest_len, 1, fp);
< break;
< case 2:
< fwrite ((const void *)crypto->encryptkey, crypto->out_cipher->keysize / 8, 1, fp);
< break;
< case 3:
< fwrite ((const void *)crypto->decryptkey, crypto->in_cipher->keysize / 8, 1, fp);
< break;
< }
< fclose(fp);
< }
< if(session->client)
< fp= fopen(ALGO_file_C, "w");
< else
< fp= fopen(ALGO_file_S, "w");
< fprintf(fp, "Encrypt: %sn", crypto->out_cipher->name);
< fprintf(fp, "Decryption: %sn", crypto->in_cipher->name);
< fprintf(fp, "do_compress_out: %dn", crypto->do_compress_out);
< fprintf(fp, "do_compress_in: %dn", crypto->do_compress_in);
< fclose(fp);
11
1.4.3 デバッグメモ
 デバッグしたときに改造したソースメモ。
受信した暗号化パケット+Decrption Key+復号したパケットの表示
srcpacket_crypt.c::ssh_packet_decrypt()
 ssh_print_hexa("Decryption key", session->current_crypto->decryptkey, 256/8);//Dec Key
 ssh_print_hexa("Source", source+start, 32);//受信した暗号化パケット
 crypto->decrypt(crypto, source + start, destination, encrypted_size);
 ssh_print_hexa("Destination", destination, 32);//復号したパケット
シーケンス番号の表示
srcpacket_crypt.c::ssh_packet_hmac_verify()
 ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t));
2. 復号プログラム作成
2.1 作成
 サーバーパケットの復号プログラムを作成する。
 インプットは、サーバー→クライアント方向のSSHパケットのバイナリ、クライアントのDecryption keyとDecryption IV
。
 前章のDecription Key、Decription IV、暗号化アルゴリズム名を使用して復号プログラムを作成する。
 詳細はチュートリアルとAPIリファレンス参照。
 ​https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption
/* ssl.c */
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
EVP_CIPHER_CTX *ctx;
void setkey(unsigned char *key, char *iv)
{
EVP_CIPHER_CTX_init(ctx);
ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv);
}
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned
char *plaintext, char *iv)
{
int len;
int plaintext_len;
EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
plaintext_len = len;
EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
plaintext_len += len;
return plaintext_len;
}
int main (void)
{
unsigned char sshkey[32], sshiv[32];
FILE *fp;
char filename[32];
unsigned char ciphertext[4096], decryptedtext[4096];
12
int decryptedtext_len, ciphertext_len;
unsigned int size;
fp = fopen("/DIV_C", "rb");
fread(sshiv, 32, 1, fp);
fclose(fp);
fp = fopen("/DKEY_C", "rb");
fread(sshkey, 32, 1, fp);
fclose(fp);
OpenSSL_add_all_algorithms();
setkey((unsigned char *)sshkey, (unsigned char *)sshiv);
for(int i=0; i<7; i++) {
sprintf(filename, "/hoge%d.bin", i);
fp = fopen(filename, "rb");
size = 4;
fread(ciphertext, size, 1, fp);
decryptedtext_len = decrypt(ciphertext, size, (unsigned char *)sshkey,
decryptedtext, (unsigned char *)sshiv);
printf("Decrypt Packet#%d Sizen", i);
BIO_dump_fp (stdout, (const char *)decryptedtext, decryptedtext_len);
size = (decryptedtext[2]<<8) + decryptedtext[3];
fread(ciphertext, size, 1, fp);
decryptedtext_len = decrypt(ciphertext, size, (unsigned char *)sshkey,
decryptedtext, (unsigned char *)sshiv);
printf("Decrypt Packet#%dn", i);
BIO_dump_fp (stdout, (const char *)decryptedtext, decryptedtext_len);
fclose(fp);
}
EVP_cleanup();
ERR_free_strings();
return 0;
}
2.2 ビルド
#gcc ssl.c -lssl -lcrypto -o decoder
2.3 実行
2.3.1 パケット準備
 sshサーバープログラム、sshクライアントプログラムを実行する。Key(/DKEY_C)、IV(/DIV_C)、暗号化されたパケッ
トのキャプチャ(sshc.pcap)が出力される。
 sshc.pcapからバイナリをエクスポートする。/配下にキャプチャした順番にhoge0.bin、hoge1.bin、、、をエクスポート
する。
13
2.3.2 復号プログラムの実行
 実行結果とサーバーが送信した平文パケットを以下に示す。復号されていることがわかる。
●  パケット#0
復号プログラムの実行結果
Decrypt Packet#0 Size
0000 - 00 00 00 9c ....
Decrypt Packet#0
0000 - 0e 07 00 00 00 01 00 00-00 0f 73 65 72 76 65 72 ..........server
0010 - 2d 73 69 67 2d 61 6c 67-73 00 00 00 71 73 73 68 -sig-algs...qssh
0020 - 2d 65 64 32 35 35 31 39-2c 65 63 64 73 61 2d 73 -ed25519,ecdsa-s
0030 - 68 61 32 2d 6e 69 73 74-70 32 35 36 2c 65 63 64 ha2-nistp256,ecd
0040 - 73 61 2d 73 68 61 32 2d-6e 69 73 74 70 33 38 34 sa-sha2-nistp384
0050 - 2c 65 63 64 73 61 2d 73-68 61 32 2d 6e 69 73 74 ,ecdsa-sha2-nist
0060 - 70 35 32 31 2c 73 73 68-2d 72 73 61 2c 72 73 61 p521,ssh-rsa,rsa
0070 - 2d 73 68 61 32 2d 35 31-32 2c 72 73 61 2d 73 68 -sha2-512,rsa-sh
0080 - 61 32 2d 32 35 36 2c 73-73 68 2d 64 73 73 02 d1 a2-256,ssh-dss..
0090 - 94 54 8d 07 f6 0e f6 17-61 4b b8 fe .T......aK..
サーバーが送信した平文パケット
●  パケット#1
復号プログラムの実行結果
Decrypt Packet#1 Size
0000 - 00 00 00 1c ....
14
Decrypt Packet#1
0000 - 0a 06 00 00 00 0c 73 73-68 2d 75 73 65 72 61 75 ......ssh-userau
0010 - 74 68 fc f1 ca ba 2b 29-e1 ac d7 4c th....+)...L
サーバーが送信した平文パケット
●  パケット#2
復号プログラムの実行結果
Decrypt Packet#2 Size
0000 - 00 00 00 0c ....
Decrypt Packet#2
0000 - 0a 34 15 e0 72 88 91 1e-e1 06 dd 55 .4..r......U
サーバーが送信した平文パケット
●  パケット#3
復号プログラムの実行結果
Decrypt Packet#3 Size
0000 - 00 00 00 1c ....
Decrypt Packet#3
0000 - 0a 5b 00 00 00 2b 00 00-00 2b 00 00 7d 00 00 00 .[...+...+..}...
0010 - 88 b8 48 2b ab da bc 05-56 57 c6 89 ..H+....VW..
サーバーが送信した平文パケット
●  パケット#4
復号プログラムの実行結果
Decrypt Packet#4 Size
0000 - 00 00 00 0c ....
Decrypt Packet#4
0000 - 06 63 00 00 00 2b f4 f1-68 f7 90 5f .c...+..h.._
サーバーが送信した平文パケット
15
●  パケット#5
復号プログラムの実行結果
Decrypt Packet#5 Size
0000 - 00 00 07 ec ....
Decrypt Packet#5
0000 - 11 5e 00 00 00 2b 00 00-07 d1 30 31 32 33 34 35 .^...+....012345
0010 - 36 37 38 39 30 31 32 33-34 35 36 37 38 39 30 31 6789012345678901
0020 - 32 33 34 35 36 37 38 39-30 31 32 33 34 35 36 37 2345678901234567
~省略~
07c0 - 34 35 36 37 38 39 30 31-32 33 34 35 36 37 38 39 4567890123456789
07d0 - 30 31 32 33 34 35 36 37-38 39 0a 39 9d 4c 4e 67 0123456789.9.LNg
07e0 - b8 44 7c 1d 2d ba 5e 95-3e 02 78 b4 .D|.-.^.>.x.
サーバーが送信した平文パケット
●  パケット#6
復号プログラムの実行結果
Decrypt Packet#6 Size
0000 - 00 00 00 2c ...,
Decrypt Packet#6
0000 - 12 62 00 00 00 2b 00 00-00 0b 65 78 69 74 2d 73 .b...+....exit-s
0010 - 74 61 74 75 73 00 00 00-00 00 1f df 3e 23 01 d3 tatus.......>#..
0020 - 72 eb c7 58 04 88 9c ed-93 75 17 05 r..X.....u..
サーバーが送信した平文パケット
16
2.4 考察
 SSHの場合、AES-CTRのCounterがパケットで送信されない。Counterはブロック番号が+1になるたびに+1され、Counter
、ブロック番号はサーバー、クライアントがそれぞれ内部で管理する。そのため、SSHセッション確立後の途中のパケットでは
Counter、ブロック番号がわからないため、復号できない。
復号のためには
 最初のパケットから復号したいパケットまでのキャプチャ or
 復号したいパケットまでのキャプチャ以前までの合計パケットサイズ、ブロック番号、Counterのどれか
が必要になる。現実的には前者。
 ちなみに、ESPの場合はPayloadでCounterが送信されてくるので、途中のパケットからでも復号できる。
 (参考)ESPでAES-CTR:​https://www.ietf.org/rfc/rfc3686.txt
17
RFC編
下線、ハイライトは個人的に重要そうなところ。斜体、#はメモ。
原文のMUST/REQUIRED/SHALL/SHOULD/MAY/OPTIONAL等の​RFC2119​用語は原文のまま残しています。
 MUST、REQUIRED、SHALL:絶対的な要求事項
 MUST NOT:絶対的な禁止事項
 SHOULD、RECOMMENDED:慎重に重要性を判断するべき要求事項
 SHOULD NOT、NOT RECOMMENDED:慎重に重要性を判断するべき禁止事項
 MAY、OPTIONAL:オプション。
SSH関連のRFCリスト
RFC 概要
RFC 4250
The Secure Shell (SSH) Protocol Assigned Numbers
https://tools.ietf.org/html/rfc4250
SSHのプロトコルで使用される番号の定義。
RFC 4251
The Secure Shell (SSH) Protocol Architecture
https://tools.ietf.org/html/rfc4251
SSHのアーキテクチャーの概要。
3つの主要コンポーネントであるTransport Layer
Protocol、User Authentication Protocol、
Coonection Protocolの概要。
RFC 4252
The Secure Shell (SSH) Authentication Protocol
https://tools.ietf.org/html/rfc4252
Authentication Protocolの詳細。
Public key、Password、Host-based client
authentication method。
RFC 4253
The Secure Shell (SSH) Transport Layer Protocol
https://tools.ietf.org/html/rfc4253
Transport Layer Protocolの詳細。
RFC 4254
The Secure Shell (SSH) Connection Protocol
https://tools.ietf.org/html/rfc4254
Connection Protocolの詳細。
Interactive login、コマンドのリモート実行、TCP/IP接
続、X11接続を提供する。
RFC 4255
Using DNS to Securely Publish Secure Shell (SSH) Key
Fingerprints
https://tools.ietf.org/html/rfc4255
DNSSECでSSH host keyを検証する方法。
DNS resource recordに”SSHFP”を追加する。
RFC 4256
Generic Message Exchange Authentication for the Secure
Shell Protocol (SSH)
https://tools.ietf.org/html/rfc4256
認証データが手入力される場合に適したSSH用の認証方式。
RFC 4335
The Secure Shell (SSH) Session Channel Break Extension
https://tools.ietf.org/html/rfc4335
SSHでBREAK signalを送信するSession Channel Break
Extension。
RFC 4344
The Secure Shell (SSH) Transport Layer Encryption Modes
https://tools.ietf.org/html/rfc4344
SSHで推奨するsymmetric encription method、Rekey頻
度。
RFC 4345
Improved Arcfour Modes for the Secure Shell (SSH) Transport
Layer Protocol
https://tools.ietf.org/html/rfc4345
Arcfour cipherの使用方法。
18
RFC 4419
Diffie-Hellman Group Exchange for the Secure Shell (SSH)
Transport Layer Protocol
https://tools.ietf.org/html/rfc4419
DH group exchangeの新しいグループの追加。
RFC 4432
RSA Key Exchange for the Secure Shell (SSH) Transport Layer
Protocol
https://tools.ietf.org/html/rfc4432
RSA public key encryptionによる鍵交換。DH鍵交換より
CPUを使わない。
RFC 4462
Generic Security Service Application Program Interface
(GSS-API) Authentication and Key Exchange for the Secure
Shell (SSH) Protocol
https://tools.ietf.org/html/rfc4462
Generic Security Service Application Program
Interface (GSS-API)で認証、key exchangeする方法。
RFC 4716
The Secure Shell (SSH) Public Key File Format
https://tools.ietf.org/html/rfc4716
Public keyを交換するためのpublic key fileフォーマッ
トの定義。
RFC 4819
Secure Shell Public Key Subsystem
https://tools.ietf.org/html/rfc4819
Public Key Subsystemというクライアントがpublic key
を追加/削除したり、サーバーがpublic keyを管理するための
メカニズムの説明。
RFC 5647
AES Galois Counter Mode for the Secure Shell Transport
Layer Protocol
https://tools.ietf.org/html/rfc5647
Transport Layer Protocolに機密性とintegrityを提供
するAES Galois Counter Modeの説明。
RFC 5656
Elliptic Curve Algorithm Integration in the Secure Shell
Transport Layer
https://tools.ietf.org/html/rfc5656
Elliptic Curve Cryptography (ECC)(楕円曲線)に基づ
くアルゴリズムの説明。
RFC 6187
X.509v3 Certificates for Secure Shell Authentication
https://tools.ietf.org/html/rfc6187
X.509v3 public key certificatesを使用する方法。
RFC 6239
Suite B Cryptographic Suites for Secure Shell (SSH)
https://tools.ietf.org/html/rfc6239
Suite Bに対応するSSHのアーキテクチャー。ECDH key
agreement、ECDSA、AES-CGM、SHA-256/SHA-384、
X.509 certificatesを使用する。
RFC 6594
Use of the SHA-256 Algorithm with RSA, Digital Signature
Algorithm (DSA), and Elliptic Curve DSA (ECDSA) in SSHFP
Resource Records
https://tools.ietf.org/html/rfc6594
SSHFP、DNSSECでSSH host keyを検証する方法用のDNS
resource recordにSHA-256 Fingerprint、ECDSAを使
用する定義を追加する。
RFC 6668
SHA-2 Data Integrity Verification for the Secure Shell
(SSH) Transport Layer Protocol
https://tools.ietf.org/html/rfc6668
データのintegrityのためのアルゴリズムとパラメーターの定
義。
RFC 4253のupdate。
RFC 7478
Ed25519 SSHFP Resource Records
https://tools.ietf.org/html/rfc7479
Ed25519 signature algorithmのアルゴリズム番号の定
義。
Errata
https://www.rfc-editor.org/errata_search.php?rfc=​XXXX
19
RFC 4251, The Secure Shell (SSH) Protocol Architecture
 SSHは安全でないネットワーク上で安全なリモートログインおよびその他のネットワークサービスをするためのプロトコルであ
る。本ドキュメントではSSHのアーキテクチャー、SSHのドキュメントで使用される用語を説明する。
 SSHは3つの主要コンポーネントで構成される。​Transport Layer Protocolはサーバー認証、機密性、integrityを提供
する。User Authentication Protocolはサーバーによるクライアント認証を提供する。Connection Protocolは暗号化
されたトンネルを複数の論理チャネルに多重化する。
1. Introduction
 SSHは安全なリモートログインおよびネットワークサービスのためのプロトコルである。以下の3つの主要なコンポーネントから
構成される。
● Transport Layer Protocol
 サーバー認証、機密性、integrityを提供する。オプションで圧縮も提供する。Transport LayerはTCP/IPが使
用されるが、他を使用してもよい。
● User Authentication Protocol
 クライアント側のユーザーをサーバー側で認証する。Transport Layer Protocolを介して実行される。
● Connection Protocol
 暗号化されたトンネルを複数の論理チャネルに多重化うる。User Authentication Protocol上で実行される。
 Transport Layerが確立されると、クライアントはサービス要求を送信する。ユーザー認証が完了すると、次のサービス要求
が送信される。これにより新しいサービスが開始する。Connection Protocolは様々な用途に使用できるチャネルを提供す
る。
4. Architecture
4.1. Host Keys
 各サーバーはhost keyをもつことが推奨される(SHOULD)。サーバーは複数の異なるアルゴリズムを使用した複数のhost
keyを持ってもよい(MAY)。複数のサーバーが同じhost keyを共有してもよい(MAY)。
 クライアントはサーバーの認証をするためにサーバーのpublic host keyについて知っておく必要がある。
 二つの異なる信頼モデルを使用できる。
● クライアントは各サーバーに対応するpublic host keyに関連付くローカルデータベースをもつ。この方法では、集
中管理のインフラは必要としない。欠点は、ホスト名とkeyのデータベースのメンテが面倒なこと。
● サーバー名とkeyの関連付けはCAが認証する。クライアントはCA root keyのみ知っていればよい。CAによって承認
された全てのkeyを検証できる。
 二つ目の方法は、クライアントに1つのCA root keyのみ格納すればよいので、メンテの問題が解消する。一方、認証前に各
サーバー keyがCAによって認証されており、CAの信頼性確保が必要になる。
 SSHにはサーバーに接続するときにサーバー名とhost keyの関連付けをチェックしないオプションがある。これにより、host
keyや証明書を事前に確認しなくても通信ができる。Connectionは保護されるが、MITMに対して脆弱になる。実装は、デフォル
トではそのような接続を許可しないことが推奨される(SHOULD NOT)。
 実装はhost keyの正当性を検証するための追加の方法、例えばpublic keyのSHA-1 hashのフィンガープリントを提供して
もよい(MAY)。そのようなフィンガープリントは、電話等の他の通信で容易に確認ができる。
4.2. Extensibility
 SSHは独自の暗号化、認証、key exchangeによって拡張される。全ての拡張を一元管理するのは面倒でありが、一元管理しな
いと識別子の競合が発生し、相互運用が困難になる。
 SSHではアルゴリズム、メソッド、フォーマット、拡張プロトコルを特定のフォーマットのテキストで識別する。
20
 設計の目標は、ベースプロトコルをできるだけシンプルにし、必須のアルゴリズムを最小限にすることである。
4.3. Policy Issues
 ​SSHでは暗号化、integrity、鍵交換、圧縮、public keyアルゴリズムとフォーマットのネゴシエーションが可能である。
それらは方向毎に異なる。
 以下のポリシーが実装の設定において可能であることが推奨される(SHOULD)。
● 暗号化、integrity、圧縮アルゴリズムは各方向で別々に設定できる。ポリシーには優先度が設定できること(MUST
)。例えば各カテゴリに設定された最初のアルゴリズムが優先される等。
● サーバー認証に使用されるpublic keyアルゴリズムと鍵交換の方法。
● 各ユーザーに対するサーバーの認証方法。サーバーのポリシーによってはユーザーに対して複数の認証方法をもってよい
(MAY)。例えば、ユーザーのアクセス場所によって認証方法を変える。
● ユーザーがconnection protocolを使用して実行できるオペレーション。例えば、サーバーがセッションを開始した
り、クライアントマシン上でコマンドを実行することは推奨されない(SHOULD NOT)。それらはファイアーウォール
の透過、迂回といったセキュリティの問題になる可能性がある。
4.4. Security Properties
 SSHの主な目的はインターネット上のセキュリティを向上させることである。多少のセキュリティを無視したとしても、デプロ
イが容易な方法を採用する。
●  全ての暗号化、integrity、public keyは既知で確立されているアルゴリズムである。
●  全てのアルゴリズムが暗号解読攻撃に対して十分に強力なkey sizeで使用される。
●  全てのアルゴリズムはネゴシエーションされ、あるアルゴリズムが危殆化した場合でもベースのプロトコルを変更する
ことなく、アルゴリズムを切り替えられる。
5. Data Type Representations Used in the SSH Protocols
Data Type 説明
byte  Byteは任意の8bit値を表す。固定長のデータはbyte[n]
(nは配列のbyte数)と表す。
boolean  Booleanは1byteとして格納される。0はFALSE、1は
TRUEを表す。0以外の値は全てTRUEとして扱うこと(MUST
)。ただし、アプリケーションは0と1以外の値を格納しない
こと(MUST NOT)。
uint32  32bitの符号なし整数を表す。ネットワークバイトオー
ダー(ビッグエンディアン)で4byteで格納される。例えば
699921578(0x29b7f4aa)は29 b7 f4 aaである。
uint64  64bitの符号なし整数を表す。ネットワークバイトオー
ダー(ビッグエンディアン)で8byteで格納される。
string  任意長のバイナリ文字列。Stringには任意のバイナリデー
タを設定できる。Stringはstring長を示すuint32と
stringとして格納される。終端文字のnull文字は使用され
ない。
 Stringはテキストを格納するためにも使用される。内部で
はUS-ASCIIが使用され、ユーザーに表示するときはUTF-8
が使用される。終端のnull文字はstringに格納しないこと
(SHOULD NOT)。
 例)"testing" = 00 00 00 07 t e s t i n g
先頭の00000007はstring長=7。
21
mpint  MSBを先頭とした、2の補数形式の多倍長整数を表す。負数
はMSBに1が設定される。
name-list  CSV形式の名前のリストのstring。name-listはbyte数
とそれに続くCSVを含むuint32で表される。名前は0以外の
lengthをもち、「,」を含めないこと(MUST)。また、
nameはUS-ASCIIであること(MUST)。個々のname、
name-listに終端のnull文字を含めないこと(MUST)。
例)("zlib,none") = 00 00 00 09 7a 6c 69 62
2c 6e 6f 6e 65
string長=9
7. Message Numbers
 SSHパケットのmessage numberは1~255である。次のように割り当てられる。
番号 Protocol 用途
1~19 Transport layer protocol Transport layer generic
20~29 Algorithm negotiation
30~49 Key exchange method specific
番号は異なる認証方式に再利用可能。
50~59 User authentication protocol User authentication generic
60~79 User authentication method
specific
番号は異なる認証方式に再利用可能。
80~89 Connection protocol Connection protocol generic
90~127 Channel related messages
128~191 - Reserve for client protocol
192~255 - Local extension
22
RFC 4253, The Secure Shell (SSH) Transport Layer Protocol
 SSH Transport layer protocolについて説明する。SSHは通常はTCP/IP上で動作し、暗号化、サーバー認証、
integrity protection、圧縮が可能である。
 鍵交換方式、public keyアルゴリズム、symmetric暗号化アルゴリズム、メッセージ認証アルゴリズム、ハッシュアルゴリ
ズムは全てネゴシエーションされる。
1. Introduction
Transport protocolの認証はサーバーベースである。このプロトコルレベルではユーザー認証を実行しない。ユーザー認証
は上位のuser authentication protocolで実行される。
このプロトコルは、パラメーターのネゴシエーションを可能とし、ラウンドトリップ回数を最小限にするためにシンプルかつ柔
軟に設計されている。鍵交換方式、public keyアルゴリズム、symmetric暗号化アルゴリズム、メッセージ認証アルゴリズ
ム、ハッシュアルゴリズムは全てネゴシエーションされる。多くの環境では鍵交換、サーバー認証、Service request、
Service requestの許可通知に必要なラウンドトリップは2回である。最悪ケースでは3回になる。
4. Connection Setup
 SSHは8bitのbinary-transparent transportで動作する。
 クライアントがコネクションを開始する。
4.1. Use over TCP/IP
 TCP/IPが使用される場合、サーバーは通常はport22で接続をlistenする。このポート番号はIANAにSSH用に登録されてい
る。
4.2. Protocol Version Exchange
 コネクション確立後、双方でidentification stringを送信すること(MUST)。Identification stringは以下である
こと(MUST)。
 SSH-protoversion-softwareversion SP comments CR LF
 
 この文章で定義されているプロトコルはバージョン2.0のため、「protoversion」は「2.0」が設定されること(MUST)。
「comments」はオプションである。「comments」が含まれる場合、space(SP, ASCII:32)と「softwareversion」と「
comments」の文字列は分離されること(MUST)。Identificationは1つのCR(ASCII:13)と1つのLF(ASCII:10)で終
端されること(MUST)。Null文字を含めないこと(MUST)。CRとLFを含めて255文字が最大長である。
 CRとLFの前のidentificationの一部はDH鍵交換で使用される。
 サーバーはversion stringを送信する前に他の文字列を送信してよい(MAY)。その文字列はCRLFで終端されること
(SHOULD)。その文字列は"SSH-"で始まらず(MUST NOT)、UTF-8でエンコードされること(SHOULD)。クライアントはその
ような文字列を処理できること(MUST)。そのような文字列は無視してもよく(MAY)、クライアントに表示してもよい(MAY
)。この機能の主な用途は、TCPが切断する前のエラーメッセージ表示である。
6. Binary Packet Protocol
 各パケットは以下のフォーマットである。
フィールド名 Data Type 説明
packet_length uint32  ​パケットのバイト数。mac、
packet_lengthは含まない。
23
padding_length byte  random paddingのバイト数。
payload byte[n1]
n1 = packet_length - padding_length - 1
 パケットのpayload。圧縮がネゴシ
エーションされている場合、このフィー
ルドは圧縮される。最初のパケットは圧
縮が"none"であること(MUST)。
random padding byte[n2]
n2 = padding_length
 任意長のパディング。 
 packet_length~random
paddingまでのバイト数が8か暗号化ア
ルゴリズムのブロックサイズの大きい方
の倍数になるようにパディングされる。
 最低でも4byteのパディングがあるこ
と(MUST)。パディングはランダム値
であることが推奨される(SHOULD)。
最大のパディングは255 byte。
mac byte[m]
m = mac_length
 Message Authentication Code
。MACがネゴシエーションされる場合、
このフィールドにはMACが含まれる。最
初のパケットはMACアルゴリズムが
"none"であること(MUST)。
 "packet_length"も暗号化されることに注意せよ。また、​可変長の"random padding"が挿入されると、トラフィックの分
析が妨げられる可能性があることにも注意せよ。
6.1. Maximum Packet Length
 ​実装は、32,768byte以下の非圧縮のpayloadおよび35,000byte以下のパケット長を処理できること(MUST)。実装はより
大きいパケット('packet_length'+'padding_length'+'payload'+'random padding'+'mac')をサポートすることが
推奨される(SHOULD)。​実装はDoS攻撃やバッファオーバーフロー攻撃を回避するためにパケット長が妥当であるかチェックする
ことが推奨される(SHOULD)。
6.2. Compression
 圧縮がネゴシエーションされる場合、​'payload'のみが圧縮される。'packet_length'と'mac'は圧縮されたpayloadで計
算される。暗号化は圧縮後に実施される。圧縮アルゴリズムによっては、圧縮はステートフルになってもよい(MAY)。​圧縮は双
方向に対して独立であり(MUST)、お互いに独立したアルゴリズムが選択できること(MUST)。ただし、圧縮アルゴリズムは双
方向で同一であることが推奨される(RECOMMENDED)。
 以下の圧縮アルゴリズムが定義されている。
none REQUIRED 圧縮なし
zlib OPTIONAL ZLIB (LZ77)圧縮
6.3. Encryption
 暗号化アルゴリズムとkeyは鍵交換時にネゴシエーションされる。暗号化が有効である場合、​各パケットのpacket length,
padding length, payload, paddingは暗号化されること(MUST)​。
 一方向に送信される全てのパケットの暗号化されたデータは1つのデータストリームとして扱われる(SHOULD)。全ての暗号は
key lengthが128bit以上のkeyを使用することが推奨される(SHOULD)。
 各方向の暗号はお互いに独立して動作すること(MUST)。複数のアルゴリズムの使用が許可されている場合、実装は各方向のア
ルゴリズムを独立して選択されることを許容すること(MUST)。ただし、暗号アルゴリズムは双方向で同一であることが推奨され
る(RECOMMENDED)。
24
 以下の暗号が現在定義されている。
3des-cbc REQUIRED 3DES CBC mode
blowfish-cbc OPTIONAL Blowfish CBC mode
twofish256-cbc OPTIONAL Twofish(256 bit key) CBC mode
twofish-cbc OPTIONAL twofish256-cbcと同じ。
twofish192-cbc OPTIONAL Twofish(192 bit key) CBC mode
twofish128-cbc OPTIONAL Twofish(128 bit key) CBC mode
aes256-cbc OPTIONAL AES(256 bit key) CBC mode
aes192-cbc OPTIONAL AES(192 bit key) CBC mode
aes128-cbc RECOMMENDED AES(128 bit key) CBC mode
serpent256-cbc OPTIONAL Serpent(256 bit key) CBC mode
serpent192-cbc OPTIONAL Serpent(192 bit key) CBC mode
serpent128-cbc OPTIONAL Serpent(128 bit key) CBC mode
arcfour OPTIONAL ARCFOUR(128 bit key)
idea-cbc OPTIONAL IDEA CBC mode
cast128-cbc OPTIONAL CAST-128 CBC mode
none OPTIONAL 暗号化無し, NOT RECOMMENDED
6.4. Data Integrity
 Integrityはshared secret, パケットシーケンス番号、パケットから計算されるMACを各パケットに含めることで保護さ
れる。
 MACアルゴリズムとkeyは鍵交換時にネゴシエーションされる。最初のパケットはMACは無効でサイズ0であること(MUST)。
鍵交換後、選択されたMACアルゴリズムの'mac'は暗号化前に計算される。
mac = MAC(key, sequence_number || unencrypted_packet)
# ||は連結。
 unencrypted_packetは、'mac'を含まないパケット全体('length', 'payload', 'random padding')で
sequence_numberはuint32のパケットシーケンス番号である。sequence_numberは最初のパケットで0初期化され、パケッ
ト毎にインクリされる。Keyやアルゴリズムが再度ネゴシエーションされてもリセットされない。2^32で0に戻る。
sequence_numberはパケット自体には含まれない。
 各方向のMACアルゴリズムは独立して処理され(MUST)、実装は各方向に独立してアルゴリズムを選択することを許容すること
(MUST)。だし、アルゴリズムは双方向で同一であることが推奨される(RECOMMENDED)。
 'mac'はパケットの最後に暗号化無しで送信されること(MUST)。'mac'のサイズは選択したアルゴリズムによって異なる。
25
 以下のMACアルゴリズムが現在定義されている。
hmac-sha1 REQUIRED HMAC-SHA1
Digest Length = 20 byte
Key Length = 20 byte
hmac-sha1-96 RECOMMENDED HMAC-SHA1
Digest Length = 12 byte
Key Length = 20 byte
hmac-md5 OPTIONAL HMAC-MD5
Digest Length = 16 byte
Key Length = 16 byte
hmac-md5-96 OPTIONAL HMAC-MD5
Digest Length = 12 byte
Key Length = 16 byte
none OPTIONAL MAC無し。NOT RECOMMENDED
6.5. Key Exchange Methods
 鍵交換は暗号化と認証のためのone-time session keyの生成方法と、サーバー認証方法を指定する。
 2つの鍵交換方式が要求される(REQUIRED)。
diffie-hellman-group1-sha1 REQUIRED
diffie-hellman-group14-sha1 REQUIRED
6.6. Public Key Algorithms
 SSHは様々なpublic keyフォーマット、エンコード、アルゴリズム(署名、暗号化)で動作できるように設計されている。
 以下のpublic key、証明書のフォーマットが定義されている。
ssh-dss REQUIRED sign Raw DSS Key
ssh-rsa RECOMMENDED sign Raw RSA Key
pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
 Public keyと証明書は以下のようにエンコードされる。
string certificate or public key format identifier
byte[n] key/certificate data
 署名は以下のようにエンコードされる。
26
string signature format identifier
byte[n] 署名
 "ssh-dss" key formatは以下である。p, q, g, yから署名を生成する。
string "ssh-dss"
mpint p
mpint q
mpint g
mpint y
 署名(SHA-1 hash)は以下のようにエンコードされる。
string "ssh-dss"
string dss_signature_blob
 "ssh-rsa"の場合は以下の通り。
 key format。
string "ssh-rsa"
mpint e
mpint n
 署名(SHA-1 hash)。
string "ssh-rsa"
string rsa_signature_blob
7. Key Exchange
 鍵交換, Key exchange(Kex)はサポートしているアルゴリズム名のリストを送信することで双方から開始する。お互いが優
先するアルゴリズムをもっている。対向がどのアルゴリズムを使用するか推定してよく(MAY)、その結果に従って鍵交換をして
もよい(MAY)。
 以下の場合、推測は誤っていると見なされる。
  kexアルゴリズムまたはhost keyアルゴリズムがサーバーとクライアントで異なる。
  一致するアルゴリズムが無い。
 それ以外の場合、推測は正しく、鍵交換のパケットは正常に処理されること(MUST)。
 鍵交換で署名またはサーバーの証明書を送信する場合は、明示的なサーバー認証である。鍵交換でサーバーとクライアントが
shared secret Kを使用したMACを送信することで認証する場合は暗黙のサーバー認証である。
27
 暗黙的なサーバー認証による鍵交換の場合、クライアントは鍵交換の後にデータを送信せず、service request messageの
応答を待つこと(MUST)。
7.1. Algorithm Negotiation
 鍵交換では双方が以下のパケットを送信する。
 アルゴリズム名のリストはアルゴリズム名のcsvである。アルゴリズムは優先順位の高い順になっていること(MUST)。各
name-listには最低限1つのアルゴリズムがあること(MUST)。
SSH_MSG_KEXINIT byte
cookie (random bytes) byte[16]  送信者が生成した乱数。Keyとsession identifierを使
用せずコネクションを識別するために使用する。
kex_algorithms name-list  最初のアルゴリズムが優先されるアルゴリズムであること(
MUST)。そのアルゴリズムが選択できない場合、以下の選択
をすること(MUST)。クライアントのKexアルゴリズムをイテ
レーションして、以下の条件を満たす最初のアルゴリズムを選
択する。
+サーバーがサポートしているアルゴリズム。
+アルゴリズムが暗号化host keyを必要とする場合、暗
号化可能なアルゴリズムで双方がサポートしていること。
つまり、サーバーのserver_host_key_algorithms
にもあること。
+アルゴリズムが署名host keyを必要とする場合、署名
可能なアルゴリズムで双方がサポートしていること。つま
り、サーバーのserver_host_key_algorithmsにも
あること。
 上記を満たすアルゴリズムが無い場合、双方は切断すること
(MUST)。
server_host_key_algorithms name-list  サーバー host keyでサポートされているアルゴリズムの
name-list。サーバーはhost keyのアルゴリズムを設定す
る。クライアントは許容するアルゴリズムを設定する。1つの
サーバーに対して複数のアルゴリズムが存在してもよい(MAY
)。
 サーバーによってサポートされている、クライアントの
name-listの先頭のアルゴリズムを選択すること(MUST)。
そのようなアルゴリズムがない場合、双方は切断すること(
MUST)。
encryption_algorithms_client_to_server name-list  暗号化アルゴリズムの優先度順のname-list。選択される
アルゴリズムは、サーバー、クライアントの両方の
name-listにある最初のアルゴリズムであること(MUST)。
そのようなアルゴリズムがない場合、双方は切断すること(
MUST)。
encryption_algorithms_server_to_client name-list
mac_algorithms_client_to_server name-list  MACアルゴリズムの優先度順のname-list。選択されるア
ルゴリズムは、サーバー、クライアントの両方のname-list
にある最初のアルゴリズムであること(MUST)。そのような
アルゴリズムがない場合、双方は切断すること(MUST)。 
mac_algorithms_server_to_client name-list
compression_algorithms_client_to_server name-list 圧縮アルゴリズムの優先度順のname-list。選択されるアル
ゴリズムは、サーバー、クライアントの両方のname-listに
ある最初のアルゴリズムであること(MUST)。そのようなア
ルゴリズムがない場合、双方は切断すること(MUST)。
compression_algorithms_server_to_client name-list
languages_client_to_server name-list  Language tagの優先度順のname-list。双方はこれを無
視してもよい(MAY)。Language設定が無い場合この
name-listは空であることが推奨される(SHOULD)。送信側languages_server_to_client name-list
28
が必要でない場合、Language tagを設定しないこと(
SHOULD NOT)。
first_kex_packet_follows boolean  鍵交換のパケットが以降送信するかを示す。送信される場合
はTRUE、送信されない場合はFALSEを設定すること(MUST
)。
 対向からSSH_MSG_KEXINITパケットを受信したとき、ネゴ
シエーションの成功、失敗を知ることができる。失敗で本
フィールドがTRUEの場合、そのパケットは無視(silently
ignored)すること(MUST)。成功かつTRUEの場合はそのパ
ケットを使用する。
0 (reserved for future extension) uint32 Reserve。
 SSH_MSG_KEXINITメッセージ交換の後、鍵交換アルゴリズムが実行される。
 ​鍵交換または再鍵交換のためにSSH_MSG_KEXINITメッセージを送信した後は、SSH_MSG_NEWKEYSを送信するまでは、以下
のメッセージ以外のメッセージを送信しないこと(MUST)​。
● Transport layer generic messages(1~19)
ただし、SSH_MSG_SERVICE_REQUEST、SSH_MSG_SERVICE_ACCEPTは送信しないこと(MUST NOT)。
● Algorithm negotiation messages(20~29)
ただし、追加でSSH_MSG_KEXINITを送信しないこと(MUST NOT)。
● Specific key exchange method messages(30~49)
7.2. Output from Key Exchange
 ​鍵交換ではShared secret K、 Exchange hash Hが生成される。暗号化keyと認証keyはこれらから計算される。最初の
鍵交換で生成されたexchange hash Hはコネクションの一意の識別子(session_id)である。再鍵交換された場合でも変更さ
れない​。
 各鍵交換方式は、鍵交換で使用されるハッシュ関数(HASH)を指定する。同じハッシュアルゴリズムをkey生成で使用しないこ
と(MUST)。
 ​以下のように暗号化keyはKとHASHから計算されること(MUST)。
Initial IV client to server HASH(K || H || "A" || session_id)
Kはmpint、"A"はASCII 65、session_idは生データでエ
ンコードされる。
#session_idは最初の鍵交換で生成されたexchange hash
H
Initial IV server to client HASH(K || H || "B" || session_id)
Encryption key client to server HASH(K || H || "C" || session_id)
Encryption key server to client HASH(K || H || "D" || session_id)
Integrity key client to server HASH(K || H || "E" || session_id)
Integrity key server to client HASH(K || H || "F" || session_id)
 Keyはハッシュ値の先頭から必要なバイト数とること(MUST)。必要なKey長がハッシュ値より大きい場合、KとHの連結とKey
の全体のHASHを計算し、必要なだけkeyに追加して拡張する。
K1 = HASH(K || H || X || session_id) (X is e.g., "A")
K2 = HASH(K || H || K1)
K3 = HASH(K || H || K1 || K2)
29
...
key = K1 || K2 || K3 || ...
 使用されるメッセージ。
 双方が送信する。
byte SSH_MSG_NEWKEYS
7.3. Taking Keys Into Use
 鍵交換は双方がSSH_MSG_NEWKEYSメッセージを送信すると終了する。このメッセージは古いkeyとアルゴリズムで送信され
る。このメッセージの後に送信されるメッセージは新しいkeyとアルゴリズムを使用すること(MUST)。このメッセージを受信す
るときは、新しいkeyとアルゴリズムが使用されること(MUST)。
8. Diffie-Hellman Key Exchange
 DH鍵交換はExchange hash Hを生成する。
p 素数。公開されている。
g GF(p)で生成されるサブグループ、生成元。公開されている。
#GF = Galois Field
q サブグループの任意の値。
V_C string クライアントの識別文字列。
V_S string サーバーの識別文字列。
I_C string クライアントが送信したSSH_MSG_KEXINITメッセージ。
I_S string サーバーが送信したSSH_MSG_KEXINITメッセージ。
K_S string サーバーの公開鍵。
e mpint DH鍵交換のA。
f mpint DH鍵交換のB。
K mpint Shared secret K。
1. クライアントは乱数x(1<x<q)を生成し、e=g^x mod pを計算。eをサーバーに送信する。
2. サーバーは乱数y(0<y<q)を生成し、f=g^y mod pを計算する。
 K = e^y mod p、H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)
を計算する。Hにprivate host keyで署名する(s)。サーバーはクライアントに(K_S || f || s)を送信する。
3. クライアントはK_Sがサーバーのhost keyであることを検証する(例:データベースや証明書を使って)。クライアン
トはベリファイ無しでhost keyを許容してもよい。
クライアントは
 K = f^x mod p、H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)
を計算し、Hに署名sをベリファイする。
上記の手順でShared secret K、Exchange hash Hが生成、ベリファイされた。
 使用するメッセージ。
 1でクライアントが送信する。
30
byte SSH_MSG_KEXDH_INIT
mpint e。(e=g^x mod p。DH鍵交換のA。)
 2でサーバーが送信する。
byte SSH_MSG_KEXDH_REPLY
string サーバーの公開host keyと証明書。(K_S)
mpint f。(f=g^y mod p。DH鍵交換のB。)
string Hに署名したもの。(K_S || f || s)
9. Key Re-Exchange
 ​鍵交換を開始していないときに、SSH_MSG_KEXINITを送信することによって再鍵交換が開始される。このメッセージが受信さ
れたとき、受信したSSH_MSG_KEXINITが応答だった場合を除き、SSH_MSG_KEXINITで応答すること(MUST)。​どちらからで
も再鍵交換を開始してもよいが、サーバー、クライアントの役割は変わらない。
 ​鍵交換を開始していないときに、SSH_MSG_KEXINITを送信することによって再鍵交換が開始される。​このメッセージが受信さ
れたとき、受信したSSH_MSG_KEXINITが応答だった場合を除き、SSH_MSG_KEXINITで応答すること(MUST)。どちらからで
も再鍵交換を開始してもよいが、サーバー、クライアントの役割は変わらない。
 再鍵交換は、交換前の暗号化で行われる。​暗号化、圧縮、MACは再鍵交換後に新しいSSH_MSG_NEWKEYSが送信されるまで変更
されない。再鍵交換はsession idが変わらないことを除いて、最初の鍵交換と同様に処理される。全てのkeyとIVは鍵交換で再
計算される​。
 G byteのデータ送信後か接続して1時間経過の早い方でkey変更することが推奨される(RECOMMENDED)。ただし、再鍵交換
は処理能力が必要であるため、頻繁に実行すべきではない。
 SSH_MSG_NEWKEYSの送信後にもアプリケーションデータが送信される可能性がある。鍵交換はSSH Transport layerより
上のプロトコルには影響しない。
10. Service Request
 鍵交換後、クライアントはサービスを要求する。サービスは名前で識別される。
 以下の名前が予約されている。ローカルサービスには"servicename@domain"のようなPRIVATE USE syntaxを用いる。
ssh-userauth
ssh-connection
 サーバーは、サービス要求を拒否する場合、SSH_MSG_DISCONNECTメッセージを送信し(SHOULD)、接続を切断すること(
MUST)。
 サービスが開始すると鍵交換中に生成されたsession idにアクセスできる。
 暗黙のサーバー認証、鍵交換の後、クライアントはservice requestの応答を待つこと(MUST)。
使用するメッセージ。
 クライアントが送信する。
31
byte SSH_MSG_SERVICE_REQUEST
string service name
 サーバーが送信する。
byte SSH_MSG_SERVICE_ACCEPT
string service name
11. Additional Messages
 クライアント、サーバーのどちらからでも下記のメッセージを送信してよい。
11.1. Disconnection Message
byte SSH_MSG_DISCONNECT
uint32 reason code
string description in ISO-10646 UTF-8 encoding
string language tag [RFC3066]
 接続の終了をするメッセージ。全ての実装はこのメッセージを処理でき(MUST)、メッセージを送信することができること(
SHOULD)。
送信者はこのメッセージの後にデータの送信、受信をしてはならず(MUST NOT)、受信者はこのメッセージのの受信後に受信
したメッセージを許容しないこと(MUST NOT)。'description'は人がわかるstringである。'reason code'は下記の値
である。
Symbolic name reason code
SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
SSH_DISCONNECT_PROTOCOL_ERROR 2
SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
SSH_DISCONNECT_RESERVED 4
SSH_DISCONNECT_MAC_ERROR 5
SSH_DISCONNECT_COMPRESSION_ERROR 6
SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
SSH_DISCONNECT_CONNECTION_LOST 10
SSH_DISCONNECT_BY_APPLICATION 11
32
SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
SSH_DISCONNECT_ILLEGAL_USER_NAME 15
11.2. Ignored Data Message
byte SSH_MSG_IGNORE
string data
 全ての実装はこのメッセージを受信した場合、理解した上で無視すること(MUST)。送信処理を実装する必要は無い。このメッ
セージはトラフィック分析に使用できる。
#DPD的な死活監視用?
11.3. Debug Message
byte SSH_MSG_DEBUG
string always_display
string message in ISO-10646 UTF-8 encoding
string language tag [RFC3066]
 全ての実装はこのメッセージを受信した場合、理解した上で(MUST)無視してよい。このメッセージはデバッグメッセージの送
信に使用される。'always_display'がTRUEの場合、メッセージは表示されることが推奨される(SHOULD)。FALSEの場合、
デバッグ情報の表示がユーザーから明示的に要求されていない限り、表示しないことが推奨される(SHOULD NOT)。
11.4. Reserved Messages
byte SSH_MSG_UNIMPLEMENTED
uint32 packet sequence number of rejected message
 実装は受信したメッセージの順にSSH_MSG_UNIMPLEMENTEDで全ての認識できないメッセージに応答すること(MUST)。その
ようなメッセージはそれ以外の処理をせず無視すること(MUST)。
12. Summary of Message Numbers
 メッセージ一覧。30-49はkex packetで使用される。異なるkexでは番号は再利用される。
SSH_MSG_DISCONNECT 1
SSH_MSG_IGNORE 2
33
SSH_MSG_UNIMPLEMENTED 3
SSH_MSG_DEBUG 4
SSH_MSG_SERVICE_REQUEST 5
SSH_MSG_SERVICE_ACCEPT 6
SSH_MSG_KEXINIT 20
SSH_MSG_NEWKEYS 21
34
RFC 4344, The Secure Shell (SSH) Transport Layer Encryption Modes
1. Introduction
 SSH Transport Protocolはプライバシー保護とカプセル化されたデータのintegrityを提供するように設計されている。
しかし、RFC4253のSSH Transport Protocolの一部にセキュリティ問題が発見された。例えば、暗号化モードは
chosen-plaintext privacy attackに対して脆弱である。また、rekeyの頻度が不十分の場合、payloadが漏洩する可能
性がある。後者は暗号化モードによらず問題になる。
3. Rekeying
RFC4253 section 9ではSSHの実装が1GBのデータ送信毎のrekeyを提案している。しかし、rekeyが不十分な場合の問題に
ついては議論していない。このsectionではrekeyに関する推奨事項について説明する。
 本sectionでは2つの推奨事項を示す。最初の推奨事項はMACタグの漏洩からの情報保護が目的であり、もう一つはブロック暗
号から発生する漏洩からの情報保護が目的である。ブロック暗号のブロック長と暗号化パケット長によっては最初の事項が優先さ
れる場合がある。
3.1. First Rekeying Recommendation
 ​MACタグを介した情報漏洩の可能性があるため、SSHの実装は少なくとも2^32パケットの送信毎に1回 rekeyすることが推奨さ
れる(SHOULD)。​別の言い方をすれば、鍵交換後、SSHの実装はrekey前に2^32パケット以上を送信しないことが推奨される(
SHOULD NOT)。
 ​SSHの実装は最後のrekey後に2**32パケットを超えるパケットを受信する前にrekeyをすることが推奨される(SHOULD)。
推奨される方法は、最後のrekey後に2**31パケットを受信した後にrekeyすることである。
3.2. Second Rekeying Recommendation
 ブロック暗号によっては、実装は多くのブロックを同一の暗号化keyで暗号化しないように注意すること。
 ブロック暗号のブロック長をL(bit)とする。AESの場合はL=128。Lが128以上の場合、​rekey前に2**(L/4)ブロックを超
えるブロックの暗号化をしないことが推奨される(SHOULD NOT)。​そのような場合は実装はrekeyを試行することが推奨され
る。Lが128より小さい場合、2**(L/4)ブロック毎のrekeyはコストがかかる場合があるが、少なくとも1GB毎にrekeyすること
が推奨される。
4. Encryption Modes
 SSH Transport Protocolで使用するための新しい暗号化方式を説明する。これらの暗号化方式はRFC4253 section 6.3
の暗号化方式に追加される。
aes128-ctr RECOMMENDED AES(128 bit key) SDCTR mode
aes192-ctr RECOMMENDED AES(192 bit key) SDCTR mode
aes256-ctr RECOMMENDED AES(256 bit key) SDCTR mode
3des-ctr RECOMMENDED 3DES SDCTR mode
blowfish-ctr OPTIONAL Blowfish SDCTR mode
twofish128-ctr OPTIONAL Twofish(128 bit key) SDCTR mode
twofish192-ctr OPTIONAL Twofish(192 bit key) SDCTR mode
35
twofish256-ctr OPTIONAL Twofish(256 bit key) SDCTR mode
serpent128-ctr OPTIONAL Serpent(128 bit key) SDCTR mode
serpent192-ctr OPTIONAL Serpent(192 bit key) SDCTR mode
serpent256-ctr OPTIONAL Serpent(256 bit key) SDCTR mode
idea-ctr OPTIONAL IDEA SDCTR mode
cast128-ctr OPTIONAL CAST-128 SDCTR mode
36

Contenu connexe

Tendances

検証環境をGoBGPで極力仮想化してみた
検証環境をGoBGPで極力仮想化してみた検証環境をGoBGPで極力仮想化してみた
検証環境をGoBGPで極力仮想化してみたToshiya Mabuchi
 
コンテナ時代のOpenStack
コンテナ時代のOpenStackコンテナ時代のOpenStack
コンテナ時代のOpenStackAkira Yoshiyama
 
AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較beyond Co., Ltd.
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能Kohei Tokunaga
 
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話Yuta Shimada
 
これからLDAPを始めるなら 「389-ds」を使ってみよう
これからLDAPを始めるなら 「389-ds」を使ってみようこれからLDAPを始めるなら 「389-ds」を使ってみよう
これからLDAPを始めるなら 「389-ds」を使ってみようNobuyuki Sasaki
 
containerdの概要と最近の機能
containerdの概要と最近の機能containerdの概要と最近の機能
containerdの概要と最近の機能Kohei Tokunaga
 
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)VirtualTech Japan Inc.
 
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディングTakuya ASADA
 
Scapyで作る・解析するパケット
Scapyで作る・解析するパケットScapyで作る・解析するパケット
Scapyで作る・解析するパケットTakaaki Hoyo
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線Motonori Shindo
 
え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理
え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理
え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理NTT DATA Technology & Innovation
 
ネットワークコンフィグ分析ツール Batfish との付き合い方
ネットワークコンフィグ分析ツール Batfish との付き合い方ネットワークコンフィグ分析ツール Batfish との付き合い方
ネットワークコンフィグ分析ツール Batfish との付き合い方akira6592
 
今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみた今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみたKohei Tokunaga
 
DPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキングDPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキングTomoya Hibi
 
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようPHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようShohei Okada
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編株式会社 NTTテクノクロス
 
root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす Akihiro Suda
 

Tendances (20)

検証環境をGoBGPで極力仮想化してみた
検証環境をGoBGPで極力仮想化してみた検証環境をGoBGPで極力仮想化してみた
検証環境をGoBGPで極力仮想化してみた
 
コンテナ時代のOpenStack
コンテナ時代のOpenStackコンテナ時代のOpenStack
コンテナ時代のOpenStack
 
AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能
 
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話
 
これからLDAPを始めるなら 「389-ds」を使ってみよう
これからLDAPを始めるなら 「389-ds」を使ってみようこれからLDAPを始めるなら 「389-ds」を使ってみよう
これからLDAPを始めるなら 「389-ds」を使ってみよう
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
containerdの概要と最近の機能
containerdの概要と最近の機能containerdの概要と最近の機能
containerdの概要と最近の機能
 
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
 
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング
 
Scapyで作る・解析するパケット
Scapyで作る・解析するパケットScapyで作る・解析するパケット
Scapyで作る・解析するパケット
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
 
え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理
え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理
え、まって。その並列分散処理、Kafkaのしくみでもできるの? Apache Kafkaの機能を利用した大規模ストリームデータの並列分散処理
 
ネットワークコンフィグ分析ツール Batfish との付き合い方
ネットワークコンフィグ分析ツール Batfish との付き合い方ネットワークコンフィグ分析ツール Batfish との付き合い方
ネットワークコンフィグ分析ツール Batfish との付き合い方
 
今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみた今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみた
 
DPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキングDPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキング
 
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようPHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編
 
root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす
 

Similaire à SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)

OpenSSH User EnumerationTime-Based Attack と Python-paramiko
OpenSSH User EnumerationTime-Based Attack と Python-paramikoOpenSSH User EnumerationTime-Based Attack と Python-paramiko
OpenSSH User EnumerationTime-Based Attack と Python-paramiko(^-^) togakushi
 
ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)Shinichi Awamoto
 
Serverspecの活用tips紹介
Serverspecの活用tips紹介Serverspecの活用tips紹介
Serverspecの活用tips紹介Daisuke Ikeda
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめMakiko Konoshima
 
MacPort_&_FTP_ver1.0
MacPort_&_FTP_ver1.0MacPort_&_FTP_ver1.0
MacPort_&_FTP_ver1.0Satoshi Kume
 
MBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライド
MBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライドMBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライド
MBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライドYoshinori Hayashi
 
社内向けTech Talk資料~Fluentdの基本紹介~
社内向けTech Talk資料~Fluentdの基本紹介~ 社内向けTech Talk資料~Fluentdの基本紹介~
社内向けTech Talk資料~Fluentdの基本紹介~ Daisuke Ikeda
 
STNSサーバーを書いてみた
STNSサーバーを書いてみたSTNSサーバーを書いてみた
STNSサーバーを書いてみたYoshinori Teraoka
 
Apache Camel Netty component
Apache Camel Netty componentApache Camel Netty component
Apache Camel Netty componentssogabe
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
debugging server with strace
debugging server with stracedebugging server with strace
debugging server with straceYoshinari Takaoka
 
QP 3min cooking(port 9100 network printing howto)
QP 3min cooking(port 9100 network printing howto)QP 3min cooking(port 9100 network printing howto)
QP 3min cooking(port 9100 network printing howto)gueste558ec
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
おまえらこのライブラリ使ってないの? m9 (2013-07)
おまえらこのライブラリ使ってないの? m9	(2013-07)おまえらこのライブラリ使ってないの? m9	(2013-07)
おまえらこのライブラリ使ってないの? m9 (2013-07)Toru Furukawa
 
Dbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishDbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishYohei Azekatsu
 
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リーリナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リーCODE BLUE
 
Openstack SPICE console (icehouse) verification
Openstack SPICE console (icehouse) verificationOpenstack SPICE console (icehouse) verification
Openstack SPICE console (icehouse) verificationyukihiro kawada
 
マルチプラットホームになった PowerShell 6 でクロスプラットホームする
マルチプラットホームになった PowerShell 6 でクロスプラットホームするマルチプラットホームになった PowerShell 6 でクロスプラットホームする
マルチプラットホームになった PowerShell 6 でクロスプラットホームするSyuichi Murashima
 

Similaire à SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File) (20)

OpenSSH User EnumerationTime-Based Attack と Python-paramiko
OpenSSH User EnumerationTime-Based Attack と Python-paramikoOpenSSH User EnumerationTime-Based Attack と Python-paramiko
OpenSSH User EnumerationTime-Based Attack と Python-paramiko
 
ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)
 
Serverspecの活用tips紹介
Serverspecの活用tips紹介Serverspecの活用tips紹介
Serverspecの活用tips紹介
 
sshdのお話
sshdのお話sshdのお話
sshdのお話
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
MacPort_&_FTP_ver1.0
MacPort_&_FTP_ver1.0MacPort_&_FTP_ver1.0
MacPort_&_FTP_ver1.0
 
MBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライド
MBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライドMBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライド
MBSD_Cybersecurity_Challenges_2017_最終審査会_発表スライド
 
社内向けTech Talk資料~Fluentdの基本紹介~
社内向けTech Talk資料~Fluentdの基本紹介~ 社内向けTech Talk資料~Fluentdの基本紹介~
社内向けTech Talk資料~Fluentdの基本紹介~
 
STNSサーバーを書いてみた
STNSサーバーを書いてみたSTNSサーバーを書いてみた
STNSサーバーを書いてみた
 
Apache Camel Netty component
Apache Camel Netty componentApache Camel Netty component
Apache Camel Netty component
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
debugging server with strace
debugging server with stracedebugging server with strace
debugging server with strace
 
Part Print
Part PrintPart Print
Part Print
 
QP 3min cooking(port 9100 network printing howto)
QP 3min cooking(port 9100 network printing howto)QP 3min cooking(port 9100 network printing howto)
QP 3min cooking(port 9100 network printing howto)
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
おまえらこのライブラリ使ってないの? m9 (2013-07)
おまえらこのライブラリ使ってないの? m9	(2013-07)おまえらこのライブラリ使ってないの? m9	(2013-07)
おまえらこのライブラリ使ってないの? m9 (2013-07)
 
Dbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishDbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publish
 
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リーリナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
 
Openstack SPICE console (icehouse) verification
Openstack SPICE console (icehouse) verificationOpenstack SPICE console (icehouse) verification
Openstack SPICE console (icehouse) verification
 
マルチプラットホームになった PowerShell 6 でクロスプラットホームする
マルチプラットホームになった PowerShell 6 でクロスプラットホームするマルチプラットホームになった PowerShell 6 でクロスプラットホームする
マルチプラットホームになった PowerShell 6 でクロスプラットホームする
 

Plus de Tetsuya Hasegawa

CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)Tetsuya Hasegawa
 
RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料Tetsuya Hasegawa
 
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料Tetsuya Hasegawa
 
面白いセキュリティツール その2
面白いセキュリティツール その2面白いセキュリティツール その2
面白いセキュリティツール その2Tetsuya Hasegawa
 
RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料Tetsuya Hasegawa
 
RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料Tetsuya Hasegawa
 
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料Tetsuya Hasegawa
 
RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。Tetsuya Hasegawa
 
RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。Tetsuya Hasegawa
 
3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要Tetsuya Hasegawa
 
RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料Tetsuya Hasegawa
 
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料Tetsuya Hasegawa
 
RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料Tetsuya Hasegawa
 
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料Tetsuya Hasegawa
 
RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料Tetsuya Hasegawa
 
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向Tetsuya Hasegawa
 
MCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモMCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモTetsuya Hasegawa
 
面白いセキュリティツール
面白いセキュリティツール面白いセキュリティツール
面白いセキュリティツールTetsuya Hasegawa
 
3GPP TS 38.300-100まとめ
3GPP TS 38.300-100まとめ3GPP TS 38.300-100まとめ
3GPP TS 38.300-100まとめTetsuya Hasegawa
 

Plus de Tetsuya Hasegawa (20)

CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)
 
RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料
 
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
 
面白いセキュリティツール その2
面白いセキュリティツール その2面白いセキュリティツール その2
面白いセキュリティツール その2
 
RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料
 
RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料
 
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
 
RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。
 
RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。
 
3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要
 
RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料
 
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
 
RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料
 
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
 
RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料
 
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
 
MCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモMCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモ
 
RFC5996(IKEv2)第2版
RFC5996(IKEv2)第2版RFC5996(IKEv2)第2版
RFC5996(IKEv2)第2版
 
面白いセキュリティツール
面白いセキュリティツール面白いセキュリティツール
面白いセキュリティツール
 
3GPP TS 38.300-100まとめ
3GPP TS 38.300-100まとめ3GPP TS 38.300-100まとめ
3GPP TS 38.300-100まとめ
 

SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)

  • 1. SSH(Secure SHell)の勉強資料です。 SSHのパケットを復号することになり、その過程で調べたり作ったりしたものをサマった資料です。 ● 使用ソフト sshクライアント&サーバー libssh 0.8.6 復号 openssl 1.0.2q 間違っていたらコメントをお願いします。 SSHの勉強資料 Table of Contents Table of Contents 1 SSH復号ツールを作ろう 3 1. デバッグ環境構築 3 1.1 libsshをビルド&インストール 3 1.2 sshクライアント 4 1.2.1 作成 4 1.2.2 ビルド 5 1.2.3 実行&トレース 5 1.3 sshサーバー 6 1.3.1 作成 6 1.3.2 ビルド 10 1.3.3 実行&トレース 10 1.4 libssh改造 10 1.4.1 処理の流れ 10 1.4.2 改造ソース 11 1.4.3 デバッグメモ 12 2. 復号プログラム作成 12 2.1 作成 12 2.2 ビルド 13 2.3 実行 13 2.3.1 パケット準備 13 2.3.2 復号プログラムの実行 14 2.4 考察 17 RFC編 18 SSH関連のRFCリスト 18 RFC 4251, The Secure Shell (SSH) Protocol Architecture 20 1. Introduction 20 4. Architecture 20 4.1. Host Keys 20 4.2. Extensibility 20 4.3. Policy Issues 21 4.4. Security Properties 21 5. Data Type Representations Used in the SSH Protocols 21 1
  • 2. 7. Message Numbers 22 RFC 4253, The Secure Shell (SSH) Transport Layer Protocol 23 1. Introduction 23 4. Connection Setup 23 4.1. Use over TCP/IP 23 6. Binary Packet Protocol 23 6.1. Maximum Packet Length 24 6.2. Compression 24 6.3. Encryption 24 6.4. Data Integrity 25 6.5. Key Exchange Methods 26 6.6. Public Key Algorithms 26 7. Key Exchange 27 7.1. Algorithm Negotiation 28 7.2. Output from Key Exchange 29 7.3. Taking Keys Into Use 30 8. Diffie-Hellman Key Exchange 30 9. Key Re-Exchange 31 10. Service Request 31 11. Additional Messages 32 11.1. Disconnection Message 32 11.2. Ignored Data Message 33 11.3. Debug Message 33 11.4. Reserved Messages 33 12. Summary of Message Numbers 34 RFC 4344, The Secure Shell (SSH) Transport Layer Encryption Modes 35 1. Introduction 35 3. Rekeying 35 3.1. First Rekeying Recommendation 35 3.2. Second Rekeying Recommendation 35 4. Encryption Modes 35 2
  • 3. SSH復号ツールを作ろう  まずRFCを読んで復号に必要な情報を特定する。 ⇒Key, IV、アルゴリズムがわかればOK。圧縮ありの場合は圧縮アルゴリズムも。  アルゴリズムによってはブロック番号、Counter、前の暗号化パケット等が必要になる。  #圧縮アルゴリズムはマジックナンバー見ればわかる。  詳細は​RFC編​の章を参照。  libsshを修正して復号に必要な情報を出力する。 ⇒libsshをデバッグして探す。  詳細は​1. デバッグ環境構築​の章を参照。  それらの情報と復号プログラムを使ってsshパケットを復号する。 ⇒libsslで復号する。  詳細は​2. 復号プログラム作成​の章を参照。  以下はSSHのコネクションフロー。SSH_MSG_NEWKWYSのときにsrcdh.cでKey、IVが生成されるので主にそのあたりを見て いく。 1. デバッグ環境構築  libsshに修正が必要なのでlibsshのデバッグ環境を構築する。 1.1 libsshをビルド&インストール  デバッグ用のオプション指定(-DCMAKE_BUILD_TYPE=Profiling、-DWITH_DEBUG_CRYPTO=ON)がポイント。 # wget https://git.libssh.org/projects/libssh.git/snapshot/libssh-0.8.6.zip # unzip libssh-0.8.6.zip # cd libssh-0.8.6 # mkdir build # cmake ​-DCMAKE_BUILD_TYPE=Profiling​ ​-DWITH_DEBUG_CRYPTO=ON​ .. # make # make install 3
  • 4. 1.2 sshクライアント 1.2.1 作成  GDBでデバッグする用のsshクライアントを作成する。  localhost:2222のsshサーバーに接続して認証用のユーザー名、パスワードを送信してcatして切断する。  catしているファイルは2,000byteのテキストファイル。  詳細はlibsshのチュートリアルとAPIリファレンス参照。  ​http://api.libssh.org/master/libssh_tutorial.html /* sshc.c */ #define LIBSSH_STATIC 1 #include <libssh/libssh.h> #include <stdlib.h> #include <stdio.h> int main() { ssh_session session; ssh_channel channel; int port = 2222; char userpass[] = "hasegawa"; char buffer[4096]; unsigned int nbytes; const char *pcap_file="debug.client.pcap"; ssh_pcap_file pcap; int state; session = ssh_new(); system("tcpdump -i any -w sshc.pcap &"); system("sleep 3"); ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); ssh_options_set(session, SSH_OPTIONS_PORT, &port); ssh_options_set(session, SSH_OPTIONS_USER, userpass); pcap=ssh_pcap_file_new(); ssh_pcap_file_open(pcap,pcap_file); ssh_set_pcap_file(session,pcap); ssh_connect(session); ssh_userauth_password(session, NULL, userpass); channel = ssh_channel_new(session); ssh_channel_open_session(channel); state = ssh_channel_request_exec(channel, "cat /hasegawa.txt"); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); while (nbytes > 0) { fwrite(buffer, 1, nbytes, stdout); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); } ssh_channel_send_eof(channel); ssh_channel_close(channel); ssh_channel_free(channel); ssh_disconnect(session); ssh_free(session); ssh_pcap_file_free(pcap); ssh_finalize(); system("sleep 3"); system("killall tcpdump"); return 0; } 4
  • 5. 1.2.2 ビルド # gcc -DLIBSSH_STATIC sshc.c -lssh -g -O0 -o sshc 1.2.3 実行&トレース # gdb ./sshc (gdb) b main Breakpoint 1 at 0xb65: file sshc.c, line 6. (gdb) r Breakpoint 1, main () at sshc.c:6 6 int main() { (gdb) s 9 int port = 2222; (gdb) 10 char userpass[] = "hasegawa"; (gdb) 13 session = ssh_new(); (gdb) ssh_new () at /root/libssh/libssh-0.8.6/src/session.c:60  ちなみに「WITH_DEBUG_CRYPTO=ON」でlibsshをビルドすると、暗号化/復号のために必要なIV、Keyが表示される。  暗号化アルゴリズム種別は出力されないので「libssh-0.8.6srcdh.c::ssh_generate_session_keys()」に手を入 れて表示する。  実行例)クライアントのログ  クライアントからサーバー方向の通信(暗号化)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無 し。  サーバーからクライアント方向の通信(復号)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無 し。 Encrypt IV: 3b:1a:a7:66:20:a3:3b:de:71:ed:9c:3d:d3:25:39:44:bd:62:66:f0:cb:b5:e3:37:80:e5:db:47:fb:04:87 :02 Decrypt IV: 6e:57:fd:ee:d4:5e:dc:d0:9c:64:44:61:3b:5f:ef:a5:8b:da:35:e7:ed:6d:c8:14:38:d1:eb:ce:19:1b:d2 :eb Encryption key: d8:8f:39:02:4c:cc:46:43:6d:9e:b9:3e:13:21:ed:f9:e4:af:56:87:5d:5c:40:2c:42:85:09:a4:f6:ab:cc :67 Decryption key: ad:d0:6b:d0:12:17:0e:73:e3:40:90:e7:ec:05:57:3e:ea:98:bc:f9:cd:3e:9d:1b:bf:a2:d1:4d:e2:d3:a5 :98 Encryption MAC: 0f:b4:ae:91:af:af:e7:55:69:49:dd:0f:93:34:53:73:c6:ca:e4:31:08:a1:d3:48:9f:e3:4d:8e:c1:80:f0 :50 Decryption MAC: 19:9e:2c:da:33:ee:90:84:3d:31:8d:31:67:c8:d7:bd:e4:2d:36:77:54:bb:f6:1f:23:d3:03:a4:f1:44:bf :39 Encrypt: aes256-ctr Decryption: aes256-ctr do_compress_out: 0 do_compress_in: 0 5
  • 6. 1.3 sshサーバー 1.3.1 作成  GDBでデバッグする用のsshサーバーを作成する。  localhost:2222でリッスン、クライアントをパスワード認証してコマンドの結果を返す。  詳細はlibsshのチュートリアルとAPIリファレンス参照。  ​http://api.libssh.org/master/libssh_tutorial.html /* sshs.c */ #include <libssh/callbacks.h> #include <libssh/server.h> #include <poll.h> #include <fcntl.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <stdio.h> #define BUF_SIZE 4096 /* A userdata struct for channel. */ struct channel_data_struct { pid_t pid; socket_t pty_master; socket_t pty_slave; socket_t child_stdin; socket_t child_stdout; socket_t child_stderr; ssh_event event; struct winsize *winsize; }; /* A userdata struct for session. */ struct session_data_struct { ssh_channel channel; int auth_attempts; int authenticated; }; static int exec_request(ssh_session session, ssh_channel channel, const char *command, void *userdata) { struct channel_data_struct *cdata = (struct channel_data_struct *) userdata; int in[2], out[2], err[2]; pipe(in); pipe(out); pipe(err); if((cdata->pid = fork()) == 0) { close(in[1]); close(out[0]); close(err[0]); dup2(in[0], STDIN_FILENO); dup2(out[1], STDOUT_FILENO); dup2(err[1], STDERR_FILENO); close(in[0]); close(out[1]); close(err[1]); execl("/bin/sh", "sh", "-c", command, NULL); exit(0); } close(in[0]); 6
  • 7. close(out[1]); close(err[1]); cdata->child_stdin = in[1]; cdata->child_stdout = out[0]; cdata->child_stderr = err[0]; return SSH_OK; } static int auth_password(ssh_session session, const char *user, const char *pass, void *userdata) { struct session_data_struct *sdata = (struct session_data_struct *) userdata; if (strcmp(user, "hasegawa") == 0 && strcmp(pass, "hasegawa") == 0) { sdata->authenticated = 1; return SSH_AUTH_SUCCESS; } sdata->auth_attempts++; return SSH_AUTH_DENIED; } static ssh_channel channel_open(ssh_session session, void *userdata) { struct session_data_struct *sdata = (struct session_data_struct *) userdata; sdata->channel = ssh_channel_new(session); return sdata->channel; } static int process_stdout(socket_t fd, int revents, void *userdata) { char buf[BUF_SIZE]; int n = -1; ssh_channel channel = (ssh_channel) userdata; if (channel != NULL && (revents & POLLIN) != 0) { n = read(fd, buf, BUF_SIZE); if (n > 0) { ssh_channel_write(channel, buf, n); } } return n; } static int process_stderr(socket_t fd, int revents, void *userdata) { char buf[BUF_SIZE]; int n = -1; ssh_channel channel = (ssh_channel) userdata; if (channel != NULL && (revents & POLLIN) != 0) { n = read(fd, buf, BUF_SIZE); if (n > 0) { ssh_channel_write_stderr(channel, buf, n); } } return n; } static void handle_session(ssh_event event, ssh_session session) { int n, rc; struct winsize wsize = { .ws_row = 0, .ws_col = 0, .ws_xpixel = 0, 7
  • 8. .ws_ypixel = 0 }; struct channel_data_struct cdata = { .pid = 0, .pty_master = -1, .pty_slave = -1, .child_stdin = -1, .child_stdout = -1, .child_stderr = -1, .event = NULL, .winsize = &wsize }; struct session_data_struct sdata = { .channel = NULL, .auth_attempts = 0, .authenticated = 0 }; struct ssh_channel_callbacks_struct channel_cb = { .userdata = &cdata, .channel_exec_request_function = exec_request, }; struct ssh_server_callbacks_struct server_cb = { .userdata = &sdata, .auth_password_function = auth_password, .channel_open_request_session_function = channel_open, }; ssh_callbacks_init(&server_cb); ssh_callbacks_init(&channel_cb); ssh_set_server_callbacks(session, &server_cb); ssh_handle_key_exchange(session); ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD); ssh_event_add_session(event, session); n = 0; while (sdata.authenticated == 0 || sdata.channel == NULL) { ssh_event_dopoll(event, 100); n++; } ssh_set_channel_callbacks(sdata.channel, &channel_cb); do { ssh_event_dopoll(event, -1); if (cdata.event != NULL || cdata.pid == 0) { continue; } cdata.event = event; if (cdata.child_stdout != -1) { ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout, sdata.channel); } if (cdata.child_stderr != -1) { ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr, sdata.channel); } } while(ssh_channel_is_open(sdata.channel) && (cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0)); close(cdata.pty_master); close(cdata.child_stdin); 8
  • 9. close(cdata.child_stdout); close(cdata.child_stderr); ssh_event_remove_fd(event, cdata.child_stdout); ssh_event_remove_fd(event, cdata.child_stderr); if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) { rc = WEXITSTATUS(rc); ssh_channel_request_send_exit_status(sdata.channel, rc); } else if (cdata.pid > 0) { kill(cdata.pid, SIGKILL); } ssh_channel_send_eof(sdata.channel); ssh_channel_close(sdata.channel); for (n = 0; n < 50 && (ssh_get_status(session) & (SSH_CLOSED | SSH_CLOSED_ERROR)) == 0; n++) { ssh_event_dopoll(event, 100); } } int main(int argc, char **argv) { ssh_bind sshbind; ssh_session session; ssh_event event; int port = 2222; const char *pcap_file="debug.server.pcap"; ssh_pcap_file pcap; ssh_init(); sshbind = ssh_bind_new(); ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port); ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, "ssh_host_rsa_key"); ssh_bind_listen(sshbind); while (1) { session = ssh_new(); pcap = ssh_pcap_file_new(); ssh_pcap_file_open(pcap, pcap_file); ssh_set_pcap_file(session, pcap); ssh_bind_accept(sshbind, session); if(fork() == 0) { ssh_bind_free(sshbind); event = ssh_event_new(); handle_session(event, session); ssh_event_free(event); ssh_disconnect(session); ssh_free(session); ssh_pcap_file_free(pcap); exit(0); } ssh_disconnect(session); ssh_free(session); } ssh_bind_free(sshbind); ssh_finalize(); return 0; }  Host認証用のRSA keyを生成する。 #ssh-keygen -t rsa -b 2048 -f ssh_host_rsa_key -N '' 9
  • 10. 1.3.2 ビルド gcc -DLIBSSH_STATIC -DWOTH_PCAP sshs.c -lssh -g -O0 -o sshs 1.3.3 実行&トレース  実行例)サーバーのログ  サーバーからクライアント方向の通信(暗号化)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無 し。  クライアントからサーバー方向の通信(復号)はAES-256-CTRで暗号化されている。なのでIV, Keyが256 bit。圧縮は無 し。  暗号化/復号のKey、IVがクライアントの例を逆になっている。 Encrypt IV: 6e:57:fd:ee:d4:5e:dc:d0:9c:64:44:61:3b:5f:ef:a5:8b:da:35:e7:ed:6d:c8:14:38:d1:eb:ce:19:1b:d2 :eb Decrypt IV: 3b:1a:a7:66:20:a3:3b:de:71:ed:9c:3d:d3:25:39:44:bd:62:66:f0:cb:b5:e3:37:80:e5:db:47:fb:04:87 :02 Encryption key: ad:d0:6b:d0:12:17:0e:73:e3:40:90:e7:ec:05:57:3e:ea:98:bc:f9:cd:3e:9d:1b:bf:a2:d1:4d:e2:d3:a5 :98 Decryption key: d8:8f:39:02:4c:cc:46:43:6d:9e:b9:3e:13:21:ed:f9:e4:af:56:87:5d:5c:40:2c:42:85:09:a4:f6:ab:cc :67 Encryption MAC: 19:9e:2c:da:33:ee:90:84:3d:31:8d:31:67:c8:d7:bd:e4:2d:36:77:54:bb:f6:1f:23:d3:03:a4:f1:44:bf :39 Decryption MAC: 0f:b4:ae:91:af:af:e7:55:69:49:dd:0f:93:34:53:73:c6:ca:e4:31:08:a1:d3:48:9f:e3:4d:8e:c1:80:f0 :50 Encrypt: aes256-ctr Decryption: aes256-ctr do_compress_out: 0 do_compress_in: 0 1.4 libssh改造  SSH_MSG_NEWKEYSを受信し、Shared secret K、 Exchange hash HからKey、IVを生成する箇所にそれらをダンプす る処理を追加する。 1.4.1 処理の流れ 処理内容 ソース ①Key, IVを生成、設定 srcpacket_cb.c::SSH_PACKET_CALLBACK(ssh_packet_newkeys) SSH_MSG_NEWKEYS受信時のコールバック。主に以下の処理を実行する。 srcdh.c::ssh_generate_session_keys(ssh_session session) Shared secret K、 Exchange hash HからKey、IVを生成。 両方向のIV、Key、MACをssh_crypto_structにセット。 srcpacket_cb.c::SSH_PACKET_CALLBACK(ssh_packet_newkeys) set_decrypt_key()、set_encrypt_key()でKey、IVを設定 10
  • 11. ②受信パケットの復号 srcpacket_crypt.c::ssh_packet_decrypt() 受信したパケットを復号する。アルゴリズム毎に復号関数は異なる。 srclibcrypto.c::struct ssh_ciphertab[] アルゴリズム定義の構造体。名前、暗号化/復号の関数等が設定される。 (例)AES-256-CTRの場合は下記。 .name = "aes256-ctr", .blocksize = 16, .ciphertype = SSH_AES256_CTR, .keysize = 256, .set_encrypt_key = evp_cipher_set_encrypt_key, .set_decrypt_key = evp_cipher_set_decrypt_key, .encrypt = evp_cipher_encrypt, .decrypt = evp_cipher_decrypt, .cleanup = evp_cipher_cleanup 1.4.2 改造ソース  改造内容は下記。①のKey、IVを生成後に値をダンプする。 diff src/dh.c src/dh_org.c 1159,1198d1158 < { < const char *filename_C[]= {"/EIV_C", "/DIV_C", "/EKEY_C", "/DKEY_C"}; < const char *filename_S[]= {"/EIV_S", "/DIV_S", "/EKEY_S", "/DKEY_S"}; < const char *ALGO_file_C="/ALGO_C"; < const char *ALGO_file_S="/ALGO_S"; < FILE *fp; < < for(int i=0; i<4; i++) { < if(session->client) < fp = fopen(filename_C[i], "wb"); < else < fp = fopen(filename_S[i], "wb"); < switch(i) { < case 0: < fwrite ((const void *)crypto->encryptIV, crypto->digest_len, 1, fp); < break; < case 1: < fwrite ((const void *)crypto->decryptIV, crypto->digest_len, 1, fp); < break; < case 2: < fwrite ((const void *)crypto->encryptkey, crypto->out_cipher->keysize / 8, 1, fp); < break; < case 3: < fwrite ((const void *)crypto->decryptkey, crypto->in_cipher->keysize / 8, 1, fp); < break; < } < fclose(fp); < } < if(session->client) < fp= fopen(ALGO_file_C, "w"); < else < fp= fopen(ALGO_file_S, "w"); < fprintf(fp, "Encrypt: %sn", crypto->out_cipher->name); < fprintf(fp, "Decryption: %sn", crypto->in_cipher->name); < fprintf(fp, "do_compress_out: %dn", crypto->do_compress_out); < fprintf(fp, "do_compress_in: %dn", crypto->do_compress_in); < fclose(fp); 11
  • 12. 1.4.3 デバッグメモ  デバッグしたときに改造したソースメモ。 受信した暗号化パケット+Decrption Key+復号したパケットの表示 srcpacket_crypt.c::ssh_packet_decrypt()  ssh_print_hexa("Decryption key", session->current_crypto->decryptkey, 256/8);//Dec Key  ssh_print_hexa("Source", source+start, 32);//受信した暗号化パケット  crypto->decrypt(crypto, source + start, destination, encrypted_size);  ssh_print_hexa("Destination", destination, 32);//復号したパケット シーケンス番号の表示 srcpacket_crypt.c::ssh_packet_hmac_verify()  ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t)); 2. 復号プログラム作成 2.1 作成  サーバーパケットの復号プログラムを作成する。  インプットは、サーバー→クライアント方向のSSHパケットのバイナリ、クライアントのDecryption keyとDecryption IV 。  前章のDecription Key、Decription IV、暗号化アルゴリズム名を使用して復号プログラムを作成する。  詳細はチュートリアルとAPIリファレンス参照。  ​https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption /* ssl.c */ #include <openssl/conf.h> #include <openssl/evp.h> #include <openssl/err.h> #include <string.h> EVP_CIPHER_CTX *ctx; void setkey(unsigned char *key, char *iv) { EVP_CIPHER_CTX_init(ctx); ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv); } int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *plaintext, char *iv) { int len; int plaintext_len; EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len); plaintext_len = len; EVP_DecryptFinal_ex(ctx, plaintext + len, &len); plaintext_len += len; return plaintext_len; } int main (void) { unsigned char sshkey[32], sshiv[32]; FILE *fp; char filename[32]; unsigned char ciphertext[4096], decryptedtext[4096]; 12
  • 13. int decryptedtext_len, ciphertext_len; unsigned int size; fp = fopen("/DIV_C", "rb"); fread(sshiv, 32, 1, fp); fclose(fp); fp = fopen("/DKEY_C", "rb"); fread(sshkey, 32, 1, fp); fclose(fp); OpenSSL_add_all_algorithms(); setkey((unsigned char *)sshkey, (unsigned char *)sshiv); for(int i=0; i<7; i++) { sprintf(filename, "/hoge%d.bin", i); fp = fopen(filename, "rb"); size = 4; fread(ciphertext, size, 1, fp); decryptedtext_len = decrypt(ciphertext, size, (unsigned char *)sshkey, decryptedtext, (unsigned char *)sshiv); printf("Decrypt Packet#%d Sizen", i); BIO_dump_fp (stdout, (const char *)decryptedtext, decryptedtext_len); size = (decryptedtext[2]<<8) + decryptedtext[3]; fread(ciphertext, size, 1, fp); decryptedtext_len = decrypt(ciphertext, size, (unsigned char *)sshkey, decryptedtext, (unsigned char *)sshiv); printf("Decrypt Packet#%dn", i); BIO_dump_fp (stdout, (const char *)decryptedtext, decryptedtext_len); fclose(fp); } EVP_cleanup(); ERR_free_strings(); return 0; } 2.2 ビルド #gcc ssl.c -lssl -lcrypto -o decoder 2.3 実行 2.3.1 パケット準備  sshサーバープログラム、sshクライアントプログラムを実行する。Key(/DKEY_C)、IV(/DIV_C)、暗号化されたパケッ トのキャプチャ(sshc.pcap)が出力される。  sshc.pcapからバイナリをエクスポートする。/配下にキャプチャした順番にhoge0.bin、hoge1.bin、、、をエクスポート する。 13
  • 14. 2.3.2 復号プログラムの実行  実行結果とサーバーが送信した平文パケットを以下に示す。復号されていることがわかる。 ●  パケット#0 復号プログラムの実行結果 Decrypt Packet#0 Size 0000 - 00 00 00 9c .... Decrypt Packet#0 0000 - 0e 07 00 00 00 01 00 00-00 0f 73 65 72 76 65 72 ..........server 0010 - 2d 73 69 67 2d 61 6c 67-73 00 00 00 71 73 73 68 -sig-algs...qssh 0020 - 2d 65 64 32 35 35 31 39-2c 65 63 64 73 61 2d 73 -ed25519,ecdsa-s 0030 - 68 61 32 2d 6e 69 73 74-70 32 35 36 2c 65 63 64 ha2-nistp256,ecd 0040 - 73 61 2d 73 68 61 32 2d-6e 69 73 74 70 33 38 34 sa-sha2-nistp384 0050 - 2c 65 63 64 73 61 2d 73-68 61 32 2d 6e 69 73 74 ,ecdsa-sha2-nist 0060 - 70 35 32 31 2c 73 73 68-2d 72 73 61 2c 72 73 61 p521,ssh-rsa,rsa 0070 - 2d 73 68 61 32 2d 35 31-32 2c 72 73 61 2d 73 68 -sha2-512,rsa-sh 0080 - 61 32 2d 32 35 36 2c 73-73 68 2d 64 73 73 02 d1 a2-256,ssh-dss.. 0090 - 94 54 8d 07 f6 0e f6 17-61 4b b8 fe .T......aK.. サーバーが送信した平文パケット ●  パケット#1 復号プログラムの実行結果 Decrypt Packet#1 Size 0000 - 00 00 00 1c .... 14
  • 15. Decrypt Packet#1 0000 - 0a 06 00 00 00 0c 73 73-68 2d 75 73 65 72 61 75 ......ssh-userau 0010 - 74 68 fc f1 ca ba 2b 29-e1 ac d7 4c th....+)...L サーバーが送信した平文パケット ●  パケット#2 復号プログラムの実行結果 Decrypt Packet#2 Size 0000 - 00 00 00 0c .... Decrypt Packet#2 0000 - 0a 34 15 e0 72 88 91 1e-e1 06 dd 55 .4..r......U サーバーが送信した平文パケット ●  パケット#3 復号プログラムの実行結果 Decrypt Packet#3 Size 0000 - 00 00 00 1c .... Decrypt Packet#3 0000 - 0a 5b 00 00 00 2b 00 00-00 2b 00 00 7d 00 00 00 .[...+...+..}... 0010 - 88 b8 48 2b ab da bc 05-56 57 c6 89 ..H+....VW.. サーバーが送信した平文パケット ●  パケット#4 復号プログラムの実行結果 Decrypt Packet#4 Size 0000 - 00 00 00 0c .... Decrypt Packet#4 0000 - 06 63 00 00 00 2b f4 f1-68 f7 90 5f .c...+..h.._ サーバーが送信した平文パケット 15
  • 16. ●  パケット#5 復号プログラムの実行結果 Decrypt Packet#5 Size 0000 - 00 00 07 ec .... Decrypt Packet#5 0000 - 11 5e 00 00 00 2b 00 00-07 d1 30 31 32 33 34 35 .^...+....012345 0010 - 36 37 38 39 30 31 32 33-34 35 36 37 38 39 30 31 6789012345678901 0020 - 32 33 34 35 36 37 38 39-30 31 32 33 34 35 36 37 2345678901234567 ~省略~ 07c0 - 34 35 36 37 38 39 30 31-32 33 34 35 36 37 38 39 4567890123456789 07d0 - 30 31 32 33 34 35 36 37-38 39 0a 39 9d 4c 4e 67 0123456789.9.LNg 07e0 - b8 44 7c 1d 2d ba 5e 95-3e 02 78 b4 .D|.-.^.>.x. サーバーが送信した平文パケット ●  パケット#6 復号プログラムの実行結果 Decrypt Packet#6 Size 0000 - 00 00 00 2c ..., Decrypt Packet#6 0000 - 12 62 00 00 00 2b 00 00-00 0b 65 78 69 74 2d 73 .b...+....exit-s 0010 - 74 61 74 75 73 00 00 00-00 00 1f df 3e 23 01 d3 tatus.......>#.. 0020 - 72 eb c7 58 04 88 9c ed-93 75 17 05 r..X.....u.. サーバーが送信した平文パケット 16
  • 17. 2.4 考察  SSHの場合、AES-CTRのCounterがパケットで送信されない。Counterはブロック番号が+1になるたびに+1され、Counter 、ブロック番号はサーバー、クライアントがそれぞれ内部で管理する。そのため、SSHセッション確立後の途中のパケットでは Counter、ブロック番号がわからないため、復号できない。 復号のためには  最初のパケットから復号したいパケットまでのキャプチャ or  復号したいパケットまでのキャプチャ以前までの合計パケットサイズ、ブロック番号、Counterのどれか が必要になる。現実的には前者。  ちなみに、ESPの場合はPayloadでCounterが送信されてくるので、途中のパケットからでも復号できる。  (参考)ESPでAES-CTR:​https://www.ietf.org/rfc/rfc3686.txt 17
  • 18. RFC編 下線、ハイライトは個人的に重要そうなところ。斜体、#はメモ。 原文のMUST/REQUIRED/SHALL/SHOULD/MAY/OPTIONAL等の​RFC2119​用語は原文のまま残しています。  MUST、REQUIRED、SHALL:絶対的な要求事項  MUST NOT:絶対的な禁止事項  SHOULD、RECOMMENDED:慎重に重要性を判断するべき要求事項  SHOULD NOT、NOT RECOMMENDED:慎重に重要性を判断するべき禁止事項  MAY、OPTIONAL:オプション。 SSH関連のRFCリスト RFC 概要 RFC 4250 The Secure Shell (SSH) Protocol Assigned Numbers https://tools.ietf.org/html/rfc4250 SSHのプロトコルで使用される番号の定義。 RFC 4251 The Secure Shell (SSH) Protocol Architecture https://tools.ietf.org/html/rfc4251 SSHのアーキテクチャーの概要。 3つの主要コンポーネントであるTransport Layer Protocol、User Authentication Protocol、 Coonection Protocolの概要。 RFC 4252 The Secure Shell (SSH) Authentication Protocol https://tools.ietf.org/html/rfc4252 Authentication Protocolの詳細。 Public key、Password、Host-based client authentication method。 RFC 4253 The Secure Shell (SSH) Transport Layer Protocol https://tools.ietf.org/html/rfc4253 Transport Layer Protocolの詳細。 RFC 4254 The Secure Shell (SSH) Connection Protocol https://tools.ietf.org/html/rfc4254 Connection Protocolの詳細。 Interactive login、コマンドのリモート実行、TCP/IP接 続、X11接続を提供する。 RFC 4255 Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints https://tools.ietf.org/html/rfc4255 DNSSECでSSH host keyを検証する方法。 DNS resource recordに”SSHFP”を追加する。 RFC 4256 Generic Message Exchange Authentication for the Secure Shell Protocol (SSH) https://tools.ietf.org/html/rfc4256 認証データが手入力される場合に適したSSH用の認証方式。 RFC 4335 The Secure Shell (SSH) Session Channel Break Extension https://tools.ietf.org/html/rfc4335 SSHでBREAK signalを送信するSession Channel Break Extension。 RFC 4344 The Secure Shell (SSH) Transport Layer Encryption Modes https://tools.ietf.org/html/rfc4344 SSHで推奨するsymmetric encription method、Rekey頻 度。 RFC 4345 Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol https://tools.ietf.org/html/rfc4345 Arcfour cipherの使用方法。 18
  • 19. RFC 4419 Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol https://tools.ietf.org/html/rfc4419 DH group exchangeの新しいグループの追加。 RFC 4432 RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol https://tools.ietf.org/html/rfc4432 RSA public key encryptionによる鍵交換。DH鍵交換より CPUを使わない。 RFC 4462 Generic Security Service Application Program Interface (GSS-API) Authentication and Key Exchange for the Secure Shell (SSH) Protocol https://tools.ietf.org/html/rfc4462 Generic Security Service Application Program Interface (GSS-API)で認証、key exchangeする方法。 RFC 4716 The Secure Shell (SSH) Public Key File Format https://tools.ietf.org/html/rfc4716 Public keyを交換するためのpublic key fileフォーマッ トの定義。 RFC 4819 Secure Shell Public Key Subsystem https://tools.ietf.org/html/rfc4819 Public Key Subsystemというクライアントがpublic key を追加/削除したり、サーバーがpublic keyを管理するための メカニズムの説明。 RFC 5647 AES Galois Counter Mode for the Secure Shell Transport Layer Protocol https://tools.ietf.org/html/rfc5647 Transport Layer Protocolに機密性とintegrityを提供 するAES Galois Counter Modeの説明。 RFC 5656 Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer https://tools.ietf.org/html/rfc5656 Elliptic Curve Cryptography (ECC)(楕円曲線)に基づ くアルゴリズムの説明。 RFC 6187 X.509v3 Certificates for Secure Shell Authentication https://tools.ietf.org/html/rfc6187 X.509v3 public key certificatesを使用する方法。 RFC 6239 Suite B Cryptographic Suites for Secure Shell (SSH) https://tools.ietf.org/html/rfc6239 Suite Bに対応するSSHのアーキテクチャー。ECDH key agreement、ECDSA、AES-CGM、SHA-256/SHA-384、 X.509 certificatesを使用する。 RFC 6594 Use of the SHA-256 Algorithm with RSA, Digital Signature Algorithm (DSA), and Elliptic Curve DSA (ECDSA) in SSHFP Resource Records https://tools.ietf.org/html/rfc6594 SSHFP、DNSSECでSSH host keyを検証する方法用のDNS resource recordにSHA-256 Fingerprint、ECDSAを使 用する定義を追加する。 RFC 6668 SHA-2 Data Integrity Verification for the Secure Shell (SSH) Transport Layer Protocol https://tools.ietf.org/html/rfc6668 データのintegrityのためのアルゴリズムとパラメーターの定 義。 RFC 4253のupdate。 RFC 7478 Ed25519 SSHFP Resource Records https://tools.ietf.org/html/rfc7479 Ed25519 signature algorithmのアルゴリズム番号の定 義。 Errata https://www.rfc-editor.org/errata_search.php?rfc=​XXXX 19
  • 20. RFC 4251, The Secure Shell (SSH) Protocol Architecture  SSHは安全でないネットワーク上で安全なリモートログインおよびその他のネットワークサービスをするためのプロトコルであ る。本ドキュメントではSSHのアーキテクチャー、SSHのドキュメントで使用される用語を説明する。  SSHは3つの主要コンポーネントで構成される。​Transport Layer Protocolはサーバー認証、機密性、integrityを提供 する。User Authentication Protocolはサーバーによるクライアント認証を提供する。Connection Protocolは暗号化 されたトンネルを複数の論理チャネルに多重化する。 1. Introduction  SSHは安全なリモートログインおよびネットワークサービスのためのプロトコルである。以下の3つの主要なコンポーネントから 構成される。 ● Transport Layer Protocol  サーバー認証、機密性、integrityを提供する。オプションで圧縮も提供する。Transport LayerはTCP/IPが使 用されるが、他を使用してもよい。 ● User Authentication Protocol  クライアント側のユーザーをサーバー側で認証する。Transport Layer Protocolを介して実行される。 ● Connection Protocol  暗号化されたトンネルを複数の論理チャネルに多重化うる。User Authentication Protocol上で実行される。  Transport Layerが確立されると、クライアントはサービス要求を送信する。ユーザー認証が完了すると、次のサービス要求 が送信される。これにより新しいサービスが開始する。Connection Protocolは様々な用途に使用できるチャネルを提供す る。 4. Architecture 4.1. Host Keys  各サーバーはhost keyをもつことが推奨される(SHOULD)。サーバーは複数の異なるアルゴリズムを使用した複数のhost keyを持ってもよい(MAY)。複数のサーバーが同じhost keyを共有してもよい(MAY)。  クライアントはサーバーの認証をするためにサーバーのpublic host keyについて知っておく必要がある。  二つの異なる信頼モデルを使用できる。 ● クライアントは各サーバーに対応するpublic host keyに関連付くローカルデータベースをもつ。この方法では、集 中管理のインフラは必要としない。欠点は、ホスト名とkeyのデータベースのメンテが面倒なこと。 ● サーバー名とkeyの関連付けはCAが認証する。クライアントはCA root keyのみ知っていればよい。CAによって承認 された全てのkeyを検証できる。  二つ目の方法は、クライアントに1つのCA root keyのみ格納すればよいので、メンテの問題が解消する。一方、認証前に各 サーバー keyがCAによって認証されており、CAの信頼性確保が必要になる。  SSHにはサーバーに接続するときにサーバー名とhost keyの関連付けをチェックしないオプションがある。これにより、host keyや証明書を事前に確認しなくても通信ができる。Connectionは保護されるが、MITMに対して脆弱になる。実装は、デフォル トではそのような接続を許可しないことが推奨される(SHOULD NOT)。  実装はhost keyの正当性を検証するための追加の方法、例えばpublic keyのSHA-1 hashのフィンガープリントを提供して もよい(MAY)。そのようなフィンガープリントは、電話等の他の通信で容易に確認ができる。 4.2. Extensibility  SSHは独自の暗号化、認証、key exchangeによって拡張される。全ての拡張を一元管理するのは面倒でありが、一元管理しな いと識別子の競合が発生し、相互運用が困難になる。  SSHではアルゴリズム、メソッド、フォーマット、拡張プロトコルを特定のフォーマットのテキストで識別する。 20
  • 21.  設計の目標は、ベースプロトコルをできるだけシンプルにし、必須のアルゴリズムを最小限にすることである。 4.3. Policy Issues  ​SSHでは暗号化、integrity、鍵交換、圧縮、public keyアルゴリズムとフォーマットのネゴシエーションが可能である。 それらは方向毎に異なる。  以下のポリシーが実装の設定において可能であることが推奨される(SHOULD)。 ● 暗号化、integrity、圧縮アルゴリズムは各方向で別々に設定できる。ポリシーには優先度が設定できること(MUST )。例えば各カテゴリに設定された最初のアルゴリズムが優先される等。 ● サーバー認証に使用されるpublic keyアルゴリズムと鍵交換の方法。 ● 各ユーザーに対するサーバーの認証方法。サーバーのポリシーによってはユーザーに対して複数の認証方法をもってよい (MAY)。例えば、ユーザーのアクセス場所によって認証方法を変える。 ● ユーザーがconnection protocolを使用して実行できるオペレーション。例えば、サーバーがセッションを開始した り、クライアントマシン上でコマンドを実行することは推奨されない(SHOULD NOT)。それらはファイアーウォール の透過、迂回といったセキュリティの問題になる可能性がある。 4.4. Security Properties  SSHの主な目的はインターネット上のセキュリティを向上させることである。多少のセキュリティを無視したとしても、デプロ イが容易な方法を採用する。 ●  全ての暗号化、integrity、public keyは既知で確立されているアルゴリズムである。 ●  全てのアルゴリズムが暗号解読攻撃に対して十分に強力なkey sizeで使用される。 ●  全てのアルゴリズムはネゴシエーションされ、あるアルゴリズムが危殆化した場合でもベースのプロトコルを変更する ことなく、アルゴリズムを切り替えられる。 5. Data Type Representations Used in the SSH Protocols Data Type 説明 byte  Byteは任意の8bit値を表す。固定長のデータはbyte[n] (nは配列のbyte数)と表す。 boolean  Booleanは1byteとして格納される。0はFALSE、1は TRUEを表す。0以外の値は全てTRUEとして扱うこと(MUST )。ただし、アプリケーションは0と1以外の値を格納しない こと(MUST NOT)。 uint32  32bitの符号なし整数を表す。ネットワークバイトオー ダー(ビッグエンディアン)で4byteで格納される。例えば 699921578(0x29b7f4aa)は29 b7 f4 aaである。 uint64  64bitの符号なし整数を表す。ネットワークバイトオー ダー(ビッグエンディアン)で8byteで格納される。 string  任意長のバイナリ文字列。Stringには任意のバイナリデー タを設定できる。Stringはstring長を示すuint32と stringとして格納される。終端文字のnull文字は使用され ない。  Stringはテキストを格納するためにも使用される。内部で はUS-ASCIIが使用され、ユーザーに表示するときはUTF-8 が使用される。終端のnull文字はstringに格納しないこと (SHOULD NOT)。  例)"testing" = 00 00 00 07 t e s t i n g 先頭の00000007はstring長=7。 21
  • 22. mpint  MSBを先頭とした、2の補数形式の多倍長整数を表す。負数 はMSBに1が設定される。 name-list  CSV形式の名前のリストのstring。name-listはbyte数 とそれに続くCSVを含むuint32で表される。名前は0以外の lengthをもち、「,」を含めないこと(MUST)。また、 nameはUS-ASCIIであること(MUST)。個々のname、 name-listに終端のnull文字を含めないこと(MUST)。 例)("zlib,none") = 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65 string長=9 7. Message Numbers  SSHパケットのmessage numberは1~255である。次のように割り当てられる。 番号 Protocol 用途 1~19 Transport layer protocol Transport layer generic 20~29 Algorithm negotiation 30~49 Key exchange method specific 番号は異なる認証方式に再利用可能。 50~59 User authentication protocol User authentication generic 60~79 User authentication method specific 番号は異なる認証方式に再利用可能。 80~89 Connection protocol Connection protocol generic 90~127 Channel related messages 128~191 - Reserve for client protocol 192~255 - Local extension 22
  • 23. RFC 4253, The Secure Shell (SSH) Transport Layer Protocol  SSH Transport layer protocolについて説明する。SSHは通常はTCP/IP上で動作し、暗号化、サーバー認証、 integrity protection、圧縮が可能である。  鍵交換方式、public keyアルゴリズム、symmetric暗号化アルゴリズム、メッセージ認証アルゴリズム、ハッシュアルゴリ ズムは全てネゴシエーションされる。 1. Introduction Transport protocolの認証はサーバーベースである。このプロトコルレベルではユーザー認証を実行しない。ユーザー認証 は上位のuser authentication protocolで実行される。 このプロトコルは、パラメーターのネゴシエーションを可能とし、ラウンドトリップ回数を最小限にするためにシンプルかつ柔 軟に設計されている。鍵交換方式、public keyアルゴリズム、symmetric暗号化アルゴリズム、メッセージ認証アルゴリズ ム、ハッシュアルゴリズムは全てネゴシエーションされる。多くの環境では鍵交換、サーバー認証、Service request、 Service requestの許可通知に必要なラウンドトリップは2回である。最悪ケースでは3回になる。 4. Connection Setup  SSHは8bitのbinary-transparent transportで動作する。  クライアントがコネクションを開始する。 4.1. Use over TCP/IP  TCP/IPが使用される場合、サーバーは通常はport22で接続をlistenする。このポート番号はIANAにSSH用に登録されてい る。 4.2. Protocol Version Exchange  コネクション確立後、双方でidentification stringを送信すること(MUST)。Identification stringは以下である こと(MUST)。  SSH-protoversion-softwareversion SP comments CR LF    この文章で定義されているプロトコルはバージョン2.0のため、「protoversion」は「2.0」が設定されること(MUST)。 「comments」はオプションである。「comments」が含まれる場合、space(SP, ASCII:32)と「softwareversion」と「 comments」の文字列は分離されること(MUST)。Identificationは1つのCR(ASCII:13)と1つのLF(ASCII:10)で終 端されること(MUST)。Null文字を含めないこと(MUST)。CRとLFを含めて255文字が最大長である。  CRとLFの前のidentificationの一部はDH鍵交換で使用される。  サーバーはversion stringを送信する前に他の文字列を送信してよい(MAY)。その文字列はCRLFで終端されること (SHOULD)。その文字列は"SSH-"で始まらず(MUST NOT)、UTF-8でエンコードされること(SHOULD)。クライアントはその ような文字列を処理できること(MUST)。そのような文字列は無視してもよく(MAY)、クライアントに表示してもよい(MAY )。この機能の主な用途は、TCPが切断する前のエラーメッセージ表示である。 6. Binary Packet Protocol  各パケットは以下のフォーマットである。 フィールド名 Data Type 説明 packet_length uint32  ​パケットのバイト数。mac、 packet_lengthは含まない。 23
  • 24. padding_length byte  random paddingのバイト数。 payload byte[n1] n1 = packet_length - padding_length - 1  パケットのpayload。圧縮がネゴシ エーションされている場合、このフィー ルドは圧縮される。最初のパケットは圧 縮が"none"であること(MUST)。 random padding byte[n2] n2 = padding_length  任意長のパディング。   packet_length~random paddingまでのバイト数が8か暗号化ア ルゴリズムのブロックサイズの大きい方 の倍数になるようにパディングされる。  最低でも4byteのパディングがあるこ と(MUST)。パディングはランダム値 であることが推奨される(SHOULD)。 最大のパディングは255 byte。 mac byte[m] m = mac_length  Message Authentication Code 。MACがネゴシエーションされる場合、 このフィールドにはMACが含まれる。最 初のパケットはMACアルゴリズムが "none"であること(MUST)。  "packet_length"も暗号化されることに注意せよ。また、​可変長の"random padding"が挿入されると、トラフィックの分 析が妨げられる可能性があることにも注意せよ。 6.1. Maximum Packet Length  ​実装は、32,768byte以下の非圧縮のpayloadおよび35,000byte以下のパケット長を処理できること(MUST)。実装はより 大きいパケット('packet_length'+'padding_length'+'payload'+'random padding'+'mac')をサポートすることが 推奨される(SHOULD)。​実装はDoS攻撃やバッファオーバーフロー攻撃を回避するためにパケット長が妥当であるかチェックする ことが推奨される(SHOULD)。 6.2. Compression  圧縮がネゴシエーションされる場合、​'payload'のみが圧縮される。'packet_length'と'mac'は圧縮されたpayloadで計 算される。暗号化は圧縮後に実施される。圧縮アルゴリズムによっては、圧縮はステートフルになってもよい(MAY)。​圧縮は双 方向に対して独立であり(MUST)、お互いに独立したアルゴリズムが選択できること(MUST)。ただし、圧縮アルゴリズムは双 方向で同一であることが推奨される(RECOMMENDED)。  以下の圧縮アルゴリズムが定義されている。 none REQUIRED 圧縮なし zlib OPTIONAL ZLIB (LZ77)圧縮 6.3. Encryption  暗号化アルゴリズムとkeyは鍵交換時にネゴシエーションされる。暗号化が有効である場合、​各パケットのpacket length, padding length, payload, paddingは暗号化されること(MUST)​。  一方向に送信される全てのパケットの暗号化されたデータは1つのデータストリームとして扱われる(SHOULD)。全ての暗号は key lengthが128bit以上のkeyを使用することが推奨される(SHOULD)。  各方向の暗号はお互いに独立して動作すること(MUST)。複数のアルゴリズムの使用が許可されている場合、実装は各方向のア ルゴリズムを独立して選択されることを許容すること(MUST)。ただし、暗号アルゴリズムは双方向で同一であることが推奨され る(RECOMMENDED)。 24
  • 25.  以下の暗号が現在定義されている。 3des-cbc REQUIRED 3DES CBC mode blowfish-cbc OPTIONAL Blowfish CBC mode twofish256-cbc OPTIONAL Twofish(256 bit key) CBC mode twofish-cbc OPTIONAL twofish256-cbcと同じ。 twofish192-cbc OPTIONAL Twofish(192 bit key) CBC mode twofish128-cbc OPTIONAL Twofish(128 bit key) CBC mode aes256-cbc OPTIONAL AES(256 bit key) CBC mode aes192-cbc OPTIONAL AES(192 bit key) CBC mode aes128-cbc RECOMMENDED AES(128 bit key) CBC mode serpent256-cbc OPTIONAL Serpent(256 bit key) CBC mode serpent192-cbc OPTIONAL Serpent(192 bit key) CBC mode serpent128-cbc OPTIONAL Serpent(128 bit key) CBC mode arcfour OPTIONAL ARCFOUR(128 bit key) idea-cbc OPTIONAL IDEA CBC mode cast128-cbc OPTIONAL CAST-128 CBC mode none OPTIONAL 暗号化無し, NOT RECOMMENDED 6.4. Data Integrity  Integrityはshared secret, パケットシーケンス番号、パケットから計算されるMACを各パケットに含めることで保護さ れる。  MACアルゴリズムとkeyは鍵交換時にネゴシエーションされる。最初のパケットはMACは無効でサイズ0であること(MUST)。 鍵交換後、選択されたMACアルゴリズムの'mac'は暗号化前に計算される。 mac = MAC(key, sequence_number || unencrypted_packet) # ||は連結。  unencrypted_packetは、'mac'を含まないパケット全体('length', 'payload', 'random padding')で sequence_numberはuint32のパケットシーケンス番号である。sequence_numberは最初のパケットで0初期化され、パケッ ト毎にインクリされる。Keyやアルゴリズムが再度ネゴシエーションされてもリセットされない。2^32で0に戻る。 sequence_numberはパケット自体には含まれない。  各方向のMACアルゴリズムは独立して処理され(MUST)、実装は各方向に独立してアルゴリズムを選択することを許容すること (MUST)。だし、アルゴリズムは双方向で同一であることが推奨される(RECOMMENDED)。  'mac'はパケットの最後に暗号化無しで送信されること(MUST)。'mac'のサイズは選択したアルゴリズムによって異なる。 25
  • 26.  以下のMACアルゴリズムが現在定義されている。 hmac-sha1 REQUIRED HMAC-SHA1 Digest Length = 20 byte Key Length = 20 byte hmac-sha1-96 RECOMMENDED HMAC-SHA1 Digest Length = 12 byte Key Length = 20 byte hmac-md5 OPTIONAL HMAC-MD5 Digest Length = 16 byte Key Length = 16 byte hmac-md5-96 OPTIONAL HMAC-MD5 Digest Length = 12 byte Key Length = 16 byte none OPTIONAL MAC無し。NOT RECOMMENDED 6.5. Key Exchange Methods  鍵交換は暗号化と認証のためのone-time session keyの生成方法と、サーバー認証方法を指定する。  2つの鍵交換方式が要求される(REQUIRED)。 diffie-hellman-group1-sha1 REQUIRED diffie-hellman-group14-sha1 REQUIRED 6.6. Public Key Algorithms  SSHは様々なpublic keyフォーマット、エンコード、アルゴリズム(署名、暗号化)で動作できるように設計されている。  以下のpublic key、証明書のフォーマットが定義されている。 ssh-dss REQUIRED sign Raw DSS Key ssh-rsa RECOMMENDED sign Raw RSA Key pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key) pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)  Public keyと証明書は以下のようにエンコードされる。 string certificate or public key format identifier byte[n] key/certificate data  署名は以下のようにエンコードされる。 26
  • 27. string signature format identifier byte[n] 署名  "ssh-dss" key formatは以下である。p, q, g, yから署名を生成する。 string "ssh-dss" mpint p mpint q mpint g mpint y  署名(SHA-1 hash)は以下のようにエンコードされる。 string "ssh-dss" string dss_signature_blob  "ssh-rsa"の場合は以下の通り。  key format。 string "ssh-rsa" mpint e mpint n  署名(SHA-1 hash)。 string "ssh-rsa" string rsa_signature_blob 7. Key Exchange  鍵交換, Key exchange(Kex)はサポートしているアルゴリズム名のリストを送信することで双方から開始する。お互いが優 先するアルゴリズムをもっている。対向がどのアルゴリズムを使用するか推定してよく(MAY)、その結果に従って鍵交換をして もよい(MAY)。  以下の場合、推測は誤っていると見なされる。   kexアルゴリズムまたはhost keyアルゴリズムがサーバーとクライアントで異なる。   一致するアルゴリズムが無い。  それ以外の場合、推測は正しく、鍵交換のパケットは正常に処理されること(MUST)。  鍵交換で署名またはサーバーの証明書を送信する場合は、明示的なサーバー認証である。鍵交換でサーバーとクライアントが shared secret Kを使用したMACを送信することで認証する場合は暗黙のサーバー認証である。 27
  • 28.  暗黙的なサーバー認証による鍵交換の場合、クライアントは鍵交換の後にデータを送信せず、service request messageの 応答を待つこと(MUST)。 7.1. Algorithm Negotiation  鍵交換では双方が以下のパケットを送信する。  アルゴリズム名のリストはアルゴリズム名のcsvである。アルゴリズムは優先順位の高い順になっていること(MUST)。各 name-listには最低限1つのアルゴリズムがあること(MUST)。 SSH_MSG_KEXINIT byte cookie (random bytes) byte[16]  送信者が生成した乱数。Keyとsession identifierを使 用せずコネクションを識別するために使用する。 kex_algorithms name-list  最初のアルゴリズムが優先されるアルゴリズムであること( MUST)。そのアルゴリズムが選択できない場合、以下の選択 をすること(MUST)。クライアントのKexアルゴリズムをイテ レーションして、以下の条件を満たす最初のアルゴリズムを選 択する。 +サーバーがサポートしているアルゴリズム。 +アルゴリズムが暗号化host keyを必要とする場合、暗 号化可能なアルゴリズムで双方がサポートしていること。 つまり、サーバーのserver_host_key_algorithms にもあること。 +アルゴリズムが署名host keyを必要とする場合、署名 可能なアルゴリズムで双方がサポートしていること。つま り、サーバーのserver_host_key_algorithmsにも あること。  上記を満たすアルゴリズムが無い場合、双方は切断すること (MUST)。 server_host_key_algorithms name-list  サーバー host keyでサポートされているアルゴリズムの name-list。サーバーはhost keyのアルゴリズムを設定す る。クライアントは許容するアルゴリズムを設定する。1つの サーバーに対して複数のアルゴリズムが存在してもよい(MAY )。  サーバーによってサポートされている、クライアントの name-listの先頭のアルゴリズムを選択すること(MUST)。 そのようなアルゴリズムがない場合、双方は切断すること( MUST)。 encryption_algorithms_client_to_server name-list  暗号化アルゴリズムの優先度順のname-list。選択される アルゴリズムは、サーバー、クライアントの両方の name-listにある最初のアルゴリズムであること(MUST)。 そのようなアルゴリズムがない場合、双方は切断すること( MUST)。 encryption_algorithms_server_to_client name-list mac_algorithms_client_to_server name-list  MACアルゴリズムの優先度順のname-list。選択されるア ルゴリズムは、サーバー、クライアントの両方のname-list にある最初のアルゴリズムであること(MUST)。そのような アルゴリズムがない場合、双方は切断すること(MUST)。  mac_algorithms_server_to_client name-list compression_algorithms_client_to_server name-list 圧縮アルゴリズムの優先度順のname-list。選択されるアル ゴリズムは、サーバー、クライアントの両方のname-listに ある最初のアルゴリズムであること(MUST)。そのようなア ルゴリズムがない場合、双方は切断すること(MUST)。 compression_algorithms_server_to_client name-list languages_client_to_server name-list  Language tagの優先度順のname-list。双方はこれを無 視してもよい(MAY)。Language設定が無い場合この name-listは空であることが推奨される(SHOULD)。送信側languages_server_to_client name-list 28
  • 29. が必要でない場合、Language tagを設定しないこと( SHOULD NOT)。 first_kex_packet_follows boolean  鍵交換のパケットが以降送信するかを示す。送信される場合 はTRUE、送信されない場合はFALSEを設定すること(MUST )。  対向からSSH_MSG_KEXINITパケットを受信したとき、ネゴ シエーションの成功、失敗を知ることができる。失敗で本 フィールドがTRUEの場合、そのパケットは無視(silently ignored)すること(MUST)。成功かつTRUEの場合はそのパ ケットを使用する。 0 (reserved for future extension) uint32 Reserve。  SSH_MSG_KEXINITメッセージ交換の後、鍵交換アルゴリズムが実行される。  ​鍵交換または再鍵交換のためにSSH_MSG_KEXINITメッセージを送信した後は、SSH_MSG_NEWKEYSを送信するまでは、以下 のメッセージ以外のメッセージを送信しないこと(MUST)​。 ● Transport layer generic messages(1~19) ただし、SSH_MSG_SERVICE_REQUEST、SSH_MSG_SERVICE_ACCEPTは送信しないこと(MUST NOT)。 ● Algorithm negotiation messages(20~29) ただし、追加でSSH_MSG_KEXINITを送信しないこと(MUST NOT)。 ● Specific key exchange method messages(30~49) 7.2. Output from Key Exchange  ​鍵交換ではShared secret K、 Exchange hash Hが生成される。暗号化keyと認証keyはこれらから計算される。最初の 鍵交換で生成されたexchange hash Hはコネクションの一意の識別子(session_id)である。再鍵交換された場合でも変更さ れない​。  各鍵交換方式は、鍵交換で使用されるハッシュ関数(HASH)を指定する。同じハッシュアルゴリズムをkey生成で使用しないこ と(MUST)。  ​以下のように暗号化keyはKとHASHから計算されること(MUST)。 Initial IV client to server HASH(K || H || "A" || session_id) Kはmpint、"A"はASCII 65、session_idは生データでエ ンコードされる。 #session_idは最初の鍵交換で生成されたexchange hash H Initial IV server to client HASH(K || H || "B" || session_id) Encryption key client to server HASH(K || H || "C" || session_id) Encryption key server to client HASH(K || H || "D" || session_id) Integrity key client to server HASH(K || H || "E" || session_id) Integrity key server to client HASH(K || H || "F" || session_id)  Keyはハッシュ値の先頭から必要なバイト数とること(MUST)。必要なKey長がハッシュ値より大きい場合、KとHの連結とKey の全体のHASHを計算し、必要なだけkeyに追加して拡張する。 K1 = HASH(K || H || X || session_id) (X is e.g., "A") K2 = HASH(K || H || K1) K3 = HASH(K || H || K1 || K2) 29
  • 30. ... key = K1 || K2 || K3 || ...  使用されるメッセージ。  双方が送信する。 byte SSH_MSG_NEWKEYS 7.3. Taking Keys Into Use  鍵交換は双方がSSH_MSG_NEWKEYSメッセージを送信すると終了する。このメッセージは古いkeyとアルゴリズムで送信され る。このメッセージの後に送信されるメッセージは新しいkeyとアルゴリズムを使用すること(MUST)。このメッセージを受信す るときは、新しいkeyとアルゴリズムが使用されること(MUST)。 8. Diffie-Hellman Key Exchange  DH鍵交換はExchange hash Hを生成する。 p 素数。公開されている。 g GF(p)で生成されるサブグループ、生成元。公開されている。 #GF = Galois Field q サブグループの任意の値。 V_C string クライアントの識別文字列。 V_S string サーバーの識別文字列。 I_C string クライアントが送信したSSH_MSG_KEXINITメッセージ。 I_S string サーバーが送信したSSH_MSG_KEXINITメッセージ。 K_S string サーバーの公開鍵。 e mpint DH鍵交換のA。 f mpint DH鍵交換のB。 K mpint Shared secret K。 1. クライアントは乱数x(1<x<q)を生成し、e=g^x mod pを計算。eをサーバーに送信する。 2. サーバーは乱数y(0<y<q)を生成し、f=g^y mod pを計算する。  K = e^y mod p、H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K) を計算する。Hにprivate host keyで署名する(s)。サーバーはクライアントに(K_S || f || s)を送信する。 3. クライアントはK_Sがサーバーのhost keyであることを検証する(例:データベースや証明書を使って)。クライアン トはベリファイ無しでhost keyを許容してもよい。 クライアントは  K = f^x mod p、H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K) を計算し、Hに署名sをベリファイする。 上記の手順でShared secret K、Exchange hash Hが生成、ベリファイされた。  使用するメッセージ。  1でクライアントが送信する。 30
  • 31. byte SSH_MSG_KEXDH_INIT mpint e。(e=g^x mod p。DH鍵交換のA。)  2でサーバーが送信する。 byte SSH_MSG_KEXDH_REPLY string サーバーの公開host keyと証明書。(K_S) mpint f。(f=g^y mod p。DH鍵交換のB。) string Hに署名したもの。(K_S || f || s) 9. Key Re-Exchange  ​鍵交換を開始していないときに、SSH_MSG_KEXINITを送信することによって再鍵交換が開始される。このメッセージが受信さ れたとき、受信したSSH_MSG_KEXINITが応答だった場合を除き、SSH_MSG_KEXINITで応答すること(MUST)。​どちらからで も再鍵交換を開始してもよいが、サーバー、クライアントの役割は変わらない。  ​鍵交換を開始していないときに、SSH_MSG_KEXINITを送信することによって再鍵交換が開始される。​このメッセージが受信さ れたとき、受信したSSH_MSG_KEXINITが応答だった場合を除き、SSH_MSG_KEXINITで応答すること(MUST)。どちらからで も再鍵交換を開始してもよいが、サーバー、クライアントの役割は変わらない。  再鍵交換は、交換前の暗号化で行われる。​暗号化、圧縮、MACは再鍵交換後に新しいSSH_MSG_NEWKEYSが送信されるまで変更 されない。再鍵交換はsession idが変わらないことを除いて、最初の鍵交換と同様に処理される。全てのkeyとIVは鍵交換で再 計算される​。  G byteのデータ送信後か接続して1時間経過の早い方でkey変更することが推奨される(RECOMMENDED)。ただし、再鍵交換 は処理能力が必要であるため、頻繁に実行すべきではない。  SSH_MSG_NEWKEYSの送信後にもアプリケーションデータが送信される可能性がある。鍵交換はSSH Transport layerより 上のプロトコルには影響しない。 10. Service Request  鍵交換後、クライアントはサービスを要求する。サービスは名前で識別される。  以下の名前が予約されている。ローカルサービスには"servicename@domain"のようなPRIVATE USE syntaxを用いる。 ssh-userauth ssh-connection  サーバーは、サービス要求を拒否する場合、SSH_MSG_DISCONNECTメッセージを送信し(SHOULD)、接続を切断すること( MUST)。  サービスが開始すると鍵交換中に生成されたsession idにアクセスできる。  暗黙のサーバー認証、鍵交換の後、クライアントはservice requestの応答を待つこと(MUST)。 使用するメッセージ。  クライアントが送信する。 31
  • 32. byte SSH_MSG_SERVICE_REQUEST string service name  サーバーが送信する。 byte SSH_MSG_SERVICE_ACCEPT string service name 11. Additional Messages  クライアント、サーバーのどちらからでも下記のメッセージを送信してよい。 11.1. Disconnection Message byte SSH_MSG_DISCONNECT uint32 reason code string description in ISO-10646 UTF-8 encoding string language tag [RFC3066]  接続の終了をするメッセージ。全ての実装はこのメッセージを処理でき(MUST)、メッセージを送信することができること( SHOULD)。 送信者はこのメッセージの後にデータの送信、受信をしてはならず(MUST NOT)、受信者はこのメッセージのの受信後に受信 したメッセージを許容しないこと(MUST NOT)。'description'は人がわかるstringである。'reason code'は下記の値 である。 Symbolic name reason code SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 SSH_DISCONNECT_PROTOCOL_ERROR 2 SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 SSH_DISCONNECT_RESERVED 4 SSH_DISCONNECT_MAC_ERROR 5 SSH_DISCONNECT_COMPRESSION_ERROR 6 SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 SSH_DISCONNECT_CONNECTION_LOST 10 SSH_DISCONNECT_BY_APPLICATION 11 32
  • 33. SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 SSH_DISCONNECT_ILLEGAL_USER_NAME 15 11.2. Ignored Data Message byte SSH_MSG_IGNORE string data  全ての実装はこのメッセージを受信した場合、理解した上で無視すること(MUST)。送信処理を実装する必要は無い。このメッ セージはトラフィック分析に使用できる。 #DPD的な死活監視用? 11.3. Debug Message byte SSH_MSG_DEBUG string always_display string message in ISO-10646 UTF-8 encoding string language tag [RFC3066]  全ての実装はこのメッセージを受信した場合、理解した上で(MUST)無視してよい。このメッセージはデバッグメッセージの送 信に使用される。'always_display'がTRUEの場合、メッセージは表示されることが推奨される(SHOULD)。FALSEの場合、 デバッグ情報の表示がユーザーから明示的に要求されていない限り、表示しないことが推奨される(SHOULD NOT)。 11.4. Reserved Messages byte SSH_MSG_UNIMPLEMENTED uint32 packet sequence number of rejected message  実装は受信したメッセージの順にSSH_MSG_UNIMPLEMENTEDで全ての認識できないメッセージに応答すること(MUST)。その ようなメッセージはそれ以外の処理をせず無視すること(MUST)。 12. Summary of Message Numbers  メッセージ一覧。30-49はkex packetで使用される。異なるkexでは番号は再利用される。 SSH_MSG_DISCONNECT 1 SSH_MSG_IGNORE 2 33
  • 34. SSH_MSG_UNIMPLEMENTED 3 SSH_MSG_DEBUG 4 SSH_MSG_SERVICE_REQUEST 5 SSH_MSG_SERVICE_ACCEPT 6 SSH_MSG_KEXINIT 20 SSH_MSG_NEWKEYS 21 34
  • 35. RFC 4344, The Secure Shell (SSH) Transport Layer Encryption Modes 1. Introduction  SSH Transport Protocolはプライバシー保護とカプセル化されたデータのintegrityを提供するように設計されている。 しかし、RFC4253のSSH Transport Protocolの一部にセキュリティ問題が発見された。例えば、暗号化モードは chosen-plaintext privacy attackに対して脆弱である。また、rekeyの頻度が不十分の場合、payloadが漏洩する可能 性がある。後者は暗号化モードによらず問題になる。 3. Rekeying RFC4253 section 9ではSSHの実装が1GBのデータ送信毎のrekeyを提案している。しかし、rekeyが不十分な場合の問題に ついては議論していない。このsectionではrekeyに関する推奨事項について説明する。  本sectionでは2つの推奨事項を示す。最初の推奨事項はMACタグの漏洩からの情報保護が目的であり、もう一つはブロック暗 号から発生する漏洩からの情報保護が目的である。ブロック暗号のブロック長と暗号化パケット長によっては最初の事項が優先さ れる場合がある。 3.1. First Rekeying Recommendation  ​MACタグを介した情報漏洩の可能性があるため、SSHの実装は少なくとも2^32パケットの送信毎に1回 rekeyすることが推奨さ れる(SHOULD)。​別の言い方をすれば、鍵交換後、SSHの実装はrekey前に2^32パケット以上を送信しないことが推奨される( SHOULD NOT)。  ​SSHの実装は最後のrekey後に2**32パケットを超えるパケットを受信する前にrekeyをすることが推奨される(SHOULD)。 推奨される方法は、最後のrekey後に2**31パケットを受信した後にrekeyすることである。 3.2. Second Rekeying Recommendation  ブロック暗号によっては、実装は多くのブロックを同一の暗号化keyで暗号化しないように注意すること。  ブロック暗号のブロック長をL(bit)とする。AESの場合はL=128。Lが128以上の場合、​rekey前に2**(L/4)ブロックを超 えるブロックの暗号化をしないことが推奨される(SHOULD NOT)。​そのような場合は実装はrekeyを試行することが推奨され る。Lが128より小さい場合、2**(L/4)ブロック毎のrekeyはコストがかかる場合があるが、少なくとも1GB毎にrekeyすること が推奨される。 4. Encryption Modes  SSH Transport Protocolで使用するための新しい暗号化方式を説明する。これらの暗号化方式はRFC4253 section 6.3 の暗号化方式に追加される。 aes128-ctr RECOMMENDED AES(128 bit key) SDCTR mode aes192-ctr RECOMMENDED AES(192 bit key) SDCTR mode aes256-ctr RECOMMENDED AES(256 bit key) SDCTR mode 3des-ctr RECOMMENDED 3DES SDCTR mode blowfish-ctr OPTIONAL Blowfish SDCTR mode twofish128-ctr OPTIONAL Twofish(128 bit key) SDCTR mode twofish192-ctr OPTIONAL Twofish(192 bit key) SDCTR mode 35
  • 36. twofish256-ctr OPTIONAL Twofish(256 bit key) SDCTR mode serpent128-ctr OPTIONAL Serpent(128 bit key) SDCTR mode serpent192-ctr OPTIONAL Serpent(192 bit key) SDCTR mode serpent256-ctr OPTIONAL Serpent(256 bit key) SDCTR mode idea-ctr OPTIONAL IDEA SDCTR mode cast128-ctr OPTIONAL CAST-128 SDCTR mode 36