我正在实现一个基本的 ssh 客户端,能够安全地将单个命令发送到 OpenSSH 服务器。我的客户端目前能够处理所有事情,直到向服务器发送服务请求(即我从 Diffie-Hellman 交换导出密钥)。我的目标是向服务器发送单个命令(即 whoami)。
成功完成密钥交换后,我将根据二进制数据包协议按以下顺序发送这些数据包。每条消息均未加密,并且我已将每条消息的消息 ID 粗体显示。
#1: Authentication service request
byte SSH_MSG_SERVICE_REQUEST
string “ssh-userauth”
数据包已发送: 00 00 00 1c 0a 05 00 00 00 0c 73 73 68 2d 75 73 65 72 61 75 74 68 31 89 4b 1f 27 2f 02 98 f0 0d
服务器响应: 00 00 00 1c 0a 06 00 00 00 0c 73 73 68 2d 75 73 65 72 61 75 74 68 89 da 3a a3 b3 63 8e 8d c5 40
#2: Authentication information
byte SSH_MSG_USERAUTH_REQUEST
string user name
string “ssh-connection”
string "password"
boolean FALSE
string plaintext password
数据包已发送: 00 00 00 3c 0b 32 00 00 00 04 XX XX XX XX 00 00 00 0e 73 73 68 2d 63 6f 6e 6e 65 63 74 69 6f 6e 00 00 00 0 8 70 61 73 73 77 6f 72 64 00 00 00 00 04 XX XX XX XX 31 89 4b 1f 27 2f 02 98 f0 0d 25
(省略用户名和密码)
服务器响应: 00 00 00 0c 0a 34 de f3 3b 8c 20 ca 6b 0f 69 43
这表明我已成功验证并且服务器已准备好让客户端打开通道。
到目前为止,我收到了预期的响应,因此我假设服务器身份验证已成功完成,因此我继续打开会话通道:
Expected #4: Open session channel
byte SSH_MSG_CHANNEL_OPEN
string "session"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
数据包已发送: 00 00 00 1c 03 5a 00 00 00 07 73 65 73 73 69 6f 6e 00 00 00 01 00 00 04 00 00 00 04 00 06 c4 3d
服务器响应: 00 00 00 1c 0a 5b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 c6 ee 88 13 f7 78 ba a0 1d ea
服务器响应 5b 代码(SSH_MSG_CHANNEL_OPEN_CONFIRMATION),因此通道打开请求似乎也已正确执行;但是,我不明白为什么窗口大小设置为 0(稍后可能相关)。
我现在想请求执行命令:“whoami”。所以我发送消息通道请求:
Expected #5: Send command to server
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "exec"
boolean want reply
string “whoami”
数据包已发送:00 00 00 2c 13 62 00 00 00 00 00 00 00 04 65 78 65 63 01 00 00 00 06 77 68 6f 61 6d 69 ad de 4d 6c dd b7 8e 19 3f 68 7a 8e 5a 63 10 99 2e 日 54
这是我感到困惑的地方,收到的数据包:00 00 00 1c 12 5d 00 00 00 00 00 20 00 00 fd fa 83 ae 1d 50 ca 25 7c 42 6b 71 a7 ea dc 9f 9a 41 12 8天ff 45 f6 84 c0 36 a0 10 12 f8 01 c5 11 80 49 4c 95 9c 是 ec b2 b2 49 70 3e e3 d8 1e 3c 68 78 79 c5 b9
服务器发回 SSH_MSG_CHANNEL_WINDOW_ADJUST 数据包,这是意外的,因为我只是请求“whoami”的结果,但我怀疑这与服务器的通道打开确认消息中服务器发送窗口大小有关是 0。另外,从阅读RFC 4254来看,服务器似乎并不希望对此窗口调整消息做出响应。
我更困惑的是这个数据包似乎偏离了二进制数据包协议。长度为 1c,但客户端发送的字节数远不止于此,并且填充长度为 12,但即使在 12 个字节的填充之后,消息还有更多内容。
知道数据包中的这些额外信息是什么吗?
我是否遗漏了连接步骤或弄乱了某个步骤?
问题是我没有意识到服务器在单个数据包中发送多条消息。
我的客户正确解密了第一条消息,但没有正确解密第二条消息。
服务器响应看起来像这样:
(加密数据包1 || MAC 1 || 加密数据包2 || MAC 2 ...)
但我希望它看起来像这样:
(加密数据包1 || MAC 1)