All posts in one long list


DNS zone transfer using Python

It is important to understand some key terms regarding Domain Name System(DNS) before trying to understand DNS zone transfer.

Zone

  • Think of zone as a “domain”: a collection of hostnames/IP pairs all managed together.
  • Sub-domains are sometimes part of the main zone, sometimes they are a separate zone.

DNS zone

Nameserver

  • This is server software that answers DNS questions.
  • Sometimes a nameserver knows the answer directly (if it's “authoritative” for the zone), other times it has to go out to the internet and ask around to find the answer (if it's a recursive nameserver).
  • There is wide variety of software that performs this service: BIND, PowerDNS etc.

Authoritative Nameserver

  • For every zone, somebody has to maintain a file of the hostnames and IP address associations. This is generally an administrative function performed by a human, and in most cases one machine has this file. It's the zone master.
  • Zones with multiple public nameservers make administrative arrangements to transfer the zone data automatically to additional slave nameservers, all of which are authoritative as far as the outside world is concerned.

More info on DNS protocol:
An Illustrated Guide to the Kaminsky DNS Vulnerability

What is DNS zone transfer?

DNS zone transfer itself is not an attack, zone transfer is a type of DNS transaction where a DNS server passes a copy of part of it's database(zone file) to another DNS server. It is a mechanism available to replicate/update DNS databases across a set of DNS servers.

DNS zone transfer is always initiated by client/slave by inducing DNS query type AXFR. Zone transfers may be performed using two methods, full AXFR and incremental IXFR.

A zone transfer uses the TCP for transport with the notion of client–server transaction. The client requesting a zone transfer may be a slave server, requesting data from a master server. The portion of the database that is replicated is a zone.

zone transfer

More info on DNS zone transfer:
DNS zone trasfer - wikipedia
RFC 5936 - DNS Zone Transfer Protocol (AXFR)

Zone transfer - security implications

