2023-11-21 18:55:04 +03:00
|
|
|
diff -Naru cryptolib/ssh/cipher.go pkg/proto/ssh/cipher.go
|
|
|
|
--- cryptolib/ssh/cipher.go 2023-11-21 18:52:03.117248053 +0300
|
|
|
|
+++ pkg/proto/ssh/cipher.go 2023-11-21 17:19:04.688042738 +0300
|
|
|
|
@@ -16,8 +16,8 @@
|
|
|
|
"hash"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
- "golang.org/x/crypto/chacha20"
|
|
|
|
"github.com/Neur0toxine/sshpoke/pkg/proto/ssh/internal/poly1305"
|
|
|
|
+ "golang.org/x/crypto/chacha20"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
diff -Naru cryptolib/ssh/common.go pkg/proto/ssh/common.go
|
|
|
|
--- cryptolib/ssh/common.go 2023-11-21 18:52:03.217249582 +0300
|
|
|
|
+++ pkg/proto/ssh/common.go 2023-11-21 17:28:23.221203344 +0300
|
|
|
|
@@ -7,14 +7,13 @@
|
|
|
|
import (
|
|
|
|
"crypto"
|
|
|
|
"crypto/rand"
|
|
|
|
+ _ "crypto/sha1"
|
|
|
|
+ _ "crypto/sha256"
|
|
|
|
+ _ "crypto/sha512"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"math"
|
|
|
|
"sync"
|
|
|
|
-
|
|
|
|
- _ "crypto/sha1"
|
|
|
|
- _ "crypto/sha256"
|
|
|
|
- _ "crypto/sha512"
|
|
|
|
)
|
|
|
|
|
|
|
|
// These are string constants in the SSH protocol.
|
|
|
|
@@ -279,6 +278,9 @@
|
|
|
|
// The allowed MAC algorithms. If unspecified then a sensible default is
|
|
|
|
// used. Unsupported values are silently ignored.
|
|
|
|
MACs []string
|
|
|
|
+
|
|
|
|
+ // Called on every incoming handshake packet for client. Only receives data and extended data packets.
|
|
|
|
+ HandshakePacketReader func(p []byte)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetDefaults sets sensible values for unset fields in config. This is
|
|
|
|
diff -Naru cryptolib/ssh/handshake.go pkg/proto/ssh/handshake.go
|
|
|
|
--- cryptolib/ssh/handshake.go 2023-11-21 18:52:03.209249460 +0300
|
|
|
|
+++ pkg/proto/ssh/handshake.go 2023-11-21 18:51:58.681180283 +0300
|
|
|
|
@@ -401,6 +401,14 @@
|
|
|
|
t.printPacket(p, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if t.config.HandshakePacketReader != nil && p[0] == msgChannelData {
|
|
|
|
+ data, err := decode(p)
|
|
|
|
+ packetData, ok := data.(*channelDataMsg)
|
|
|
|
+ if err == nil && ok && packetData != nil {
|
|
|
|
+ t.config.HandshakePacketReader(packetData.Rest)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if first && p[0] != msgKexInit {
|
|
|
|
return nil, fmt.Errorf("ssh: first packet should be msgKexInit")
|
|
|
|
}
|
|
|
|
diff -Naru cryptolib/ssh/tcpip.go pkg/proto/ssh/tcpip.go
|
|
|
|
--- cryptolib/ssh/tcpip.go 2023-11-21 18:52:03.129248237 +0300
|
|
|
|
+++ pkg/proto/ssh/tcpip.go 2023-11-21 17:19:04.688042738 +0300
|
2023-11-18 21:51:44 +03:00
|
|
|
@@ -101,14 +101,18 @@
|
|
|
|
// ListenTCP requests the remote peer open a listening socket
|
|
|
|
// on laddr. Incoming connections will be available by calling
|
|
|
|
// Accept on the returned net.Listener.
|
|
|
|
-func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
|
|
|
|
+func (c *Client) ListenTCP(laddr *net.TCPAddr, fakeHost ...string) (net.Listener, error) {
|
|
|
|
c.handleForwardsOnce.Do(c.handleForwards)
|
|
|
|
if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
|
|
|
|
return c.autoPortListenWorkaround(laddr)
|
|
|
|
}
|
2023-11-18 22:29:18 +03:00
|
|
|
|
2023-11-18 21:51:44 +03:00
|
|
|
+ host := laddr.IP.String()
|
|
|
|
+ if len(fakeHost) > 0 {
|
|
|
|
+ host = fakeHost[0]
|
|
|
|
+ }
|
|
|
|
m := channelForwardMsg{
|
|
|
|
- laddr.IP.String(),
|
|
|
|
+ host,
|
|
|
|
uint32(laddr.Port),
|
|
|
|
}
|
|
|
|
// send message
|
2023-11-18 22:29:18 +03:00
|
|
|
@@ -133,7 +137,12 @@
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register this forward, using the port number we obtained.
|
|
|
|
- ch := c.forwards.add(laddr)
|
|
|
|
+ var ch chan forward
|
|
|
|
+ if len(fakeHost) > 0 {
|
|
|
|
+ ch = c.forwards.add(laddr, fakeHost[0])
|
|
|
|
+ } else {
|
|
|
|
+ ch = c.forwards.add(laddr)
|
|
|
|
+ }
|
|
|
|
|
|
|
|
return &tcpListener{laddr, c, ch}, nil
|
|
|
|
}
|
|
|
|
@@ -142,7 +151,9 @@
|
|
|
|
// forward requests and the tcpListeners.
|
|
|
|
type forwardList struct {
|
|
|
|
sync.Mutex
|
|
|
|
- entries []forwardEntry
|
|
|
|
+ fdm sync.RWMutex
|
|
|
|
+ fakeDomainsMap map[string]string
|
|
|
|
+ entries []forwardEntry
|
|
|
|
}
|
|
|
|
|
|
|
|
// forwardEntry represents an established mapping of a laddr on a
|
|
|
|
@@ -160,17 +171,30 @@
|
|
|
|
raddr net.Addr // the raddr of the incoming connection
|
|
|
|
}
|
|
|
|
|
|
|
|
-func (l *forwardList) add(addr net.Addr) chan forward {
|
|
|
|
+func (l *forwardList) add(addr net.Addr, fakeHost ...string) chan forward {
|
|
|
|
l.Lock()
|
|
|
|
defer l.Unlock()
|
|
|
|
f := forwardEntry{
|
|
|
|
laddr: addr,
|
|
|
|
c: make(chan forward, 1),
|
|
|
|
}
|
|
|
|
+ if len(fakeHost) > 0 {
|
|
|
|
+ if l.fakeDomainsMap == nil {
|
|
|
|
+ l.fakeDomainsMap = make(map[string]string)
|
|
|
|
+ }
|
|
|
|
+ defer l.fdm.Unlock()
|
|
|
|
+ l.fdm.Lock()
|
|
|
|
+ l.fakeDomainsMap[fakeHost[0]] = l.ipFromAddr(addr)
|
|
|
|
+ }
|
|
|
|
l.entries = append(l.entries, f)
|
|
|
|
return f.c
|
|
|
|
}
|
|
|
|
|
|
|
|
+func (l *forwardList) ipFromAddr(addr net.Addr) string {
|
|
|
|
+ host, _, _ := net.SplitHostPort(addr.String())
|
|
|
|
+ return host
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
// See RFC 4254, section 7.2
|
|
|
|
type forwardedTCPPayload struct {
|
|
|
|
Addr string
|
|
|
|
@@ -206,6 +230,15 @@
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
+ l.fdm.RLock()
|
|
|
|
+ if addr, ok := l.fakeDomainsMap[payload.Addr]; ok {
|
|
|
|
+ payload.Addr = addr
|
|
|
|
+ }
|
|
|
|
+ if addr, ok := l.fakeDomainsMap[payload.OriginAddr]; ok {
|
|
|
|
+ payload.OriginAddr = addr
|
|
|
|
+ }
|
|
|
|
+ l.fdm.RUnlock()
|
|
|
|
+
|
|
|
|
// RFC 4254 section 7.2 specifies that incoming
|
|
|
|
// addresses should list the address, in string
|
|
|
|
// format. It is implied that this should be an IP
|