This is the script
import nmap
import optparse
def nmapScan(tgtHost,tgtPort):
nmScan = nmap.PortScanner()
nmScan.scan(tgtHost,tgtPort)
state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
print "[*] " + tgtHost + " tcp/"+tgtPort +" "+state
def main():
parser = optparse.OptionParser('-H <target host> -p <target port>')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port[s] separated by comma')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str(options.tgtPort).split(',')
if (tgtHost == None) | (tgtPorts[0] == None):
print parser.usage
exit(0)
for tgtPort in tgtPorts:
nmapScan(tgtHost, tgtPort)
if __name__ == '__main__':
main()
When I try to enter a range of ports in the command line, I get this error. Could someone help me out? I'm a newbie to python. Thanks in advance!!
:~$ python nmapScan.py -H 192.168.1.6 -p 20-25
Traceback (most recent call last):
File "nmapScan.py", line 27, in <module>
main()
File "nmapScan.py", line 23, in main
nmapScan(tgtHost, tgtPort)
File "nmapScan.py", line 7, in nmapScan
state=nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
ValueError: invalid literal for int() with base 10: '20-25'
You need to distinguish between those two different formats, and if the m-n range format is used, split at '-' to get the boundaries, create the list of port using range(), and set tgtPorts to that range.
Here's a function to implement this. You can simply plug it into your code by doing
tgtPorts = parse_port_spec(options.tgtPort)
instead of your current tgtPorts = str(options.tgtPort).split(','):
def parse_port_spec(spec):
if ',' in spec:
# Port list
ports = spec.split(',')
elif '-' in spec:
# Port range
start, end = map(int, spec.split('-'))
ports = range(start, end + 1)
else:
# Single port
ports = [spec]
return map(int, ports)
Note however that this still does not support the full nmap port range specification syntax. You can only use a comma separated list, or a range defined by m-n, but not both.
See the documentation for range() and map() for details on how those functions work.
import nmap
import optparse
def nmapScan(tgtHost,tgtPort):
nmScan = nmap.PortScanner()
nmScan.scan(tgtHost,tgtPort)
state = nmScan[tgtHost]['tcp'][int(tgtPort)]['state']
print "[*] " + tgtHost + " tcp/"+tgtPort +" "+state
def main():
parser = optparse.OptionParser('-H <target host> -p <target port>')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port[s] separated by comma')
(options, args) = parser.parse_args()
if not options.tgtHost or not options.tgtPort:
print parser.usage
exit(0)
tgtHost = options.tgtHost
ports = options.tgtPort
tgtPorts = options.tgtPort.split(',') if "," in options.tgtPort else map(str,range(int(ports.split("-")[0]),int(ports.split("-")[1]+1)))
for tgtPort in tgtPorts:
nmapScan(tgtHost, tgtPort)
if __name__ == '__main__':
main()
Like I said in a comment you should really use some try/excepts to avoid your script crashing.
~$ python nm.py -H 10.10.10.100 -p 20-25
[*] 10.10.10.100 tcp/20 closed
[*] 10.10.10.100 tcp/21 closed
[*] 10.10.10.100 tcp/22 open
[*] 10.10.10.100 tcp/23 closed
[*] 10.10.10.100 tcp/24 closed
$ python nm.py -H 10.10.10.100 -p 20,21
[*] 10.10.10.100 tcp/20 closed
[*] 10.10.10.100 tcp/21 closed
~$ python nm.py -H 10.10.10.100
-H <target host> -p <target port>
As per the documentation you can use nmap.PortScanner() which takes a string in the form 20-25 for a range which you could just use that in your script, parse the dict to get the output and make your life easier:
In [7]: import nmap
In [8]: nm = nmap.PortScanner()
In [9]: nm = nmap.PortScanner()
In [10]: nm.scan('127.0.0.1', '20-25')
We can shorten your script using the proper nmap syntax:
import nmap
import optparse
def main():
parser = optparse.OptionParser('-H <target host> -p <target port>')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port[s] separated by comma')
(options, args) = parser.parse_args()
if not options.tgtHost or not options.tgtPort:
print parser.usage
exit(0)
tgtHost = options.tgtHost
tgtPorts = options.tgtPort
nm = nmap.PortScanner()
res = nm.scan(tgtHost,tgtPorts)
for port in nm[tgtHost]["tcp"].keys():
print "[*] {} tcp/{} {}".format(tgtHost,port,res["scan"][tgtHost]["tcp"][int(port)]["state"])
if __name__ == '__main__':
main()
~$ python nm.py -H 10.10.10.100 -p 20-25
[*] 10.10.10.100 tcp/20 closed
[*] 10.10.10.100 tcp/21 closed
[*] 10.10.10.100 tcp/22 open
[*] 10.10.10.100 tcp/23 closed
[*] 10.10.10.100 tcp/24 closed
[*] 10.10.10.100 tcp/25 open
Related
Just typed up an banner grabber and port scanner from the 'Violent Python' book by TJ 'O Connor, I'm not getting any syntax errors when I run it, but I don't get any output what so ever either, can someone tell me what's potentially wrong? The books written in python 2.6, i'm using 2.7, I don't know if that's the issue maybe? Any help would be greatly appreciated! The book also had 'import socket as Ú' but that got syntax errors so I took it out, not sure what it did anyway
import optparse
import socket
def connScan(tgtHost,tgtPort):
try:
connSkt= socket(AF_INET,SOCK_STREAM)
connSkt.connect((tgtHost,tgtPort))
connSkt.send('Violent Python\r\n')
results= connSkt.recv(1024)
print '[+]%d/tcp open' % tgtPort
print '[+]' + str(results)
connSkt.close()
except:
print '[-]%d/tcp closed' % tgtPort
def portScan(tgtHost,tgtPorts):
try:
tgtIP=gethostbyname(tgtHost)
except:
print "[-] Cannot resolve '%s': Unkonwn host" % tgtHost
return
try:
tgtName= gethostbyaddr(tgtIP)
print '\n[+]Scan results for: ' + tgtIP
setdefaulttimeout(1)
for tgtPort in tgtPorts:
print 'Scanning port ' + tgtPort
connScan(tgtHost,int(tgtPort))
except:
print 'exception granted'
def main():
parser = optparse.OptionParser('usage %prog -h'+'<target host> -p <target port>')
parser.add_option('-h', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='int', help='specify target port[s] seperated by comma')
(options,args) = parser.parse_args()
tgtHost= options.tgtHost
tgtPorts= str(options.tgtPort).split(',')
if (tgtHost == None)|(tgtPorts[0] == None):
print '[*] You must specify a target host and port[s]'
exit(0)
portScan(tgtHost,tgtPorts)
if __name__=='__main__':
main()
The reason nothing is happening is because your code consists entirely of function declarations. At no point do you actually tell python to run anything.
That job is supposed to be done by this if statement:
if __name__=='__main__':
main()
However, you have mistakenly indented too much, thus making it a part of the main() function. For the code to work, you need to unindent it like so:
def main():
parser = optparse.OptionParser('usage %prog -h'+'<target host> -p <target port>')
parser.add_option('-h', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='int', help='specify target port[s] seperated by comma')
(options,args) = parser.parse_args()
tgtHost= options.tgtHost
tgtPorts= str(options.tgtPort).split(',')
if (tgtHost == None)|(tgtPorts[0] == None):
print '[*] You must specify a target host and port[s]'
exit(0)
portScan(tgtHost,tgtPorts)
if __name__=='__main__': # NOT a part of the main()
main()
As for import socket as Ú, the purpose of this line is to import the module called socket, but give it an alias, in this case Ú. From then on, instead of referring to it as socket in your code, you refer to it as Ú.
i am working on a python script to be a multi tool for getting DNS information on servers in a enterprise env. so far the script i have is using python 3.5. i am using argparse for creating command line options, which i am trying to create an if/ elif / else statement which contains the different selections. the main error message i am getting is:
./GetHostName.py
Traceback (most recent call last):
File "./GetHostName.py", line 34, in <module>
remoteServer = sys.argv[1]
IndexError: list index out of range
that is when the command is run by itself.
when it is run with a host name at the end ./GetHostName.py hostName
it gives this message:
GetHostName.py: error: unrecognized arguments: hostName
I didn't put real name of server for security issues....
When i use the argparse options say like the -f option for getting the FQDN, it gives this response...
./GetHostName.py -f hostName
3
-f
from the way it appears, it is taking the -f as input for the server name, when it should only be the input for argparse input. i have tried everything to fix it that i can think of. i have encased the main code body in a main function, that didn't work so i removed it. i use the try: statement and exception statements. that didn't work. i am wondering if there is something just basically wrong with my programming logic at this point...
this here is the code from the script:
#!C:\Bin\Python35\python.exe
#
# import libraries
import sys, os
import argparse as ap
import socket
# Command Line interface setup
def argParse():
#Command Line arg parse
parser=ap.ArgumentParser(description='A tool to get a remote servers DNS information.')
parser.add_argument("-a", "--address", default="fqdn", help="Gets IP address from host name.")
parser.add_argument("-f", "--fqdn", default="fqdn", help="Gets the FQDN address of server.")
parser.add_argument("-d", "--addrinfo", default="fqdn", help="Gets the FQDN address of server.")
parser.add_argument("-l", "--local", default="fqdn", help="Gets info on local host.")
parser.add_argument("-Pr", "--proto", default="fqdn", help="Translate an Internet protocol name to a constant suitable for passing as the (optional) third argument to the socket() function.")
parser.add_argument("-n", "--nameinfo", default="fqdn", help="Gets name and port on remote host.")
parser.add_argument("-Sn", "--servbyname", default="fqdn", help="Translate an Internet service name and protocol name to a port number for that service.")
parser.add_argument("-Sp", "--servbyport", default="fqdn", help="Translate an Internet port number and protocol name to a service name for that service.")
parser.add_argument("-t", "--timeout", default="fqdn", help="Return the default timeout in seconds for new socket objects.")
parser.add_argument("-v", "--verbose", default="fqdn", help="Increase output verbosity")
return parser.parse_args()
#remoteServer = input().strip().split()
args=argParse()
if args.fqdn:
remoteServer = sys.argv[1]
print (len(sys.argv))
remoteServerIP = socket.getfqdn(remoteServer)
print (remoteServerIP)
elif args.address:
remoteServer = sys.argv[2]
print (len(sys.argv))
remoteServerIP = socket.gethostbyname(remoteServer)
print (remoteServerIP)
elif args.addrinfo:
remoteServer = sys.argv[3]
print (len(sys.argv))
remoteServerIP = socket.getaddrinfo(remoteServer)
print (remoteServerIP)
elif args.local:
remoteServer = sys.argv[4]
print (len(sys.argv))
remoteServerIP = socket.gethostname()
print (remoteServerIP)
elif args.proto:
remoteServer = sys.argv[5]
print (len(sys.argv))
remoteServerIP = socket.getprotobyname(remoteServer)
print (remoteServerIP)
elif args.servbyname:
remoteServer = sys.argv[6]
print (len(sys.argv))
remoteServerIP = socket.getservbyname(remoteServer)
print (remoteServerIP)
elif args.servbyport:
remoteServer = sys.argv[7]
print (len(sys.argv))
remoteServerIP = socket.getservbyport(remoteServer)
print (remoteServerIP)
elif args.timeout:
remoteServer = sys.argv[8]
print (len(sys.argv))
remoteServerIP = socket.getdefaulttimeout(remoteServer)
print (remoteServerIP)
elif args.verbose:
remoteServer = sys.argv[9]
print (len(sys.argv))
remoteServerIP = socket.gethostbyaddr(remoteServer)
print (remoteServerIP)
else:
args.nameinfo
remoteServer = sys.argv[10]
print (len(sys.argv))
remoteServerIP = socket.getnameinfo(remoteServer)
print (remoteServerIP)
any help would be appreciated. please note that when i run a script with just this in it, it works just fine:
#!C:\Bin\Python35\python.exe
#
import sys, os
import argparse
import socket
# Command Line interface setup
def main():
remoteServer = sys.argv[1]
remoteServerIP = socket.gethostbyaddr(remoteServer)
print (remoteServerIP)
if __name__ == '__main__':
main()
thanks in advance.
-Betzelel
P.S. the code may look out of format, due to having to copy and paste into this blog, and manually putting 4 spaces on to each line to get it to show up as code lol.
I've had this problem long time ago. To fix this I've changed
parser.add_argument("-a", "--address", default="fqdn", help="Gets IP address from host name.")
in
parser.add_argument("-a", "--address", default="fqdn", help="Gets IP address from host name.", dest=ipfromhostname)
So for getting the value from -a you have to change
remoteServer = sys.argv[1]
in
remoteServer = args.ipfromhostname
where ipfromhostname is the dest value.
EDIT:
You have to do this operation for every parser.add_argument
I'm really getting mad 'cause of a problem I do not manage to get through while programming a simple and didactic portscanner in python. Here's the code:
def main():
parser = optparse.OptionParser("usage%prog "+\
"-H <target host> -p <target port>")
parser.add_option('-H', dest='tgtHost', type='string', \
help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', \
help='specify target port[s] separated by comma')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str((options.tgtPort)).replace(",", " ").split()
if (tgtHost is None) | (tgtPorts is None):
print '[-] You must specify a target host and port[s].'
exit(0)
it all works as expected, apart from one thing: the (tgtPorts is None) check does not seem to work, while the tgtHost control works fine. In other words, this is what happens without a specified -H option:
$ python portscanner.py -p 21
[-] You must specify a target host and port[s].
while with the host and without -p here's what happens:
$ python portscanner.py -H 1234
[+] Scan Results for: 0.0.4.210
Scanning port None
Traceback (most recent call last):
File "portscanner.py", line 45, in <module>
main()
File "portscanner.py", line 43, in main
portScan(tgtHost, tgtPorts)
File "portscanner.py", line 29, in portScan
connScan(tgtHost, int(tgtPort))
ValueError: invalid literal for int() with base 10: 'None'
So the script throws an error because it cannot convert None to int, and that's the point of the consistence check. I've already tried to change (tgtPorts is None) in (tgtPorts[0] is None), but nothing changed. Googled for it as well, but noone seems to have had the same problem. Any ideas?
You have a string with the word 'None' in it, not the None object.
You made it a string here:
tgtPorts = str((options.tgtPort)).replace(",", " ").split()
Rather than use str() there, test for options.tgtPort having a true value (e.g. not None or an empty string):
if options.tgtPort:
tgtPorts = options.tgtPort.replace(",", " ").split()
Note that | is bitwise OR, you should really use or instead. I'd test for the options first, then parse:
if not (options.tgtHost and options.tgtPort):
print '[-] You must specify a target host and port[s].'
exit(1)
Here both omitting the options and not specificing a value is an error.
Personally, I'd use the argparse module here and use required arguments, with the ports argument set to nargs='+' to capture one or more values. Error handling is then done by argparse as well.
Im not entirely sure how to call my tasklist function with all the required arguments. Im guessing im getting the syntax wrong. Can anyone point out my stupidity please?
CODE
#!/usr/bin/python
"""
Description:
Used for checking users logged into a list of servers.
Usage:
hunter.py (-u <username>) (-p <password>) (-d <domain>) (-s <FILE>)
hunter.py -h | --help
hunter.py --version
Options:
-u --username
-h --help Show this screen.
--version Show version.
-p --password
-d --domain
-s --serverfile=FILE
"""
from docopt import docopt
import subprocess
from subprocess import CalledProcessError
def tasklist(serverlist, domain, username):
for serverl in serverlist():
try:
print "%s Services Listed Below" % serverl
cmd = 'tasklist /V /S %s -u%s\%s /FI "USERNAME eq $s"' % serverl, domain, username, domain
print cmd
subprocess.check_output(cmd)
except CalledProcessError as e:
print(e.returncode)
def getservers(servers):
slist = open(servers).readlines()
return [s.replace('\n', '') for s in slist]
if __name__ == "__main__":
arguments = docopt(__doc__, version='0.1a')
print arguments
serverlist = getservers(arguments['--serverfile'])
print serverlist
tasklist(serverlist,(arguments['<domain>'], ['<username>']))
COMMANDLINE EXAMPLE
c:\Python27>hunter.py -u xpuser -p xpuser -d WORKGROUP -s servers.txt
TRACEBACK
{'--domain': True,
'--help': False,
'--password': True,
'--serverfile': 'servers.txt',
'--username': True,
'--version': False,
'<domain>': 'WORKGROUP',
'<password>': 'xpuser',
'<username>': 'xpuser'}
['192.168.1.122', '192.168.1.121']
Traceback (most recent call last):
File "C:\Python27\hunter.py", line 44, in <module>
tasklist(serverlist,(arguments['<domain>'], ['<username>']))
TypeError: tasklist() takes exactly 3 arguments (2 given)
tasklist() function requires 3 arguments, you are passing just two. Replace:
tasklist(serverlist,(arguments['<domain>'], ['<username>']))
with:
tasklist(serverlist, arguments['<domain>'], arguments['<username>'])
Also, you don't need to call serverlist, it's a list, omit the parenthesis:
for serverl in serverlist:
Also, replace:
cmd = 'tasklist /V /S %s -u%s\%s /FI "USERNAME eq $s"' % serverl, domain, username, domain
with:
cmd = 'tasklist /V /S %s -u%s\%s /FI "USERNAME eq %s"' % (serverl, domain, username, domain)
Hope that helps.
im creating my first python "app" and im having problems with the args or lack of. If i execute the script with no arguments id expect a message stating usage, but instead im getting the following error
ERROR
unknown#ubuntu:~$ ./attack.py
Traceback (most recent call last):
File "./attack.py", line 60, in <module>
main(sys.argv[1:])
File "./attack.py", line 57, in main
print fread(FWORD)
File "./attack.py", line 19, in fread
flist = open(FWORD).readlines()
TypeError: coercing to Unicode: need string or buffer, NoneType found
CODE
#!/usr/bin/python
import sys, getopt, socket, fileinput, traceback
from Queue import Queue
from threading import Thread
def usage():
print "-h --help: help\n"
print "-f --file: File to read potential Sub-domains from.\n"
print "-p --PROXY: PROXY address and port. e.g http://192.168.1.64:8080\n"
print "-d --DOMAIN: DOMAIN to bruteforce.\n"
print "-t --thread: Thread count.\n"
print "-e: Turn debug on.\n"
sys.exit()
def fread(FWORD, *args):
flist = open(FWORD).readlines()
return flist
#def addcheck(fcontent):
def main(argv):
PROXY = None
DOMAIN = None
FWORD= None
try:
opts, argv =getopt.getopt(argv, "h:f:p:d:t:e",["help", "file=", "PROXY=", "DOMAIN=", "thread="])
except getopt.GetoptError as err:
print str(err)
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-f", "--file"):
FWORD = arg
elif opt in ("-p", "--PROXY"):
PROXY = arg
elif opt in ("-d", "--DOMAIN"):
DOMAIN = arg
elif opt in ("-t", "--thread"):
thread = arg
elif opt in '-e':
global _debug
_debug = 1
else:
usage()
sys.exit()
print fread(FWORD)
if __name__ == "__main__":
main(sys.argv[1:])
Ok thanks all for the comments and pointers. ZMO im going to go with docopt it looks clean and simple (simple just like me). Im not entire sure what i need to do to my old code so am uploading what i think i need to do. Can anyone tell me if this is the right direction?
What do i do with def main() now? and
#!/usr/bin/python
import sys, getopt, socket, fileinput, traceback
from Queue import Queue
from threading import Thread
def fread(FWORD, *args):
flist = open(FWORD).readlines()
return flist
def main(argv):
"""
Usage:
your_script.py [-f <file>] [-p <proxy>] [-d <domain>] [-t] [-v]
your_script.py -h | --help
Options:
-h --help Show this screen.
-f --file File to read potential Sub-domains from.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080]
-d --domain Domain to bruteforce.
-t --thread Thread count.
-v --verbose Turn debug on.
"""
# […] your code (NOT SURE WHAT CODE YOU MEAN?
if __name__ == "__main__":
from docopt import docopt
arguments = docopt(__doc__, version='0.1a')
print fread(FWORD)
geptopt is deprecated in modern python, you should use argparse instead. I personally prefer the 3rd party docopt
It's useless to give the sys.argv array as argument to main() because you import the sys module globally in your module context (and there are many other things you'd use from sys aside from argv). Your code would only make sense if you were doing the import in the if __name__ == "__main__", but then that would be not good python practice. A better thing to do is to actually parse the arguments and then give the returned NamedTuple as an argument to main().
Argparse example
# […] your code
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Your script.')
parser.add_argument('--file', '-f', metavar='FILE', dest='file', type=file,
help='File to read potential Sub-domains from.')
parser.add_argument('--proxy', '-p', dest='proxy', action='store',
help='Proxy address and port.', default='http://127.0.0.1:8080')
parser.add_argument('--domain', '-d', dest='domain', action='store',
help='Domain to bruteforce.')
parser.add_argument('--thread', '-t', dest='thread', action='store_true',
help='Thread count.')
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true',
help='Turn debug on.')
args = parser.parse_args()
main(args)
docopt example
Your script presentation.
"""
Usage:
your_script.py [-f <file>] [-p <proxy>] [-d <domain>] [-t] [-v]
your_script.py -h | --help
Options:
-h --help Show this screen.
-f --file File to read potential Sub-domains from.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080]
-d --domain Domain to bruteforce.
-t --thread Thread count.
-v --verbose Turn debug on.
"""
# […] your code
if __name__ == "__main__":
from docopt import docopt
arguments = docopt(__doc__, version='Naval Fate 2.0')
main(arguments) # here using the parameter makes sense ;-)