2

I am trying to create a script that generates a list of IP addresses based on a users input for a start and end IP range. For example, they could enter 192.168.1.25 & 192.168.1.50. The list would then be fed into scapy to test for open ports. I think I have the list generated, but I am stuck on getting the individual IP's out and into the rest of my code. I think I am trying to use the whole list vs. an item in the list. If there is a better way of doing this, that is fine. I am doing this mainly to improve my understanding of Python.

Thanks!

from scapy.all import *

ip_start = raw_input('Please provide the starting IP address for your scan --> ')
start_list = ip_start.split(".")
ip_end = raw_input('Please provide the ending IP address for your scan --> ')
end_list = ip_end.split(".")
top = int(start_list[3])
bot = int(end_list[3])
octet_range = range(top,bot)
#print octet_range
for i in octet_range:
    #new_ip_start = ip_start.replace(str(top),str(i))

    start_list[3] = i
    #print top
    #print i
    print type(start_list)    
    src_port = RandShort()
    dst_port = 80
    scan = sr1(IP(dst=str(start_list))/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)
2
  • 1
    Your not up to something good are you? Commented Dec 11, 2013 at 17:25
  • I am taking a class on python for pentesting. Commented Dec 11, 2013 at 18:05

2 Answers 2

10

It'd be easier to use a format like nmap's:

192.168.1.1-255

As now, you can do:

octets = '192.168.1.1-255'.split('.')
parsed_ranges = [map(int, octet.split('-')) for octet in octets]

parsed_ranges will look like [[192], [168], [1], [1, 255]]. From there, generating the addresses is simple with itertools:

import itertools

ranges = [range(r[0], r[1] + 1) if len(r) == 2 else r for r in parsed_ranges]
addresses = itertools.product(*ranges)

Here's a simple implementation:

import itertools

def ip_range(input_string):
    octets = input_string.split('.')
    chunks = [map(int, octet.split('-')) for octet in octets]
    ranges = [range(c[0], c[1] + 1) if len(c) == 2 else c for c in chunks]

    for address in itertools.product(*ranges):
        yield '.'.join(map(str, address))

And the result:

>>> for address in ip_range('192.168.1-2.1-12'):  print(address)
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
192.168.1.8
192.168.1.9
192.168.1.10
192.168.1.11
192.168.1.12
192.168.2.1
192.168.2.2
192.168.2.3
192.168.2.4
192.168.2.5
192.168.2.6
192.168.2.7
192.168.2.8
192.168.2.9
192.168.2.10
192.168.2.11
192.168.2.12
Sign up to request clarification or add additional context in comments.

4 Comments

Let me try and wrap my head around this. Your solution is much cleaner, I just need get a better understanding of some of the functions and new module.
I tried using your fuction with the parameter I gathered using raw_input. range = raw_input('Enter range'), for i in ip_range(range): print i
The error I am getting is: TypeError: 'str' object is not callable
For Python 3: wrap map around a list. (in Python 3, map returns an iterable object of type map, and not a subscriptable list)
5

Remember that a dotted IPv4-address "x.x.x.x" is nothing more than a human-readable representation of a 32-bit integer. Using this, you can generate the ranges like this:

def undotIPv4 (dotted):
    return sum (int (octet) << ( (3 - i) << 3) for i, octet in enumerate (dotted.split ('.') ) )

def dotIPv4 (addr):
    return '.'.join (str (addr >> off & 0xff) for off in (24, 16, 8, 0) )

def rangeIPv4 (start, stop):
    for addr in range (undotIPv4 (start), undotIPv4 (stop) ):
        yield dotIPv4 (addr)

for x in rangeIPv4 ('1.2.3.4', '1.2.4.22'):
    print (x)

2 Comments

+1 for a more elegant solution. You could also use struct.unpack with socket.inet_aton and socket.inet_ntoa.
@Blender Those would be the more "native" approach without doubt, but I think it would hide a bit the simple maths that's behind it, and would thus obfuscate the logic. For production use, I would go with your option, for the sake of explaining my approach, I would stick to the "manual" way of dotting and undotting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.