unauthenticated-public-key-exchange¶
Ensure for secure connections where the public key exchange is verified against a list of trusted entitities
Public key exchange is vulnerable to man-in-the-middle (MITM) attack without authentication. Authentication can be performed using a mutually trusted certificate authority (or using a known, authorized host key).
Examples¶
Insecure Example
package main
import (
"bytes"
"fmt"
"golang.org/x/crypto/ssh"
"log"
"os"
"strings"
)
func errorCheck(err error, msg string) {
if err != nil {
log.Fatal(msg)
}
}
func insecureConfig(user, pass string) *ssh.ClientConfig {
return &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(pass),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
}
func connect(config *ssh.ClientConfig, host string) {
client, err := ssh.Dial("tcp", host, config)
errorCheck(err, "Cannot dial")
defer client.Close()
session, err := client.NewSession()
errorCheck(err, "Cannot establish session")
defer session.Close()
var b bytes.Buffer
session.Stdout = &b
err = session.Run("/usr/bin/whoami")
errorCheck(err, "Cannot send command")
banner := b.String()
if strings.Contains(banner, config.User) {
fmt.Println("It works!")
} else {
fmt.Println("Looks like it did not work!?")
}
}
func main() {
host, user, pass := os.Args[1], os.Args[2], os.Args[3]
connect(insecureConfig(user, pass), host)
}
Secure Example
package main
import (
"bytes"
"fmt"
"golang.org/x/crypto/ssh"
"log"
"os"
"strings"
)
func errorCheck(err error, msg string) {
if err != nil {
log.Fatal(msg)
}
}
func secureConfig(user, pass, hostKey string) *ssh.ClientConfig {
pinnedHostKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(hostKey))
errorCheck(err, "Cannot parse SSH host key")
return &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(pass),
},
HostKeyCallback: ssh.FixedHostKey(pinnedHostKey),
}
}
func connect(config *ssh.ClientConfig, host string) {
client, err := ssh.Dial("tcp", host, config)
errorCheck(err, "Cannot dial")
defer client.Close()
session, err := client.NewSession()
errorCheck(err, "Cannot establish session")
defer session.Close()
var b bytes.Buffer
session.Stdout = &b
err = session.Run("/usr/bin/whoami")
errorCheck(err, "Cannot send command")
banner := b.String()
if strings.Contains(banner, config.User) {
fmt.Println("It works!")
} else {
fmt.Println("Looks like it did not work!?")
}
}
func main() {
host, user, pass, hostKey := os.Args[1], os.Args[2], os.Args[3], os.Args[4]
connect(secureConfig(user, pass, hostKey), host)
}