1

Over the years, there have been some changes in how some functions and commands provide an output. Which is why, it is difficult to follow older tutorials, which sometimes do not conform with the latest revisions to software and its commands.

One such change happened whilst I was using nslookup and python to lookup ip addresses on windows, as I do not primarily own a mac or linux.

How, can we fetch, only the IP address of a 'Top Level Url' (tld) using python and nslookup, as of 2019?

SowingFiber
  • 1,194
  • 1
  • 12
  • 32
  • You mean how to resolve a hostname? TLDs themselves don't have IP addresses. Can you give examples of input and expected output? – Ulrich Eckhardt Oct 02 '19 at 17:37
  • 2
    Do not execute external command when your programming language have all the libraries needed to do the same operation. See the `dnspython` library. Which is why, regarding " there have been some changes in how some functions and commands provide an output." you should stop try to parse external commands never expected to be parsed and use proper features to get the result you need. – Patrick Mevzek Oct 03 '19 at 03:02

3 Answers3

1

I looked up on SO and found this answer

The solution provided is a good starting point. Based on the above requirements, the solution could be modified to fit the above use case.

If you use nslookup google.com in your console in windows, you will find a similar output:

Non-authoritative answer:

Server:  UnKnown
Address:  192.168.0.1

Name:    facebook.com
Addresses:  2a03:2880:f12f:183:face:b00c:0:25de
      31.13.79.35

Following the referenced solution, these two lines are the heart of our solution:

process = subprocess.Popen(["nslookup", url], stdout=subprocess.PIPE)
output = str(process.communicate()[0]).split('\\r\\n')

If you print the output in the console, you'll get a similar result to this:

["b'Server:  UnKnown", 'Address:  192.168.0.1', '', 'Name:    facebook.com', 'Addresses:  2a03:2880:f12f:183:face:b00c:0:25de', '\\t  31.13.79.35', '', "'"]

This list is enough for the above use case. Next thing to do is to find a reliable way to always get the 6th element which is "\\t 31.13.79.35"

To make things simpler, I used index slicing to get the 6th element using output[5].

I've tested this code about 10-15 times using different urls and I've gotten similar results. A better way would be to somehow detect the address by iterating through the list items in output.

Again for the above use case, using output[5] works well enough. If someone can contribute a more reliable way to detect the ip address in the list, please do so.

get_ip_address.py

import subprocess


def get_ip_address(url):
    process = subprocess.Popen(
        ["nslookup", url], stdout=subprocess.PIPE)
    output = str(process.communicate()[0]).split('\\r\\n')
    address = output[5].replace('\\t ', '')
    return address


print(get_ip_address('google.com'))

SowingFiber
  • 1,194
  • 1
  • 12
  • 32
  • 1
    Do not execute external command when your programming language have all the libraries needed to do the same operation. See the `dnspython` library. Parsing textual result of the command never designed to be parsed is brittle. – Patrick Mevzek Oct 03 '19 at 03:03
1

Do not use external tools for needs that can be done completely inside your programming language using the proper library, which can be dnspython in your case.

In [2]: import dns

In [3]: import dns.resolver

In [5]: import dns.rdataclass

In [7]: import dns.rdatatype

In [9]: ans = dns.resolver.query('www.example.com', rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN)

In [10]: print ans.rrset
www.example.com. 43193 IN A 93.184.216.34

In [12]: print ans.rrset[0]
93.184.216.34

Read the full featured documentation at http://www.dnspython.org/docs/1.16.0/ for more details, especially input and output parameters.

Two important points:

  • do not assume query will always succeed; make sure to handle its errors
  • do not assume query will necessarily gives you back records of the type you expected, you may get something completely different, so you have to check and not blindly assume.
Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
-1

You can probably save yourself some time using nmap

pip install python-nmap

Then your python script is simply:

import nmap

scan = nmap.Portscanner()

scan.scan('127.0.0.1', '21-443') # Returns scan on ports from 21-433 

If you are scanning something you want to be careful with consider using proxychains which is a tor based service using SOCKS5. You can use variations such as -O -I to identify the operating systems the IP address is using and some information as to which sockets are open or closed.

There are a lot of helpful methods such as:

>>> scan.scaninfo()
{'tcp': {'services': '22-443', 'method': 'connect'}}

>>> scan.all_hosts()
['127.0.0.1']

>>> scan['127.0.0.1'].hostname()
'localhost'

>>> scan['127.0.0.1'].state()
'up'

>>> scan['127.0.0.1'].all_protocols()
['tcp']

>>> scan['127.0.0.1']['tcp'].keys()
[80, 25, 443, 22, 111]

>>> scan['127.0.0.1'].has_tcp(22)
True

>>> scan['127.0.0.1'].has_tcp(23)
False

>>> scan['127.0.0.1']['tcp'][22]
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}

>>> scan['127.0.0.1'].tcp(22)
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}
Barb
  • 427
  • 3
  • 14
  • 1
    Using `nmap` and resolving a name to an IP address are two things completely unrelated. – Patrick Mevzek Oct 03 '19 at 03:04
  • nmap `-sn` returns all hostnames and IP addresses in its newer version. I think the OP is trying to get hostnames because TLD doesnt have an IP address – Barb Oct 03 '19 at 13:08
  • 1
    `nmap` is a tool to connect to hosts and discover which ports are open (among other things). `nslookup` is a tool that does DNS queries to, typically, map a name to an IP address. They are conceptually completely different things. – Patrick Mevzek Oct 03 '19 at 14:22
  • Nmap has a parallel reverse DNS resolution engine that is normally employed as part of an nmap scan, but can also be used independently of the scan function to do DNS enumeration. – Barb Oct 03 '19 at 15:02
  • 1
    For the fact you ignore that TLD does not have an IP address is speaking more volume than an attempt to debunk an easier method to resolve the issue of what the OP **intends to mean** – Barb Oct 03 '19 at 15:32
  • 2
    Your solution is a little misleading. The thing is on windows, unless you install `nmap` and add it to path, the command `nmap.PortScanner()` doesn’t work. – Hikki Oct 03 '19 at 18:18
  • 1
    " TLD does not have an IP address " Which is false. `.DK` has an IP address. And it is not the only one. – Patrick Mevzek Oct 05 '19 at 15:46