Concatenating list items with string - python

I'm taking a list generated from reading a file and trying to take each item and concatenating it to another input string. I can understand the error; I can't concat a list item with a string. But how do I convert each item from the list into a string. I tried ' '.join(list) but that didn't work either.
I'm getting the following error:
ERROR
Traceback (most recent call last):
File "./attack2.py", line 40, in <module>
print subcheck(returned_list, ['--domain'])
File "./attack2.py", line 31, in subcheck
socket.gethostbyname(sub + domain)
TypeError: cannot concatenate 'str' and 'list' objects
CODE
#!/usr/bin/python
"""
Description:
Basic Domain bruteforcer
Usage:
attack2.py (-f <file>) (-d <domain>) [-t 10] [-v]
attack2.py -h | --help
Arguments:
-f --file File to read potential Sub-domains from. (Required)
-d --domain Domain to bruteforce. (Required)
Options:
-h --help Show this screen.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080] (Optional)
-t --thread Thread count. (Optional)
-v --verbose Turn debug on. (Optional)
"""
import socket
from docopt import docopt
def fread(dwords):
flist = open(dwords).readlines()
return [s.replace('\n', '.') for s in flist]
def subcheck(subdomain, domain):
for sub in subdomain:
socket.gethostbyname(sub + domain)
return output
if __name__ == "__main__":
arguments = docopt(__doc__, version='0.1a')
print arguments
print fread(arguments['--file'])
returned_list = fread(arguments['--file'])
print subcheck(returned_list, ['--domain'])

print subcheck(returned_list, ['--domain'])
Did you mean to retrieve the domain option from the arguments object?
print subcheck(returned_list, arguments['--domain'])

Related

Ch. 2 Violent Python syntax error: ValueError: invalid literal for int() with base 10: '21,'

I am working my way through 'Violent Python'. I am in chapter 2, and I receive this syntax error when attempting to run the below code:
python2 portscanner.py -H perl6.org -p 21, 22, 80
['21,'] [+] Scan results for: www.p6c.org Scanning port 21, Traceback
(most recent call last): File
"/home/wolf/python/Violent-Python-Examples/Chapter-2/portscan.py",
line 53, in
main() File "/home/wolf/python/Violent-Python-Examples/Chapter-2/portscan.py",
line 49, in main
portScan(tgtHost, tgtPorts) File "/home/wolf/python/Violent-Python-Examples/Chapter-2/portscan.py",
line 32, in portScan
connScan(tgtHost, int(tgtPort)) ValueError: invalid literal for int() with base 10: '21,'
I copied it mostly directly from the code, but I did a few things to make it Python3 instead of Python2, such as adding the parenthesis for the print() function. However, I being new to Python, I don't understand what the problem is here. I assume it is something with the split() method?
import optparse
import socket
from socket import *
def connScan(tgtHost, tgtPort):
try:
connSkt = socket(AF_INET, SOCK_STREAM)
connSkt.connect((tgtHost, tgtPort))
connSkt.send('ViolentPython\r\n')
results = connSkt.recv(100)
print('[+]%d/tcp open' % tgtPort)
connSkt.close()
except:
print('[-]%d/tcp closed' % tgtPort)
def portScan(tgtHost, tgtPorts):
try:
tgtIP = gethostbyname(tgtHost)
except:
print("[-] Cannot resolve '%s': Unknown host" % tgtHost)
return
try:
tgtName = gethostbyaddr(tgtIP)
print('\n[+] Scan results for: ' + tgtName[0])
except:
print('\n[+] Scan results for: ' + tgtIP)
setdefaulttimeout(1)
for tgtPort in tgtPorts:
print('Scanning port ' + tgtPort)
connScan(tgtHost, int(tgtPort))
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')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str(options.tgtPort).split(', ')
print(tgtPorts)
if (tgtHost is None) | (tgtPorts[0] is None):
print('[-] You must specify a target host and port[s].')
exit(0)
portScan(tgtHost, tgtPorts)
if __name__ == '__main__':
main()
The options you are parsing is just looking for one port -p <target port> so it cuts off everything after "21,".
str(options.tgtPort).split(', ') is looking for a comma followed by a space. "21," just has the comma.
See Split by comma and strip whitespace in Python if you need to split by both but really, just send the command python2 portscanner.py -H perl6.org -p 21 and it should work. Or as Tripleee pointed out, just put quotes around the argument.
If you need to support multiple arguments without quotes, this question will help: Processing multiple values for one single option using getopt/optparse?
By the way, if it makes you feel any better, this is an issue with the original unmodified code from the book. The book's Python 2 code gives the same error for the command the book suggests.

