ssh: fix malformed exec payload panic (#5428)

This commit is contained in:
fatedier
2026-07-21 23:04:56 +08:00
committed by GitHub
parent d486018885
commit 7dc7be930e
7 changed files with 120 additions and 32 deletions

View File

@@ -16,7 +16,6 @@ package ssh
import (
"context"
"encoding/binary"
"errors"
"fmt"
"net"
@@ -52,6 +51,11 @@ type tcpipForward struct {
Port uint32
}
// https://datatracker.ietf.org/doc/html/rfc4254#section-6.5
type execPayload struct {
Command string
}
// https://datatracker.ietf.org/doc/html/rfc4254#page-16
type forwardedTCPPayload struct {
Addr string
@@ -309,14 +313,13 @@ func (s *TunnelServer) handleNewChannel(channel ssh.NewChannel, extraPayloadCh c
if req.WantReply {
_ = req.Reply(true, nil)
}
if req.Type != "exec" || len(req.Payload) <= 4 {
if req.Type != "exec" {
continue
}
end := 4 + binary.BigEndian.Uint32(req.Payload[:4])
if len(req.Payload) < int(end) {
extraPayload, ok := parseExecPayload(req.Payload)
if !ok {
continue
}
extraPayload := string(req.Payload[4:end])
select {
case extraPayloadCh <- extraPayload:
default:
@@ -324,6 +327,14 @@ func (s *TunnelServer) handleNewChannel(channel ssh.NewChannel, extraPayloadCh c
}
}
func parseExecPayload(payload []byte) (string, bool) {
var msg execPayload
if err := ssh.Unmarshal(payload, &msg); err != nil {
return "", false
}
return msg.Command, true
}
func (s *TunnelServer) keepAlive(ch ssh.Channel) {
tk := time.NewTicker(time.Second * 30)
defer tk.Stop()