Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

executer une function pickle en remote a travers un server TCP

+2 votes

le server a l'air de bien se lancer quand je lance par paramiko, mais je n'arrive pas a #me connecter au socket. :/

Attention, j'en ai fait un packet pour plus de commodités pour l'execution en remote.

import socket
import threading
import SocketServer
import dill 
import psutil
import os
import sys
from  importlib import import_module
import paramiko
import time
import random
import hashlib
import ssl
from Crypto.Cipher import AES
import base64
import os
import time

def start_remotely(HOST,USER,PASSWORD, PORT):
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(HOST, 22, username=USER, password=PASSWORD)
        client.invoke_shell()
        cmd = """python -c 'from remotefunction.remotefunction import start_server;start_server("%s", %s)' """ % (HOST, PORT,)  
        print cmd
        stdin, stdout, stderr = client.exec_command(cmd)
        print stderr.readlines(),stdout.readlines()

def encryption():
    BLOCK_SIZE = 32
    PADDING = '{'
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
    EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
    secret = os.urandom(BLOCK_SIZE)
    cipher = AES.new(secret)
    encoded = EncodeAES(cipher, 'password') 
    print 'Encrypted string:', encoded
    decoded = DecodeAES(cipher, encoded)
    print 'Decrypted string:', decoded


def start_server(HOST, PORT):
        print HOST, PORT
        server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) 
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.daemon = True
        server_thread.start()


def remotely(HOST):
    def decorate(func):         
        def wrapper(*args, **kwds):             
            PORT = random.randrange(10000, 20000)
            #threads = []
            #t = threading.Thread(target=start_remotely, args=('localhost',"xxxxxx","xxxxx", PORT))
            #threads.append(t)
            #t.daemon = True
            #t.start()   
            start_server(HOST, PORT)
            time.sleep(2)
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((HOST, PORT))
            modules_list = sys.modules.keys()
            # i dont know why sys.modules.keys give psutils.sys, i remove this 
            modules_list = [i for i in modules_list if i.count('.') == 0]
            h = hashlib.sha1()
            h.update(dill.dumps(func))
            hexdigestkey = h.hexdigest()
            lis = [func, modules_list, args, kwds, hexdigestkey]                
            lis = dill.dumps(lis)
            sock.sendall(lis)   
            response = sock.recv(4096)             
            response = dill.loads(response)
            return response
        return wrapper
    return decorate

def remoteTest(HOST, PORT, *args, **kwds):
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((HOST, PORT))
            modules_list = sys.modules.keys()
            modules_list = [i for i in modules_list if i.count('.') == 0]
            h = hashlib.sha1()

            def func():
                 vale = os.listdir('.')
                 return vale
            h.update(dill.dumps(func))
            hexdigestkey = h.hexdigest()
            lis = [func, modules_list, args,kwds, hexdigestkey]                
            lis = dill.dumps(lis)
            sock.sendall(lis)   
            response = sock.recv(4096)             
            response = dill.loads(response)
            return response 

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(4096)
        cur_thread = threading.current_thread()
        response = "{}: {}".format(cur_thread.name, data)
        rec = dill.loads(data)
        modulesNames = rec[1]
        for mod_name in modulesNames:
            globals()[mod_name] = import_module(mod_name)
        h = hashlib.sha1()
        h.update(dill.dumps(rec[0]))
        hexdigestkey = h.hexdigest() 
        print "received"
        if hexdigestkey != rec[4]:
         sys.exit(1)
        res = rec[0](*rec[2], **rec[3])
        res_pack = dill.dumps(res) 
        self.request.sendall(res_pack)


class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass


@remotely('localhost')
def toto():
    ret = os.listdir(".")
    return ret

if __name__ == "__main__":
    PORT = random.randrange(10000, 20000)
    #start_server('localhost', PORT)
    #avec start_server ça fonctionne nickel, mais en remote .... ça ne tourne pas, j'ai tout essayé 
    #serveur lancé en remote
    start_remotely('localhost','loic','xxxxxx', PORT)
    #connection au socket et envoie d'une fonction au serveur
    print remoteTest('localhost', PORT)
demandé 4-Jul-2015 par Hackolite (292 points)
edité 5-Jul-2015 par Hackolite

J'ai édité ta question pour formater ton code, du coup j'ai réouvert ta question, t'en penses quoi maintenant? C'est plus propre non?

