The Apache Traffic Server versions 2.1.1 and 2.0.0 suffer from a DNS cache poisoning vulnerability.
1dc0e9378f377c2bbcc492f5d1dc879dd8fb8b702f63ec2c802e48c3bdc43d67
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Nth Dimension Security Advisory (NDSA20100830)
Date: 30th August 2010
Author: Tim Brown <mailto:timb@nth-dimension.org.uk>
URL: <http://www.nth-dimension.org.uk/> / <http://www.machine.org.uk/>
Product: Traffic Server 2.1.1, 2.0.0 <http://trafficserver.apache.org/>
Vendor: Apache Software Foundation <http://www.apache.org/> / Yahoo! Inc
Risk: Medium
Summary
This advisory comes in 3 related parts:
1) Traffic Server uses a static (per DNS server) source port for making
outgoing DNS queries.
2) Traffic Server uses a sequential transaction ID when constructing
asynchronous DNS queries. Moreover the algorithm used to select the
intitial transation ID is not sufficiently random.
3) Traffic Server does not validate the DNS response to ensure that
it pertains to the correct outgoing query but simply relies on the
transaction ID to validate that the response is requested.
These vulnerabilities might significantly increase the chances of
Traffic Server's internal DNS cache being poisoned.
After discussions with the vendor, CVE-2010-2952 was assigned to this
vulnerability.
Technical Details
1) Traffic Server uses a static (per DNS server) source port for making
outgoing DNS queries. The port is chosen at runtime using the
DNSConnection::connect() method from iocore/dns/DNSConnection.cc:
struct sockaddr_in bind_sa;
memset(&sa, 0, sizeof(bind_sa));
bind_sa.sin_family = AF_INET;
bind_sa.sin_addr.s_addr = INADDR_ANY;
int p = time(NULL) + offset;
p = (p % (LAST_RANDOM_PORT - FIRST_RANDOM_PORT)) + FIRST_RANDOM_PORT;
bind_sa.sin_port = htons(p);
Debug("dns", "random port = %d\n", p);
if ((res = socketManager.ink_bind(fd, (struct sockaddr *) &bind_sa, sizeof(bind_sa), Proto)) < 0) {
offset += 101;
continue;
}
Note that since FIRST_RANDOM_PORT is set to 16000, LAST_RANDOM_PORT is
defined as 32000 and since the underlying algorith is predictable,
the source port may be guessed.
2) Traffic Server uses sequential DNS transaction IDs for queries.
The base number is set at runtime using the DNSProcessor::dns_init()
method from iocore/dns/DNS.cc:
if (cval > 0) {
dns_sequence_number = (unsigned int) (cval + DNS_SEQUENCE_NUMBER_RESTART_OFFSET);
Debug("dns", "initial dns_sequence_number (cval) = %d\n", (u_short) dns_sequence_number);
} else { // select a sequence number at random
dns_sequence_number = (unsigned int) (ink_get_hrtime() / HRTIME_MSECOND);
Debug("dns", "initial dns_sequence_number (time) = %d\n", (u_short) dns_sequence_number);
}
and then incremented on each subsequent request as seen in the
write_dns_event() function:
++dns_sequence_number;
...
u_short i = (u_short) dns_sequence_number;
((HEADER *) (buffer))->id = htons(i);
3) When processing responses, Traffic Server walks a linked list
which holds details of each attempted request and compares the incoming
ID with its list to ascertain which request a given response relates.
This can be seen in the dns_process() function from iocore/dns/DNS.cc:
DNSEntry *e = get_dns(handler, (u_short) ntohs(h->id));
...
inline static DNSEntry *
get_dns(DNSHandler * h, u_short id)
{
for (DNSEntry * e = h->entries.head; e; e = (DNSEntry *) e->link.next) {
if (e->once_written_flag)
for (int j = 0; j < MAX_DNS_RETRIES; j++)
if (e->id[j] == id)
return e;
else if (e->id[j] < 0)
goto Lnext;
Lnext:;
}
return NULL;
}
Solutions
Nth Dimension recommends that the vendor supplied patches should be
applied.
History
On 20th August 2010, Nth Dimension contacted both Yahoo! Inc and the
Apache Software Foundation's security teams to report the described
vulnerabilities affecting Traffic Server. Yahoo's team responded
immediately to confirm that that the report had been recieved and
forwarded to the relevant people.
Following on from this, Nth Dimension and the Traffic Server
developers opened a dialogue and the issue and potential remediations
were discussed at length. After offering feedback on Leif Hedstrom's
original analysis, Steve Jiang went away and produced a patch based on
Nth Dimension's comments.
On the 27th August, the vulnerability was assigned CVE-1010-2952
and Lief distributed a proposed patch for feedback from other Traffic
Server developers.
Current
As of the 30th August 2010, the state of the vulnerabilities is believed to
be as follows. A patch has been supplied by the upstream which it is
believed successfully mitigates the final symptoms of this vulnerability.
New releases of both 2.0.x and 2.1.x have also been created which
incorporate this patch.
Thanks
Nth Dimension would like to thank the Apache Software Foundation for
the way they worked to resolve the issue.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iQIcBAEBCAAGBQJMh4S+AAoJEPJhpTVyySo7kwMP/0wIPmO4nNyOhoF0VuUWqLvj
Q7JzQ5xqLeU932Yp+AlDGvHgWYtKZP64Oi5vrkNavhhCRNhSuWMWrbiFb7NgmTdv
EFualmdRXjhZY8O5cLoS6MuCYelosjuO2qDncgrV0xFZ59HXf7FRr/QSc/22Kaum
Mp/DHItk3E1pTZD0BaVX34waCo01q6bPbfsJW0qZyPGUagfk8av6DobgQOwuiPXJ
4bNh4kgaZIY8bgCnOB/TmZM+pz7Tgh6yF2tbjc+0Qx/jdKi4Y+T9Jpv8oKx8+scM
eHpb2iTFXUI7n5uie8nA8F1+Y0InEUr/GfppvEUzk/bHnfNuv5RAH7AuCpabf/kK
+wnYMyhIN2vTmuxDfU/OB8uyzZIrCn6YmH/CFToutzP03I6SssdpsUM6qZd3p8Q/
GM+BYyNcBGk9IC1ikcalCjswtjekHjITJfpmosKyMGR2oFUR3Lh3dWGoDaG+7mSC
w0TxA6FYtqfpJZngfnoBGwU3TGOpIf8S3KOBc7pYPsLBn9VFNAShJtHMi+Tcd/CD
2W9GJ0qJxy4EETJE5MG+PWrBOLQUVGheOxPtAmojHDXnBcfufAKpvCQkUmvdleTG
ASqE0AiHB5r+4gXr7LIvvhT6hQrbDk3EEEseAGV2e7bT+jjHKA0IlbBcB1XW1kOW
Y5sKeOJfAHl1iFu41rT4
=8naX
-----END PGP SIGNATURE-----