The Conficker worms I’ve been trying to chase down since late August have been eradicated. At least, so I thought.

As a matter of curiosity, I’d set up DNS query logging on our internal root servers, not really expecting anything untoward to turn up. Boy, was I wrong: it turns out, that we had a client connecting over a VPN, and that client was infected as well. (Unfortunately, the organization I work for doesn’t want to set up Network Access Control, which is understandable, because of the cost and maintenance involved, but a shame, nevertheless.)

I’m almost sure there are more Conficker waiting around there someplace, and under certain circumstances (which I cannot comment on because I’m not familiar enough with them) it appears that the corporate anti-virus system cannot or will not detect them. One thing that seems fool proof though, is the DNS. (The DNS always helps.)

I’ve decided to set up a honey pot DNS server, which will give an alert whenever a query for one of the conficker domains shows up. In order to do so, I grabbed a list of 90.884 domains that are apparently used by conficker, and dumped that list into a CDB database. (I didn’t have Tokyo Cabinet on that machine.)

I then grabbed a copy of Paul Sheer’s sheerdns, which I knew because I briefly mention it in my book Alternative DNS Servers, and hacked that up to check whether the incoming DNS query matches one of the 90,000 domain names. I also had to ensure sheerdns correctly returned NXDOMAIN, so I fixed it like this:

    *** sheerdns.c.orig     2009-09-20 08:49:58.000000000 +0200
    --- sheerdns.c  2009-09-20 08:51:48.000000000 +0200
    *** 547,552 ****
    --- 547,555 ----
            extra_queries[extra_results_len] = NULL; }
          packet_len = (p1 - out_buf);
    +    /* JPM */
    +    if (!nanswers) {
    +           flags = (flags & ~0xf) | 3; } /* NXDOMAIN */
          if (nanswers || nservers) {
            flags |= 0x0400; }                              /* authority-bit 0x0400 */

Setting up sheerdns isn’t difficult. It looks more difficult than it is, because the server expects domain names in a hashed directory. (You create the hash with the sheerdnshash utility.) I did it my way:

    sdir() {
            dir="/var/spool/sheerdns/`sheerdnshash ${domain}`/${domain}"
            test -d $dir || mkdir -p $dir
            echo $value > ${dir}/${qtype}
    sdir cc NS
    sdir A 
    sdir cn NS
    sdir info NS
    sdir ws NS

That sets up a name server called on and delegates the gTLDs to that name server. The other changes to sheerdns meant adding a function to grab the DNS query and verify that against the CDB database. Verification of the queried domain against the CDB database is very fast. If it isn’t contained in that database, I do nothing. But if it is, I insert a record containing the DNS client’s IP address, a timestamp, the query and the query type into a MySQL database, and make its content available via an RSS feed.

In essence I

  • Set up the honeypot DNS server with logging, etc..
  • Delegated from our internal root DNS servers to this honeypot.

As the organization has its own root name servers, I can afford to delegate, but I don’t want to break anything by messing with the gTLD we use. All in all, that leaves the nice and juicy ones such as biz, cc, cn, info, and ws – close on 80,000 domain names in the CDB database.

It is unfortunate, that I can’t rely on the logged IP address to be the address of the conficker client PC. Due to the nature of DNS, it will usually be the address of the caching server via which Conficker queried the domain, but at least we’ll get an indication as to where to start looking (i.e. in which log file) when an alarm is triggered.

Software, DNS, conficker, virus, and honeypot :: 21 Sep 2009 :: e-mail