Skip to content
GoNetSim

Getting Started

Write your first custom listener handler in Lua

Custom listeners let GoNetSim simulate almost any TCP or UDP protocol, using small scripts written in Lua. When malware speaks a protocol that DNS or HTTP can’t cover, such as SMTP, IRC or a bespoke C2 channel, you can write a handler for it in a few lines.

The idea is simple. When a client connects, GoNetSim hands the connection to your script. Your script reads what the client sends, decides what to reply, and GoNetSim takes care of logging, timeouts, and saving what the client sent.

A script is just a file that defines a handle function:

function handle(conn)
-- your protocol logic here
end

A few rules keep scripts predictable:

  • Each client gets its own run of the script, so connections do not share state with each other.
  • A script can’t touch the file system or run programs. It talks to the network through the provided conn object, writes to the log with log, and saves client data with capture.
  • If a script fails mid-connection, that connection is closed and the error is logged, but the listener can still serve other clients.

Let’s write a handler that pretends to be a simple greeting service. Save the following as greet.lua:

function handle(conn)
conn:write("Welcome to GoNetSim\r\n")
while true do
local line = conn:read_line()
if not line then break end -- client closed the connection
capture:write("greet", line)
conn:write("You said: " .. line)
end
end

Every line the client sends is captured to the artifacts directory, then echoed back with a prefix.

The quickest way to run a script is an inline listener:

Terminal window
gonetsim run greet.lua@:8080

The .lua file extension tells GoNetSim this is a Lua handler, so no configuration is needed at all. Inline listeners are perfect for quickly testing a handler before wiring it into your setup.

To run the handler every time, add it to your config file as a custom listener:

[[listeners]]
name = "greet"
type = "tcp"
listen = ":8080"
handler = "lua:handlers/greet.lua"

Script paths are relative to the config file, so keeping your handlers next to the config keeps things tidy. See the listeners reference for the full list of options.

You can test the handler with netcat:

  1. Start the listener in one terminal

    Terminal window
    gonetsim run greet.lua@:8080
  2. Connect from another terminal and type a message

    Terminal window
    netcat localhost 8080
  3. Type hello and press enter, the server should reply with You said: hello. Leave with Ctrl+C.

  4. Check the GoNetSim terminal, it should show the message was logged and captured.

For faster iteration, the script command runs a handler over stdin/stdout with no port at all:

Terminal window
echo "hello" | gonetsim script greet.lua

This is the fastest way to try changes.

  • Read the full Lua API to see everything handlers can do
  • Browse ready-made examples for common protocols like IRC & FTP
  • See the listeners reference for configuration options like TLS & UDP