Name changes to library, remove global config
This commit is contained in:
parent
f99445c05b
commit
9bbc2ea8f4
@ -13,7 +13,7 @@ import (
|
||||
|
||||
// clientAuthenticate authenticates with the remote server. See RFC 4252.
|
||||
func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
||||
if c.transport.config.ConnLog != nil && !pkgConfig.CollectUserAuth {
|
||||
if c.transport.config.ConnLog != nil && !config.DontAuthenticate {
|
||||
// Use ConnLog existence to indicate that this is a run and not testing
|
||||
return nil
|
||||
}
|
||||
|
@ -225,6 +225,14 @@ type Config struct {
|
||||
|
||||
// A pointer to the handshake log IOT allow incremental building
|
||||
ConnLog *HandshakeLog
|
||||
|
||||
// Whether or not the package should operate in verbose mode
|
||||
// (save more output)
|
||||
Verbose bool
|
||||
|
||||
GexMinBits uint
|
||||
GexMaxBits uint
|
||||
GexPreferredBits uint
|
||||
}
|
||||
|
||||
// SetDefaults sets sensible values for unset fields in config. This is
|
||||
|
@ -1,11 +1,74 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func MakeXSSHConfig() *ClientConfig {
|
||||
ret := new(ClientConfig)
|
||||
ret.DontAuthenticate = true // IOT scan ethically, never attempt to authenticate
|
||||
ret.ClientVersion = pkgConfig.ClientID
|
||||
ret.HostKeyAlgorithms = pkgConfig.HostKeyAlgorithms.Get()
|
||||
ret.KeyExchanges = pkgConfig.KexAlgorithms.Get()
|
||||
ret.Ciphers = pkgConfig.Ciphers.Get()
|
||||
ret.HostKeyAlgorithms = supportedHostKeyAlgos
|
||||
ret.KeyExchanges = defaultKexAlgos
|
||||
ret.Ciphers = defaultCiphers
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *ClientConfig) SetHostKeyAlgorithms(value string) error {
|
||||
for _, alg := range strings.Split(value, ",") {
|
||||
isValid := false
|
||||
for _, val := range supportedHostKeyAlgos {
|
||||
if val == alg {
|
||||
isValid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isValid {
|
||||
return errors.New(fmt.Sprintf(`host key algorithm not supported: "%s"`, alg))
|
||||
}
|
||||
|
||||
c.HostKeyAlgorithms = append(c.HostKeyAlgorithms, alg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClientConfig) SetKexAlgorithms(value string) error {
|
||||
for _, alg := range strings.Split(value, ",") {
|
||||
isValid := false
|
||||
for _, val := range allSupportedKexAlgos {
|
||||
if val == alg {
|
||||
isValid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isValid {
|
||||
return errors.New(fmt.Sprintf(`DH KEX algorithm not supported: "%s"`, alg))
|
||||
}
|
||||
|
||||
c.KeyExchanges = append(c.KeyExchanges, alg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClientConfig) SetCiphers(value string) error {
|
||||
for _, inCipher := range strings.Split(value, ",") {
|
||||
isValid := false
|
||||
for _, knownCipher := range allSupportedCiphers {
|
||||
if inCipher == knownCipher {
|
||||
isValid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isValid {
|
||||
return errors.New(fmt.Sprintf(`cipher not supported: "%s"`, inCipher))
|
||||
}
|
||||
|
||||
c.Ciphers = append(c.Ciphers, inCipher)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro
|
||||
return err
|
||||
}
|
||||
|
||||
if pkgConfig.Verbose {
|
||||
if t.config.Verbose {
|
||||
if t.config.ConnLog != nil {
|
||||
t.config.ConnLog.ClientKex = myInit
|
||||
}
|
||||
@ -417,7 +417,7 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro
|
||||
} else {
|
||||
result, err = t.client(kex, algs, &magics)
|
||||
}
|
||||
if pkgConfig.Verbose {
|
||||
if t.config.Verbose {
|
||||
if t.config.ConnLog != nil {
|
||||
t.config.ConnLog.Crypto = result
|
||||
}
|
||||
@ -452,12 +452,12 @@ func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *
|
||||
}
|
||||
}
|
||||
|
||||
r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey)
|
||||
r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.config)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
|
||||
result, err := kex.Client(t.conn, t.config.Rand, magics)
|
||||
result, err := kex.Client(t.conn, t.config.Rand, magics, t.config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -145,11 +145,11 @@ func LogServerHostKey(sshRawKey []byte) *ServerHostKeyJsonLog {
|
||||
type kexAlgorithm interface {
|
||||
// Server runs server-side key agreement, signing the result
|
||||
// with a hostkey.
|
||||
Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error)
|
||||
Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer, c *Config) (*kexResult, error)
|
||||
|
||||
// Client runs the client-side key agreement. Caller is
|
||||
// responsible for verifying the host key signature.
|
||||
Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)
|
||||
Client(p packetConn, rand io.Reader, magics *handshakeMagics, c *Config) (*kexResult, error)
|
||||
|
||||
// Create a JSON object for the kexAlgorithm group
|
||||
MarshalJSON() ([]byte, error)
|
||||
@ -276,7 +276,7 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer, config *Config) (result *kexResult, err error) {
|
||||
hashFunc := crypto.SHA1
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
@ -381,10 +381,10 @@ func (kex *ecdh) GetNew(keyType string) kexAlgorithm {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||
func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics, config *Config) (*kexResult, error) {
|
||||
kex.JsonLog.Parameters = new(ztoolsKeys.ECDHParams)
|
||||
kex.JsonLog.Parameters.ServerPublic = new(ztoolsKeys.ECPoint)
|
||||
if pkgConfig.Verbose {
|
||||
if config.Verbose {
|
||||
kex.JsonLog.Parameters.ClientPublic = new(ztoolsKeys.ECPoint)
|
||||
kex.JsonLog.Parameters.ClientPrivate = new(ztoolsKeys.ECDHPrivateParams)
|
||||
}
|
||||
@ -394,7 +394,7 @@ func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if pkgConfig.Verbose {
|
||||
if config.Verbose {
|
||||
kex.JsonLog.Parameters.ClientPublic.X = ephKey.PublicKey.X
|
||||
kex.JsonLog.Parameters.ClientPublic.Y = ephKey.PublicKey.Y
|
||||
kex.JsonLog.Parameters.ClientPrivate.Value = ephKey.D.Bytes()
|
||||
@ -494,7 +494,7 @@ func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer, config *Config) (result *kexResult, err error) {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -639,13 +639,13 @@ func (kp *curve25519KeyPair) generate(rand io.Reader) error {
|
||||
// wrong order.
|
||||
var curve25519Zeros [32]byte
|
||||
|
||||
func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||
func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics, config *Config) (*kexResult, error) {
|
||||
var kp curve25519KeyPair
|
||||
if err := kp.generate(rand); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if pkgConfig.Verbose {
|
||||
if config.Verbose {
|
||||
kex.JsonLog.Parameters.ClientPublic = kp.pub[:]
|
||||
kex.JsonLog.Parameters.ClientPrivate = kp.priv[:]
|
||||
}
|
||||
@ -700,7 +700,7 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer, config *Config) (result *kexResult, err error) {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -83,12 +83,12 @@ func (gex *dhGEXSHA) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, e
|
||||
return new(big.Int).Exp(theirPublic, myPrivate, gex.p), nil
|
||||
}
|
||||
|
||||
func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||
func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics, config *Config) (*kexResult, error) {
|
||||
// Send GexRequest
|
||||
kexDHGexRequest := kexDHGexRequestMsg{
|
||||
MinBits: uint32(pkgConfig.GexMinBits),
|
||||
PreferedBits: uint32(pkgConfig.GexPreferredBits),
|
||||
MaxBits: uint32(pkgConfig.GexMaxBits),
|
||||
MinBits: uint32(config.GexMinBits),
|
||||
PreferedBits: uint32(config.GexPreferredBits),
|
||||
MaxBits: uint32(config.GexMaxBits),
|
||||
}
|
||||
if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil {
|
||||
return nil, err
|
||||
@ -111,7 +111,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
|
||||
}
|
||||
|
||||
// reject if p's bit length < pkgConfig.GexMinBits or > pkgConfig.GexMaxBits
|
||||
if kexDHGexGroup.P.BitLen() < int(pkgConfig.GexMinBits) || kexDHGexGroup.P.BitLen() > int(pkgConfig.GexMaxBits) {
|
||||
if kexDHGexGroup.P.BitLen() < int(config.GexMinBits) || kexDHGexGroup.P.BitLen() > int(config.GexMaxBits) {
|
||||
return nil, fmt.Errorf("Server-generated gex p (dont't ask) is out of range (%d bits)", kexDHGexGroup.P.BitLen())
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
|
||||
X: X,
|
||||
}
|
||||
|
||||
if gex.JsonLog != nil && pkgConfig.Verbose {
|
||||
if gex.JsonLog != nil && config.Verbose {
|
||||
gex.JsonLog.Parameters.ClientPrivate = x
|
||||
gex.JsonLog.Parameters.ClientPublic = X
|
||||
}
|
||||
@ -164,9 +164,9 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
|
||||
h := gex.hashFunc.New()
|
||||
magics.write(h)
|
||||
writeString(h, kexDHGexReply.HostKey)
|
||||
binary.Write(h, binary.BigEndian, uint32(pkgConfig.GexMinBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(pkgConfig.GexPreferredBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(pkgConfig.GexMaxBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(config.GexMinBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(config.GexPreferredBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(config.GexMaxBits))
|
||||
writeInt(h, gex.p)
|
||||
writeInt(h, gex.g)
|
||||
writeInt(h, X)
|
||||
@ -184,7 +184,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer, config *Config) (result *kexResult, err error) {
|
||||
// *Receive GexRequest*
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
@ -196,11 +196,11 @@ func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshak
|
||||
}
|
||||
|
||||
// smoosh the user's preferred size into our own limits
|
||||
if kexDHGexRequest.PreferedBits > uint32(pkgConfig.GexMaxBits) {
|
||||
kexDHGexRequest.PreferedBits = uint32(pkgConfig.GexMaxBits)
|
||||
if kexDHGexRequest.PreferedBits > uint32(config.GexMaxBits) {
|
||||
kexDHGexRequest.PreferedBits = uint32(config.GexMaxBits)
|
||||
}
|
||||
if kexDHGexRequest.PreferedBits < uint32(pkgConfig.GexMinBits) {
|
||||
kexDHGexRequest.PreferedBits = uint32(pkgConfig.GexMinBits)
|
||||
if kexDHGexRequest.PreferedBits < uint32(config.GexMinBits) {
|
||||
kexDHGexRequest.PreferedBits = uint32(config.GexMinBits)
|
||||
}
|
||||
// fix min/max if they're inconsistent. technically, we could just pout
|
||||
// and hang up, but there's no harm in giving them the benefit of the
|
||||
@ -251,9 +251,9 @@ func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshak
|
||||
h := gex.hashFunc.New()
|
||||
magics.write(h)
|
||||
writeString(h, hostKeyBytes)
|
||||
binary.Write(h, binary.BigEndian, uint32(pkgConfig.GexMinBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(pkgConfig.GexPreferredBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(pkgConfig.GexMaxBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(config.GexMinBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(config.GexPreferredBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(config.GexMaxBits))
|
||||
writeInt(h, gex.p)
|
||||
writeInt(h, gex.g)
|
||||
writeInt(h, kexDHGexInit.X)
|
||||
|
@ -1,8 +1,13 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zmap/zgrab2"
|
||||
"github.com/zmap/zgrab2/lib/ssh"
|
||||
)
|
||||
|
||||
type SSHFlags struct {
|
||||
@ -11,6 +16,11 @@ type SSHFlags struct {
|
||||
KexAlgorithms string `long:"kex-algorithms" description:"Set SSH Key Exchange Algorithms"`
|
||||
HostKeyAlgorithms string `long:"host-key-algorithms" description:"Set SSH Host Key Algorithms"`
|
||||
NegativeOne bool `long:"negative-one" description:"Set SSH DH kex value to -1 in the selected group"`
|
||||
Ciphers string `long:"ciphers" description:"A comma-separated list of which ciphers to offer."`
|
||||
CollectUserAuth bool `long:"userauth" description:"Use the 'none' authentication request to see what userauth methods are allowed"`
|
||||
GexMinBits uint `long:"gex-min-bits" description:"The minimum number of bits for the DH GEX prime." default:"1024"`
|
||||
GexMaxBits uint `long:"gex-max-bits" description:"The maximum number of bits for the DH GEX prime." default:"8192"`
|
||||
GexPreferredBits uint `long:"gex-preferred-bits" description:"The preferred number of bits for the DH GEX prime." default:"2048"`
|
||||
}
|
||||
|
||||
type SSHModule struct {
|
||||
@ -57,6 +67,44 @@ func (s *SSHScanner) InitPerSender(senderID int) error {
|
||||
func (s *SSHScanner) GetName() string {
|
||||
return s.config.Name
|
||||
}
|
||||
func (s *SSHScanner) Scan(t zgrab2.ScanTarget, port uint) (interface{}, error) {
|
||||
return nil, nil
|
||||
|
||||
func (s *SSHScanner) makeSSHGrabber(hlog *ssh.HandshakeLog) func(string) error {
|
||||
return func(netAddr string) error {
|
||||
sshConfig := ssh.MakeSSHConfig()
|
||||
sshConfig.Timeout = time.Duration(s.config.Timeout) * time.Second
|
||||
sshConfig.ConnLog = hlog
|
||||
sshConfig.ClientVersion = s.ClientID
|
||||
if err := sshConfig.SetHostKeyAlgorithms(s.config.HostKeyAlgorithms); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := sshConfig.SetKexAlgorithms(s.config.KexAlgorithms); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := sshConfig.SetCiphers(s.config.Ciphers); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sshConfig.Verbose = s.config.Verbose
|
||||
sshConfig.DontAuthenticate = s.config.CollectUserAuth
|
||||
sshConfig.GexMinBits = s.config.GexMinBits
|
||||
sshConfig.GexMaxBits = s.config.GexMaxBits
|
||||
sshConfig.GexPreferredBits = s.config.GexPreferredBits
|
||||
_, err := ssh.Dial("tcp", netAddr, sshConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SSHScanner) Scan(t zgrab2.ScanTarget) (interface{}, error) {
|
||||
data := new(ssh.HandshakeLog)
|
||||
sshGrabber := s.makeSSHGrabber(data)
|
||||
|
||||
//TODO: domain name?
|
||||
port := strconv.FormatUint(uint64(s.config.Port), 10)
|
||||
rhost := net.JoinHostPort(t.IP.String(), port)
|
||||
|
||||
err := sshGrabber(rhost)
|
||||
|
||||
return data, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user