diff options
Diffstat (limited to 'exploits/7350bindnxt/dnslib.c')
| -rw-r--r-- | exploits/7350bindnxt/dnslib.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/exploits/7350bindnxt/dnslib.c b/exploits/7350bindnxt/dnslib.c new file mode 100644 index 0000000..d1afb13 --- /dev/null +++ b/exploits/7350bindnxt/dnslib.c | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | #include "dnslib.h" | ||
| 2 | #include <netinet/in.h> | ||
| 3 | #include <arpa/inet.h> | ||
| 4 | |||
| 5 | /* make a full dns query including header. Returns length of packet. | ||
| 6 | */ | ||
| 7 | int | ||
| 8 | makequery (char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id) | ||
| 9 | { | ||
| 10 | HEADER *head; | ||
| 11 | |||
| 12 | head = (HEADER *)buffer; | ||
| 13 | |||
| 14 | bzero (head, DNSHDRSIZE); | ||
| 15 | head->id = htons (id); | ||
| 16 | head->qr = 0; | ||
| 17 | head->opcode = 0; | ||
| 18 | head->aa = 0; | ||
| 19 | head->tc = 0; | ||
| 20 | head->rd = 1; | ||
| 21 | head->ra = 0; | ||
| 22 | head->rcode = 0; | ||
| 23 | head->qdcount = htons (1); | ||
| 24 | head->ancount = 0; | ||
| 25 | head->nscount = 0; | ||
| 26 | head->arcount = 0; | ||
| 27 | |||
| 28 | return (makeqbody (name, type, buffer + DNSHDRSIZE) + DNSHDRSIZE); | ||
| 29 | } | ||
| 30 | |||
| 31 | /* convert a \0-terminated string to a DNS domain name. | ||
| 32 | * www.yahoo.com(.) => \003www\005yahoo\003\com\000 | ||
| 33 | */ | ||
| 34 | int | ||
| 35 | formatname (char *in, u_int8_t *out) | ||
| 36 | { | ||
| 37 | char *start = in, c = 0; | ||
| 38 | int n = strlen (in); | ||
| 39 | |||
| 40 | in += n - 1; | ||
| 41 | out += n + 1; | ||
| 42 | |||
| 43 | *out-- = 0; | ||
| 44 | |||
| 45 | n = 0; | ||
| 46 | while (in >= start) { | ||
| 47 | c = *in--; | ||
| 48 | if (c == '.') { | ||
| 49 | *out-- = n; | ||
| 50 | n = 0; | ||
| 51 | } else { | ||
| 52 | *out-- = c; | ||
| 53 | n++; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | if (n) | ||
| 58 | *out-- = n; | ||
| 59 | |||
| 60 | return (strlen (out + 1) + 1); | ||
| 61 | } | ||
| 62 | |||
| 63 | /* simple function for making a, ptr and ns resource records | ||
| 64 | * doesn't support more complicated stuph. | ||
| 65 | */ | ||
| 66 | |||
| 67 | int | ||
| 68 | makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl, | ||
| 69 | char *rdata, char *buf) | ||
| 70 | { | ||
| 71 | int n; | ||
| 72 | rrec_body *rec; | ||
| 73 | char *ptr = buf; | ||
| 74 | |||
| 75 | /* name the resource record pertains too */ | ||
| 76 | ptr += formatname (name, ptr); | ||
| 77 | rec = (rrec_body *)ptr; | ||
| 78 | rec->type = htons (type); | ||
| 79 | rec->class = htons (class); | ||
| 80 | rec->ttl = htonl (ttl); | ||
| 81 | rec->rdlength = 0; | ||
| 82 | ptr += 10; | ||
| 83 | |||
| 84 | switch (type) { | ||
| 85 | case T_A: | ||
| 86 | *(u_int32_t *)ptr = inet_addr (rdata); | ||
| 87 | rec->rdlength = htons (4); | ||
| 88 | ptr += 4; | ||
| 89 | break; | ||
| 90 | case T_PTR: | ||
| 91 | case T_NS: | ||
| 92 | n = formatname (rdata, ptr); | ||
| 93 | ptr += n; | ||
| 94 | rec->rdlength = htons (n); | ||
| 95 | break; | ||
| 96 | default: | ||
| 97 | /**/ | ||
| 98 | } | ||
| 99 | return (ptr - buf); | ||
| 100 | } | ||
| 101 | |||
| 102 | /* make just the body of a DNS query. | ||
| 103 | */ | ||
| 104 | int | ||
| 105 | makeqbody (char *name, u_int16_t type, u_int8_t *buffer) | ||
| 106 | { | ||
| 107 | int len; | ||
| 108 | |||
| 109 | len = formatname (name, buffer); | ||
| 110 | buffer += len; | ||
| 111 | PUTSHORT (type, buffer); | ||
| 112 | PUTSHORT (C_IN, buffer); | ||
| 113 | return (len + 4); | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 117 | /* uncompress compressed dns names. ugh. | ||
| 118 | * works for normal formatted dns names too.. | ||
| 119 | * returns the length of the first part of the compressed name (i.e. | ||
| 120 | * before redirection). | ||
| 121 | */ | ||
| 122 | |||
| 123 | int | ||
| 124 | uncompress (u_int8_t *in, char *out, u_int8_t *msg) | ||
| 125 | { | ||
| 126 | u_int8_t *start = in, *end = NULL; | ||
| 127 | u_int8_t len; | ||
| 128 | u_int16_t off; | ||
| 129 | |||
| 130 | while ((len = *in++)) { | ||
| 131 | if (len & INDIR_MASK) { | ||
| 132 | if (end == NULL) | ||
| 133 | end = in + 1; | ||
| 134 | off = (len & ~INDIR_MASK); | ||
| 135 | off |= *in++ << 8; | ||
| 136 | off = ntohs (off); | ||
| 137 | in = msg + off; | ||
| 138 | continue; | ||
| 139 | } | ||
| 140 | memcpy (out, in, len); | ||
| 141 | out += len; | ||
| 142 | in += len; | ||
| 143 | *out++ = '.'; | ||
| 144 | } | ||
| 145 | if (end == NULL) | ||
| 146 | end = in; | ||
| 147 | *out++ = 0; | ||
| 148 | return (end - start); | ||
| 149 | } | ||
