Hacking Linux Exposed





previous article
next article
Running custom DNS queries - stealthily managing iptables rules remotely, Part 3
By Bri Hatch.

Summary: Now that we have our DNS sniffer running, we need to send it commands.

We're on the home stretch now. The thread that began five articles ago is concluded this week. Forgot what we were trying to do in the first place? Let's recap:

  • My friend Dan started working at place that had never heard of Linux.
  • They refused to let him have a Linux machine unless it had a firewall blocking all inbound access.
  • We created a very simple 10 minute host firewall that blocks everything inbound, but allows everything outbound.
  • Dan really wanted to be able to SSH to his machine on demand.
  • We created a new chain in our Netfilter setup called allow_in. Nothing's in it currently.
  • We created a perl script, watch_dns, to use Net::Pcap to sniff the network for DNS packets and print them to STDOUT.
  • We created a master perl script handle_remote_dns_commands that ran our Net::Pcap sniffer and read the results and created new entries in the allow_in chain to allow in access from the sending machine for a short window of time.
The only thing that's left in our procedure is how exactly we can create these fake DNS requests on various machines.

We need to send DNS queries to our machine with a hostname that matches one of the %mapping hash keys in order to trigger the commands. Assuming our key is openssh, we can use any of the following commands, depending on what software you have installed and what operating system you're running:

  # Some or all of these will work on Linux, Mac OS X, and
  # other Unix-like systems.
  # These will wait a long time if you don't hit ctrl-c since
  # our sniffer never sends a response.
  othermachine$ host openssh. my_linux_box_ip_address
  othermachine$ dig openssh. my_linux_box_ip_address
  othermachine$ nslookup openssh. my_linux_box_ip_address
  othermachine$ dnsq a openssh. my_linux_box_ip_address

  # Or, to have them timeout in a second or two automatically
  othermachine$ host -W 1 openssh. my_linux_box_ip_address
  othermachine$ dig +time=1 openssh. my_linux_box_ip_address
  othermachine$ nslookup -timeout=1 openssh. my_linux_box_ip_address

  # If you're on a Windows NT/2000/etc machine, use the following
  windows> nslookup openssh. my_linux_box_ip_address

  # If you're on a Windows 95/98/etc machine,
  # or Mac OS <=9.x you're out of luck.
  # Suggestions welcome...

  # Once you've done any of the above, the port should
  # be open for you, so it's time to SSH in.
  othermachine$ ssh my_linux_box

You'll need to supply the IP address or hostname of your Linux machine to the lookup command to make sure that the packet goes here directly, since the command hostnames (e.g. 'openssh') you use will not actually resolve.

Also, note that I couldn't figure out what program you'd use on a default Windows 95/98/etc machine or old-style Mac OS. I'm sure there must be something available, but I couldn't find it If anyone has a hint, let me know.

So the drawbacks we have are that

  1. I couldn't find a Windows 95/98/etc command that we could use to send the DNS packet
  2. These commands take a lot of typing, and you need to manually provide your linux box's IP address/hostname.

Here's a trick to save you some typing. If you control an authoritative domain server, say 'example.net', you can cheat a bit.

Create a new subdomain of 'example.net', for example 'magic.example.net', where the NS record for 'magic.example.net' points to an A record which points to your Linux box's IP address. Thus any queries for 'anything.magic.example.net' will go to your Linux machine.

You do a DNS query of a host on this subdomain, such as 'openssh.magic.example.net', to send a DNS packet to our sniffer. Make sure that the key you use in the %mappings hash has the full host name, of course.

Now, since the DNS packet requesting openssh.magic.example.net comes from a DNS server, not the machine at which you performed the original host/dig/etc command, the rules in handle_remote_dns_commands I presented last time won't work. Modify them to open up access to the port for all machines (drop the --source SSSSSSSS/32 part).

Now instead of the large DNS query commands above, you can eliminate the need for the Linux box's IP addr/hostname from the command line.

  othermachine$ host -W 1 openssh.magic.example.net; ssh linuxbox

What's better, we don't need to use a lookup tool at all, which will help out on those machines that don't provide them. Since any attempt to look up this magical hostname will result in a DNS packet to our Linux box, we can use any tool, such as ping or even your webbrowser:

  othermachine$ ping openssh.magic.example.net
  othermachine$ telnet openssh.magic.example.net
  othermachine$ lynx http://openssh.magic.example.net
  (hit ctrl-c)

  othermachine$ ssh linuxbox

There you have it - a funky hackish way to have a inbound-restricting firewall, yet dynamically open ports using tools that should be available to you on any random computer in front of which you may unfortunately find yourself.


Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He loves to create functionality from horrible bastardizations of existing protocols. Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2003

This is the August 25, 2003 issue of the Linux Security: Tips, Tricks, and Hackery newsletter. If you wish to subscribe, visit http://lists.onsight.com/ or send email to Linux_Security-request@lists.onsight.com.

previous article
next article