Lab 1.4: Recon-ng for DNS Analysis

Objectives

  • To use the Recon-ng tool to retrieve and analyze DNS records
  • To iterate through an IP address block, sending DNS Reverse Record (PTR) lookups for each address to find potential target machines
  • To query for a series of domain names associated with antivirus update servers so that the penetration tester can determine which antivirus tools are likely in use by a target organization for more focus on AV evasion tactics

Table of Contents

 

Lab Setup

In this lab, you’ll gain familiarity with the user interface of Recon-ng and use it to gather useful information from the target organization’s DNS infrastructure.

In particular, you’ll run a Recon-ng module called "reverse-resolve", which takes a netblock of IP addresses and sends PTR (reverse record) lookups to a DNS server to determine which of those IP addresses resolve into names. That’s a useful feature for a penetration tester because it can help you identify hosts that could be included in your scope, provided that these hosts have PTR records in their DNS. Many organizations provide PTR records for important hosts on the internet, so this technique can be helpful during the reconnaissance phase.

Next, you’ll use a Recon-ng module called "cache-snoop" that performs DNS cache snooping against a target DNS server. This module looks for cached DNS records that are associated with DNS records from signature update sites of a couple dozen antivirus firms. If the target organization relies on any of those AV products, it likely will perform regular updates of its AV signatures, which will leave residual records associated with the AV company cached in the organization’s DNS servers. By identifying those cached entries, a penetration tester can determine which AV products the target organization is using, a helpful piece of information useful in evading the organization’s AV product.

For this lab, you need to be connected to the 560 target network environment. Make sure you can ping 10.10.10.60 (where there is a DNS server) before you begin the lab:

$ ping 10.10.10.60

If your ping doesn’t work, that means your Linux guest machine isn’t properly connected to the 560 target network. Consult the network configuration section earlier in this book or reach out to an instructor or TA for assistance.

 

Step-by-Step Instructions

1. Launch Recon-ng

Start the lab by running recon-ng root privileges using sudo:

$ sudo recon-ng --no-check

On the screen, you should see ASCII art announcing RECON-NG. You’ll also see an inventory of the types of modules, including Recon, Reporting, Import, Exploitation, and Discovery.

Note: You may see error messages mentioning key not set. You can safely ignore those messages.

Launching Recon-ng

2. Explore the Interface

To become familiar with Recon-ng’s user interface, let’s explore its help feature. Below you can see all the commands supported by Recon-ng.

[recon-ng][default] > help

Commands (type [help|?] <topic>):
---------------------------------
add             Adds records to the database
back            Exits the current context
delete          Deletes records from the database
exit            Exits the framework
help            Displays this menu
keys            Manages framework API keys
load            Loads specified module
pdb             Starts a Python Debugger session
query           Queries the database
record          Records commands to a resource file
reload          Reloads all modules
resource        Executes commands from a resource file
search          Searches available modules
set             Sets module options
shell           Executes shell commands
show            Shows various framework items
snapshots       Manages workspace snapshots
spool           Spools output to a file
unset           Unsets module options
use             Loads specified module
workspaces      Manages workspaces

3. The Show Command

One of the most important commands is the show command because it lets you look at Recon-ng’s options, configuration, and variable settings. Let’s run show by itself to see the various items we can explore using show:

[recon-ng][default] > show
Shows various framework items

Usage: show [banner|companies|contacts|credentials|dashboard|domains|
hosts|keys|leaks|locations|modules|netblocks|options|ports|profiles|
pushpins|repositories|schema|vulnerabilities|workspaces]

Here we can see that we can show banner to get version information. We can likewise run show followed by an item type in Recon-ng’s database, such as show hosts or show domains. We’ll do that later in the lab.

4. Show Options

To see the variables set in Recon-ng, run show options:

[recon-ng][default] > show options
Name        Current Value  Required  Description
`----------  -------------  --------  -----------`
NAMESERVER  8.8.8.8        yes       nameserver for DNS interrogation
PROXY                      no        proxy server (address:port)
THREADS     10             yes       number of threads (where applicable)
TIMEOUT     10             yes       socket timeout (seconds)
USER-AGENT  Recon-ng/v4    yes       user-agent string
VERBOSITY   1              yes       verbosity level (0 = minimal, 1 = verbose, 2 = debug)