argparse function arguments

I am trying to use argparse to create my script with parameters but I am not being able to.
The name of my script is pipeline and it has some options arguments like -b, -c, -i and -r.
If you call the script ./pipeline -b should give an error asking for a git repository path but I am not being able to do this.
from git import Repo
import os
import sys
import subprocess
import argparse
class Ci:
def build(self,args):
cloned_repo = Repo.clone_from(args)
print("clonning repository " + args)
cloned_repo
dir = git.split('/')(-1)
if os.path.isdir(dir):
print("repository cloned successfully")
else:
print("error to clone repository")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-b','-build',action='store_true', help='execute mvn clean install')
parser.add_argument('-c','-compress',action='store_true',help='zip a directory recursively')
parser.add_argument('-i','-integration',action='store_true',help='execute mvn verify')
parser.add_argument('-r','-release',action='store_true',help='execute build,integration and compress respectively')
args = parser.parse_args()
if args.b:
a = Ci()
a.build()
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
I can't make this sub-parameter work and I can't find a way to pass this parameter to my build function.
e.g:
./pipeline -b
Output: error missins git path
./pipeline -b https://git/repo
Output: clonning repo
and the string "https://git/repo" has to be passed as the argument to my build function:
How can I make it work?
first a note about convention: usually the longer option name is preceded by two hyphens like this '--build'
second, 'store_true' is the action you perform with '-b', which means argparse doesnt expect an argument after it, it just sets the args.build variable to True (and if the argument wasn't there it would set it to False)
try removing the action='store_true' and then it will default to storing the next value it finds in the argument list into args.build
Reducing your code to:
import argparse
class Ci:
def build(self,args):
print("clonning repository " + args)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-b','-build',action='store_true', help='execute mvn clean install')
parser.add_argument('-c','-compress',action='store_true',help='zip a directory recursively')
parser.add_argument('-i','-integration',action='store_true',help='execute mvn verify')
parser.add_argument('-r','-release',action='store_true',help='execute build,integration and compress respectively')
args = parser.parse_args()
print(args)
if args.b:
a = Ci()
a.build()
I get:
1313:~/mypy$ python3 stack49408644.py -b
Namespace(b=True, c=False, i=False, r=False)
Traceback (most recent call last):
File "stack49408644.py", line 22, in <module>
a.build()
TypeError: build() missing 1 required positional argument: 'args'
The parser runs fine, seeing args.b to True. But the call to build is wrong. It does not match the method's definition.
Providing a 'directory' doesn't help either, because -b is True/False
1313:~/mypy$ python3 stack49408644.py -b foo
usage: stack49408644.py [-h] [-b] [-c] [-i] [-r]
stack49408644.py: error: unrecognized arguments: foo
You need to either change -b to take an value, or add another argument that takes a value.
#AntiMatterDynamite showed how to change -b. Instead let's add:
parser.add_argument('adir', help='a directory for build')
and change the build call
a.build(args.adir)
Now the value is passed on to the method:
1322:~/mypy$ python3 stack49408644.py -b
usage: stack49408644.py [-h] [-b] [-c] [-i] [-r] adir
stack49408644.py: error: the following arguments are required: adir
1322:~/mypy$ python3 stack49408644.py -b foo
Namespace(adir='foo', b=True, c=False, i=False, r=False)
clonning repository foo
Instead redefining -b:
parser.add_argument('-b','-build', help='execute mvn clean install')
if args.b is not None:
a = Ci()
a.build(args.b)
test runs:
1322:~/mypy$ python3 stack49408644.py -b
usage: stack49408644.py [-h] [-b B] [-c] [-i] [-r]
stack49408644.py: error: argument -b/-build: expected one argument
1324:~/mypy$ python3 stack49408644.py -b foo
Namespace(b='foo', c=False, i=False, r=False)
clonning repository foo
So your parser needs to accept a value. And you need to pass that value on to your code. You seem to have read enough of the argparse docs to get things like print_help and store_true, but missed the simpler use of store (default) or positional. Were you trying to do something more sophisticated?
I agree with #hpaulj (why isn't an accepted answer?). I guess you found your problem, i.e., store_true does not take argument, then follow hpaulj indications.
In addition, I opened the question because of its title, I was expecting something different such as the following. I wanted to find a way to pass the argparse arguments to a function and possibly modify them with the function arguments. Here is the solution I wrote in case others come looking for this. It may need to be adjusted to account for positional arguments, I also highlight the possible use of vars(args) to get a dictionary from the argparse arguments to compare dict-to-dict with the args_dict:
def get_options(args_dict: dict):
""" get options from command-line,
update with function args_dict if needed """
args = get_cmd() # this is the function taking cmd-line arguments
for key, val in args_dict.items():
if not hasattr(args, key):
raise AttributeError('unrecognized option: ', key)
else:
setattr(args, key, val)
return(args)

Python docopt usage menu issues

Im getting an error i believe is being caused by my usage descriptions but cant work out why. The idea is to grab a list of valid users in a file (username password), split that into a dictionary and return the dictionary. Then grab a file of servers (ip perline), turn that into a list. Then ill call a subprocess to mtstc, either populating a .rdp conf file or directly entering creds on cli (not got this far yet)
Any help would be appreciated.
ERROR
unknown#ubuntu:~$ ./rdpcheck.py -u userpass.txt -s servers.txt
Traceback (most recent call last):
File "./rdpcheck.py", line 30, in <module>
arguments = docopt(__doc__, version='0.1a')
File "/usr/local/lib/python2.7/dist-packages/docopt.py", line 560, in docopt
pattern = parse_pattern(formal_usage(DocoptExit.usage), options)
File "/usr/local/lib/python2.7/dist-packages/docopt.py", line 373, in parse_pattern
result = parse_expr(tokens, options)
File "/usr/local/lib/python2.7/dist-packages/docopt.py", line 387, in parse_expr
seq = parse_seq(tokens, options)
File "/usr/local/lib/python2.7/dist-packages/docopt.py", line 396, in parse_seq
atom = parse_atom(tokens, options)
File "/usr/local/lib/python2.7/dist-packages/docopt.py", line 415, in parse_atom
raise tokens.error("unmatched '%s'" % token)
docopt.DocoptLanguageError: unmatched '('
CODE
#!/usr/bin/python
"""
Script to check valid login credentials have ability to rdp to list of server.
Usage:
rdpcheck.py (-u <user>) (-s <server>)
rdpcheck.py -h | --help
Options:
-u --user
-s --server
-h --help This help screen this screen.
"""
from docopt import docopt
def getuserpass(userpass):
list = {}
with open(userpass, 'r') as text:
for line in text:
key, value = line.split()
return list
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
It seems I missed the --version option.
NEW CODE
#!/usr/bin/python
"""
Description:
Users to test a list of credentials against a list of servers
Usage:
rdpcheck.py (-u <FILE>) (-s <FILE>)
rdpcheck.py -h | --help
rdpcheck.py --version
Options:
-h --help Show this screen.
--version Show version.
-u --user=FILE
-s --server=FILE
"""
from docopt import docopt
def getuserpass(userpass):
list = {}
with open(userpass, 'r') as text:
for line in text:
key, value = line.split()
return list
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

Removing newline characters not working

Im trying to remove the \n from a list created in a function. My code for removing it doesnt seem to be working. Im not getting an error either??
CODE
#!/usr/bin/python
"""
Description:
Basic Domain bruteforcer
Usage:
your_script.py (-f <file>) (-d <domain>) [-t 10] [-v]
your_script.py -h | --help
Arguments:
-f --file File to read potential Sub-domains from. (Required)
-d --domain Domain to bruteforce. (Required)
Options:
-h --help Show this screen.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080] (Optional)
-t --thread Thread count. (Optional)
-v --verbose Turn debug on. (Optional)
"""
from docopt import docopt
def fread(dwords, *args):
flist = open(dwords).readlines()
#print current list
print flist
nlist = flist
for i in nlist:
i.rstrip('\n')
return nlist
if __name__ == "__main__":
arguments = docopt(__doc__, version='0.1a')
# print new list with removed \n
print fread(arguments['--file'])
Strings are not mutable, i.rstrip('\n') returns a new string.
Use a list comprehension:
def fread(dwords):
flist = open(dwords).readlines()
return [s.rstrip('\n') for s in flist]
or, since you are reading the whole file into memory anyway, str.splitlines():
def fread(dwords):
return open(dwords).read().splitlines()

Error handling with verbose output

Im trying to implement the --verbose option in my script. The idea is to turn on extra printing of errors etc for debugging, but for some reason it doesnt seem to work. Ive tried a few variations of the if verbose statement but no joy. Im hoping someone could point me in the right direction?
CLI EXAMPLE
./attack2.py -f wordfile.txt -d google.com --verbose 1
CLI OUTPUT
unknown#ubuntu:~$ ./attack2.py -f wordfile.txt -d google.com --verbose 1
173.194.34.149
173.194.34.130
unknown#ubuntu:~$
ARG PRINT
{'--domain': 'google.com',
'--file': 'wordfile.txt',
'--help': False,
'--thread': False,
'--verbose': True,
'10': False,
'<1>': '1'}
CODE
#!/usr/bin/python
"""
Description:
Basic Domain bruteforcer
Usage:
attack2.py (-f <file>) (-d <domain>) [-t 10] [-v <1>]
attack2.py -h | --help
Arguments:
-f --file File to read potential Sub-domains from. (Required)
-d --domain Domain to bruteforce. (Required)
Options:
-h --help Show this screen.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080] (Optional)
-t --thread Thread count. (Optional)
-v --verbose Turn debug on. (Optional)
"""
import socket
from docopt import docopt
def fread(dwords):
flist = open(dwords).readlines()
return [s.replace('\n', '.') for s in flist]
def subcheck(subdomain, domain, verbose):
vdomain = {}
for sub in subdomain:
try:
check = socket.gethostbyname(sub + domain)
vdomain[sub + domain] = check
except socket.gaierror, e:
if verbose == True:
print arguments
print e, sub + domain
else:
pass
return vdomain
if __name__ == "__main__":
arguments = docopt(__doc__, version='0.1a')
fread(arguments['--file'])
returned_list = fread(arguments['--file'])
returned_domains = subcheck(returned_list, arguments['--domain'], ['--verbose'])
The below line in function subcheck
returned_domains = subcheck(returned_list, arguments['--domain'], ['--verbose'])
should be
returned_domains = subcheck(returned_list, arguments['--domain'], arguments['--verbose'])
You forgot to pass the verbose param from arguments, instead you passed a list
It seems I was calling the subcheck incorrectly.
Code should have looked like this
Working CODE
if __name__ == "__main__":
arguments = docopt(__doc__, version='0.1a')
fread(arguments['--file'])
returned_list = fread(arguments['--file'])
returned_domains = subcheck(returned_list, arguments['--domain'], arguments['--verbose'])
print returned_domains

Categories

Resources