The data contained in a DNS zone may be sensitive from a security aspect(details such as name Servers, host names, MX records, CNAME records, glue records (delegation for child Domains), zone serial number, Time To Live etc.

From an attacker perspective, a zone file contains treasure trove of information regarding the target network. DNS zone may reveal a lot of topological information about internal network.

Having list of all the sub-domains that are part of a domain will make work of a vulnerability hunter easy.

Zone transfer attack

In a zone transfer attack, an attacker acts like a slave server and requests the master for a copy of the zone records. If the DNS server responds with requested records, your attack is successful.

Although most DNS servers these days deny zone transfers made by unauthorized/external clients, it's not hard to find vulnerable DNS servers esp. DNS servers maintained by organizations themselves as part of the internal networks.

To perform a zone transfer you need the following details:

  • A domain that you want to gather information about.
  • A zone master/primary DNS server that holds the zone information for a domain.
The legality of performing zone transfer on domains you don\'t own is uncertain and is out right illegal in some jurisdictions.
Perform zone transfers at your own risk. Obtain permission before performing zone transfer to play safe.

If you want to practice with out getting into trouble, there is a deliberately vulnerable nameserver out there for the exact purpose:
ZoneTransfer.me
Nameserver: nsztm1.digi.ninja
Domain: zonetransfer.me

Zone transfer attack using dig
  • dig is a very handy DNS utility available on most linux machines.
  • Let's perform a simple zone transfer using dig utility.
  • Let's say we want to find the sub-domains of iitk.ac.in, we need to find the nameservers for a target domain(NS records).
verax@untamed $ dig +nocmd +nocomments NS iitk.ac.in
;iitk.ac.in.			IN	NS
iitk.ac.in.		43200	IN	NS	proxy.iitk.ac.in.
iitk.ac.in.		43200	IN	NS	ns1.iitk.ac.in.
iitk.ac.in.		43200	IN	NS	ns2.iitk.ac.in.
  • Let's initiate a zone transfer with the nameserver ns1.iitk.ac.in., for domain iitk.ac.in. As a result of the query we retrived 166 records, with careful analysis it's trivial to map the internal network. Another interesting note is that SOA record is retrived before initiating a zone transfer.
verax@untamed ~/$ dig +nocmd +nocomments AXFR @ns1.iitk.ac.in. iitk.ac.in
iitk.ac.in.		43200	IN	SOA	ns1.iitk.ac.in. root.ns1.iitk.ac.in. 201609222 10800 3600 1209600 43200
iitk.ac.in.		43200	IN	NS	ns1.iitk.ac.in.
iitk.ac.in.		43200	IN	NS	ns2.iitk.ac.in.
iitk.ac.in.		43200	IN	NS	proxy.iitk.ac.in.
home.iitk.ac.in.	43200	IN	A	202.3.77.174
m3cloud.iitk.ac.in.	43200	IN	A	103.246.106.161
mail.iitk.ac.in.	43200	IN	A	202.3.77.162
[... snipped ...]
mail4.iitk.ac.in.	43200	IN	A	202.3.77.189
webmail.iitk.ac.in.	43200	IN	A	202.3.77.185
www.webmap.iitk.ac.in.	43200	IN	A	202.3.77.74
wiki.iitk.ac.in.	43200	IN	A	103.246.106.116
www.iitk.ac.in.		43200	IN	A	202.3.77.184
iitk.ac.in.		43200	IN	SOA	ns1.iitk.ac.in. root.ns1.iitk.ac.in. 201609222 10800 3600 1209600 43200
;; Query time: 219 msec
;; SERVER: 202.3.77.171#53(202.3.77.171)
;; WHEN: Wed Oct 12 18:38:01 IST 2016
;; XFR size: 166 records (messages 1, bytes 3769)
Zone transfer attack using Python
  • Python does'nt have an inbuit DNS module. We'll use dnspython, a third party module/toolkit for DNS operations in Python.
  • Let's find out the nameservers for the domain iitk.ac.in using dnspython. I'll go ahead and retrive all the common DNS records for the domain.
    • dns.resolver is the client part of dnspython.
    • dns.resolver.query is how you make a query. provide domain name, query type as arguments.
import argparse, dns.resolver

def lookup(name):
    print name
    for qtype in 'A', 'AAAA', 'MX', 'TXT', 'SOA':
        answer = dns.resolver.query(name,qtype, raise_on_no_answer=False)
        if answer.rrset is not None:
            print(answer.rrset)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Resolve a name using DNS')
    parser.add_argument('name', help='name that you want to look up in DNS')
    lookup(parser.parse_args().name)
verax@untamed ~/dns_scripts $ python dns_queries.py iitk.ac.in
iitk.ac.in
iitk.ac.in. 37799 IN A 202.3.77.184
iitk.ac.in. 43180 IN MX 10 mail0.iitk.ac.in.
iitk.ac.in. 43180 IN MX 10 mail1.iitk.ac.in.
iitk.ac.in. 43200 IN NS proxy.iitk.ac.in.
iitk.ac.in. 43200 IN NS ns2.iitk.ac.in.
iitk.ac.in. 43200 IN NS ns1.iitk.ac.in.
iitk.ac.in. 43181 IN SOA ns1.iitk.ac.in. root.ns1.iitk.ac.in. 201609222 10800 3600 1209600 43200
  • Let’s initiate a zone transfer with the nameserver ns1.iitk.ac.in., for domain iitk.ac.in using dnspython.
    • dns.querysupports XFR query i.e. zone transfer.
    • dns.zone helps use manage the zone details
    • we are trying to extract only the sub-domain details from the zone details.
import dns.query
import dns.zone

z = dns.zone.from_xfr(dns.query.xfr('ns1.iitk.ac.in', 'iitk.ac.in'))
names = z.nodes.keys()
names.sort()
for n in names:
    print z[n].to_text(n)
  • In this example, it's very clear that first the SOA records are transferred.
  • All the nameservers, mail servers are represented with their hostnames, rather than FQDN.
verax@untamed ~ $ python zone_transfer.py 
@ 43200 IN SOA ns1 root.ns1 201609222 10800 3600 1209600 43200
@ 43200 IN NS ns1
@ 43200 IN NS ns2
@ 43200 IN NS proxy
@ 43200 IN A 202.3.77.184
@ 43200 IN MX 10 mail0
@ 43200 IN MX 10 mail1
agrotagger 43200 IN CNAME m3cloud
all-iits 43200 IN A 202.3.77.160
alumni 43200 IN A 202.3.77.176
antaragni 43200 IN CNAME students
appsgate 43200 IN A 202.3.77.165
aqi 43200 IN A 103.246.106.117
[... snipped ...]
DO NOT assume that all the records that are part of zone transfer must be part of the organization/domain that you are targeting.
There is nothing stopping the administrator from adding additional records from anywhere on the Internet to this zone.
Be cautious, if you are pentesting, check all the records using DNS-reverse resolution, traceroute and whois to determine the ownership.
Securing DNS zone transfer

The default behavior for DNS zone transfer permits any host to request and receive a full zone transfer for a Domain. The consequences of revealing zone details to any potential attacker could be devastating.

Two methods to secure zone transfers are BIND DNS access control list and DNS Transaction Signatures (TSIG). I’ll not delve into the details of securing DNS zone transfer in this post but readers can explore on their own.

More about securing zone transfer:
Why securing zone transfer is necessary? [PDF]


References

DNS zone trasfer - wikipedia
dnspython docs - examples
An Illustrated Guide to the Kaminsky DNS Vulnerability
ZoneTransfer.me
Why securing zone transfer is necessary? [PDF]
Image courtesy: Name Servers and Zones
Image courtesy: DNS & BIND - Chap 10

VirtualBox's little secret: command-line

We often run into features on some software that are little known but are very handy. VirtualBox has one such feature, the command-line.

VBoxManage is the command-line interface to VirtualBox. With it, you can completely control VirtualBox from the command line of your host operating system. VBoxManage supports all the features that the GUI gives you access to, but it supports a lot more than that. It exposes really all the features of the virtualization engine, even those that cannot (yet) be accessed from the GUI.

Fortunately, VBoxManage has extensive documentation which makes life easy. It covers every available option that there is in VBoxManage. If you ever find yourself using VBoxManage, the docs are your go-to reference.

VBoxManage documentation

Rather than going over what's already covered in documentation extensively and making this article an yet-another tutorial on VBoxManage, I'll go over a problem that I solved using VirtualBox command-line recently.

The problem at hand

I started coducting workshops at an open security community. The thing about running workshops at open communties is that it is hard to predict the kinda of software/hardware people walk-in with. You'll have to be conscious about software dependencies and hardware requirements.

We planned to conduct a workshop on network reconnisance. We faced a bunch of challenges as part of the lab setup:

  • We wanted to run couple of full blown VMs as part of labs to do remote OS detection using differences in kernel implementations so using containers is not an option.
  • We wanted to run “React OS” to avoid the messy Windows licensing terms. Running React OS means, using Vagrant, containers is not an easy option.
  • Audience carry laptops with various host operating systems. No native SSH client on Windows is available, so Vagrant is again not an option.
  • We wanted the lab setup to be as automated as possible rather than making audience click through every step, simple VirtualBox GUI won't cut it.
VBoxManage our saviour

At this point we were not left with many options and had to turn to good old VirtualBox, that's when I gave a serious thought to VirtualBox command-line.

  • VirtualBox can run almost every *nix machines and also React OS.
  • VBoxManage supports full automation of lab setup(Infact Vagrant uses VBoxManage in the backend)
  • VBoxManage is available on all platforms that has VirtualBox installation.
Steps towards solution

Creating the lab setup
We created a bunch of virtual machines. Few of them act as victims and one VM acts as attacker in the labs. We exported the VMs in OVA format from our Linux machine using VirtualBox GUI. At this point we had a directory with all lab VMs in OVA format.

Importing lab setup

  • A bash script for *nix and batch file for Windows were created to automate the lab setup importing using VBoxManage.
  • The problem with windows is that VBoxManage is available as a command only from VirtualBox installation directory, so we had to tweak the batch file.

  • The following script imports all the required OVA files and lists all the virtual machines available on the host to check if the OVAs are imported sucessfully.
#!/usr/bin/env bash
VBoxManage import "victim1.ova"
VBoxManage import "victim2.ova"
VBoxManage import "attacker.ova"
printf "\n\nList of all the VMs\n------------------------\n"
VBoxManage list vms
PATH=%PATH%;C:\Program Files\Oracle\VirtualBox
vboxmanage import "victim1.ova"
vboxmanage import "victim2.ova"
vboxmanage import "attacker.ova"
echo. && echo 'List of all VMs' && echo. && echo '-------------------------'
vboxmanage list vms
cmd \k

Starting the labs

  • A bash script for *nix and batch file for Windows were created to run the labs.
  • We wanted to run the victims in the background and only display the attacker. VirtualBox headless mode runs a VM in the background.
  • We exported OVAs from a Linux machine and the VirtualBox host-only network adapter name on windows is not consistent with Linux so we had to use vboxmanage modifyvm to modify the adapter name.
  • The following script run all the victims in background and displays attacker VM. This script lists all running VMs to check if everything is running.
#!/usr/bin/env bash

vboxmanage startvm "victim1" --type headless
vboxmanage startvm "victim2" --type headless
vboxmanage startvm "attacker"

printf "\n\nList of all the VMs running\n------------------------------\n"

vboxmanage list runningvms
PATH=%PATH%;C:\Program Files\Oracle\VirtualBox
vboxmanage modifyvm "victim1" --nic1 hostonly --hostonlyadapter1 "VirtualBox Host-Only Ethernet Adapter"
vboxmanage modifyvm "victim2" --nic1 hostonly --hostonlyadapter1 "VirtualBox Host-Only Ethernet Adapter"
vboxmanage modifyvm "attacker" --nic1 hostonly --hostonlyadapter1 "VirtualBox Host-Only Ethernet Adapter"
vboxmanage startvm "victim1" --type headless
vboxmanage startvm "victim2" --type headless
vboxmanage startvm "attacker"
echo. && echo 'List of all the running VMs' && echo. && echo '-------------------------'
vboxmanage list runningvms
cmd \k

Stopping labs

  • A bash script for *nix and batch file for Windows were created to gracefully shutdown the labs.
  • vboxmanage controlvm has an option to poweroff running VMs.
  • The following script shuts down all the lab VMs running and lists current running VMs to check if everything shutdown properly.
#!/usr/bin/env bash

vboxmanage controlvm "victim1" poweroff
vboxmanage controlvm "victim2" poweroff
vboxmanage controlvm "attacker" poweroff

printf "\n\nList of all the VMs running\n------------------------------\n"

vboxmanage list runningvms
PATH=%PATH%;C:\Program Files\Oracle\VirtualBox
vboxmanage controlvm "victim1" poweroff
vboxmanage controlvm "victim2" poweroff
vboxmanage controlvm "attacker" poweroff
echo. && echo 'List of all the running VMs' && echo. && echo '-------------------------'
vboxmanage list runningvms
cmd \k
Conclusion

VBoxManage is a pretty neat and powerful interface provided by VirtualBox. It comes handy when trying to automate your virtual environments especially when trying to distribute your environments. This article looks into one such solution to a problem, this isn't even tip of the iceberg, find a problem/challenge, read through VBoxManage docs and have fun!

The art of packet crafting with Scapy

License: Creative Commons Attribution-Share Alike 4.0 International License for notes
               Apache 2.0 License for code

Class Pre-requisites: Python programming: Foundations or equivalent.

Lab setup: will be updated after first delivery

Recommended Class Duration: 1-2 days

Class Notes: disruptivelabs.in/art-of-packet-crafting-with-scapy

Class videos: To-be-developed.

Network programming in Python

License: Creative Commons Attribution-Share Alike 4.0 International License for notes
               Apache 2.0 License for code

Class Pre-requisites: Python programming: Foundations or equivalent.

Lab setup: Network playground by Brandon Rhodes

Recommended Class Duration: 1-2 days

Class Notes: disruptivelabs.in/python-network-programming

Class videos: To-be-developed.

Python programming: Foundations

License: Creative Commons Attribution-Share Alike 4.0 International License for notes
               Apache 2.0 License for code

Class Pre-requisites: Familiarity with some programming language(Not necessarily Python).

Lab setup: Any machine with Python 2.7.x installed is enough to practice.

Recommended Class Duration: 1-2 days

Class Notes: disruptivelabs.in/python-foundations/

Class videos: To-be-developed.