Here you can see that by default, Recon-ng resolves information using the 8.8.8.8 name server provided by Google. We’ll change that shortly to our target organization’s DNS server.

Before we do that, though, let’s take a quick look at Recon-ng’s database structure so you can see the tables and their columns where Recon-ng will store data. Type the command below:

[recon-ng][default] > show schema

Your output will look similar to this:

[recon-ng][default] > show schema

+---------------+
|    domains    |
+---------------+
| domain | TEXT |
| module | TEXT |
+---------------+


+--------------------+
|     companies      |
+--------------------+
| company     | TEXT |
| description | TEXT |
| module      | TEXT |
+--------------------+

... truncated for brevity ...

Note that there is a domains table, a hosts table, and several other tables that are automatically populated as we run various Recon-ng modules.

5. External Commands

The Recon-ng prompt handles a variety of Recon-ng commands. But when it receives a command it doesn’t recognize, Recon-ng passes that command to the underlying operating system shell for execution. This is handy because it means we can run general-purpose commands at the Recon-ng prompt. Let’s try it by running a ping command to ping 10.10.10.60 four times (-c 4 for a count of four):

[recon-ng][default] > ping -c 4 10.10.10.60
[*] Command: ping -c 4 10.10.10.60
PING 10.10.10.60 (10.10.10.60) 56(84) bytes of data.
64 bytes from 10.10.10.60: icmp_seq=1 ttl=64 time=0.705 ms
64 bytes from 10.10.10.60: icmp_seq=2 ttl=64 time=0.341 ms
64 bytes from 10.10.10.60: icmp_seq=3 ttl=64 time=0.344 ms
64 bytes from 10.10.10.60: icmp_seq=4 ttl=64 time=0.475 ms

--- 10.10.10.60 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.341/0.466/0.705/0.148 ms

Your ping should work, and you should see its output. It’s important to note that Recon-ng does NOT have a ping command. Instead, Recon-ng is simply taking our ping command and handing it to the underlying shell for execution.

To start performing recon against the target organization’s DNS server, let’s configure Recon-ng to use that nameserver, as follows:

[recon-ng][default] > set NAMESERVER 10.10.10.60
NAMESERVER => 10.10.10.60

Now when we run show options, we can see that the original 8.8.8.8 nameserver has been altered to 10.10.10.60.

[recon-ng][default] > show options

Name        Current Value  Required  Description
`----------  -------------  --------  -----------`
NAMESERVER  10.10.10.60    yes       nameserver for DNS interrogation
PROXY                      no        proxy server (address:port)
THREADS     10             yes       number of threads (where applicable)
TIMEOUT     10             yes       socket timeout (seconds)
USER-AGENT  Recon-ng/v4    yes       user-agent string
VERBOSITY   1              yes       verbosity level (0 = minimal, 1 = verbose, 2 = debug)

6. Modules

Let’s now explore the various modules Recon-ng has:

[recon-ng][default] > show modules

  Discovery
  ---------
    discovery/info_disclosure/cache_snoop
    discovery/info_disclosure/interesting_files

  Exploitation
  ------------
    exploitation/injection/command_injector
    exploitation/injection/xpath_bruter

  Import
  ------
    import/csv_file
    import/list

  Recon
  -----
    recon/companies-contacts/bing_linkedin_cache
    recon/companies-contacts/jigsaw/point_usage
    recon/companies-contacts/jigsaw/purchase_contact
    recon/companies-contacts/jigsaw/search_contacts
    recon/companies-multi/github_miner
    recon/companies-multi/whois_miner
    recon/contacts-contacts/mailtester
    ... truncated for brevity ...

Here you’ll see different groups of modules, including Discovery, Exploitation, Import, Recon, and more. Under each module group, you can see the individual modules, totaling several dozen.

Often, a penetration tester has a sense of the type of module he would like to use but doesn’t know the full module name or its path to access it in Recon-ng. If that’s the case, we can use the search command to find specific modules based on strings in the module’s name or path.

