CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/byakugan/exts.cpp
Views: 11766
1
#include "byakugan.h"
2
#include "msfpattern.h"
3
#include "jutsu.h"
4
#include "tenketsu.h"
5
#include "mushishi.h"
6
#include "symPort.h"
7
8
#include "csv_parser.hpp"
9
#include <ios>
10
#include <iostream>
11
#include <sstream>
12
13
char *registers[] = {
14
"eax",
15
"ebx",
16
"ecx",
17
"edx",
18
"esp",
19
"ebp",
20
"eip",
21
NULL
22
};
23
24
HRESULT CALLBACK byakugan(PDEBUG_CLIENT4 Client, PCSTR args) {
25
INIT_API();
26
UNREFERENCED_PARAMETER(args);
27
28
dprintf(HELPSTRING);
29
dprintf("!jutsu <command> <args> - Perform Jutsu: !jutsu help\n");
30
dprintf("!tenketsu - Begin realtime heap vizualization: !tenketsu help\n");
31
dprintf("!pattern_offset <length> <optional: addr>\n");
32
dprintf("!mushishi <detect|defeat>- Detect or defeat anti-debugging mechanisms\n");
33
34
EXIT_API();
35
return (S_OK);
36
}
37
38
HRESULT CALLBACK pattern_offset(PDEBUG_CLIENT4 Client, PCSTR args) {
39
char *arg1, **arg2, *holder[2], *context;
40
ULONG length, addr;
41
int offset, i;
42
43
INIT_API();
44
UNREFERENCED_PARAMETER(args);
45
46
arg1 = strtok((char *)args, " ");
47
arg2 = holder;
48
arg2[0] = strtok(NULL, " ");
49
arg2[1] = NULL;
50
51
if (arg1 == NULL) {
52
dprintf("[Byakugan] Please provide a length.\n");
53
return (S_OK);
54
}
55
56
length = strtoul(arg1, NULL, 10);
57
58
if (arg2[0] == NULL)
59
arg2 = registers;
60
61
for (i = 0; arg2[i] != NULL; i++) {
62
addr = GetExpression(arg2[i]);
63
64
offset = msf_pattern_offset(length, addr);
65
if (offset != -1)
66
dprintf("[Byakugan] Control of %s at offset %d.\n", arg2[i], offset);
67
}
68
69
EXIT_API();
70
return (S_OK);
71
}
72
73
HRESULT CALLBACK mushishi(PDEBUG_CLIENT4 Client, PCSTR args) {
74
char *command;
75
76
INIT_API();
77
78
command = strtok((char *)args, " ");
79
if (command != NULL) {
80
if (!_stricmp(command, "detect")) {
81
mushishiDetect();
82
return (S_OK);
83
}
84
if (!_stricmp(command, "defeat")) {
85
mushishiDefeat();
86
return (S_OK);
87
}
88
}
89
dprintf("[Mushishi] Proper commands are: 'detect' 'defeat'\n");
90
91
EXIT_API();
92
return (S_OK);
93
}
94
95
HRESULT CALLBACK symport(PDEBUG_CLIENT4 Client, PCSTR args) {
96
char *command, *module, *path;
97
98
INIT_API();
99
100
module = strtok((char *)args, " ");
101
path = strtok(NULL, " ");
102
if (module != NULL && path != NULL) {
103
addMapFile(module, path);
104
return (S_OK);
105
} else {
106
dprintf("[symPort] Proper format is: !symport <moduleName> <map file path>\n");
107
}
108
EXIT_API();
109
return (S_OK);
110
}
111
112
HRESULT CALLBACK jutsu(PDEBUG_CLIENT4 Client, PCSTR args) {
113
char *command, *bufName, *bufPatt, *bindPort, *bufSize, *bufType, *bufAddr;
114
using namespace std;
115
INIT_API();
116
117
command = strtok((char *)args, " ");
118
if (command != NULL) {
119
if (!_stricmp(command, "help")) {
120
helpJutsu();
121
return (S_OK);
122
}
123
if (!_stricmp(command, "moduleInfo")) {
124
125
}
126
if (!_stricmp(command, "memDiff")) {
127
bufType = strtok(NULL, " ");
128
bufSize = strtok(NULL, " ");
129
bufPatt = strtok(NULL, " ");
130
bufAddr = strtok(NULL, " ");
131
if (!bufAddr) {
132
dprintf("[J] Format: memDiff <type> <size> <value> <address>\n");
133
dprintf("Valid Types:\n\thex: Value is any hex characters\n");
134
dprintf("\tfile: Buffer is read in from file at path <value>\n");
135
dprintf("\tbuf: Buffer is taken from known tracked Buffers\n");
136
return (S_OK);
137
}
138
memDiffJutsu(bufType, strtoul(bufSize, NULL, 10),
139
bufPatt, strtoul(bufAddr, NULL, 0x10));
140
}
141
if (!_stricmp(command, "trackVal")) {
142
bufName = strtok(NULL, " ");
143
bufSize = strtok(NULL, " ");
144
bufPatt = strtok(NULL, " ");
145
146
if (bufName == NULL) {
147
listTrackedVals();
148
} else if (bufSize == NULL) {
149
listTrackedValByName(bufName);
150
} else
151
trackValJutsu(bufName, strtoul(bufSize, NULL, 10),
152
strtoul(bufPatt, NULL, 0x10));
153
}
154
if (!_stricmp(command, "searchOpcode")) {
155
char *instructions;
156
157
instructions = (char *) args + strlen(command) + 1;
158
searchOpcodes(instructions);
159
return (S_OK);
160
}
161
if (!_stricmp(command, "searchVtptr")) {
162
char *instructions, *offsetString;
163
DWORD offset;
164
165
offsetString = strtok(NULL, " ");
166
offset = strtoul(offsetString, NULL, 16);
167
instructions = offsetString + strlen(offsetString) + 1;
168
searchVtptr(offset, instructions);
169
return (S_OK);
170
}
171
if (!_stricmp(command, "listen")) {
172
bindPort = strtok(NULL, " ");
173
if (bindPort == NULL)
174
bindPort = DEFAULT_PORT;
175
bindJutsu(bindPort);
176
return (S_OK);
177
}
178
if (!_stricmp(command, "listBuf")) {
179
listTrackedBufJutsu();
180
return (S_OK);
181
}
182
if (!_stricmp(command, "listReqs")) {
183
showRequestsJutsu();
184
return (S_OK);
185
}
186
if (!_stricmp(command, "rmBuf")) {
187
bufName = strtok(NULL, " ");
188
if (bufName == NULL) {
189
dprintf("[Byakugan] This command requires a buffer name\n");
190
return (S_OK);
191
}
192
rmBufJutsu(bufName);
193
return (S_OK);
194
}
195
if (!_stricmp(command, "identBuf")) {
196
197
bufType = strtok(NULL, " ");
198
bufName = strtok(NULL, " ");
199
bufPatt = strtok(NULL, " ");
200
bufSize = strtok(NULL, " ");
201
if (bufPatt == NULL) {
202
dprintf("[Byakugan] This command requires a buffer type, name, (sometimes) value, and size\n");
203
return (S_OK);
204
}
205
if (bufSize == NULL)
206
identBufJutsu(bufType, bufName, bufPatt, 0, 0);
207
else
208
identBufJutsu(bufType, bufName, bufPatt, strtoul(bufSize, NULL, 10), 0);
209
return (S_OK);
210
}
211
if (!_stricmp(command, "identBufFile")) {
212
char *bufFile, *bufMap;
213
bufFile = strtok(NULL, " ");
214
bufMap = strtok(NULL, " ");
215
bufType = "smartFile";
216
217
if (bufFile == NULL) {
218
dprintf("[Byakugan] This command requires a path to an input file and map (CSV) from 010\n");
219
return (S_OK);
220
}
221
222
//these settings are explicting for 010 CSV export
223
const char field_terminator = ',';
224
const char line_terminator = '\n';
225
const char enclosure_char = '"';
226
227
//create parse object
228
csv_parser file_parser;
229
230
/* Define how many records we're gonna skip. This could be used to skip the column definitions. */
231
file_parser.set_skip_lines(1);
232
233
/* Specify the file to parse */
234
file_parser.init(bufMap);
235
236
/* Here we tell the parser how to parse the file */
237
file_parser.set_enclosed_char(enclosure_char, ENCLOSURE_OPTIONAL);
238
239
file_parser.set_field_term_char(field_terminator);
240
241
file_parser.set_line_term_char(line_terminator);
242
243
/* Check to see if there are more records, then grab each row one at a time */
244
while(file_parser.has_more_rows())
245
{
246
csv_row fileRecord = file_parser.get_row();
247
248
//the miracle of STL hex string conversion :)
249
istringstream stFileOffset(fileRecord[2].c_str());
250
istringstream stOffSetSize(fileRecord[3].c_str());
251
unsigned int offset;
252
unsigned int size;
253
stFileOffset >> hex >> offset;
254
stOffSetSize >> hex >> size;
255
256
//dprintf("Allocating Buffer Name:%s at offset: %d with size: %d\n", fileRecord[0].c_str(), offset, size);
257
258
//create individual buffers with the record type as a name and using the offset and size
259
identBufJutsu(bufType, (char *)fileRecord[0].c_str(), bufFile, size, offset);
260
}
261
return (S_OK);
262
}
263
if (!_stricmp(command, "hunt")) {
264
hunterJutsu();
265
}
266
267
if (!_stricmp(command, "findReturn")) {
268
returnAddressHuntJutsu();
269
}
270
}
271
EXIT_API();
272
return (S_OK);
273
}
274
HRESULT CALLBACK tenketsu(PDEBUG_CLIENT4 Client, PCSTR args) {
275
char *command, *heapName, *logName;
276
PVOID heapHandle;
277
278
INIT_API();
279
280
command = strtok((char *)args, " ");
281
282
if (command == NULL) {
283
tenkHelp();
284
return (S_OK);
285
}
286
else if (!_stricmp(command, "model")) {
287
if(hookRtlHeap(1, NULL)) {
288
dprintf("[Byakugan] Unable to begin realtime heap modeling.\n");
289
EXIT_API();
290
return (S_FALSE);
291
}
292
}
293
else if (!_stricmp(command, "log")) {
294
logName = strtok(NULL, " ");
295
if (logName == NULL) {
296
dprintf("[Byakugan] Please provide a log name.\n");
297
return (S_FALSE);
298
}
299
if(hookRtlHeap(2, logName)) {
300
dprintf("[Byakugan] Unable to begin realtime heap modeling.\n");
301
EXIT_API();
302
return (S_FALSE);
303
}
304
}
305
else if (!_stricmp(command, "help")) {
306
tenkHelp();
307
return (S_OK);
308
}
309
else if (!_stricmp(command, "validate")) {
310
heapName = strtok(NULL, " ");
311
if (heapName == NULL) {
312
dprintf("[Byakugan] Please provide a heap handle.\n");
313
return (S_OK);
314
}
315
heapHandle = (PVOID) strtoul(heapName, NULL, 16);
316
tenkValidate(heapHandle);
317
return (S_OK);
318
}
319
else if (!_stricmp(command, "listHeaps")) {
320
tenkListHeaps();
321
return (S_OK);
322
}
323
else if (!_stricmp(command, "listChunks")) {
324
heapName = strtok(NULL, " ");
325
if (heapName == NULL) {
326
dprintf("[Byakugan] Please provide a heap handle.\n");
327
return (S_OK);
328
}
329
heapHandle = (PVOID) strtoul(heapName, NULL, 16);
330
tenkListChunks(heapHandle);
331
return (S_OK);
332
}
333
334
EXIT_API();
335
336
return (S_OK);
337
}
338
339