Open NHAS opened 4 weeks ago
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
note that we can't change the Channel
interface definition for backwards compatibility reasons.
CC @golang/security
note that we can't change the
Channel
interface definition for backwards compatibility reasons.
Does that freeze include adding a method? As I don't want to change any existing function signatures.
Even adding a public ReadPacket method to the ssh.channel struct would make implementation easier as it wouldn't rely on getting an unsafe pointer to the ssh.buffer to interact with it directly.
Two other alternatives could be:
ssh.ReadPacket(ssh.Channel) []byte
That does an internal cast to ssh.channel and calls the public method ReadSSHPacket()
as defined previously.
This would mean there wasn't a requirement to change the ssh.Channel
interface
ssh.Channel
so that the Read()
only reads a single buffer element then returns eof. E.g
spr := ssh.SinglePacketReader(channel)
Which returns ssh.Channel with concrete implementation.
type singlePacketChannel struct {
channel
}
func (spc *singlePacketChannel) Read([]byte) (int, error) {
// Reads until single element in buffer is exhausted
}
Proposal Details
I propose a new
ssh.Channel
function to read a single SSH packet.This is required in to inter-opt with some channel types in use by OpenSSH.
For example to inter-opt with the
tun@openssh.com
channel type defined in section 2.3 of the openssh protocol standard:It is required that you are able to read each individual SSH packet as it defines the length of each Network packet.
Currently the
Read(...)
function defined by thessh.Channel
interface reads all buffered SSH packets. This requires the implementer oftun@openssh.com
and other similar channel types to attempt to determine SSH packet size (and thus network packet size) from the data that is returned fromRead(...)
.This is error prone and in some cases not feasible.
The following are two snippets to show how this may be implemented.
Example addition to
ssh.buffer
:Example addition to
ssh.channel
(and thus thessh.Channel
interface):Additionally, here is a working example of how this must currently be done which uses incredibly brittle reflections.
https://github.com/NHAS/reverse_ssh/blob/f5d2a6cd8562e5f5ff33551aa37285651b90a309/internal/client/handlers/tun.go#L356