Suppose, for example, we wanted to find modules that would resolve names (via either a forward or a reverse DNS lookup). We could simply run search resolve. Do that now:

[recon-ng][default] > search resolve

Here we can see several modules associated with resolving names. Notice that their paths all start with recon, as they are in the recon module group.

[recon-ng][default] > search resolve
[*] Searching for 'resolve'...

  Recon
  -----
    recon/hosts-hosts/resolve
    recon/hosts-hosts/reverse_resolve
    recon/netblocks-hosts/reverse_resolve

8. The reverse_resolve Module

For this lab, we would like to iterate through a given target netblock (10.10.10.0/24) to see which host IP addresses have an associated PTR record. This is a useful way to find hosts and explore our scope in a penetration test. Of course, not every host on the internet has a PTR record, but many DMZ systems do, and we can use this module to help identify them.

To achieve this, we’ll use the recon/netblocks-hosts/reverse_resolve module. There is also a recon/hosts-hosts/reverse_resolve module, which takes as its input individual IP addresses. We’ll use the netblocks module, though, as we’ve been given the full 10.10.10 network as our target scope.

Let’s select that recon/netblocks-hosts/reverse_resolve module with the use command, followed by the full path to the module:

[recon-ng][default] > use recon/netblocks-hosts/reverse_resolve

Now, to get the details of that module, we can run show info:

[recon-ng][default] > use recon/netblocks-hosts/reverse_resolve
[recon-ng][default][reverse_resolve] > show info

      Name: Reverse Resolver
      Path: modules/recon/netblocks-hosts/reverse_resolve.py
    Author: John Babio (@3vi1john)

Description:
  Conducts a reverse lookup for each of a netblock's IP addresses to
  resolve the hostname. Updates the 'hosts' table with the results.

Options:
  Name    Current Value  Required  Description
  ------  -------------  --------  -----------
  SOURCE  default        yes       source of input (see 'show info' for details)

Source Options:
  default        SELECT DISTINCT netblock FROM netblocks WHERE netblock IS NOT NULL
  <string>       string representing a single input
  <path>         path to a file containing a list of inputs
  query <sql>    database query returning one column of inputs

Here we see a brief description of the module, plus the different variables it supports. For this module, the SOURCE variable specifies where the information about our target netblock comes from. By default, Recon-ng simply looks in the netblocks table. We can specify other places, including a string that contains a single netblock or a path to a file that contains a list of netblocks, one per line.

For this lab, we’ll leave it as its default and place a netblock in the netblocks table next.

9. Add a Netblock

Let’s add a netblock to the netblocks table using the add command:

[recon-ng][default][reverse_resolve] > add netblocks 10.10.10.0/24

We can now look at the netblocks table to see our information there:

[recon-ng][default][reverse_resolve] > show netblocks

  +--------------------------------------+
  | rowid |    netblock   |    module    |
  +--------------------------------------+
  | 1     | 10.10.10.0/24 | user_defined |
  +--------------------------------------+

[*] 1 rows returned

Because we left the SOURCE for the reverse_resolve module as the default, Recon-ng will pull this information from the database to do the PTR lookups.

10. Running the Module

With our module configured, we can now run it as follows:

[recon-ng][default][reverse_resolve] > run

-------------
10.10.10.0/24
-------------
[*] 10.10.10.0 => No record found.
[*] 10.10.10.1 => No record found.
[*] 10.10.10.2 => No record found.
[*] 10.10.10.3 => No record found.
[*] 10.10.10.4 => No record found.
[*] 10.10.10.5 => No record found.
[*] 10.10.10.6 => No record found.
[*] 10.10.10.7 => No record found.
[*] 10.10.10.8 => No record found.
[*] 10.10.10.9 => No record found.
[*] [host] trinity.target.tgt (10.10.10.10)
[*] 10.10.10.11 => No record found.
[*] 10.10.10.12 => No record found.
... snipped for brevity ...
[*] 10.10.10.18 => No record found.
[*] 10.10.10.19 => No record found.
[*] [host] morpheus.target.tgt (10.10.10.20)
[*] 10.10.10.21 => No record found.
... snipped for brevity ...
[*] 10.10.10.49 => No record found.
[*] [host] neo.target.tgt (10.10.10.50)
[*] 10.10.10.51 => No record found.
[*] 10.10.10.52 => No record found.
... snipped for brevity ...
[*] 10.10.10.59 => No record found.
[*] [host] smith.target.tgt (10.10.10.60)
[*] 10.10.10.61 => No record found.
... snipped for brevity ...
[*] 10.10.10.254 => No record found.
[*] 10.10.10.255 => No record found.

