/* ci returns a string containing info from an ssh.ConnMetadata */ func ci(m ssh.ConnMetadata) string { return fmt.Sprintf( "Address:%v Target:%v Version:%q User:%q", m.RemoteAddr(), victimName(m), m.ClientVersion(), m.User(), ) }
/* logAttempt logs an authorization attempt. */ func logAttempt(conn ssh.ConnMetadata, method, cred string, suc bool) { log.Printf( "Address:%v Authorization Attempt Version:%q User:%q %v:%q "+ "Successful:%v", conn.RemoteAddr(), string(conn.ClientVersion()), conn.User(), method, cred, suc, ) }
func passAuthCallback(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { guid := uuid.NewV4() ip, remotePort := parseIpPortFrom(conn) login := SshLogin{RemoteAddr: ip, RemotePort: remotePort, Username: conn.User(), Password: string(password), Guid: guid.String(), Version: string(conn.ClientVersion()), LoginType: "password", } login.Save() return &ssh.Permissions{Extensions: map[string]string{"guid": guid.String()}}, nil }
// authPassword records any incoming request trying to auth with a username/password func authPassword(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { r := &AuthEvent{ Time: fmt.Sprintf("%d", time.Now().Unix()), AuthType: "sshPass", SrcIP: strings.Split(conn.RemoteAddr().String(), ":")[0], DestIP: extIP, User: conn.User(), TypeData: fmt.Sprintf("client-version: %s", strconv.QuoteToASCII(string(conn.ClientVersion()))), Credentials: strconv.QuoteToASCII(string(password)), } addToBatch(r) return nil, errAuthenticationFailed }
func keyAuthCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { guid := uuid.NewV4() ip, remotePort := parseIpPortFrom(conn) login := SshLogin{RemoteAddr: ip, RemotePort: remotePort, Username: conn.User(), Guid: guid.String(), Version: string(conn.ClientVersion()), PublicKey: key.Marshal(), KeyType: string(key.Type()), LoginType: "key", } go login.Save() //log.Println("Fail to authenticate", conn, ":", err) //return nil, errors.New("invalid authentication") return &ssh.Permissions{Extensions: map[string]string{"guid": guid.String()}}, nil }
/* decidePassword decides whether the connection attempt is allowed and logs the attempt with the auth type (password, keyboard-interactive). */ func decidePassword( conn ssh.ConnMetadata, password []byte, authType string, ) (*ssh.Permissions, error) { /* Check if the version string is on the whitelist */ /* Check if the version string is on the blacklist */ /* TODO: Finish these */ u := conn.User() /* Username */ p := string(password) /* Password */ ua := false /* User allowed */ pa := false /* Password allowed */ /* Make sure the client's version is allowed */ if !versionAllowed(string(conn.ClientVersion())) { log.Printf("%v VersionFail", ci(conn)) return nil, fmt.Errorf("version") } /* Check if the username is allowed */ if _, ok := allowedUsers[u]; ok { ua = true } /* Check if the password is allowed for all users */ if _, ok := allowedPasswords[p]; ok { pa = true } /* Check if there's a user-specific password if he's not allowed yet */ if !ua || !pa { if ps, ok := allowedUserPasswords[u]; ok { if _, ok := ps[p]; ok { ua = true pa = true } } } /* If there's a random chance, apply it and save the password */ if !ua || !pa && 0 != allowedRandProb { if rand.Float64() < allowedRandProb { /* If we're here, we win */ ua = true pa = true /* Save if we're meant to */ if saveAllowedPasswords { saveUserPass(u, p) verbose("Saved allowed creds: %q / %q", u, p) } } } /* If the user's allowed, log it, give up */ if ua && pa { log.Printf("%v Type:%v PasswordOK:%q", ci(conn), authType, p) return nil, nil } /* If not, :( */ log.Printf("%v Type:%v PasswordFail:%q", ci(conn), authType, p) return nil, fmt.Errorf("no") }
// authKey records any incoming request trying to auth with an ssh key func authKey(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { r := &AuthEvent{ Time: fmt.Sprintf("%d", time.Now().Unix()), AuthType: "sshKey", SrcIP: strings.Split(conn.RemoteAddr().String(), ":")[0], DestIP: extIP, User: conn.User(), TypeData: fmt.Sprintf("ssh-key-type: %s client-version: %s", key.Type(), strconv.QuoteToASCII(string(conn.ClientVersion()))), } h := sha256.New() h.Write(key.Marshal()) r.Credentials = base64.StdEncoding.EncodeToString(h.Sum(nil)) addToBatch(r) return nil, errAuthenticationFailed }