So basically I have this remote computer with a bunch of files.
I want to run unix commands (such as ls or cat) and receive them locally.
Currently I have connected via python's sockets (I know the IP address of remote computer). But doing:
data = None
message = "ls\n"
sock.send(message)
while not data:
data = sock.recv(1024) <- stalls here forever
...
is not getting me anything.
There is an excellent Python library for this. It's called Paramiko: http://www.paramiko.org/
Paramiko is, among other things, an SSH client which lets you invoke programs on remote machines running sshd (which includes lots of standard servers).
You can use Python's subprocess module to accomplish your task. It is a built-in module and does not have much dependencies.
For your problem, I would suggest the Popen method, which runs command on remote computer and returns the result to your machine.
out = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
t = out.stdout.read() + out.stderr.read()
socket.send(t)
where cmd is your command which you want to execute.
This will return the result of the command to your screen.
Hope that helps !!!
This is what I did for your situation.
In terminal 1, I set up a remote shell over a socket using ncat, a nc variant:
$ ncat -l -v 50007 -e /bin/bash
In terminal 2, I connect to the socket with this Python code:
$ cat python-pass-unix-commands-socket.py
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('', 50007))
sock.send('ls\n')
data = sock.recv(1024)
print data
sock.close()
$ python pass-unix-commands-socket.py
This is the output I get in terminal 1 after running the command:
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::50007
Ncat: Listening on 0.0.0.0:50007
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:39507.
$
And in terminal 2:
$ python pass-unix-commands-socket.py
alternating-characters.in
alternating-characters.rkt
angry-children.in
angry-children.rkt
angry-professor.in
angry-professor.rkt
$
Related
I am developing a python 3.11 program which will run on a few different servers and needs to connect to the local Redis server. On each machine the latter might run on a different port, sometimes the default 6379 but not always.
On the commandline I can issue the following command which on both my Linux and MacOS servers works well:
(base) bob#Roberts-Mac-mini ~ % sudo lsof -n -i -P | grep LISTEN | grep IPv4 | grep redis
redis-ser 60014 bob 8u IPv4 0x84cd01f56bf0ee21 0t0 TCP *:9001 (LISTEN)
What's the better way to get the running port using python functions/libraries?
What if you run your commands within a py script using the os library:
import os
cmd = 'ls -l' <-- change the command you want to run
os.system(cmd)
or else you could also use subprocess library as well:
import subprocess
print(subprocess.check_output(['ls', '-l']))
Problem
I've got a program using "Pexpect" to send commands over SSH. Its purpose is to SSH into a Panduit PDU (smartzone G5) and turn off port 1.
I can SSH into the PDU and run dev outlet 1 1 off and get the port to turn off, but it doesn't work when I try to run the same command from my program. It puzzles me as this method is no different than me logging in via SSH using iterm and typing. Is this a me problem or just how the PDU behaves?
What I've Tried
I've tested pexpect thoroughly on a Linux server using mkdir and touch to create directories and files so I know it works without issue there, but when I use it on the Panduit PDU the PDU ignores the commands.
I use time.sleep() to allow the PDU to catch up as it is a slow system and seems to have a queue for multiple commands.
It's not a module issue or interpreter issue or anything silly like that; the program itself is fine. (Though I'm sure it's not up to standards or safe but who cares if I can't get the program to work in the first place seriously.)
Why Pexpect?
I must use Pexpect as Paramiko and Fabric don't work for this particular connection.
I must specify ssh -F /dev/null admin#ipaddress otherwise the PDU rejects the SSH session and I cannot get pxssh or fabric or paramiko to do this so that's why I don't use them.
I'm aware of stuff like .set_missing_host_key_policy(paramiko.AutoAddPolicy()) for Paramiko and s = pxssh.pxssh(options={"StrictHostKeyChecking": "no", "UserKnownHostsFile": "/dev/null"}) and they do not work. Hence Pexpect.
Code
import os
import pexpect
import time
import sys
server_ip = "192.168.0.1"
server_user = "admin"
server_pass = "password"
child = pexpect.spawn('bash')
child.logfile_read = sys.stdout.buffer
child.expect('')
# This is the only way to access the PDU, Paramiko wont work either.
child.sendline('ssh -F /dev/null %s#%s -oStrictHostKeyChecking=no' % (server_user, server_ip))
child.expect("admin#192.168.0.1's password:")
child.sendline(server_pass)
child.expect('PANDUIT>')
time.sleep(3) # Wait for PDU to catch up or it wont recognise the command
child.sendline('dev outlet 1 1 off') # Power off port 1
print('\nfinished') # \n is there otherwise it gets sucked into the stdout
For reference this is what happens when I use Iterm to manually connect and enter commands, it works perfectly.
I've tried to use child.expect('SUCCESS') but it can't be seen. The only thing pexpect seems to be able to find inside the PDU is child.expect('\n') which I think may be from a buffer or something.
~/Documents ❯ ssh -F /dev/null admin#192.168.0.1
admin#192.168.0.1's password:
Type ? for command listing
sys PDU system configure and setting
net PDU net application configure and setting
usr PDU user operation
dev PDU device setting
pwr PDU power setting
PANDUIT>dev outlet 1 1 off
SUCCESS
And this is what my code outputs:
~/Documents❯ python3 code.py
ssh -F /dev/null admin#192.168.0.1 -oStrictHostKeyChecking=no
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2$ ssh -F /dev/null admin#192.168.0.1 -oStrictHostKeyChecking=no
admin#192.168.0.1's password:
Type ? for command listing
sys PDU system configure and setting
net PDU net application configure and setting
usr PDU user operation
dev PDU device setting
pwr PDU power setting
PANDUIT>
finished
I'm trying to run netsh command on remote windows hosts (windows domain environment with admin rights). The following code works fine on local host but I would like to run it on remote hosts as well using python.
import subprocess
netshcmd=subprocess.Popen('netsh advfirewall show rule name=\”all\”', shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE )
output, errors = netshcmd.communicate()
The problem is that I'm no sure how/what method to use to initiate the connection to remote hosts and then run the subprocess commands. I cannot use ssh or pstools and would like try to implement it using existing pywin32 modules if possible.
I have used WMI module in a past which makes it very easy to query remote host but I couldn't find any way to query firewall policies over WMI and that's why using subprocess.
First you login the remote host machine using of pxssh modules Python: How can remote from my local pc to remoteA to remoteb to remote c using Paramiko
remote login of windows:
child = pexpect.spawn('ssh tiger#172.16.0.190 -p 8888')
child.logfile = open("/tmp/mylog", "w")
print child.before
child.expect('.*Are you sure you want to continue connecting (yes/no)?')
child.sendline("yes")
child.expect(".*assword:")
child.sendline("tiger\r")
child.expect('Press any key to continue...')
child.send('\r')
child.expect('C:\Users\.*>')
child.sendline('dir')
child.prompt('C:\Users\.*>')
Python - Pxssh - Getting an password refused error when trying to login to a remote server
and send your netsh command
I will recommend using Fabric, it's a powerful python tool with a suite of operations for executing local or remote shell commands, as well as auxiliary functionality such as prompting the running user for input, or aborting execution:
install fabric : pip install fabric
write the following script named remote_cmd.py:
"""
Usage:
python remote_cmd.py ip_address username password your_command
"""
from sys import argv
from fabric.api import run, env
def set_host_config(ip, user, password):
env.host_string = ip
env.user = user
env.password = password
def cmd(your_command):
"""
executes command remotely
"""
output = run(your_command)
return output
def main():
set_host_config(argv[1], argv[2], argv[3])
cmd(argv[4]))
if __name__ == '__main__':
main()
Usage:
python remote_cmd.py ip_address username password command
When trying to traverse a SOCKS5 proxy to a RHEL5 Linux host using Fabric 1.6, the command returns but no output is returned to the stdout.
$> fab -H myhost -f ./fabfile.py remote_test --show=debug
Using fabfile '/home/myuser/fabric/fabfile.py'
Commands to run: remote_test
Parallel tasks now using pool size of 1
[myhost] Executing task 'remote_test'
[myhost] run: echo testing
Enter SOCKS5 password for myuser:
[myhost] Login password for 'myuser':
$> echo $?
0
$>
The remote_test function is:
def remote_test():
run('echo testing')
If I run the command against a non SOCKS5 host it works fine.
I am running the latest builds, although I haven't to date gotten this to work:
Python 2.7.3
Paramiko == 1.10.0
pycrypto == 2.6
fabric == 1.6.0
RHEL5.9
openssh-4.3p2-82.el5
My ~/.ssh/config looks like the following:
Host *.domain
ProxyCommand connect -S socksproxy.domain:1080 %h %p
And using the connect binary built from http://www.meadowy.org/~gotoh/ssh/connect.c
I haven't got access to github from the Company network so I will ask there when I get a chance as well.
Has anyone got any ideas why this could be occuring?
Thanks
Matt
I use connect rather than fabric but the answer is surely the same. There is an explination in connect.c that the SOCKS5_PASSWORD, HTTP_PROXY_PASSWORD, and CONNECT_PASSWORD do what you want. I've a script called ssh-tbb that goes as follows.
#!/bin/bash
export CONNECT_PASSWORD=""
exec ssh -o ProxyCommand="connect -5 -S 127.0.0.1:9150 %h %p" $*
Ideally, one should call this script ssh-tor and detect if tor lives on port 9050 or 9150 of course.
How do I bind cmd.exe onto a port in Python? I want to do the same thing as
Netcats "-e" argument. So the equivilent in Netcat would be:
netcat -l -p 8080 -e cmd.exe
But I want to code it myself in Python, without using Netcat. So how is this
done? Are there any functions/modules that can do this? How can I convert the process (cmd.exe) and make it a server so it runs on a port?
Listen to a port
Read the input
Pipe it to cmd.exe
Send back the output
Something along the lines of this, except you would have to change it into running on Windows (this example runs fine on Linux):
#!/usr/bin/env python
import socket
import subprocess
s = socket.socket(socket.AF_INET)
s.setsockopt(socket.IPPROTO_IP, socket.SO_REUSEADDR, 1)
s.bind(("", 9999))
s.listen(1)
(conn, address) = s.accept()
p = subprocess.Popen(["/bin/bash"],
stdin=conn, stdout=conn, stderr=conn)
If you run this program, and then in another terminal use netcat to connect to port 9999, you'll have a bash shell to play with. Be careful not to let the whole internet get access to this port, that would give anyone instant shell access on your machine :-)