-------
SUMMARY
-------
[*] 4 total (4 new) hosts found.

In the output, we can see it sending a PTR query for each IP address in 10.10.10.0/24, looking for a response. For most of the IP addresses, no record will be found. But for 10.10.10.10, 10.10.10.20, 10.10.10.50, and 10.10.10.60, it should get a PTR record response, displaying that information on the screen.

When the module is finished running, it will show us how many hosts it found. It should find four.

11. Examining the Results

In addition to scrolling back on the screen to see what Recon-ng found, we can also look at the hosts table because the reverse_resolve module automatically populates it. Let’s look at our newly discovered hosts:

[recon-ng][default][reverse_resolve] > show hosts

  +-------------------------------------------------------------------------------------------------------+
  | rowid |         host        |  ip_address | region | country | latitude | longitude |      module     |
  +-------------------------------------------------------------------------------------------------------+
  | 1     | trinity.target.tgt  | 10.10.10.10 |        |         |          |           | reverse_resolve |
  | 2     | morpheus.target.tgt | 10.10.10.20 |        |         |          |           | reverse_resolve |
  | 3     | neo.target.tgt      | 10.10.10.50 |        |         |          |           | reverse_resolve |
  | 4     | smith.target.tgt    | 10.10.10.60 |        |         |          |           | reverse_resolve |
  +-------------------------------------------------------------------------------------------------------+

[*] 4 rows returned

Note that we have a domain name and IP address for each of the hosts based on the returned PTR record. The hostnames are all associated with the target.tgt domain (which we can check against our target scope) and include names such as trinity, morpheus, neo, and smith, a naming scheme based on a movie.

12. The cache_snoop Module

Now that we’ve gathered some hosts associated with the target environment, let’s use another Recon-ng module to determine the most likely antivirus tool or tools the target organization is using. We can do that with the cache_snoop module in Recon-ng’s discovery group.

We can back out of our current module to the general Recon-ng prompt using the back command:

[recon-ng][default][reverse_resolve] > back
[recon-ng][default] >

We’ll now use the discovery/info_disclosure/cache_snoop module:

[recon-ng][default] > use discovery/info_disclosure/cache_snoop
[recon-ng][default][cache_snoop] >

Let’s look at the options for this module:

[recon-ng][default][cache_snoop] > show options

  Name        Current Value                             Required  Description
  ----------  -------------                             --------  -----------
  DOMAINS     /opt/recon-ng-v4.9.3/data/av_domains.lst  yes       file containing the list of domains to snoop for
  NAMESERVER                                            yes       IP address of authoritative nameserver

Here we see that this module needs a NAMESERVER. (Unfortunately, the module doesn’t automatically populate the NAMESERVER value with the one configured overall for Recon-ng.) This module also needs a list of names that it should look for in the target DNS server’s cache. By default, it searches for names stored in the av_domains.lst file that comes with Recon-ng. Let’s look at the contents of that file:

[recon-ng][default][cache_snoop] > cat /opt/recon-ng-v4.9.3/data/av_domains.lst
[*] Command: cat /opt/recon-ng-v4.9.3/data/av_domains.lst
www.es-latest-3.sophos.com/update
www.es-web.sophos.com
www.es-web.sophos.com.edgesuite.net
www.es-web-2.sophos.com
www.es-web-2.sophos.com.edgesuite.net
www.dnl-01.geo.kaspersky.com
www.downloads2.kaspersky-labs.com
www.liveupdate.symantecliveupdate.com
www.liveupdate.symantec.com
www.update.symantec.com
... truncated for brevity ...

