2023-12-26 16:44:59 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2023-12-26 17:30:41 +01:00
|
|
|
"bufio"
|
2023-12-26 16:44:59 +01:00
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/pem"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
2023-12-26 17:11:51 +01:00
|
|
|
"os"
|
2023-12-26 16:44:59 +01:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2023-12-26 18:36:18 +01:00
|
|
|
path := os.Getenv("LOGPATH")
|
2023-12-26 17:11:51 +01:00
|
|
|
if path == "" {
|
2023-12-26 18:36:18 +01:00
|
|
|
path = "./data/ssh-honeypot.log"
|
2023-12-26 17:11:51 +01:00
|
|
|
}
|
2023-12-26 16:44:59 +01:00
|
|
|
|
2023-12-26 17:11:51 +01:00
|
|
|
logFile, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
|
|
|
if err != nil {
|
2023-12-26 17:30:41 +01:00
|
|
|
panic(err)
|
2023-12-26 17:11:51 +01:00
|
|
|
}
|
|
|
|
defer logFile.Close()
|
2023-12-26 17:30:41 +01:00
|
|
|
|
|
|
|
w := bufio.NewWriter(logFile)
|
2023-12-26 17:11:51 +01:00
|
|
|
|
|
|
|
port := os.Getenv("PORT")
|
|
|
|
if port == "" {
|
|
|
|
port = "22"
|
|
|
|
}
|
2023-12-26 16:44:59 +01:00
|
|
|
|
|
|
|
key, err := generateKeyPair()
|
|
|
|
if err != nil {
|
2023-12-26 17:30:41 +01:00
|
|
|
panic(err)
|
2023-12-26 16:44:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
config := &ssh.ServerConfig{
|
|
|
|
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
|
|
|
|
ip, _, err := net.SplitHostPort(c.RemoteAddr().String())
|
|
|
|
if err != nil {
|
|
|
|
ip = c.RemoteAddr().String()
|
|
|
|
}
|
2023-12-26 18:36:18 +01:00
|
|
|
_, err = fmt.Fprintf(w, "[%s] \"honeypot login attempt: ssh - %s - %s - %s\"\n", time.Now().Format("2006-01-02 15:04:05.000"), ip, c.User(), string(pass))
|
2023-12-26 17:30:41 +01:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Error writing to log file: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Flush()
|
|
|
|
|
2023-12-26 16:44:59 +01:00
|
|
|
return nil, fmt.Errorf("password rejected for %q", c.User())
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
config.AddHostKey(key)
|
|
|
|
|
2023-12-26 17:11:51 +01:00
|
|
|
listener, err := net.Listen("tcp", "0.0.0.0:"+port)
|
2023-12-26 16:44:59 +01:00
|
|
|
if err != nil {
|
2023-12-26 17:30:41 +01:00
|
|
|
panic(err)
|
2023-12-26 16:44:59 +01:00
|
|
|
}
|
2023-12-26 18:36:18 +01:00
|
|
|
fmt.Printf("Listening on port %s...\n", port)
|
2023-12-26 16:44:59 +01:00
|
|
|
|
|
|
|
for {
|
|
|
|
conn, err := listener.Accept()
|
|
|
|
if err != nil {
|
2023-12-26 17:30:41 +01:00
|
|
|
fmt.Printf("Failed to accept incoming connection: %s", err)
|
2023-12-26 16:44:59 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2023-12-26 18:36:18 +01:00
|
|
|
ip, _, err := net.SplitHostPort(conn.RemoteAddr().String())
|
|
|
|
if err != nil {
|
|
|
|
ip = conn.RemoteAddr().String()
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprintf(w, "[%s] \"honeypot connection: ssh - %s\"\n", time.Now().Format("2006-01-02 15:04:05.000"), ip)
|
|
|
|
|
|
|
|
w.Flush()
|
|
|
|
|
2023-12-26 16:44:59 +01:00
|
|
|
go handleConn(conn, config)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateKeyPair() (ssh.Signer, error) {
|
|
|
|
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
privateKeyPEM := pem.EncodeToMemory(&pem.Block{
|
|
|
|
Type: "RSA PRIVATE KEY",
|
|
|
|
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
|
|
|
|
})
|
|
|
|
|
|
|
|
signer, err := ssh.ParsePrivateKey(privateKeyPEM)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return signer, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleConn(c net.Conn, config *ssh.ServerConfig) {
|
|
|
|
ssh.NewServerConn(c, config)
|
|
|
|
}
|