-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
_______________________________________________________________________
~ iKu Advisory _______________________________________________________________________
Product : Java Runtime Environment Date : November 8th 2004 Affected versions : 1.4.2, 1.5.0, probably more Vulnerability Type : remote denial of service Severity (1-10) : 3 Remote : yes _______________________________________________________________________
0. contents
~ 1. problem description ~ 2. symptoms ~ 3. bug description/possible fix ~ 4. sample code ~ 5. workaround
1. problem description
Java uses an 'InitialDirContext' to perform DNS lookups. A wrap-around of an internal variable renders the context unusable after 32768 requests for the next 32768 requests. A remote attacker might trick an application into performing a lot of DNS requests which renders the application unusable. It might also be the cause of some problems with long running server processes.
2. symptoms
When the 32768 requests are done, the following requests throw this exception:
javax.naming.CommunicationException: DNS error: ID doesn't match; remaining name 'sun.com' at com.sun.jndi.dns.DnsClient.checkHeader(DnsClient.java:426) at com.sun.jndi.dns.DnsClient.query(DnsClient.java:162) at com.sun.jndi.dns.Resolver.query(Resolver.java:63) at com.sun.jndi.dns.DnsContext.c_getAttributes(DnsContext.java:410) at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getAttributes(ComponentDirContext.java:213) at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(PartialCompositeDirContext.java:121) at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(PartialCompositeDirContext.java:109) at javax.naming.directory.InitialDirContext.getAttributes(InitialDirContext.java:121) at DNSLookupBug.main(DNSLookupBug.java:17)
3. bug description/possible fix
In com/sun/jndi/dns/DnsClient.java, 'xid' is of type 'int' but initialized by the 'short' 'ident'. Thus if 'ident' reaches 32768, it becomes negative, rendering 'xid' negative to '-32768':
~ private short ident = 0; // used to set the msg ID field [...] int xid; synchronized (identLock) { xid = ++ident; }
In the class com/sun/jndi/dns/Header.java, the answer from the DNS server is converted backwards but to an 'int' instead of a 'short':
~ private static int getShort(byte[] msg, int pos) { return (((msg[pos] & 0xFF) << 8) | (msg[pos + 1] & 0xFF)); ~ }
So, the result of this method gives '32768' which is not equal to '-32768' and therefore the failure. A possible fix would be to replace
xid = getShort(msg, pos); by xid = (short) getShort(msg, pos);
in com/sun/jndi/dns/Header.java.
4. sample code
- ---------- BEGIN SOURCE ---------- import java.util.*;
import javax.naming.directory.*;
public class DNSLookupBug { ~ public static void main(String[] args) { ~ try { ~ final Hashtable env = new Hashtable(); ~ env.put("java.naming.factory.initial", ~ "com.sun.jndi.dns.DnsContextFactory");
~ DirContext dnsContext = new InitialDirContext(env);
~ final String[] domain = new String[] {"A"}; ~ for (int i = 0; i < 0xffff; i++) { ~ dnsContext.getAttributes("sun.com", domain); ~ if (i % 1000 == 0) { ~ // use this as a workaround ~ //dnsContext = new InitialDirContext(env); ~ System.out.println(i); ~ } ~ }
~ } catch (Exception e) { ~ e.printStackTrace(); ~ } ~ } } - ---------- END SOURCE ----------
5. workaround
The application has to be rewritten to use a new InitialDirContext before the limit of 32768 requests is reached. Another solution would be to subclass InitialDirContext and let 'xid' have only positive values. - -- Kurt Huwig iKu Systemhaus AG http://www.iku-ag.de/ Vorstand Am Römerkastell 4 Telefon 0681/96751-0 ~ 66121 Saarbrücken Telefax 0681/96751-66 GnuPG 1024D/99DD9468 64B1 0C5B 82BC E16E 8940 EB6D 4C32 F908 99DD 9468 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBj3MXTDL5CJndlGgRAvdZAKC6HyzZV5zP5usJ0SwuWXn87oE3QgCdF43u ZmmwrG7fV/Kufclo8PxKNW4= =wqBC -----END PGP SIGNATURE-----