Here we can see the names of update servers for numerous different AV product firms. You could expand this list or even create your own in future penetration tests, based on different items you’d like to snoop for in a target organization’s DNS cache. For this lab, we’ll keep this default list, which is quite good.

13. Running cache_snoop

We now set NAMESERVER. (Remember that this module does NOT use the name server configured overall for Recon-ng, so we must set it now in the context of the cache_snoop module.)

[recon-ng][default][cache_snoop] > set NAMESERVER 10.10.10.60
NAMESERVER => 10.10.10.60

With all our settings now in place, we can run the module:

[recon-ng][default][cache_snoop] > run
[*] www.es-latest-3.sophos.com/update => Not Found.
[*] www.es-web.sophos.com => Not Found.
[*] www.es-web.sophos.com.edgesuite.net => Not Found.
[*] www.es-web-2.sophos.com => Not Found.
[*] www.es-web-2.sophos.com.edgesuite.net => Not Found.
[*] www.dnl-01.geo.kaspersky.com => Not Found.
[*] www.downloads2.kaspersky-labs.com => Not Found.
[*] www.liveupdate.symantecliveupdate.com => Not Found.
[*] www.liveupdate.symantec.com => Not Found.
[*] www.update.symantec.com => Not Found.
[*] www.update.nai.com => Not Found.
[*] www.download797.avast.com => Not Found.
[*] www.guru.avg.com => Not Found.
[*] www.osce8-p.activeupdate.trendmicro.com => Not Found.
[*] www.forefrontdl.microsoft.com => Not Found.
[*] es-latest-3.sophos.com/update => Not Found.
[*] es-web.sophos.com => Not Found.
[*] es-web.sophos.com.edgesuite.net => Not Found.
[*] es-web-2.sophos.com => Not Found.
[*] es-web-2.sophos.com.edgesuite.net => Not Found.
[*] dnl-01.geo.kaspersky.com => Not Found.
[*] downloads2.kaspersky-labs.com => Not Found.
[*] liveupdate.symantecliveupdate.com => Not Found.
[*] liveupdate.symantec.com => Not Found.
[*] update.symantec.com => Snooped!
[*] update.nai.com => Not Found.
[*] download797.avast.com => Not Found.
[*] guru.avg.com => Snooped!
[*] osce8-p.activeupdate.trendmicro.com => Not Found.
[*] forefrontdl.microsoft.com => Not Found.

As the module runs, look carefully at its output. You’ll note that it says "Not Found" for the majority of the domain names. But for two of them (update.symantec.com and guru.avg.com), it does show that it "Snooped!" a name (that is, it found the name in the target DNS server cache). Look specifically at the lines below.

[*] update.symantec.com => Snooped!
[*] guru.avg.com => Snooped!

Thus, it is likely that the target organization is utilizing Symantec and/or AVG as its antivirus product, given that the target’s DNS server was used to resolve those names recently (and the DNS Time to Live for those records has not expired, so it remains in the cache). Of course, once that TTL expires, the cached entries will be dropped.

This information about the target’s AV vendor is tremendously useful in our penetration test, especially if we are going to create any malware for the target organization to send via spear phishing or other means.

14. Wrapping Up

To finish the lab, we can exit the Recon-ng tool:

[recon-ng][default][cache_snoop] > exit
sec560@slingshot:~$

We should also clean up the Recon-ng configuration file and database, which are automatically created in our home directory (~):

sec560@slingshot:~$ sudo rm -rf .recon-ng/

This will remove all the information in the database, as well as the custom name server configuration we set for Recon-ng.

 

Conclusion

In this lab, we have used Recon-ng to get familiar with its user interface and look at its database. More importantly, though, we ran Recon-ng to pull some highly useful information about the target organization.

Particularly, we iterated through a target netblock given to us in our scope to identify individual target host IP addresses. This information will be useful as we move into the Scanning phase of our penetration test to be covered later in this course. And, perhaps even more important, we determined the likely antivirus products in use by the target organization. That information will be extremely useful as we move into the Exploitation phase of the penetration test.