Encore faut-il savoir qu'entendais tu par

impossible de formater mon code

Bref, je pense que ta question est plus propre maintenant.

merci boblinux, j'ai perdu patience, les quotes ne formataient pas mon code.;)

1 Réponse

+1 vote
 
Meilleure réponse

J' ai supprimé le multithreading dans start_server(), et remplacé par un server.serve_forever().
La raison principale pour laquelle ça ne tournait pas est que mon décorateur en manipulant la fonction , ne renvoyait pas les globals de la function, qu'on peut récupérer par un print func.__globals__.

import socket
import threading
import SocketServer
import dill 
import psutil
import sys
from  importlib import import_module
import paramiko
import time
import random
import hashlib
import ssl
from Crypto.Cipher import AES
import base64
import os
import time
from  importlib import import_module


def start_remote(HOST,USER,PASSWORD, PORT):
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(HOST, 22, username=USER, password=PASSWORD)
        cmd = """python -c 'from remote.remote import start_server;start_server("%s", %s)' """ % (HOST, PORT,)
        print cmd
        stdin, stdout, stderr = client.exec_command(cmd)
        print stderr.readlines(),stdout.readlines()

def encryption():
    BLOCK_SIZE = 32
    PADDING = '{'
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
    EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
    secret = os.urandom(BLOCK_SIZE)
    cipher = AES.new(secret)
    encoded = EncodeAES(cipher, 'password') 
    print 'Encrypted string:', encoded
    decoded = DecodeAES(cipher, encoded)
    print 'Decrypted string:', decoded


def start_server(HOST, PORT):
        print HOST, PORT
        server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) 
        server.serve_forever()
        #server_thread = threading.Thread(target=server.serve_forever)
        #server_thread.daemon = True
        #server_thread.start()


def remoteFunction(HOST, USER,PASSWORD):
    def decorate(func):         
        def wrapper(*args, **kwds):
            PORT = random.randrange(10000, 20000)
            threads = []
            t = threading.Thread(target=start_remote, args=(HOST,USER,PASSWORD,PORT))
            threads.append(t)
            t.daemon = True
            t.start()
            time.sleep(0.9)
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((HOST, PORT))
            modules_list = sys.modules.keys()
            # i dont know why sys.modules.keys give psutils.sys, i remove this
            modules_list = [i for i in modules_list if i.count('.') == 0]
            print 'module list', modules_list
            h = hashlib.sha1()
            pickledfunc = dill.dumps(func)
            h.update(pickledfunc)
            hexdigestkey = h.hexdigest()
            lis = [pickledfunc, modules_list, args, kwds, hexdigestkey]
            lis = dill.dumps(lis)
            sock.sendall(lis)   
            response = sock.recv(4096)             
            response = dill.loads(response)
            sock.close()
            print response
        return wrapper
    return decorate


class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(4096)
        cur_thread = threading.current_thread()
        response = "{}: {}".format(cur_thread.name, data)
        rec = dill.loads(data)
        modulesNames = rec[1]
        h = hashlib.sha1()
        h.update(rec[0])
        hexdigestkey = h.hexdigest() 
        print rec[4],hexdigestkey
        if hexdigestkey != rec[4]:
            sys.exit(1)
        remfunc = dill.loads(rec[0])
        for mod_name in modulesNames:
            remfunc.__globals__[mod_name] = import_module(mod_name)
        res = remfunc(*rec[2], **rec[3])
        res_pack = dill.dumps(res)
        self.request.sendall(res_pack)

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
            pass


@remoteFunction('localhost', 'user', 'password')
def toto(path):
        ret = os.listdir(path)
        return ret


toto('.')
répondu 7-Jul-2015 par Hackolite (292 points)
sélectionné 7-Jul-2015 par Hackolite

les underscores sont supprimés. :/
CF: attention quand vous executez ce code, vérifié que vous avez bien killé le process à la fin. c'est une backdoor.

Pour les underscores, il faut soit que tu les escape avec un backslash (\), soit que tu mette tes bouts de code entre des backquotes (`)

\_code_ -> _code_

`_code_` -> _code_

Je me suis permis d’éditer ta réponse.

Au passage, je me rend compte que le plugin fait un peu nimp entre la preview et le résultat effectif :/

...