I've been playing with the module straight from the python command line to try and figure out how it all works, and start to piece together how the script I want to write is going to need to work. What I'd like to do, is do a simple host discovery scan first, such as -n -sP -PE, then use the all_hosts() function to generate the host list for the actual port scan. So if I do...
import nmap
nm = nmap.PortScanner()
nm.scan(hosts='XXX.XXX.XXX.X/24', arguments='-n -sP -PE')
Then nm.all_hosts() gives me exactly what I'm looking for, a shortened list of all the active hosts that the scan found. Now, the problem I'm having is passing that into the next scan. If you just do something like
hostlist = nm.all_hosts()
nm.scan(hosts=hostlist etc)
Then it complains about not being able to use a list for the hosts argument. Ok, makes sense. So I tried to make it comma separted, so they'd show up as aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb etc, by doing...
hostlist = ""
for item in nm.all_hosts():
hostlist = item + ", " + hostlist
Then, just dumping hostlist, it looks just how I'd like it to, but if you try to plug that into the hosts argument, it says "Failed to resolve "alltheipslisted" WARNING: No targets were specified, so 0 hosts scanned.
Does anyone have any good ideas for how to go about this? Maybe dumping the IPs to then pulling them from a file? Seems like I'd run into the same problem if a string isn't working...
If you remove the comma it will work. Multiple hosts are listed with only a space between them.
Example of use:
import nmap
nm = nmap.PortScanner()
hostlist = ' '.join(nm.all_hosts())
nm.scan(hosts=hostlist, arguments='-n -sP -PE')
Related
i have try to scan some port in list. I know nmap has support for port scan from file. I'm tried on nmap and that working:
nmap 141.101.220.172 -p $(tr '\n' , </home/congminhcpt/donnq/ports.list)
but when i'm try to use it on python, some thing has problems with error code in nmap scan result:
Error #485: Your port specifications are illegal.
That my python code:
import json
import nmap
nm = nmap.PortScanner()
arg = '-sV -p $(tr \'\\n\' , </home/congminhcpt/donnq/ports.list)'
data = nm.scan(hosts='141.101.220.172', arguments=arg)
this is ports.list file:
25
80
110
143
443
Hope some one can help me!
Thanks!
The nmap python library won't accept the redirection from the file, you'd better list the ports right in the command line, since there are just a few:
arg = '-sV -p T:21-25,80,139,8080' # or whatever ports you want
T: means you want to scan TCP ports. If you want UDP, put U there.
thanks, simple way is convert list to string and scan with argument='-p ' + port_string
thanks for help!
I'm creating a script wherein I want to grep all a specific address based on the list?
before what I usually do run a grep 1 by 1 using this command ex. grep "192.168.1.1" *
Now I'm creating a script.
Example of the output.
print(i) output.
192.168.1.0
192.168.1.1
192.168.1.2
192.168.1.3
but how to call the list and put into loop under os.system so I can grep all the list?
Thanks
import ipaddress
import os
#Ask the ipaddress in CIDR format
ip = input("Enter the IP/CIDR: ")
os.chdir("/rs/configs")
print("pwd=%s" % os.getcwd())
for i in ipaddress.IPv4Network(ip):
print (i)
os.system("grep $i '*') #<--Grep from list and run to all directory *
The basic answer is "grep {} '*'".format(ip) but there are a number of problems with your script.
To improve usability, I would suggest you change the script so it accepts a list of IP addresses as command-line arguments instead.
You want to avoid os.system() in favor of subprocess.run()
There is no need to cd to the directory which contains the files you want to examine.
Finally, there is no need really to run grep, as Python itself is quite capable of searching a set of files.
import ipaddress
import glob
ips = set([ipaddress.IPv4Network(ip) for ip in sys.argv[1:]])
for file in glob.glob('/rs/configs/*'):
with open(file) as lines:
for line in lines:
if any(x in line for x in ips):
print("{0}:{1}".format(file, line))
This should be significantly more efficient by way of examining the files only once.
It's not entirely clear what you hope to gain by using ipaddress here if you are grepping for individual IP addresses anyway.
I'm trying out snakebite. I started the following client:
from snakebite.client import Client
client = Client("my.host.com", 8020, effective_user='datascientist')
First, I tried to list the users directory:
for x in client.ls(['/user/datascientist']):
print x
This worked nicely and printed couple of dictionaries; one for each item in the directory. One of the items is a file foobar.txt which I'd like to see. To that end, I believe I should use Client.cat:
for cat in client.cat(['/user/datascientist/da-foobar.txt',]):
print(cat)
for item in cat:
print(item)
However, this didn't work. I got the following error message:
ConnectionFailureException: Failure to connect to data node at (10.XXX.YYY.ZZZ:50010)
What am I doing wrongly?
BTW: using PyWebHdfsClient from pywebhdfs.webhdfs I managed to see the file by starting a client with the same address but with port 50070. I don't know whether this is relevant or not.
Edit 1: I also tried to use snakebite.client.Client.text and got the same error. I guess this is not surprising.
BTW, the file's content is my file is this\ntest file.
I found a/the solution. It seems like the listing operation can be accomplished on the name-node alone. In contrast, the printing of the text file needs to access the data-nodes! By instantiating the client as follows
client = Client("stage-gap-namenode-2.srv.glispa.com", 8020, effective_user='datascientist',
use_datanode_hostname=True)
the cat operation works as it is not using the internal IP, but the hostname. I summarized a minimal example.
I have an issue that has been giving me a headache for a few days. I am using the Paramiko module with Python 2.7.10 and I'd like to issue multiple commands to a Brocade router, but only return output from one of the given commands like so:
#!/usr/bin/env python
import paramiko, time
router = 'r1.test.example.com'
password = 'password'
username = 'testuser'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(router, username=username, password=password)
print('Successfully connected to %s' % router)
remote_conn = ssh.invoke_shell()
output = remote_conn.recv(1000)
# Disable paging on Brocade.
remote_conn.send('terminal length 0\n')
# Check interface status.
remote_conn.send('show interfaces ethernet 0/1\n') # I only want output from this command.
time.sleep(2)
output = remote_conn.recv(5000)
print(output)
If I were to print the full output it would contain everything issued to the router, but I only want to see output from the show interfaces ethernet 0/1\n command.
Can anyone help with this issue?
One final thing I would like to ask. I want to filter through the output variable and check for occurrences of strings like "up" or "down", but I can't seem to get it to work because everything in the output appears to be on new lines?
For example:
If I iterate over the output variable in a for loop I get all of the characters in the variable like so:
for line in output:
print(line)
I get an output like this:
t
e
r
m
i
n
a
l
l
e
n
g
t
h
0
Any way around this?
Again,
Thanks in advance for any help.
Best regards,
Aaron C.
After reading all of the comment I have made the following changes:
#!/usr/bin/env python
import paramiko, time
router = 'r2.test.example.com'
password = 'password'
username = 'testuser'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(router, username=username, password=password)
print('Successfully connected to %s' % router)
remote_conn = ssh.invoke_shell()
output = remote_conn.recv(1000)
# Disable paging on Brocade.
remote_conn.send('terminal length 0\n')
time.sleep(2)
# Clearing output.
if remote_conn.recv_ready():
output = remote_conn.recv(1000)
# Check interface status.
remote_conn.send('show interfaces ethernet 4/1\n') # I only want output from this command.
time.sleep(2)
# Getting output I want.
if remote_conn.recv_ready():
output = remote_conn.recv(5000)
print(output)
# Test: Check if interface is up.
for line in output.split('\n'):
if 'line protocol is up' in line:
print(line)
Everything works great now.
Thank you for all the help.
Best regards,
Aaron C.
For your second question: Though I am not specialist of paramiko, I see that function recv, according to the doc, returns a string. If you apply a for loop on a string, you will get characters (and not lines as one might perhaps expect). The newline is caused by your use of the print function as explained on this page, at paragraph 6.3.
I haven't studied what paramiko suggests to do. But why don't you treat the full string as a single entity? For example, you could check the presence of "up" as:
if "up" in output:
Or, if that suits your needs better, you could split the string into lines and then do whatever test you want to do:
for line in output.split('\n'):
If you can, the exec_command() call provides a simpler mechanism to invoke a command. I have seen Cisco switches abruptly drop connections that try exec_command(), so that may not be usable with Brocade devices.
If you must go the invoke_shell() route, be sure to clear all pending output after connecting and after send('terminal length 0\n'), checking recv_ready() before calling recv() to avoid blocking on reading data that might not ever arrive. Since you are controlling an interactive shell, sleep() calls might be needed to allow the server adequate time to process and send data, or it might be necessary to poll the output string to confirm that your last command completed by recognizing the shell prompt string.
I have a text file with a list of about 50 hostnames and I am looking to script a way to run through them to get each associated IP address in the Command Prompt.
I thought pasting the hostname list in to the following code might be the easiest way but socket.gethostbyname will take no more than 1 argument at a time.
import socket
socket.gethostbyname("***hostnames***")
Is there a way to work around this argument issue, or is there a way to have the hostnames read from the textfile?
The easiest work around is to pass a filename and iterate through it:
#!/usr/bin/python
import sys
import socket
file_nm = sys.argv[1]
with open(file_nm, 'r') as f:
for host in f:
print socket.gethostbyname(host.strip())