package services import ( "bufio" "net" "strings" "time" ) func NewTelnetHandler(log LoggerFunc) Handler { return func(conn net.Conn) { defer conn.Close() remote := conn.RemoteAddr().String() _, _ = conn.Write([]byte("\r\nUbuntu 20.04.3 LTS\r\n\r\nlogin: ")) conn.SetDeadline(time.Now().Add(2 * time.Minute)) scanner := bufio.NewScanner(conn) var username string expectingPassword := false inShell := false for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if inShell { // fake shell: log the command and respond with minimal output cmd := line if cmd == "exit" || cmd == "logout" { _, _ = conn.Write([]byte("logout\r\n")); return } log(Record{Timestamp: Now(), RemoteAddr: remoteIP(remote), RemotePort: remotePort(remote), Service: "telnet", Details: map[string]string{"event":"shell_cmd","cmd":cmd}}) _, _ = conn.Write([]byte("sh: " + cmd + ": command not found\r\n$ ")) continue } if !expectingPassword { username = line log(Record{Timestamp: Now(), RemoteAddr: remoteIP(remote), RemotePort: remotePort(remote), Service: "telnet", Details: map[string]string{"event":"username_attempt","username":username}}) _, _ = conn.Write([]byte("Password: ")) expectingPassword = true } else { password := line log(Record{Timestamp: Now(), RemoteAddr: remoteIP(remote), RemotePort: remotePort(remote), Service: "telnet", Details: map[string]string{"event":"password_attempt","username":username,"password":password}}) // drop into a fake shell prompt to encourage interaction _, _ = conn.Write([]byte("\r\nWelcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-42-generic x86_64)\r\n$ ")) inShell = true } } } }