On the 6th, I posted hashes of a file, “the_dirt.txt”, to titillate my readership while I was busy shopping the information contained within it to TippingPoint and iDefense (in case I had a shot at monetizing it ). Here are the contents of “the_dirt.txt”:
The idea here is that Ruby implements its own threading model that’s independent of the operating system’s implementation of threads. While you can have several Ruby threads rolling at once, it’ll all show up as one process to the OS. A nice effect of this is that Ruby threads can work the same way on multiple operating systems that may not have the same native threading model.
One problem with this, is that if Ruby has to ask the operating system to do something, and that function is blocking (the thread cannot continue until the function returns), all of the Ruby threads run by that process have to wait. Making an operating system call to do a DNS query will block all of the Ruby threads of a multithreaded application until the result is returned. This is sub-optimal. Ruby’s solution in this case is to carry around it’s own DNS resolver (called “Resolv”) that plays nicely with Ruby threads, since it’s written in Ruby itself. It can even be used as a drop-in replacement for normal DNS resolution simply by doing a “require ‘resolv-replace’”.
The problem with this DNS resolver is that it’s probably the worst you’ve seen since Windows 95 when it comes to random transaction IDs and source ports. I noticed this when I was working out a bug in my MITM DNS Metasploit module. Take a look at the TIDs and source ports for the first 8 requests to come out of a test script:
- TID = 0 , SOURCE = 53571
- TID = 1 , SOURCE = 53571
- TID = 2 , SOURCE = 53571
- TID = 3 , SOURCE = 53571
- TID = 4 , SOURCE = 53571
- TID = 5 , SOURCE = 53571
- TID = 6 , SOURCE = 53571
- TID = 7 , SOURCE = 53571
Anyone posting a comment pointing out the subtle pattern in these requests gets to become a charter member of the Little Kaminsky Urban Achievers.
Congrats to Keita Yamaguchi, Christian Neukirchen, sheepman, and Tanaka Akira (according to the ruby-lang.org announcement) for beating me to the punch on it :
- Multiple Vulnerabilities in Ruby (search for “DNS spoofing”)
There’s a patch now, but I’ll bet pentesters will be seeing applications vulnerable to this for quite some time.